From 801008a0d6e94088c214bbfa3d87df732c5878db Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Mon, 27 Apr 2020 08:07:56 +0200 Subject: [PATCH 01/35] [MIG][pos_payment_change] from 8.0 to 12.0 - Black python code - OCA Convention - Add tests - add configuration on pos.config, with two option 'refund' or 'update' - The 'refund' option makes the module compatible with (French) certification - make the module compatible with pos_order_return --- pos_payment_change/README.rst | 8 + pos_payment_change/__init__.py | 2 + pos_payment_change/__manifest__.py | 20 ++ pos_payment_change/i18n/fr.po | 183 ++++++++++++++++++ pos_payment_change/models/__init__.py | 2 + pos_payment_change/models/pos_config.py | 46 +++++ pos_payment_change/models/pos_order.py | 82 ++++++++ pos_payment_change/readme/CONFIGURE.rst | 23 +++ pos_payment_change/readme/CONTRIBUTORS.rst | 2 + pos_payment_change/readme/CREDITS.rst | 4 + pos_payment_change/readme/DESCRIPTION.rst | 6 + pos_payment_change/readme/USAGE.rst | 19 ++ .../static/description/pos_config_form.png | Bin 0 -> 34601 bytes .../static/description/pos_order_form.png | Bin 0 -> 13944 bytes .../static/description/pos_order_tree.png | Bin 0 -> 32269 bytes .../pos_payment_change_wizard_form.png | Bin 0 -> 25111 bytes pos_payment_change/tests/__init__.py | 1 + pos_payment_change/tests/test_module.py | 172 ++++++++++++++++ pos_payment_change/views/view_pos_config.xml | 29 +++ pos_payment_change/views/view_pos_order.xml | 21 ++ pos_payment_change/wizards/__init__.py | 2 + .../wizards/pos_payment_change_wizard.py | 77 ++++++++ .../wizards/pos_payment_change_wizard_line.py | 46 +++++ .../view_pos_payment_change_wizard.xml | 43 ++++ 24 files changed, 788 insertions(+) create mode 100644 pos_payment_change/README.rst create mode 100644 pos_payment_change/__init__.py create mode 100644 pos_payment_change/__manifest__.py create mode 100644 pos_payment_change/i18n/fr.po create mode 100644 pos_payment_change/models/__init__.py create mode 100644 pos_payment_change/models/pos_config.py create mode 100644 pos_payment_change/models/pos_order.py create mode 100644 pos_payment_change/readme/CONFIGURE.rst create mode 100644 pos_payment_change/readme/CONTRIBUTORS.rst create mode 100644 pos_payment_change/readme/CREDITS.rst create mode 100644 pos_payment_change/readme/DESCRIPTION.rst create mode 100644 pos_payment_change/readme/USAGE.rst create mode 100644 pos_payment_change/static/description/pos_config_form.png create mode 100644 pos_payment_change/static/description/pos_order_form.png create mode 100644 pos_payment_change/static/description/pos_order_tree.png create mode 100644 pos_payment_change/static/description/pos_payment_change_wizard_form.png create mode 100644 pos_payment_change/tests/__init__.py create mode 100644 pos_payment_change/tests/test_module.py create mode 100644 pos_payment_change/views/view_pos_config.xml create mode 100644 pos_payment_change/views/view_pos_order.xml create mode 100644 pos_payment_change/wizards/__init__.py create mode 100644 pos_payment_change/wizards/pos_payment_change_wizard.py create mode 100644 pos_payment_change/wizards/pos_payment_change_wizard_line.py create mode 100644 pos_payment_change/wizards/view_pos_payment_change_wizard.xml diff --git a/pos_payment_change/README.rst b/pos_payment_change/README.rst new file mode 100644 index 0000000000..5cba6561d7 --- /dev/null +++ b/pos_payment_change/README.rst @@ -0,0 +1,8 @@ +============================== +Point Of Sale - Change Payment +============================== + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! diff --git a/pos_payment_change/__init__.py b/pos_payment_change/__init__.py new file mode 100644 index 0000000000..aee8895e7a --- /dev/null +++ b/pos_payment_change/__init__.py @@ -0,0 +1,2 @@ +from . import models +from . import wizards diff --git a/pos_payment_change/__manifest__.py b/pos_payment_change/__manifest__.py new file mode 100644 index 0000000000..a3bfd8b18c --- /dev/null +++ b/pos_payment_change/__manifest__.py @@ -0,0 +1,20 @@ +# Copyright (C) 2013 - Today: GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +{ + "name": "Point Of Sale - Change Payment", + "version": "12.0.1.0.0", + "category": "Point Of Sale", + "author": "GRAP, Odoo Community Association (OCA)", + "website": "https://www.github.com/OCA/pos", + "license": "AGPL-3", + "depends": ["point_of_sale"], + "maintainers": ["legalsylvain"], + "development_status": "Beta", + "data": [ + "wizards/view_pos_payment_change_wizard.xml", + "views/view_pos_config.xml", + "views/view_pos_order.xml", + ], + "installable": True, +} diff --git a/pos_payment_change/i18n/fr.po b/pos_payment_change/i18n/fr.po new file mode 100644 index 0000000000..8dbda29dab --- /dev/null +++ b/pos_payment_change/i18n/fr.po @@ -0,0 +1,183 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * pos_payment_change +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-04-21 02:33+0000\n" +"PO-Revision-Date: 2020-04-21 02:33+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: pos_payment_change +#: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_config_form +msgid "Payment Change Policy" +msgstr "Méthode de changement de paiement" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__amount +msgid "Amount" +msgstr "Montant" + +#. module: pos_payment_change +#: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_payment_change_wizard_form +msgid "Cancel" +msgstr "Annuler" + +#. module: pos_payment_change +#: model:ir.actions.act_window,name:pos_payment_change.action_pos_payment_change_wizard +#: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_order_form +#: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_payment_change_wizard_form +msgid "Change Payments" +msgstr "Changer les paiements" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__create_uid +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__create_uid +msgid "Created by" +msgstr "Créé par" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__create_date +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__create_date +msgid "Created on" +msgstr "Créé le" + +#. module: pos_payment_change +#: code:addons/pos_payment_change/wizards/pos_payment_change_wizard.py:54 +#, python-format +msgid "Differences between the two values for the POS Order '%s':\n" +"\n" +" * Total of all the new payments %s;\n" +" * Total of the POS Order %s;\n" +"\n" +"Please change the payments." +msgstr "Différences entre les deux valeurs pour la vente '%s':\n" +"\n" +" * Total des nouveaux paiements %s;\n" +" * Total de la vente %s;\n" +"\n" +"Veuillez changer les paiements." + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__display_name +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__display_name +msgid "Display Name" +msgstr "Nom affiché" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__id +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__id +msgid "ID" +msgstr "ID" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__new_journal_id +msgid "Journal" +msgstr "Journal" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard____last_update +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line____last_update +msgid "Last Modified on" +msgstr "Dernière modification le" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__write_uid +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__write_uid +msgid "Last Updated by" +msgstr "Dernière mise à jour par" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__write_date +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__write_date +msgid "Last Updated on" +msgstr "Dernière mise à jour le" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__order_id +msgid "Order" +msgstr "Commande" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_config__payment_change_policy +msgid "Payment Change Policy" +msgstr "Méthode de changement de paiement" + +#. module: pos_payment_change +#: model:ir.model.fields,help:pos_payment_change.field_pos_config__payment_change_policy +msgid "Payment Change Policy when users want to change the payment lines of a given PoS Order.\n" +"* 'Refund and Resale': Odoo will refund the current Pos Order to cancel it, and create a new PoS Order with the correct payment lines.\n" +"* 'Update Payments': Odoo will change payment lines.\n" +"\n" +"Note : In some countries the 'Update Payments' Option is not allowed by law, because orders history shouldn't not be altered." +msgstr "Méthode de changement de paiement quand les utilisateurs veulent changer des lignes de paiement d'une vente en caisse.\n" +"* 'Retourner et revendre': Odoo va réaliser un retour du la vente pour l'annuler, puis recréera une nouvelle vente, avec les paiements corrects.\n" +"* 'Modifier les paiements': Odoo va changer les lignes de paiements.\n" +"\n" +"Note : dans certains pays, l'option 'Modifier les paiements' n'est pas autorisé par la loi, parce que l'historique des ventes ne doit pas être altéré." + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__line_ids +#: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_payment_change_wizard_form +msgid "Payment Lines" +msgstr "Lignes de paiement" + +#. module: pos_payment_change +#: model:ir.model,name:pos_payment_change.model_pos_payment_change_wizard +msgid "PoS Payment Change Wizard" +msgstr "Assistant de changement de paiement du Point de Vente" + +#. module: pos_payment_change +#: model:ir.model,name:pos_payment_change.model_pos_payment_change_wizard_line +msgid "PoS Payment Change Wizard Line" +msgstr "Ligne d'assistant de changement de paiement du Point de Vente" + +#. module: pos_payment_change +#: model:ir.model,name:pos_payment_change.model_pos_config +msgid "Point of Sale Configuration" +msgstr "Paramétrage du point de vente" + +#. module: pos_payment_change +#: model:ir.model,name:pos_payment_change.model_pos_order +msgid "Point of Sale Orders" +msgstr "Commandes du point de vente" + +#. module: pos_payment_change +#: selection:pos.config,payment_change_policy:0 +msgid "Refund and Resale" +msgstr "Retourner et revendre" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__amount_total +#: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_payment_change_wizard_form +msgid "Total" +msgstr "Total" + +#. module: pos_payment_change +#: code:addons/pos_payment_change/models/pos_config.py:43 +#, python-format +msgid "Unable to use the 'Update Payments' options for companies that have unalterable accounting." +msgstr "Impossible d'utiliser l'option 'Modifier les paiements' pour les sociétés qui ont une comptabilité inaltérable." + +#. module: pos_payment_change +#: selection:pos.config,payment_change_policy:0 +msgid "Update Payments" +msgstr "Modifier les paiements" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__wizard_id +msgid "Wizard" +msgstr "Assistant" + +#. module: pos_payment_change +#: code:addons/pos_payment_change/models/pos_order.py:80 +#, python-format +msgid "You can not change payments of the POS '%s' because the associated session '%s' has been closed!" +msgstr "Vous ne pouvez pas changer les paiements de la Vente '%s' car la session associée '%s' a été clôturé !" diff --git a/pos_payment_change/models/__init__.py b/pos_payment_change/models/__init__.py new file mode 100644 index 0000000000..234b311eae --- /dev/null +++ b/pos_payment_change/models/__init__.py @@ -0,0 +1,2 @@ +from . import pos_config +from . import pos_order diff --git a/pos_payment_change/models/pos_config.py b/pos_payment_change/models/pos_config.py new file mode 100644 index 0000000000..199791e10e --- /dev/null +++ b/pos_payment_change/models/pos_config.py @@ -0,0 +1,46 @@ +# Copyright (C) 2020 - Today: GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError + + +class PosConfig(models.Model): + _inherit = "pos.config" + + _PAYMENT_CHANGE_POLICY_SELECTION = [ + ('refund', "Refund and Resale"), + ('update', "Update Payments"), + ] + + payment_change_policy = fields.Selection( + selection=_PAYMENT_CHANGE_POLICY_SELECTION, + default="refund", required=True, + help="Payment Change Policy when users want" + " to change the payment lines of a given PoS Order.\n" + "* 'Refund and Resale': Odoo will refund the current" + " Pos Order to cancel it, and create a new PoS Order" + " with the correct payment lines.\n" + "* 'Update Payments': Odoo will change payment lines.\n\n" + "Note : In some countries the 'Update Payments' Option" + " is not allowed by law, because orders history shouldn't" + " not be altered.") + + @api.constrains("payment_change_policy") + def _check_payment_change_policy(self): + # Check if certification module is installed + # and if yes, if 'update payments' option is allowed + module_states = self.env["ir.module.module"].search([ + ("name", "=", "l10n_fr_certification")] + ).mapped("state") + if "installed" not in module_states: + return + for config in self.filtered( + lambda x: x.payment_change_policy == "update" + ): + if config.company_id._is_accounting_unalterable(): + raise ValidationError(_( + "Unable to use the 'Update Payments' options" + " for companies that have unalterable accounting." + )) diff --git a/pos_payment_change/models/pos_order.py b/pos_payment_change/models/pos_order.py new file mode 100644 index 0000000000..5589d1df30 --- /dev/null +++ b/pos_payment_change/models/pos_order.py @@ -0,0 +1,82 @@ +# Copyright (C) 2015 - Today: GRAP (http://www.grap.coop) +# @author: Julien WESTE +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import _, api, fields, models +from odoo.tools import float_is_zero +from odoo.exceptions import Warning as UserError + + +class PosOrder(models.Model): + _inherit = "pos.order" + + @api.multi + def change_payment(self, payment_lines): + """ + Change payment of a given order. + payment_lines should be a list of data that are + the argument of the Odoo Core function add_payment() + Return a list of order ids, depending on the + payment_change_policy of the related pos_config. + """ + self.ensure_one() + order_ids = [self.id] + + # Removing zero lines + precision = self.pricelist_id.currency_id.decimal_places + payment_lines = [ + x for x in payment_lines if not float_is_zero( + x["amount"], precision_digits=precision) + ] + + self._check_payment_change_allowed() + + if self.config_id.payment_change_policy == "update": + self.statement_ids.with_context().unlink() + + # Create new payment + for line in payment_lines: + self.add_payment(line) + + elif self.config_id.payment_change_policy == "refund": + # Refund order and mark it as paid + # with same payment method as the original one + refund_result = self.refund() + refund_order = self.browse(refund_result["res_id"]) + + for statement in self.statement_ids: + refund_order.add_payment({ + "journal": statement.journal_id.id, + "amount": - statement.amount, + "payment_date": fields.Date.context_today(self), + }) + refund_order.action_pos_order_paid() + + # Resale order and mark it as paid + # with the new payment + resale_order = self.copy() + + for line in payment_lines: + resale_order.add_payment(line) + resale_order.action_pos_order_paid() + + order_ids += [refund_order.id, resale_order.id] + return order_ids + + @api.multi + def _check_payment_change_allowed(self): + """Return True if the user can change the payment of a POS, depending + of the state of the current session.""" + closed_orders = self.filtered(lambda x: x.session_id.state == "closed") + if len(closed_orders): + raise UserError( + _( + "You can not change payments of the POS '%s' because" + " the associated session '%s' has been closed!" + % ( + ", ".join(closed_orders.mapped("name")), + ", ".join(closed_orders.mapped("session_id.name")), + ) + ) + ) diff --git a/pos_payment_change/readme/CONFIGURE.rst b/pos_payment_change/readme/CONFIGURE.rst new file mode 100644 index 0000000000..fd1eba8dbb --- /dev/null +++ b/pos_payment_change/readme/CONFIGURE.rst @@ -0,0 +1,23 @@ +* Go to Point of Sale > Configuration > Point of Sale +* Edit your point of sale, and select a value for the field + 'Payment Change Policy'. + +Two options are available: + +* 'Refund and Resale': Odoo will refund the current + Pos Order to cancel it, and create a new PoS Order + with the correct payment lines + +* 'Update Payments': Odoo will change payment lines. + +.. figure:: ../static/description/pos_config_form.png + + +**Note** +In some countries the 'Update Payments' Option +is not allowed by law, because orders history shouldn't not be altered. + +For that purpose, a constrains is present to check the value of this +field. If the module ``l10n_fr_certification`` is installed and if the +current company has an inalterable accounting, it will not be possible +to select the value 'Update Payments'. diff --git a/pos_payment_change/readme/CONTRIBUTORS.rst b/pos_payment_change/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000000..7754037b21 --- /dev/null +++ b/pos_payment_change/readme/CONTRIBUTORS.rst @@ -0,0 +1,2 @@ +* Sylvain LE GAL +* Julien WESTE diff --git a/pos_payment_change/readme/CREDITS.rst b/pos_payment_change/readme/CREDITS.rst new file mode 100644 index 0000000000..4832a8457f --- /dev/null +++ b/pos_payment_change/readme/CREDITS.rst @@ -0,0 +1,4 @@ +The development of this module has been financially supported by: + +* GRAP, Groupement Régional Alimentaire de proximité (www.grap.coop) +* Vracoop (www.vracoop.fr) diff --git a/pos_payment_change/readme/DESCRIPTION.rst b/pos_payment_change/readme/DESCRIPTION.rst new file mode 100644 index 0000000000..f725ca719c --- /dev/null +++ b/pos_payment_change/readme/DESCRIPTION.rst @@ -0,0 +1,6 @@ +This module extends the functionnality of the Odoo Point of Sale to +allow the cashier to change the payments of a PoS order. + +This feature is usefull when the user realized that he did a mistake, +just after he marked the order as paid, or during the close of the session, +Only if entries has not been generated. diff --git a/pos_payment_change/readme/USAGE.rst b/pos_payment_change/readme/USAGE.rst new file mode 100644 index 0000000000..604022c883 --- /dev/null +++ b/pos_payment_change/readme/USAGE.rst @@ -0,0 +1,19 @@ +* Go to a PoS Order + +* Click on the button 'Change Payments' + +.. figure:: ../static/description/pos_order_form.png + +* In the pop up wizard, select the real payment(s) that have been + used to pay the order + +.. figure:: ../static/description/pos_payment_change_wizard_form.png + +* Then click on the button 'Change Payments' + +**Note** + +If the option 'Refund and Resale' is selected, changing the payments will +display the three PoS orders. the oringal one, the refund one, and the new one. + +.. figure:: ../static/description/pos_order_tree.png diff --git a/pos_payment_change/static/description/pos_config_form.png b/pos_payment_change/static/description/pos_config_form.png new file mode 100644 index 0000000000000000000000000000000000000000..d47d0de851483d0660e90817142c3e14f29b127b GIT binary patch literal 34601 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∨4d(XrZA-MhbITiP5ull8rfuOcppc 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 literal 0 HcmV?d00001 diff --git a/pos_payment_change/static/description/pos_payment_change_wizard_form.png b/pos_payment_change/static/description/pos_payment_change_wizard_form.png new file mode 100644 index 0000000000000000000000000000000000000000..19d86e9ddfcedcf0e1399f9670366f9867038571 GIT binary patch literal 25111 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 + + + + + + pos.config + + + +
+
+ Payment Change Policy +
+ +
+
+
+
+
+
+ +
diff --git a/pos_payment_change/views/view_pos_order.xml b/pos_payment_change/views/view_pos_order.xml new file mode 100644 index 0000000000..701ec7888e --- /dev/null +++ b/pos_payment_change/views/view_pos_order.xml @@ -0,0 +1,21 @@ + + + + + + + pos.order + + + + + + diff --git a/pos_payment_change/wizards/__init__.py b/pos_payment_change/wizards/__init__.py new file mode 100644 index 0000000000..87ea5667bc --- /dev/null +++ b/pos_payment_change/wizards/__init__.py @@ -0,0 +1,2 @@ +from . import pos_payment_change_wizard +from . import pos_payment_change_wizard_line diff --git a/pos_payment_change/wizards/pos_payment_change_wizard.py b/pos_payment_change/wizards/pos_payment_change_wizard.py new file mode 100644 index 0000000000..f0294b9e26 --- /dev/null +++ b/pos_payment_change/wizards/pos_payment_change_wizard.py @@ -0,0 +1,77 @@ +# Copyright (C) 2015-Today GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import _, api, fields, models +from odoo.exceptions import Warning as UserError + + +class PosPaymentChangeWizard(models.TransientModel): + _name = "pos.payment.change.wizard" + _description = "PoS Payment Change Wizard" + + # Column Section + order_id = fields.Many2one( + comodel_name="pos.order", string="Order", readonly=True + ) + + line_ids = fields.One2many( + comodel_name="pos.payment.change.wizard.line", + inverse_name="wizard_id", + string="Payment Lines", + ) + + amount_total = fields.Float(string="Total", readonly=True) + + # View Section + @api.model + def default_get(self, fields): + PosOrder = self.env["pos.order"] + res = super().default_get(fields) + order = PosOrder.browse(self._context.get("active_id")) + res.update({"order_id": order.id}) + res.update({"amount_total": order.amount_total}) + return res + + # View section + @api.multi + def button_change_payment(self): + self.ensure_one() + order = self.order_id + + # Check if the total is correct + total = 0 + for line in self.line_ids: + total += line.amount + if total != self.amount_total: + raise UserError( + _( + "Differences between the two values for the POS" + " Order '%s':\n\n" + " * Total of all the new payments %s;\n" + " * Total of the POS Order %s;\n\n" + "Please change the payments." + % (order.name, total, order.amount_total) + ) + ) + + # Change payment + new_payments = [{ + "journal": line.new_journal_id.id, + "amount": line.amount, + "payment_date": fields.Date.context_today(self), + } for line in self.line_ids] + + order_ids = order.change_payment(new_payments) + + if len(order_ids) == 1: + # if policy is 'update', only close the pop up + action = {'type': 'ir.actions.act_window_close'} + else: + # otherwise (refund policy), displays the 3 orders + action = self.env.ref( + "point_of_sale.action_pos_pos_form" + ).read()[0] + action['domain'] = [('id', 'in', order_ids)] + + return action diff --git a/pos_payment_change/wizards/pos_payment_change_wizard_line.py b/pos_payment_change/wizards/pos_payment_change_wizard_line.py new file mode 100644 index 0000000000..2db402b053 --- /dev/null +++ b/pos_payment_change/wizards/pos_payment_change_wizard_line.py @@ -0,0 +1,46 @@ +# Copyright (C) 2015 - Today: GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import api, fields, models + + +class PosPaymentChangeWizardLine(models.TransientModel): + _name = "pos.payment.change.wizard.line" + _description = "PoS Payment Change Wizard Line" + + wizard_id = fields.Many2one( + comodel_name="pos.payment.change.wizard", required=True, + ) + + new_journal_id = fields.Many2one( + comodel_name="account.journal", + string="Journal", + required=True, + domain=lambda s: s._domain_new_journal_id(), + ) + + amount = fields.Float(string="Amount", required=True) + + @api.model + def _domain_new_journal_id(self): + PosOrder = self.env["pos.order"] + order = PosOrder.browse(self.env.context.get("active_id")) + # return [("id", "in", order.session_id.journal_ids.ids)] + return [("id", "in", order.mapped( + "session_id.statement_ids.journal_id").ids)] + + # View Section + @api.model + def default_get(self, fields): + res = super().default_get(fields) + if "line_ids" not in self._context: + return res + balance = self._context.get("amount_total", 0.0) + for line in self.wizard_id.resolve_2many_commands( + "line_ids", + self._context["line_ids"], + fields=["amount"]): + balance -= line.get("amount") + res.update({'amount': balance}) + return res diff --git a/pos_payment_change/wizards/view_pos_payment_change_wizard.xml b/pos_payment_change/wizards/view_pos_payment_change_wizard.xml new file mode 100644 index 0000000000..3a3f9fd2e7 --- /dev/null +++ b/pos_payment_change/wizards/view_pos_payment_change_wizard.xml @@ -0,0 +1,43 @@ + + + + + + + pos.payment.change.wizard + +
+ + + + + + + + + + + +
+
+
+
+
+ + + Change Payments + pos.payment.change.wizard + form + form + new + + +
From 349300202b2809f7016ebcb1e116863426dc53ec Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Mon, 27 Apr 2020 12:50:19 +0200 Subject: [PATCH 02/35] [IMP] use refund() to resale order (in 'refund' mode) ; [ADD] a note on PoS Order(s) to know the history of the payments --- pos_payment_change/__manifest__.py | 4 +- pos_payment_change/i18n/fr.po | 18 +- .../i18n/pos_payment_change.pot | 187 ++++++++++++++++++ pos_payment_change/models/pos_order.py | 26 ++- .../wizards/pos_payment_change_wizard.py | 6 +- 5 files changed, 230 insertions(+), 11 deletions(-) create mode 100644 pos_payment_change/i18n/pos_payment_change.pot diff --git a/pos_payment_change/__manifest__.py b/pos_payment_change/__manifest__.py index a3bfd8b18c..a905910b31 100644 --- a/pos_payment_change/__manifest__.py +++ b/pos_payment_change/__manifest__.py @@ -2,8 +2,10 @@ # @author: Sylvain LE GAL (https://twitter.com/legalsylvain) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { - "name": "Point Of Sale - Change Payment", + "name": "Point Of Sale - Change Payments", "version": "12.0.1.0.0", + "summary": "Allow cashier to change order payments, as long as" + " the session is not closed", "category": "Point Of Sale", "author": "GRAP, Odoo Community Association (OCA)", "website": "https://www.github.com/OCA/pos", diff --git a/pos_payment_change/i18n/fr.po b/pos_payment_change/i18n/fr.po index 8dbda29dab..9e146502a6 100644 --- a/pos_payment_change/i18n/fr.po +++ b/pos_payment_change/i18n/fr.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 12.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-21 02:33+0000\n" -"PO-Revision-Date: 2020-04-21 02:33+0000\n" +"POT-Creation-Date: 2020-04-27 10:44+0000\n" +"PO-Revision-Date: 2020-04-27 10:44+0000\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -15,6 +15,12 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: \n" +#. module: pos_payment_change +#: code:addons/pos_payment_change/models/pos_order.py:78 +#, python-format +msgid " (Refund Order: %s ; Resale Order: %s)" +msgstr " (Remboursement: %s ; Revente : %s)" + #. module: pos_payment_change #: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_config_form msgid "Payment Change Policy" @@ -154,6 +160,12 @@ msgstr "Commandes du point de vente" msgid "Refund and Resale" msgstr "Retourner et revendre" +#. module: pos_payment_change +#: code:addons/pos_payment_change/models/pos_order.py:43 +#, python-format +msgid "The payments of the Order %s (Ref: %s) has been changed by %s at %s." +msgstr "Les paiements de la commande %s (Réf: %s) ont été changés par %s à %s." + #. module: pos_payment_change #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__amount_total #: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_payment_change_wizard_form @@ -177,7 +189,7 @@ msgid "Wizard" msgstr "Assistant" #. module: pos_payment_change -#: code:addons/pos_payment_change/models/pos_order.py:80 +#: code:addons/pos_payment_change/models/pos_order.py:96 #, python-format msgid "You can not change payments of the POS '%s' because the associated session '%s' has been closed!" msgstr "Vous ne pouvez pas changer les paiements de la Vente '%s' car la session associée '%s' a été clôturé !" diff --git a/pos_payment_change/i18n/pos_payment_change.pot b/pos_payment_change/i18n/pos_payment_change.pot new file mode 100644 index 0000000000..94eb4b4ca8 --- /dev/null +++ b/pos_payment_change/i18n/pos_payment_change.pot @@ -0,0 +1,187 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * pos_payment_change +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-04-27 10:48+0000\n" +"PO-Revision-Date: 2020-04-27 10:48+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: pos_payment_change +#: code:addons/pos_payment_change/models/pos_order.py:78 +#, python-format +msgid " (Refund Order: %s ; Resale Order: %s)" +msgstr "" + +#. module: pos_payment_change +#: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_config_form +msgid "Payment Change Policy" +msgstr "" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__amount +msgid "Amount" +msgstr "" + +#. module: pos_payment_change +#: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_payment_change_wizard_form +msgid "Cancel" +msgstr "" + +#. module: pos_payment_change +#: model:ir.actions.act_window,name:pos_payment_change.action_pos_payment_change_wizard +#: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_order_form +#: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_payment_change_wizard_form +msgid "Change Payments" +msgstr "" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__create_uid +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__create_uid +msgid "Created by" +msgstr "" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__create_date +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__create_date +msgid "Created on" +msgstr "" + +#. module: pos_payment_change +#: code:addons/pos_payment_change/wizards/pos_payment_change_wizard.py:54 +#, python-format +msgid "Differences between the two values for the POS Order '%s':\n" +"\n" +" * Total of all the new payments %s;\n" +" * Total of the POS Order %s;\n" +"\n" +"Please change the payments." +msgstr "" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__display_name +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__display_name +msgid "Display Name" +msgstr "" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__id +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__id +msgid "ID" +msgstr "" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__new_journal_id +msgid "Journal" +msgstr "" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard____last_update +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line____last_update +msgid "Last Modified on" +msgstr "" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__write_uid +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__write_date +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__write_date +msgid "Last Updated on" +msgstr "" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__order_id +msgid "Order" +msgstr "" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_config__payment_change_policy +msgid "Payment Change Policy" +msgstr "" + +#. module: pos_payment_change +#: model:ir.model.fields,help:pos_payment_change.field_pos_config__payment_change_policy +msgid "Payment Change Policy when users want to change the payment lines of a given PoS Order.\n" +"* 'Refund and Resale': Odoo will refund the current Pos Order to cancel it, and create a new PoS Order with the correct payment lines.\n" +"* 'Update Payments': Odoo will change payment lines.\n" +"\n" +"Note : In some countries the 'Update Payments' Option is not allowed by law, because orders history shouldn't not be altered." +msgstr "" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__line_ids +#: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_payment_change_wizard_form +msgid "Payment Lines" +msgstr "" + +#. module: pos_payment_change +#: model:ir.model,name:pos_payment_change.model_pos_payment_change_wizard +msgid "PoS Payment Change Wizard" +msgstr "" + +#. module: pos_payment_change +#: model:ir.model,name:pos_payment_change.model_pos_payment_change_wizard_line +msgid "PoS Payment Change Wizard Line" +msgstr "" + +#. module: pos_payment_change +#: model:ir.model,name:pos_payment_change.model_pos_config +msgid "Point of Sale Configuration" +msgstr "" + +#. module: pos_payment_change +#: model:ir.model,name:pos_payment_change.model_pos_order +msgid "Point of Sale Orders" +msgstr "" + +#. module: pos_payment_change +#: selection:pos.config,payment_change_policy:0 +msgid "Refund and Resale" +msgstr "" + +#. module: pos_payment_change +#: code:addons/pos_payment_change/models/pos_order.py:43 +#, python-format +msgid "The payments of the Order %s (Ref: %s) has been changed by %s at %s." +msgstr "" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__amount_total +#: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_payment_change_wizard_form +msgid "Total" +msgstr "" + +#. module: pos_payment_change +#: code:addons/pos_payment_change/models/pos_config.py:43 +#, python-format +msgid "Unable to use the 'Update Payments' options for companies that have unalterable accounting." +msgstr "" + +#. module: pos_payment_change +#: selection:pos.config,payment_change_policy:0 +msgid "Update Payments" +msgstr "" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__wizard_id +msgid "Wizard" +msgstr "" + +#. module: pos_payment_change +#: code:addons/pos_payment_change/models/pos_order.py:96 +#, python-format +msgid "You can not change payments of the POS '%s' because the associated session '%s' has been closed!" +msgstr "" + diff --git a/pos_payment_change/models/pos_order.py b/pos_payment_change/models/pos_order.py index 5589d1df30..a0796a29fe 100644 --- a/pos_payment_change/models/pos_order.py +++ b/pos_payment_change/models/pos_order.py @@ -3,6 +3,8 @@ # @author: Sylvain LE GAL (https://twitter.com/legalsylvain) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from datetime import datetime + from odoo import _, api, fields, models from odoo.tools import float_is_zero from odoo.exceptions import Warning as UserError @@ -21,7 +23,7 @@ def change_payment(self, payment_lines): payment_change_policy of the related pos_config. """ self.ensure_one() - order_ids = [self.id] + orders = self # Removing zero lines precision = self.pricelist_id.currency_id.decimal_places @@ -32,6 +34,16 @@ def change_payment(self, payment_lines): self._check_payment_change_allowed() + comment = _( + "The payments of the Order %s (Ref: %s) has been changed" + " by %s at %s." % ( + self.name, + self.pos_reference, + self.env.user.name, + datetime.today(), + ) + ) + if self.config_id.payment_change_policy == "update": self.statement_ids.with_context().unlink() @@ -55,14 +67,20 @@ def change_payment(self, payment_lines): # Resale order and mark it as paid # with the new payment - resale_order = self.copy() + resale_order = self.copy( + default={"pos_reference": self.pos_reference} + ) for line in payment_lines: resale_order.add_payment(line) resale_order.action_pos_order_paid() - order_ids += [refund_order.id, resale_order.id] - return order_ids + orders += refund_order + resale_order + comment += _(" (Refund Order: %s ; Resale Order: %s)" % ( + refund_order.name, resale_order.name)) + for order in orders: + order.note = "%s\n%s" % (order.note or "", comment) + return orders @api.multi def _check_payment_change_allowed(self): diff --git a/pos_payment_change/wizards/pos_payment_change_wizard.py b/pos_payment_change/wizards/pos_payment_change_wizard.py index f0294b9e26..54f8e6d3ec 100644 --- a/pos_payment_change/wizards/pos_payment_change_wizard.py +++ b/pos_payment_change/wizards/pos_payment_change_wizard.py @@ -62,9 +62,9 @@ def button_change_payment(self): "payment_date": fields.Date.context_today(self), } for line in self.line_ids] - order_ids = order.change_payment(new_payments) + orders = order.change_payment(new_payments) - if len(order_ids) == 1: + if len(orders) == 1: # if policy is 'update', only close the pop up action = {'type': 'ir.actions.act_window_close'} else: @@ -72,6 +72,6 @@ def button_change_payment(self): action = self.env.ref( "point_of_sale.action_pos_pos_form" ).read()[0] - action['domain'] = [('id', 'in', order_ids)] + action['domain'] = [('id', 'in', orders.ids)] return action From 87c9b7be4313909002aa05b2ff5d5d3a86ab1eae Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Mon, 18 May 2020 19:32:28 +0200 Subject: [PATCH 03/35] [FIX] error in balance computation if change is done during closing control ; [ADD] display old payment lines --- pos_payment_change/i18n/fr.po | 68 +++++++++++------- .../i18n/pos_payment_change.pot | 63 ++++++++++------ .../pos_payment_change_wizard_form.png | Bin 25111 -> 30966 bytes pos_payment_change/tests/test_module.py | 8 +-- pos_payment_change/wizards/__init__.py | 3 +- .../wizards/pos_payment_change_wizard.py | 39 +++++++--- ... => pos_payment_change_wizard_new_line.py} | 11 ++- .../pos_payment_change_wizard_old_line.py | 23 ++++++ .../view_pos_payment_change_wizard.xml | 14 ++-- 9 files changed, 159 insertions(+), 70 deletions(-) rename pos_payment_change/wizards/{pos_payment_change_wizard_line.py => pos_payment_change_wizard_new_line.py} (82%) create mode 100644 pos_payment_change/wizards/pos_payment_change_wizard_old_line.py diff --git a/pos_payment_change/i18n/fr.po b/pos_payment_change/i18n/fr.po index 9e146502a6..f9253ce4f5 100644 --- a/pos_payment_change/i18n/fr.po +++ b/pos_payment_change/i18n/fr.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 12.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-27 10:44+0000\n" -"PO-Revision-Date: 2020-04-27 10:44+0000\n" +"POT-Creation-Date: 2020-05-18 17:33+0000\n" +"PO-Revision-Date: 2020-05-18 17:33+0000\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -16,7 +16,7 @@ msgstr "" "Plural-Forms: \n" #. module: pos_payment_change -#: code:addons/pos_payment_change/models/pos_order.py:78 +#: code:addons/pos_payment_change/models/pos_order.py:79 #, python-format msgid " (Refund Order: %s ; Resale Order: %s)" msgstr " (Remboursement: %s ; Revente : %s)" @@ -27,7 +27,8 @@ msgid "Payment Change Policy" msgstr "Méthode de changement de paiement" #. module: pos_payment_change -#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__amount +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__amount +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__amount msgid "Amount" msgstr "Montant" @@ -45,18 +46,20 @@ msgstr "Changer les paiements" #. module: pos_payment_change #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__create_uid -#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__create_uid +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__create_uid +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__create_uid msgid "Created by" msgstr "Créé par" #. module: pos_payment_change #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__create_date -#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__create_date +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__create_date +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__create_date msgid "Created on" msgstr "Créé le" #. module: pos_payment_change -#: code:addons/pos_payment_change/wizards/pos_payment_change_wizard.py:54 +#: code:addons/pos_payment_change/wizards/pos_payment_change_wizard.py:69 #, python-format msgid "Differences between the two values for the POS Order '%s':\n" "\n" @@ -73,39 +76,55 @@ msgstr "Différences entre les deux valeurs pour la vente '%s':\n" #. module: pos_payment_change #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__display_name -#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__display_name +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__display_name +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__display_name msgid "Display Name" msgstr "Nom affiché" #. module: pos_payment_change #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__id -#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__id +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__id +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__id msgid "ID" msgstr "ID" #. module: pos_payment_change -#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__new_journal_id +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__new_journal_id +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__old_journal_id msgid "Journal" msgstr "Journal" #. module: pos_payment_change #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard____last_update -#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line____last_update +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line____last_update +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line____last_update msgid "Last Modified on" msgstr "Dernière modification le" #. module: pos_payment_change #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__write_uid -#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__write_uid +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__write_uid +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__write_uid msgid "Last Updated by" msgstr "Dernière mise à jour par" #. module: pos_payment_change #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__write_date -#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__write_date +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__write_date +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__write_date msgid "Last Updated on" msgstr "Dernière mise à jour le" +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__new_line_ids +msgid "New Payment Lines" +msgstr "Nouveaux paiements" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__old_line_ids +msgid "Old Payment Lines" +msgstr "Anciens paiements" + #. module: pos_payment_change #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__order_id msgid "Order" @@ -129,21 +148,20 @@ msgstr "Méthode de changement de paiement quand les utilisateurs veulent change "\n" "Note : dans certains pays, l'option 'Modifier les paiements' n'est pas autorisé par la loi, parce que l'historique des ventes ne doit pas être altéré." -#. module: pos_payment_change -#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__line_ids -#: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_payment_change_wizard_form -msgid "Payment Lines" -msgstr "Lignes de paiement" - #. module: pos_payment_change #: model:ir.model,name:pos_payment_change.model_pos_payment_change_wizard msgid "PoS Payment Change Wizard" msgstr "Assistant de changement de paiement du Point de Vente" #. module: pos_payment_change -#: model:ir.model,name:pos_payment_change.model_pos_payment_change_wizard_line -msgid "PoS Payment Change Wizard Line" -msgstr "Ligne d'assistant de changement de paiement du Point de Vente" +#: model:ir.model,name:pos_payment_change.model_pos_payment_change_wizard_new_line +msgid "PoS Payment Change Wizard New Line" +msgstr "Nouvelle ligne de l'ssistant de changement de paiement du Point de Vente" + +#. module: pos_payment_change +#: model:ir.model,name:pos_payment_change.model_pos_payment_change_wizard_old_line +msgid "PoS Payment Change Wizard Old Line" +msgstr "Ancienne ligne de l'ssistant de changement de paiement du Point de Vente" #. module: pos_payment_change #: model:ir.model,name:pos_payment_change.model_pos_config @@ -184,12 +202,14 @@ msgid "Update Payments" msgstr "Modifier les paiements" #. module: pos_payment_change -#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__wizard_id +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__wizard_id +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__wizard_id msgid "Wizard" msgstr "Assistant" #. module: pos_payment_change -#: code:addons/pos_payment_change/models/pos_order.py:96 +#: code:addons/pos_payment_change/models/pos_order.py:97 #, python-format msgid "You can not change payments of the POS '%s' because the associated session '%s' has been closed!" msgstr "Vous ne pouvez pas changer les paiements de la Vente '%s' car la session associée '%s' a été clôturé !" + diff --git a/pos_payment_change/i18n/pos_payment_change.pot b/pos_payment_change/i18n/pos_payment_change.pot index 94eb4b4ca8..61ad7b34cf 100644 --- a/pos_payment_change/i18n/pos_payment_change.pot +++ b/pos_payment_change/i18n/pos_payment_change.pot @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 12.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-27 10:48+0000\n" -"PO-Revision-Date: 2020-04-27 10:48+0000\n" +"POT-Creation-Date: 2020-05-18 17:33+0000\n" +"PO-Revision-Date: 2020-05-18 17:33+0000\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -16,7 +16,7 @@ msgstr "" "Plural-Forms: \n" #. module: pos_payment_change -#: code:addons/pos_payment_change/models/pos_order.py:78 +#: code:addons/pos_payment_change/models/pos_order.py:79 #, python-format msgid " (Refund Order: %s ; Resale Order: %s)" msgstr "" @@ -27,7 +27,8 @@ msgid "Payment Change Policy" msgstr "" #. module: pos_payment_change -#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__amount +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__amount +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__amount msgid "Amount" msgstr "" @@ -45,18 +46,20 @@ msgstr "" #. module: pos_payment_change #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__create_uid -#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__create_uid +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__create_uid +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__create_uid msgid "Created by" msgstr "" #. module: pos_payment_change #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__create_date -#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__create_date +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__create_date +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__create_date msgid "Created on" msgstr "" #. module: pos_payment_change -#: code:addons/pos_payment_change/wizards/pos_payment_change_wizard.py:54 +#: code:addons/pos_payment_change/wizards/pos_payment_change_wizard.py:69 #, python-format msgid "Differences between the two values for the POS Order '%s':\n" "\n" @@ -68,39 +71,55 @@ msgstr "" #. module: pos_payment_change #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__display_name -#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__display_name +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__display_name +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__display_name msgid "Display Name" msgstr "" #. module: pos_payment_change #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__id -#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__id +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__id +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__id msgid "ID" msgstr "" #. module: pos_payment_change -#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__new_journal_id +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__new_journal_id +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__old_journal_id msgid "Journal" msgstr "" #. module: pos_payment_change #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard____last_update -#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line____last_update +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line____last_update +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line____last_update msgid "Last Modified on" msgstr "" #. module: pos_payment_change #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__write_uid -#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__write_uid +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__write_uid +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__write_uid msgid "Last Updated by" msgstr "" #. module: pos_payment_change #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__write_date -#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__write_date +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__write_date +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__write_date msgid "Last Updated on" msgstr "" +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__new_line_ids +msgid "New Payment Lines" +msgstr "" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__old_line_ids +msgid "Old Payment Lines" +msgstr "" + #. module: pos_payment_change #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__order_id msgid "Order" @@ -121,19 +140,18 @@ msgid "Payment Change Policy when users want to change the payment lines of a gi msgstr "" #. module: pos_payment_change -#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__line_ids -#: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_payment_change_wizard_form -msgid "Payment Lines" +#: model:ir.model,name:pos_payment_change.model_pos_payment_change_wizard +msgid "PoS Payment Change Wizard" msgstr "" #. module: pos_payment_change -#: model:ir.model,name:pos_payment_change.model_pos_payment_change_wizard -msgid "PoS Payment Change Wizard" +#: model:ir.model,name:pos_payment_change.model_pos_payment_change_wizard_new_line +msgid "PoS Payment Change Wizard New Line" msgstr "" #. module: pos_payment_change -#: model:ir.model,name:pos_payment_change.model_pos_payment_change_wizard_line -msgid "PoS Payment Change Wizard Line" +#: model:ir.model,name:pos_payment_change.model_pos_payment_change_wizard_old_line +msgid "PoS Payment Change Wizard Old Line" msgstr "" #. module: pos_payment_change @@ -175,12 +193,13 @@ msgid "Update Payments" msgstr "" #. module: pos_payment_change -#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_line__wizard_id +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__wizard_id +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__wizard_id msgid "Wizard" msgstr "" #. module: pos_payment_change -#: code:addons/pos_payment_change/models/pos_order.py:96 +#: code:addons/pos_payment_change/models/pos_order.py:97 #, python-format msgid "You can not change payments of the POS '%s' because the associated session '%s' has been closed!" msgstr "" diff --git a/pos_payment_change/static/description/pos_payment_change_wizard_form.png b/pos_payment_change/static/description/pos_payment_change_wizard_form.png index 19d86e9ddfcedcf0e1399f9670366f9867038571..3411fa491d37e3a734179d8653affad7c5cb466e 100644 GIT binary patch literal 30966 zcmd?QWl&t-);9Dg1ZK{Ai+HZhoFtSySp~79bAG0cL?sTjk~)yI`F^u*3>*x zQ#0@LVd{NnK6I_FUFYnx_tM|qYppOvc?qOX_@AJlppc{_#gw6-UhJBlyx≧*#WtK)0OMYoqk_R=-tCAhh^iTN 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 - + + + + + + + - - + + From c28f192b4810584f404033fc0ee0c63a2810d617 Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Wed, 3 Jun 2020 12:25:17 +0200 Subject: [PATCH 04/35] Update __manifest__.py --- pos_payment_change/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pos_payment_change/__manifest__.py b/pos_payment_change/__manifest__.py index a905910b31..868b4d6b77 100644 --- a/pos_payment_change/__manifest__.py +++ b/pos_payment_change/__manifest__.py @@ -5,7 +5,7 @@ "name": "Point Of Sale - Change Payments", "version": "12.0.1.0.0", "summary": "Allow cashier to change order payments, as long as" - " the session is not closed", + " the session is not closed.", "category": "Point Of Sale", "author": "GRAP, Odoo Community Association (OCA)", "website": "https://www.github.com/OCA/pos", From 0ac84af360eb60aab7838883af3dc38098596d72 Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Fri, 12 Jun 2020 23:34:58 +0200 Subject: [PATCH 05/35] [FIX] access to ir.module.module should be done with sudo --- pos_payment_change/README.rst | 143 ++++- pos_payment_change/__manifest__.py | 2 +- pos_payment_change/i18n/fr.po | 51 +- .../i18n/pos_payment_change.pot | 4 +- pos_payment_change/models/pos_config.py | 2 +- .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 488 ++++++++++++++++++ 7 files changed, 667 insertions(+), 23 deletions(-) create mode 100644 pos_payment_change/static/description/icon.png create mode 100644 pos_payment_change/static/description/index.html diff --git a/pos_payment_change/README.rst b/pos_payment_change/README.rst index 5cba6561d7..600e2ec741 100644 --- a/pos_payment_change/README.rst +++ b/pos_payment_change/README.rst @@ -1,8 +1,145 @@ -============================== -Point Of Sale - Change Payment -============================== +=============================== +Point Of Sale - Change Payments +=============================== .. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fpos-lightgray.png?logo=github + :target: https://github.com/OCA/pos/tree/12.0/pos_payment_change + :alt: OCA/pos +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/pos-12-0/pos-12-0-pos_payment_change + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/184/12.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module extends the functionnality of the Odoo Point of Sale to +allow the cashier to change the payments of a PoS order. + +This feature is usefull when the user realized that he did a mistake, +just after he marked the order as paid, or during the close of the session, +Only if entries has not been generated. + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +* Go to Point of Sale > Configuration > Point of Sale +* Edit your point of sale, and select a value for the field + 'Payment Change Policy'. + +Two options are available: + +* 'Refund and Resale': Odoo will refund the current + Pos Order to cancel it, and create a new PoS Order + with the correct payment lines + +* 'Update Payments': Odoo will change payment lines. + +.. figure:: https://raw.githubusercontent.com/OCA/pos/12.0/pos_payment_change/static/description/pos_config_form.png + + +**Note** +In some countries the 'Update Payments' Option +is not allowed by law, because orders history shouldn't not be altered. + +For that purpose, a constrains is present to check the value of this +field. If the module ``l10n_fr_certification`` is installed and if the +current company has an inalterable accounting, it will not be possible +to select the value 'Update Payments'. + +Usage +===== + +* Go to a PoS Order + +* Click on the button 'Change Payments' + +.. figure:: https://raw.githubusercontent.com/OCA/pos/12.0/pos_payment_change/static/description/pos_order_form.png + +* In the pop up wizard, select the real payment(s) that have been + used to pay the order + +.. figure:: https://raw.githubusercontent.com/OCA/pos/12.0/pos_payment_change/static/description/pos_payment_change_wizard_form.png + +* Then click on the button 'Change Payments' + +**Note** + +If the option 'Refund and Resale' is selected, changing the payments will +display the three PoS orders. the oringal one, the refund one, and the new one. + +.. figure:: https://raw.githubusercontent.com/OCA/pos/12.0/pos_payment_change/static/description/pos_order_tree.png + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* GRAP + +Contributors +~~~~~~~~~~~~ + +* Sylvain LE GAL +* Julien WESTE + +Other credits +~~~~~~~~~~~~~ + +The development of this module has been financially supported by: + +* GRAP, Groupement Régional Alimentaire de proximité (www.grap.coop) +* Vracoop (www.vracoop.fr) + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +.. |maintainer-legalsylvain| image:: https://github.com/legalsylvain.png?size=40px + :target: https://github.com/legalsylvain + :alt: legalsylvain + +Current `maintainer `__: + +|maintainer-legalsylvain| + +This module is part of the `OCA/pos `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/pos_payment_change/__manifest__.py b/pos_payment_change/__manifest__.py index 868b4d6b77..914d7a9292 100644 --- a/pos_payment_change/__manifest__.py +++ b/pos_payment_change/__manifest__.py @@ -3,7 +3,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { "name": "Point Of Sale - Change Payments", - "version": "12.0.1.0.0", + "version": "12.0.1.0.1", "summary": "Allow cashier to change order payments, as long as" " the session is not closed.", "category": "Point Of Sale", diff --git a/pos_payment_change/i18n/fr.po b/pos_payment_change/i18n/fr.po index f9253ce4f5..954ff3e870 100644 --- a/pos_payment_change/i18n/fr.po +++ b/pos_payment_change/i18n/fr.po @@ -10,6 +10,7 @@ msgstr "" "PO-Revision-Date: 2020-05-18 17:33+0000\n" "Last-Translator: <>\n" "Language-Team: \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" @@ -61,13 +62,15 @@ msgstr "Créé le" #. module: pos_payment_change #: code:addons/pos_payment_change/wizards/pos_payment_change_wizard.py:69 #, python-format -msgid "Differences between the two values for the POS Order '%s':\n" +msgid "" +"Differences between the two values for the POS Order '%s':\n" "\n" " * Total of all the new payments %s;\n" " * Total of the POS Order %s;\n" "\n" "Please change the payments." -msgstr "Différences entre les deux valeurs pour la vente '%s':\n" +msgstr "" +"Différences entre les deux valeurs pour la vente '%s':\n" "\n" " * Total des nouveaux paiements %s;\n" " * Total de la vente %s;\n" @@ -137,16 +140,25 @@ msgstr "Méthode de changement de paiement" #. module: pos_payment_change #: model:ir.model.fields,help:pos_payment_change.field_pos_config__payment_change_policy -msgid "Payment Change Policy when users want to change the payment lines of a given PoS Order.\n" -"* 'Refund and Resale': Odoo will refund the current Pos Order to cancel it, and create a new PoS Order with the correct payment lines.\n" +msgid "" +"Payment Change Policy when users want to change the payment lines of a given " +"PoS Order.\n" +"* 'Refund and Resale': Odoo will refund the current Pos Order to cancel it, " +"and create a new PoS Order with the correct payment lines.\n" "* 'Update Payments': Odoo will change payment lines.\n" "\n" -"Note : In some countries the 'Update Payments' Option is not allowed by law, because orders history shouldn't not be altered." -msgstr "Méthode de changement de paiement quand les utilisateurs veulent changer des lignes de paiement d'une vente en caisse.\n" -"* 'Retourner et revendre': Odoo va réaliser un retour du la vente pour l'annuler, puis recréera une nouvelle vente, avec les paiements corrects.\n" +"Note : In some countries the 'Update Payments' Option is not allowed by law, " +"because orders history shouldn't not be altered." +msgstr "" +"Méthode de changement de paiement quand les utilisateurs veulent changer des " +"lignes de paiement d'une vente en caisse.\n" +"* 'Retourner et revendre': Odoo va réaliser un retour du la vente pour " +"l'annuler, puis recréera une nouvelle vente, avec les paiements corrects.\n" "* 'Modifier les paiements': Odoo va changer les lignes de paiements.\n" "\n" -"Note : dans certains pays, l'option 'Modifier les paiements' n'est pas autorisé par la loi, parce que l'historique des ventes ne doit pas être altéré." +"Note : dans certains pays, l'option 'Modifier les paiements' n'est pas " +"autorisé par la loi, parce que l'historique des ventes ne doit pas être " +"altéré." #. module: pos_payment_change #: model:ir.model,name:pos_payment_change.model_pos_payment_change_wizard @@ -156,12 +168,14 @@ msgstr "Assistant de changement de paiement du Point de Vente" #. module: pos_payment_change #: model:ir.model,name:pos_payment_change.model_pos_payment_change_wizard_new_line msgid "PoS Payment Change Wizard New Line" -msgstr "Nouvelle ligne de l'ssistant de changement de paiement du Point de Vente" +msgstr "" +"Nouvelle ligne de l'ssistant de changement de paiement du Point de Vente" #. module: pos_payment_change #: model:ir.model,name:pos_payment_change.model_pos_payment_change_wizard_old_line msgid "PoS Payment Change Wizard Old Line" -msgstr "Ancienne ligne de l'ssistant de changement de paiement du Point de Vente" +msgstr "" +"Ancienne ligne de l'ssistant de changement de paiement du Point de Vente" #. module: pos_payment_change #: model:ir.model,name:pos_payment_change.model_pos_config @@ -193,8 +207,12 @@ msgstr "Total" #. module: pos_payment_change #: code:addons/pos_payment_change/models/pos_config.py:43 #, python-format -msgid "Unable to use the 'Update Payments' options for companies that have unalterable accounting." -msgstr "Impossible d'utiliser l'option 'Modifier les paiements' pour les sociétés qui ont une comptabilité inaltérable." +msgid "" +"Unable to use the 'Update Payments' options for companies that have " +"unalterable accounting." +msgstr "" +"Impossible d'utiliser l'option 'Modifier les paiements' pour les sociétés " +"qui ont une comptabilité inaltérable." #. module: pos_payment_change #: selection:pos.config,payment_change_policy:0 @@ -210,6 +228,9 @@ msgstr "Assistant" #. module: pos_payment_change #: code:addons/pos_payment_change/models/pos_order.py:97 #, python-format -msgid "You can not change payments of the POS '%s' because the associated session '%s' has been closed!" -msgstr "Vous ne pouvez pas changer les paiements de la Vente '%s' car la session associée '%s' a été clôturé !" - +msgid "" +"You can not change payments of the POS '%s' because the associated session " +"'%s' has been closed!" +msgstr "" +"Vous ne pouvez pas changer les paiements de la Vente '%s' car la session " +"associée '%s' a été clôturé !" diff --git a/pos_payment_change/i18n/pos_payment_change.pot b/pos_payment_change/i18n/pos_payment_change.pot index 61ad7b34cf..d3d944012f 100644 --- a/pos_payment_change/i18n/pos_payment_change.pot +++ b/pos_payment_change/i18n/pos_payment_change.pot @@ -1,13 +1,11 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: -# * pos_payment_change +# * pos_payment_change # msgid "" msgstr "" "Project-Id-Version: Odoo Server 12.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-05-18 17:33+0000\n" -"PO-Revision-Date: 2020-05-18 17:33+0000\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" diff --git a/pos_payment_change/models/pos_config.py b/pos_payment_change/models/pos_config.py index 199791e10e..2b6d1a78a9 100644 --- a/pos_payment_change/models/pos_config.py +++ b/pos_payment_change/models/pos_config.py @@ -31,7 +31,7 @@ class PosConfig(models.Model): def _check_payment_change_policy(self): # Check if certification module is installed # and if yes, if 'update payments' option is allowed - module_states = self.env["ir.module.module"].search([ + module_states = self.env["ir.module.module"].sudo().search([ ("name", "=", "l10n_fr_certification")] ).mapped("state") if "installed" not in module_states: diff --git a/pos_payment_change/static/description/icon.png b/pos_payment_change/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/pos_payment_change/static/description/index.html b/pos_payment_change/static/description/index.html new file mode 100644 index 0000000000..b2179e428b --- /dev/null +++ b/pos_payment_change/static/description/index.html @@ -0,0 +1,488 @@ + + + + + + +Point Of Sale - Change Payments + + + +
+

Point Of Sale - Change Payments

+ + +

Beta License: AGPL-3 OCA/pos Translate me on Weblate Try me on Runbot

+

This module extends the functionnality of the Odoo Point of Sale to +allow the cashier to change the payments of a PoS order.

+

This feature is usefull when the user realized that he did a mistake, +just after he marked the order as paid, or during the close of the session, +Only if entries has not been generated.

+

Table of contents

+ +
+

Configuration

+
    +
  • Go to Point of Sale > Configuration > Point of Sale
  • +
  • Edit your point of sale, and select a value for the field +‘Payment Change Policy’.
  • +
+

Two options are available:

+
    +
  • ‘Refund and Resale’: Odoo will refund the current +Pos Order to cancel it, and create a new PoS Order +with the correct payment lines
  • +
  • ‘Update Payments’: Odoo will change payment lines.
  • +
+
+https://raw.githubusercontent.com/OCA/pos/12.0/pos_payment_change/static/description/pos_config_form.png +
+

Note +In some countries the ‘Update Payments’ Option +is not allowed by law, because orders history shouldn’t not be altered.

+

For that purpose, a constrains is present to check the value of this +field. If the module l10n_fr_certification is installed and if the +current company has an inalterable accounting, it will not be possible +to select the value ‘Update Payments’.

+
+
+

Usage

+
    +
  • Go to a PoS Order
  • +
  • Click on the button ‘Change Payments’
  • +
+
+https://raw.githubusercontent.com/OCA/pos/12.0/pos_payment_change/static/description/pos_order_form.png +
+
    +
  • In the pop up wizard, select the real payment(s) that have been +used to pay the order
  • +
+
+https://raw.githubusercontent.com/OCA/pos/12.0/pos_payment_change/static/description/pos_payment_change_wizard_form.png +
+
    +
  • Then click on the button ‘Change Payments’
  • +
+

Note

+

If the option ‘Refund and Resale’ is selected, changing the payments will +display the three PoS orders. the oringal one, the refund one, and the new one.

+
+https://raw.githubusercontent.com/OCA/pos/12.0/pos_payment_change/static/description/pos_order_tree.png +
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • GRAP
  • +
+
+
+

Contributors

+ +
+
+

Other credits

+

The development of this module has been financially supported by:

+
    +
  • GRAP, Groupement Régional Alimentaire de proximité (www.grap.coop)
  • +
  • Vracoop (www.vracoop.fr)
  • +
+
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

Current maintainer:

+

legalsylvain

+

This module is part of the OCA/pos project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + From 0d58501173f26cbe7f7829bd1f7f0f77eaffa7b5 Mon Sep 17 00:00:00 2001 From: Daniel Martinez Vila Date: Mon, 27 Jul 2020 09:32:40 +0000 Subject: [PATCH 06/35] Added translation using Weblate (Spanish) Translated using Weblate (Spanish) Currently translated at 100.0% (31 of 31 strings) Translation: pos-12.0/pos-12.0-pos_payment_change Translate-URL: https://translation.odoo-community.org/projects/pos-12-0/pos-12-0-pos_payment_change/es/ --- pos_payment_change/i18n/es.po | 225 ++++++++++++++++++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100644 pos_payment_change/i18n/es.po diff --git a/pos_payment_change/i18n/es.po b/pos_payment_change/i18n/es.po new file mode 100644 index 0000000000..20eb42153e --- /dev/null +++ b/pos_payment_change/i18n/es.po @@ -0,0 +1,225 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * pos_payment_change +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2020-07-27 11:19+0000\n" +"Last-Translator: Daniel Martinez Vila \n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 3.10\n" + +#. module: pos_payment_change +#: code:addons/pos_payment_change/models/pos_order.py:79 +#, python-format +msgid " (Refund Order: %s ; Resale Order: %s)" +msgstr " (Orden de reembolso: %s ; Orden de reventa: %s)" + +#. module: pos_payment_change +#: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_config_form +msgid "Payment Change Policy" +msgstr "Política de cambio de pago" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__amount +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__amount +msgid "Amount" +msgstr "Importe" + +#. module: pos_payment_change +#: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_payment_change_wizard_form +msgid "Cancel" +msgstr "Cancelar" + +#. module: pos_payment_change +#: model:ir.actions.act_window,name:pos_payment_change.action_pos_payment_change_wizard +#: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_order_form +#: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_payment_change_wizard_form +msgid "Change Payments" +msgstr "Cambiar pagos" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__create_uid +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__create_uid +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__create_uid +msgid "Created by" +msgstr "Creado por" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__create_date +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__create_date +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__create_date +msgid "Created on" +msgstr "Creado el" + +#. module: pos_payment_change +#: code:addons/pos_payment_change/wizards/pos_payment_change_wizard.py:69 +#, python-format +msgid "Differences between the two values for the POS Order '%s':\n" +"\n" +" * Total of all the new payments %s;\n" +" * Total of the POS Order %s;\n" +"\n" +"Please change the payments." +msgstr "" +"Diferencias entre los dos valores para la orden PdV '%s':\n" +"\n" +" * Total de todos los nuevos pagos %s;\n" +" * Total del pedido del punto de venta %s;\n" +"\n" +"Por favor cambie los pagos." + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__display_name +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__display_name +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__display_name +msgid "Display Name" +msgstr "Nombre a mostrar" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__id +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__id +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__id +msgid "ID" +msgstr "ID" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__new_journal_id +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__old_journal_id +msgid "Journal" +msgstr "Diario" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard____last_update +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line____last_update +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line____last_update +msgid "Last Modified on" +msgstr "Última modificación en" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__write_uid +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__write_uid +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__write_uid +msgid "Last Updated by" +msgstr "Última actualización por" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__write_date +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__write_date +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__write_date +msgid "Last Updated on" +msgstr "Última actualización el" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__new_line_ids +msgid "New Payment Lines" +msgstr "Nuevas líneas de pago" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__old_line_ids +msgid "Old Payment Lines" +msgstr "Viejas líneas de pago" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__order_id +msgid "Order" +msgstr "Orden" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_config__payment_change_policy +msgid "Payment Change Policy" +msgstr "Política de cambio de pago" + +#. module: pos_payment_change +#: model:ir.model.fields,help:pos_payment_change.field_pos_config__payment_change_policy +msgid "Payment Change Policy when users want to change the payment lines of a given PoS Order.\n" +"* 'Refund and Resale': Odoo will refund the current Pos Order to cancel it, and create a new PoS Order with the correct payment lines.\n" +"* 'Update Payments': Odoo will change payment lines.\n" +"\n" +"Note : In some countries the 'Update Payments' Option is not allowed by law, because orders history shouldn't not be altered." +msgstr "" +"Política de cambio de pago cuando los usuarios desean cambiar las líneas de " +"pago de un pedido PdV determinado.\n" +"* 'Reembolso y reventa': Odoo reembolsará el pedido de posición actual para " +"cancelarlo y creará un nuevo pedido de PoS con las líneas de pago correctas." +"\n" +"* 'Actualizar pagos': Odoo cambiará las líneas de pago.\n" +"\n" +"Nota: En algunos países, la opción 'Actualizar pagos' no está permitida por " +"ley, ya que el historial de pedidos no debe modificarse." + +#. module: pos_payment_change +#: model:ir.model,name:pos_payment_change.model_pos_payment_change_wizard +msgid "PoS Payment Change Wizard" +msgstr "Asistente de cambio de pago del PdV" + +#. module: pos_payment_change +#: model:ir.model,name:pos_payment_change.model_pos_payment_change_wizard_new_line +msgid "PoS Payment Change Wizard New Line" +msgstr "Asistente de cambio de pago de una nueva línea del PdV" + +#. module: pos_payment_change +#: model:ir.model,name:pos_payment_change.model_pos_payment_change_wizard_old_line +msgid "PoS Payment Change Wizard Old Line" +msgstr "Asistente de cambio de pago de una línea antigua del PdV" + +#. module: pos_payment_change +#: model:ir.model,name:pos_payment_change.model_pos_config +msgid "Point of Sale Configuration" +msgstr "Configuración del punto de venta" + +#. module: pos_payment_change +#: model:ir.model,name:pos_payment_change.model_pos_order +msgid "Point of Sale Orders" +msgstr "Pedidos de Punto de Venta" + +#. module: pos_payment_change +#: selection:pos.config,payment_change_policy:0 +msgid "Refund and Resale" +msgstr "Reembolso y reventa" + +#. module: pos_payment_change +#: code:addons/pos_payment_change/models/pos_order.py:43 +#, python-format +msgid "The payments of the Order %s (Ref: %s) has been changed by %s at %s." +msgstr "Los pagos de la orden %s (Ref: %s) han sido modificados por %s en %s." + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__amount_total +#: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_payment_change_wizard_form +msgid "Total" +msgstr "Total" + +#. module: pos_payment_change +#: code:addons/pos_payment_change/models/pos_config.py:43 +#, python-format +msgid "Unable to use the 'Update Payments' options for companies that have unalterable accounting." +msgstr "" +"No se pueden usar las opciones de 'Actualizar pagos' para empresas que " +"tienen contabilidad inalterable." + +#. module: pos_payment_change +#: selection:pos.config,payment_change_policy:0 +msgid "Update Payments" +msgstr "Actualizar pagos" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__wizard_id +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__wizard_id +msgid "Wizard" +msgstr "Asistente" + +#. module: pos_payment_change +#: code:addons/pos_payment_change/models/pos_order.py:97 +#, python-format +msgid "You can not change payments of the POS '%s' because the associated session '%s' has been closed!" +msgstr "" +"¡No puede cambiar los pagos del PdV '%s' porque la sesión asociada '%s' se " +"ha cerrado!" From 555f353689f5de0d62583127887fc6d32c0a3eaf Mon Sep 17 00:00:00 2001 From: Florent THOMAS Date: Tue, 28 Jul 2020 21:30:22 +0200 Subject: [PATCH 07/35] Use currency and monetary so that rounding will be done by the ORM* add new line Pylint fix pylint --- .../wizards/pos_payment_change_wizard_new_line.py | 10 +++++++++- .../wizards/pos_payment_change_wizard_old_line.py | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/pos_payment_change/wizards/pos_payment_change_wizard_new_line.py b/pos_payment_change/wizards/pos_payment_change_wizard_new_line.py index a9119c19fe..8d7a6b2731 100644 --- a/pos_payment_change/wizards/pos_payment_change_wizard_new_line.py +++ b/pos_payment_change/wizards/pos_payment_change_wizard_new_line.py @@ -20,7 +20,15 @@ class PosPaymentChangeWizardLine(models.TransientModel): domain=lambda s: s._domain_new_journal_id(), ) - amount = fields.Float(string="Amount", required=True) + company_currency_id = fields.Many2one( + comodel_name='res.currency', store=True, + related='new_journal_id.currency_id', + string="Company Currency", readonly=True, + help='Utility field to express amount currency') + + amount = fields.Monetary(string="Amount", + required=True, default=0.0, + currency_field='company_currency_id') @api.model def _domain_new_journal_id(self): diff --git a/pos_payment_change/wizards/pos_payment_change_wizard_old_line.py b/pos_payment_change/wizards/pos_payment_change_wizard_old_line.py index b40c8601f7..82084aca72 100644 --- a/pos_payment_change/wizards/pos_payment_change_wizard_old_line.py +++ b/pos_payment_change/wizards/pos_payment_change_wizard_old_line.py @@ -19,5 +19,13 @@ class PosPaymentChangeWizardOldLine(models.TransientModel): required=True, readonly=True, ) + + company_currency_id = fields.Many2one( + comodel_name='res.currency', store=True, + related='old_journal_id.currency_id', + string="Company Currency", readonly=True, + help='Utility field to express amount currency') - amount = fields.Float(string="Amount", required=True, readonly=True) + amount = fields.Monetary(string="Amount", required=True, + readonly=True, default=0.0, + currency_field='company_currency_id') From 2f6430fa59e88f9547c5716ab89bcdd08d50e752 Mon Sep 17 00:00:00 2001 From: Florent THOMAS Date: Thu, 10 Sep 2020 08:57:32 +0200 Subject: [PATCH 08/35] more fix pyilint --- pos_payment_change/__manifest__.py | 2 +- pos_payment_change/i18n/es.po | 39 ++++++++++++++----- pos_payment_change/i18n/fr.po | 12 ++++++ .../i18n/pos_payment_change.pot | 12 ++++++ .../pos_payment_change_wizard_new_line.py | 19 +++++---- .../pos_payment_change_wizard_old_line.py | 20 ++++++---- 6 files changed, 78 insertions(+), 26 deletions(-) diff --git a/pos_payment_change/__manifest__.py b/pos_payment_change/__manifest__.py index 914d7a9292..5fe98e67f7 100644 --- a/pos_payment_change/__manifest__.py +++ b/pos_payment_change/__manifest__.py @@ -3,7 +3,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { "name": "Point Of Sale - Change Payments", - "version": "12.0.1.0.1", + "version": "12.0.1.0.2", "summary": "Allow cashier to change order payments, as long as" " the session is not closed.", "category": "Point Of Sale", diff --git a/pos_payment_change/i18n/es.po b/pos_payment_change/i18n/es.po index 20eb42153e..95d2b11649 100644 --- a/pos_payment_change/i18n/es.po +++ b/pos_payment_change/i18n/es.po @@ -1,6 +1,6 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: -# * pos_payment_change +# * pos_payment_change # msgid "" msgstr "" @@ -45,6 +45,12 @@ msgstr "Cancelar" msgid "Change Payments" msgstr "Cambiar pagos" +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__company_currency_id +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__company_currency_id +msgid "Company Currency" +msgstr "" + #. module: pos_payment_change #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__create_uid #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__create_uid @@ -62,7 +68,8 @@ msgstr "Creado el" #. module: pos_payment_change #: code:addons/pos_payment_change/wizards/pos_payment_change_wizard.py:69 #, python-format -msgid "Differences between the two values for the POS Order '%s':\n" +msgid "" +"Differences between the two values for the POS Order '%s':\n" "\n" " * Total of all the new payments %s;\n" " * Total of the POS Order %s;\n" @@ -139,17 +146,21 @@ msgstr "Política de cambio de pago" #. module: pos_payment_change #: model:ir.model.fields,help:pos_payment_change.field_pos_config__payment_change_policy -msgid "Payment Change Policy when users want to change the payment lines of a given PoS Order.\n" -"* 'Refund and Resale': Odoo will refund the current Pos Order to cancel it, and create a new PoS Order with the correct payment lines.\n" +msgid "" +"Payment Change Policy when users want to change the payment lines of a given " +"PoS Order.\n" +"* 'Refund and Resale': Odoo will refund the current Pos Order to cancel it, " +"and create a new PoS Order with the correct payment lines.\n" "* 'Update Payments': Odoo will change payment lines.\n" "\n" -"Note : In some countries the 'Update Payments' Option is not allowed by law, because orders history shouldn't not be altered." +"Note : In some countries the 'Update Payments' Option is not allowed by law, " +"because orders history shouldn't not be altered." msgstr "" "Política de cambio de pago cuando los usuarios desean cambiar las líneas de " "pago de un pedido PdV determinado.\n" "* 'Reembolso y reventa': Odoo reembolsará el pedido de posición actual para " -"cancelarlo y creará un nuevo pedido de PoS con las líneas de pago correctas." -"\n" +"cancelarlo y creará un nuevo pedido de PoS con las líneas de pago " +"correctas.\n" "* 'Actualizar pagos': Odoo cambiará las líneas de pago.\n" "\n" "Nota: En algunos países, la opción 'Actualizar pagos' no está permitida por " @@ -200,7 +211,9 @@ msgstr "Total" #. module: pos_payment_change #: code:addons/pos_payment_change/models/pos_config.py:43 #, python-format -msgid "Unable to use the 'Update Payments' options for companies that have unalterable accounting." +msgid "" +"Unable to use the 'Update Payments' options for companies that have " +"unalterable accounting." msgstr "" "No se pueden usar las opciones de 'Actualizar pagos' para empresas que " "tienen contabilidad inalterable." @@ -210,6 +223,12 @@ msgstr "" msgid "Update Payments" msgstr "Actualizar pagos" +#. module: pos_payment_change +#: model:ir.model.fields,help:pos_payment_change.field_pos_payment_change_wizard_new_line__company_currency_id +#: model:ir.model.fields,help:pos_payment_change.field_pos_payment_change_wizard_old_line__company_currency_id +msgid "Utility field to express amount currency" +msgstr "" + #. module: pos_payment_change #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__wizard_id #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__wizard_id @@ -219,7 +238,9 @@ msgstr "Asistente" #. module: pos_payment_change #: code:addons/pos_payment_change/models/pos_order.py:97 #, python-format -msgid "You can not change payments of the POS '%s' because the associated session '%s' has been closed!" +msgid "" +"You can not change payments of the POS '%s' because the associated session " +"'%s' has been closed!" msgstr "" "¡No puede cambiar los pagos del PdV '%s' porque la sesión asociada '%s' se " "ha cerrado!" diff --git a/pos_payment_change/i18n/fr.po b/pos_payment_change/i18n/fr.po index 954ff3e870..eebb932426 100644 --- a/pos_payment_change/i18n/fr.po +++ b/pos_payment_change/i18n/fr.po @@ -45,6 +45,12 @@ msgstr "Annuler" msgid "Change Payments" msgstr "Changer les paiements" +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__company_currency_id +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__company_currency_id +msgid "Company Currency" +msgstr "" + #. module: pos_payment_change #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__create_uid #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__create_uid @@ -219,6 +225,12 @@ msgstr "" msgid "Update Payments" msgstr "Modifier les paiements" +#. module: pos_payment_change +#: model:ir.model.fields,help:pos_payment_change.field_pos_payment_change_wizard_new_line__company_currency_id +#: model:ir.model.fields,help:pos_payment_change.field_pos_payment_change_wizard_old_line__company_currency_id +msgid "Utility field to express amount currency" +msgstr "" + #. module: pos_payment_change #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__wizard_id #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__wizard_id diff --git a/pos_payment_change/i18n/pos_payment_change.pot b/pos_payment_change/i18n/pos_payment_change.pot index d3d944012f..84a54550f2 100644 --- a/pos_payment_change/i18n/pos_payment_change.pot +++ b/pos_payment_change/i18n/pos_payment_change.pot @@ -42,6 +42,12 @@ msgstr "" msgid "Change Payments" msgstr "" +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__company_currency_id +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__company_currency_id +msgid "Company Currency" +msgstr "" + #. module: pos_payment_change #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__create_uid #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__create_uid @@ -190,6 +196,12 @@ msgstr "" msgid "Update Payments" msgstr "" +#. module: pos_payment_change +#: model:ir.model.fields,help:pos_payment_change.field_pos_payment_change_wizard_new_line__company_currency_id +#: model:ir.model.fields,help:pos_payment_change.field_pos_payment_change_wizard_old_line__company_currency_id +msgid "Utility field to express amount currency" +msgstr "" + #. module: pos_payment_change #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__wizard_id #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__wizard_id diff --git a/pos_payment_change/wizards/pos_payment_change_wizard_new_line.py b/pos_payment_change/wizards/pos_payment_change_wizard_new_line.py index 8d7a6b2731..d234d1d0e6 100644 --- a/pos_payment_change/wizards/pos_payment_change_wizard_new_line.py +++ b/pos_payment_change/wizards/pos_payment_change_wizard_new_line.py @@ -21,14 +21,17 @@ class PosPaymentChangeWizardLine(models.TransientModel): ) company_currency_id = fields.Many2one( - comodel_name='res.currency', store=True, - related='new_journal_id.currency_id', - string="Company Currency", readonly=True, - help='Utility field to express amount currency') - - amount = fields.Monetary(string="Amount", - required=True, default=0.0, - currency_field='company_currency_id') + comodel_name='res.currency', store=True, + related='new_journal_id.currency_id', + string="Company Currency", readonly=True, + help='Utility field to express amount currency' + ) + + amount = fields.Monetary( + string="Amount", + required=True, default=0.0, + currency_field='company_currency_id' + ) @api.model def _domain_new_journal_id(self): diff --git a/pos_payment_change/wizards/pos_payment_change_wizard_old_line.py b/pos_payment_change/wizards/pos_payment_change_wizard_old_line.py index 82084aca72..8829fd1f82 100644 --- a/pos_payment_change/wizards/pos_payment_change_wizard_old_line.py +++ b/pos_payment_change/wizards/pos_payment_change_wizard_old_line.py @@ -19,13 +19,17 @@ class PosPaymentChangeWizardOldLine(models.TransientModel): required=True, readonly=True, ) - + company_currency_id = fields.Many2one( - comodel_name='res.currency', store=True, - related='old_journal_id.currency_id', - string="Company Currency", readonly=True, - help='Utility field to express amount currency') + comodel_name='res.currency', store=True, + related='old_journal_id.currency_id', + string="Company Currency", readonly=True, + help='Utility field to express amount currency' + ) - amount = fields.Monetary(string="Amount", required=True, - readonly=True, default=0.0, - currency_field='company_currency_id') + amount = fields.Monetary( + string="Amount", + required=True, + readonly=True, default=0.0, + currency_field='company_currency_id' + ) From b1a6d8c9c82a9269cec0471aca820c81bdf3435a Mon Sep 17 00:00:00 2001 From: Daniel Martinez Vila Date: Mon, 26 Oct 2020 09:09:58 +0000 Subject: [PATCH 09/35] Translated using Weblate (Spanish) Currently translated at 100.0% (33 of 33 strings) Translation: pos-12.0/pos-12.0-pos_payment_change Translate-URL: https://translation.odoo-community.org/projects/pos-12-0/pos-12-0-pos_payment_change/es/ --- pos_payment_change/i18n/es.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pos_payment_change/i18n/es.po b/pos_payment_change/i18n/es.po index 95d2b11649..651be7cc33 100644 --- a/pos_payment_change/i18n/es.po +++ b/pos_payment_change/i18n/es.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 12.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2020-07-27 11:19+0000\n" +"PO-Revision-Date: 2020-10-26 11:08+0000\n" "Last-Translator: Daniel Martinez Vila \n" "Language-Team: none\n" "Language: es\n" @@ -49,7 +49,7 @@ msgstr "Cambiar pagos" #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__company_currency_id #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__company_currency_id msgid "Company Currency" -msgstr "" +msgstr "Moneda de la compañía" #. module: pos_payment_change #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__create_uid @@ -227,7 +227,7 @@ msgstr "Actualizar pagos" #: model:ir.model.fields,help:pos_payment_change.field_pos_payment_change_wizard_new_line__company_currency_id #: model:ir.model.fields,help:pos_payment_change.field_pos_payment_change_wizard_old_line__company_currency_id msgid "Utility field to express amount currency" -msgstr "" +msgstr "Campo de utilidad para expresar la cantidad de la moneda" #. module: pos_payment_change #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__wizard_id From dc22c0ef3aad8289614c3cd77a149c0a0a9c8d1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Volksdorf?= Date: Wed, 7 Apr 2021 22:42:55 +0000 Subject: [PATCH 10/35] Added translation using Weblate (German) Translated using Weblate (German) Currently translated at 100.0% (33 of 33 strings) Translation: pos-12.0/pos-12.0-pos_payment_change Translate-URL: https://translation.odoo-community.org/projects/pos-12-0/pos-12-0-pos_payment_change/de/ --- pos_payment_change/i18n/de.po | 237 ++++++++++++++++++++++++++++++++++ 1 file changed, 237 insertions(+) create mode 100644 pos_payment_change/i18n/de.po diff --git a/pos_payment_change/i18n/de.po b/pos_payment_change/i18n/de.po new file mode 100644 index 0000000000..20c98513d4 --- /dev/null +++ b/pos_payment_change/i18n/de.po @@ -0,0 +1,237 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * pos_payment_change +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2021-04-08 07:52+0000\n" +"Last-Translator: André Volksdorf \n" +"Language-Team: none\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.3.2\n" + +#. module: pos_payment_change +#: code:addons/pos_payment_change/models/pos_order.py:79 +#, python-format +msgid " (Refund Order: %s ; Resale Order: %s)" +msgstr " (Rückerstattungsauftrag: %s ; Wiederverkaufsauftrag: %s)" + +#. module: pos_payment_change +#: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_config_form +msgid "Payment Change Policy" +msgstr "Richtlinie für Zahlungsänderungen" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__amount +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__amount +msgid "Amount" +msgstr "Betrag" + +#. module: pos_payment_change +#: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_payment_change_wizard_form +msgid "Cancel" +msgstr "Abbrechen" + +#. module: pos_payment_change +#: model:ir.actions.act_window,name:pos_payment_change.action_pos_payment_change_wizard +#: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_order_form +#: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_payment_change_wizard_form +msgid "Change Payments" +msgstr "Zahlung ändern" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__company_currency_id +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__company_currency_id +msgid "Company Currency" +msgstr "Währung" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__create_uid +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__create_uid +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__create_uid +msgid "Created by" +msgstr "Erstellt von" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__create_date +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__create_date +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__create_date +msgid "Created on" +msgstr "Erstellt am" + +#. module: pos_payment_change +#: code:addons/pos_payment_change/wizards/pos_payment_change_wizard.py:69 +#, python-format +msgid "Differences between the two values for the POS Order '%s':\n" +"\n" +" * Total of all the new payments %s;\n" +" * Total of the POS Order %s;\n" +"\n" +"Please change the payments." +msgstr "" +"Differenzen zwischen den beiden Werten für den POS-Auftrag '%s':\n" +"\n" +" * Summe aller neuen Zahlungen %s;\n" +" * Summe des POS-Auftrags %s;\n" +"\n" +"Bitte ändern Sie die Zahlungen." + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__display_name +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__display_name +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__display_name +msgid "Display Name" +msgstr "Anzeigename" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__id +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__id +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__id +msgid "ID" +msgstr "ID" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__new_journal_id +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__old_journal_id +msgid "Journal" +msgstr "Journal" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard____last_update +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line____last_update +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line____last_update +msgid "Last Modified on" +msgstr "Zuletzt geändert am" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__write_uid +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__write_uid +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__write_uid +msgid "Last Updated by" +msgstr "Zuletzt aktualisiert von" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__write_date +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__write_date +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__write_date +msgid "Last Updated on" +msgstr "Zuletzt aktualisiert am" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__new_line_ids +msgid "New Payment Lines" +msgstr "Neue Zahlungslinien" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__old_line_ids +msgid "Old Payment Lines" +msgstr "Alte Zahlungslinien" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__order_id +msgid "Order" +msgstr "Auftrag" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_config__payment_change_policy +msgid "Payment Change Policy" +msgstr "Richtlinie für Zahlungsänderungen" + +#. module: pos_payment_change +#: model:ir.model.fields,help:pos_payment_change.field_pos_config__payment_change_policy +msgid "Payment Change Policy when users want to change the payment lines of a given PoS Order.\n" +"* 'Refund and Resale': Odoo will refund the current Pos Order to cancel it, and create a new PoS Order with the correct payment lines.\n" +"* 'Update Payments': Odoo will change payment lines.\n" +"\n" +"Note : In some countries the 'Update Payments' Option is not allowed by law, because orders history shouldn't not be altered." +msgstr "" +"Richtlinie für Zahlungsänderungen, wenn Benutzer die Zahlungszeilen eines " +"bestimmten PoS-Auftrags ändern möchten.\n" +"* 'Rückerstattung und Wiederverkauf': Odoo erstattet den aktuellen PoS-" +"Auftrag zurück, um ihn zu stornieren, und erstellt einen neuen PoS-Auftrag " +"mit den korrekten Zahlungszeilen.\n" +"* 'Zahlungen aktualisieren': Odoo wird die Zahlungszeilen ändern.\n" +"\n" +"Hinweis: In einigen Ländern ist die Option 'Zahlungen aktualisieren' " +"gesetzlich nicht erlaubt, da die Bestellhistorie nicht verändert werden darf." + +#. module: pos_payment_change +#: model:ir.model,name:pos_payment_change.model_pos_payment_change_wizard +msgid "PoS Payment Change Wizard" +msgstr "PoS-Zahlungsänderungs-Assistent" + +#. module: pos_payment_change +#: model:ir.model,name:pos_payment_change.model_pos_payment_change_wizard_new_line +msgid "PoS Payment Change Wizard New Line" +msgstr "PoS-Zahlungsänderungsassistent Neue Zeile" + +#. module: pos_payment_change +#: model:ir.model,name:pos_payment_change.model_pos_payment_change_wizard_old_line +msgid "PoS Payment Change Wizard Old Line" +msgstr "PoS-Zahlungsänderungsassistent Alte Zeile" + +#. module: pos_payment_change +#: model:ir.model,name:pos_payment_change.model_pos_config +msgid "Point of Sale Configuration" +msgstr "Konfiguration der Verkaufsstelle" + +#. module: pos_payment_change +#: model:ir.model,name:pos_payment_change.model_pos_order +msgid "Point of Sale Orders" +msgstr "Bestellungen am Point of Sale" + +#. module: pos_payment_change +#: selection:pos.config,payment_change_policy:0 +msgid "Refund and Resale" +msgstr "Rückerstattung und Wiederverkauf" + +#. module: pos_payment_change +#: code:addons/pos_payment_change/models/pos_order.py:43 +#, python-format +msgid "The payments of the Order %s (Ref: %s) has been changed by %s at %s." +msgstr "Die Zahlungen des Auftrags %s (Ref: %s) wurden von %s bei %s geändert." + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__amount_total +#: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_payment_change_wizard_form +msgid "Total" +msgstr "Gesamt" + +#. module: pos_payment_change +#: code:addons/pos_payment_change/models/pos_config.py:43 +#, python-format +msgid "Unable to use the 'Update Payments' options for companies that have unalterable accounting." +msgstr "" +"Die Optionen 'Zahlungen aktualisieren' können nicht für Firmen mit " +"unveränderlicher Buchhaltung verwendet werden." + +#. module: pos_payment_change +#: selection:pos.config,payment_change_policy:0 +msgid "Update Payments" +msgstr "Zahlungen aktualisieren" + +#. module: pos_payment_change +#: model:ir.model.fields,help:pos_payment_change.field_pos_payment_change_wizard_new_line__company_currency_id +#: model:ir.model.fields,help:pos_payment_change.field_pos_payment_change_wizard_old_line__company_currency_id +msgid "Utility field to express amount currency" +msgstr "Utility-Feld zur Angabe der Betragswährung" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__wizard_id +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__wizard_id +msgid "Wizard" +msgstr "Assistent" + +#. module: pos_payment_change +#: code:addons/pos_payment_change/models/pos_order.py:97 +#, python-format +msgid "You can not change payments of the POS '%s' because the associated session '%s' has been closed!" +msgstr "" +"Sie können Zahlungen der Kasse '%s' nicht ändern, da die zugehörige Sitzung " +"'%s' geschlossen wurde!" From 3878563d47118f4886a4a3126c609ea575440028 Mon Sep 17 00:00:00 2001 From: fshah Date: Mon, 24 May 2021 16:45:11 +0530 Subject: [PATCH 11/35] [IMP] pos_payment_change: isort, black, prettier. --- pos_payment_change/__manifest__.py | 2 +- pos_payment_change/models/pos_config.py | 33 +++--- pos_payment_change/models/pos_order.py | 32 +++--- pos_payment_change/tests/test_module.py | 103 +++++++++--------- pos_payment_change/views/view_pos_config.xml | 15 +-- pos_payment_change/views/view_pos_order.xml | 11 +- .../wizards/pos_payment_change_wizard.py | 52 +++++---- .../pos_payment_change_wizard_new_line.py | 28 ++--- .../pos_payment_change_wizard_old_line.py | 18 +-- .../view_pos_payment_change_wizard.xml | 31 ++++-- 10 files changed, 179 insertions(+), 146 deletions(-) diff --git a/pos_payment_change/__manifest__.py b/pos_payment_change/__manifest__.py index 5fe98e67f7..c0865707f9 100644 --- a/pos_payment_change/__manifest__.py +++ b/pos_payment_change/__manifest__.py @@ -8,7 +8,7 @@ " the session is not closed.", "category": "Point Of Sale", "author": "GRAP, Odoo Community Association (OCA)", - "website": "https://www.github.com/OCA/pos", + "website": "https://github.com/OCA/pos", "license": "AGPL-3", "depends": ["point_of_sale"], "maintainers": ["legalsylvain"], diff --git a/pos_payment_change/models/pos_config.py b/pos_payment_change/models/pos_config.py index 2b6d1a78a9..2e34a153ea 100644 --- a/pos_payment_change/models/pos_config.py +++ b/pos_payment_change/models/pos_config.py @@ -10,13 +10,14 @@ class PosConfig(models.Model): _inherit = "pos.config" _PAYMENT_CHANGE_POLICY_SELECTION = [ - ('refund', "Refund and Resale"), - ('update', "Update Payments"), + ("refund", "Refund and Resale"), + ("update", "Update Payments"), ] payment_change_policy = fields.Selection( selection=_PAYMENT_CHANGE_POLICY_SELECTION, - default="refund", required=True, + default="refund", + required=True, help="Payment Change Policy when users want" " to change the payment lines of a given PoS Order.\n" "* 'Refund and Resale': Odoo will refund the current" @@ -25,22 +26,26 @@ class PosConfig(models.Model): "* 'Update Payments': Odoo will change payment lines.\n\n" "Note : In some countries the 'Update Payments' Option" " is not allowed by law, because orders history shouldn't" - " not be altered.") + " not be altered.", + ) @api.constrains("payment_change_policy") def _check_payment_change_policy(self): # Check if certification module is installed # and if yes, if 'update payments' option is allowed - module_states = self.env["ir.module.module"].sudo().search([ - ("name", "=", "l10n_fr_certification")] - ).mapped("state") + module_states = ( + self.env["ir.module.module"] + .sudo() + .search([("name", "=", "l10n_fr_certification")]) + .mapped("state") + ) if "installed" not in module_states: return - for config in self.filtered( - lambda x: x.payment_change_policy == "update" - ): + for config in self.filtered(lambda x: x.payment_change_policy == "update"): if config.company_id._is_accounting_unalterable(): - raise ValidationError(_( - "Unable to use the 'Update Payments' options" - " for companies that have unalterable accounting." - )) + raise ValidationError( + _( + "Unable to use the 'Update Payments' options" + " for companies that have unalterable accounting." + ) + ) diff --git a/pos_payment_change/models/pos_order.py b/pos_payment_change/models/pos_order.py index a0796a29fe..f7f121d96f 100644 --- a/pos_payment_change/models/pos_order.py +++ b/pos_payment_change/models/pos_order.py @@ -6,8 +6,8 @@ from datetime import datetime from odoo import _, api, fields, models -from odoo.tools import float_is_zero from odoo.exceptions import Warning as UserError +from odoo.tools import float_is_zero class PosOrder(models.Model): @@ -28,15 +28,17 @@ def change_payment(self, payment_lines): # Removing zero lines precision = self.pricelist_id.currency_id.decimal_places payment_lines = [ - x for x in payment_lines if not float_is_zero( - x["amount"], precision_digits=precision) + x + for x in payment_lines + if not float_is_zero(x["amount"], precision_digits=precision) ] self._check_payment_change_allowed() comment = _( "The payments of the Order %s (Ref: %s) has been changed" - " by %s at %s." % ( + " by %s at %s." + % ( self.name, self.pos_reference, self.env.user.name, @@ -58,26 +60,28 @@ def change_payment(self, payment_lines): refund_order = self.browse(refund_result["res_id"]) for statement in self.statement_ids: - refund_order.add_payment({ - "journal": statement.journal_id.id, - "amount": - statement.amount, - "payment_date": fields.Date.context_today(self), - }) + refund_order.add_payment( + { + "journal": statement.journal_id.id, + "amount": -statement.amount, + "payment_date": fields.Date.context_today(self), + } + ) refund_order.action_pos_order_paid() # Resale order and mark it as paid # with the new payment - resale_order = self.copy( - default={"pos_reference": self.pos_reference} - ) + resale_order = self.copy(default={"pos_reference": self.pos_reference}) for line in payment_lines: resale_order.add_payment(line) resale_order.action_pos_order_paid() orders += refund_order + resale_order - comment += _(" (Refund Order: %s ; Resale Order: %s)" % ( - refund_order.name, resale_order.name)) + comment += _( + " (Refund Order: %s ; Resale Order: %s)" + % (refund_order.name, resale_order.name) + ) for order in orders: order.note = "%s\n%s" % (order.note or "", comment) return orders diff --git a/pos_payment_change/tests/test_module.py b/pos_payment_change/tests/test_module.py index a27d430e34..6dcc56f629 100644 --- a/pos_payment_change/tests/test_module.py +++ b/pos_payment_change/tests/test_module.py @@ -3,8 +3,8 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo import fields -from odoo.tests.common import TransactionCase from odoo.exceptions import UserError +from odoo.tests.common import TransactionCase class TestModule(TransactionCase): @@ -15,7 +15,7 @@ def setUp(self): self.PosSession = self.env["pos.session"] self.PosOrder = self.env["pos.order"] self.AccountJournal = self.env["account.journal"] - self.PosMakePayment = self.env['pos.make.payment'] + self.PosMakePayment = self.env["pos.make.payment"] self.PosPaymentChangeWizard = self.env["pos.payment.change.wizard"] self.PosPaymentChangeWizardNewLine = self.env[ "pos.payment.change.wizard.new.line" @@ -25,16 +25,20 @@ def setUp(self): def _initialize_journals_open_session(self): - self.check_journal = self.AccountJournal.create({ - "name": "Demo Check Journal", - "type": "bank", - "journal_user": True, - }) - self.cash_journal = self.AccountJournal.create({ - "name": "Demo Cash Journal", - "type": "cash", - "journal_user": True, - }) + self.check_journal = self.AccountJournal.create( + { + "name": "Demo Check Journal", + "type": "bank", + "journal_user": True, + } + ) + self.cash_journal = self.AccountJournal.create( + { + "name": "Demo Cash Journal", + "type": "cash", + "journal_user": True, + } + ) # create new session and open it self.pos_config.journal_ids = [ @@ -60,40 +64,42 @@ def _sale(self, journal_1, price_1, journal_2=False, price_2=0.0): "price_subtotal": price, "price_subtotal_incl": price, } - order = self.PosOrder.create({ - "session_id": self.session.id, - "amount_tax": 0, - "amount_total": price, - "amount_paid": price, - "amount_return": 0, - "lines": [[0, False, line_vals]], - }) - order.add_payment({ - 'amount': price_1, - 'payment_date': fields.Date.today(), - 'payment_name': "Demo", - 'journal': journal_1.id, - }) + order = self.PosOrder.create( + { + "session_id": self.session.id, + "amount_tax": 0, + "amount_total": price, + "amount_paid": price, + "amount_return": 0, + "lines": [[0, False, line_vals]], + } + ) + order.add_payment( + { + "amount": price_1, + "payment_date": fields.Date.today(), + "payment_name": "Demo", + "journal": journal_1.id, + } + ) if journal_2: - order.add_payment({ - 'amount': price_2, - 'payment_date': fields.Date.today(), - 'payment_name': "Demo", - 'journal': journal_2.id, - }) + order.add_payment( + { + "amount": price_2, + "payment_date": fields.Date.today(), + "payment_name": "Demo", + "journal": journal_2.id, + } + ) order.action_pos_order_paid() return order def _change_payment( - self, order, journal_1, amount_1, journal_2=False, amount_2=0.0 + self, order, journal_1, amount_1, journal_2=False, amount_2=0.0 ): # Switch to check journal - wizard = self.PosPaymentChangeWizard.with_context( - active_id=order.id - ).create({}) - self.PosPaymentChangeWizardNewLine.with_context( - active_id=order.id - ).create( + wizard = self.PosPaymentChangeWizard.with_context(active_id=order.id).create({}) + self.PosPaymentChangeWizardNewLine.with_context(active_id=order.id).create( { "wizard_id": wizard.id, "new_journal_id": journal_1.id, @@ -101,9 +107,7 @@ def _change_payment( } ) if journal_2: - self.PosPaymentChangeWizardNewLine.with_context( - active_id=order.id - ).create( + self.PosPaymentChangeWizardNewLine.with_context(active_id=order.id).create( { "wizard_id": wizard.id, "new_journal_id": journal_2.id, @@ -124,11 +128,9 @@ def test_01_payment_change_policy_update(self): with self.assertRaises(UserError): # Should not work if total is not correct - self._change_payment( - order, self.cash_journal, 10, self.check_journal, 10) + self._change_payment(order, self.cash_journal, 10, self.check_journal, 10) - self._change_payment( - order, self.cash_journal, 10, self.check_journal, 90) + self._change_payment(order, self.cash_journal, 10, self.check_journal, 90) # check Session self.assertEqual( @@ -147,8 +149,7 @@ def test_01_payment_change_policy_update(self): self.assertEqual( order_qty, len(self.PosOrder.search([])), - "In 'Update' mode, changing payment should not create" - " other PoS Orders", + "In 'Update' mode, changing payment should not create" " other PoS Orders", ) def test_02_payment_change_policy_refund(self): @@ -160,13 +161,11 @@ def test_02_payment_change_policy_refund(self): order_qty = len(self.PosOrder.search([])) - self._change_payment( - order, self.cash_journal, 50, self.check_journal, 50) + self._change_payment(order, self.cash_journal, 50, self.check_journal, 50) # Check Order quantity self.assertEqual( order_qty + 2, len(self.PosOrder.search([])), - "In 'Refund' mode, changing payment should generate" - " two new PoS Orders", + "In 'Refund' mode, changing payment should generate" " two new PoS Orders", ) diff --git a/pos_payment_change/views/view_pos_config.xml b/pos_payment_change/views/view_pos_config.xml index 8fa4bcdc12..e4fadc80c4 100644 --- a/pos_payment_change/views/view_pos_config.xml +++ b/pos_payment_change/views/view_pos_config.xml @@ -1,24 +1,25 @@ - + - pos.config - + - +
Payment Change Policy
- +
diff --git a/pos_payment_change/views/view_pos_order.xml b/pos_payment_change/views/view_pos_order.xml index 701ec7888e..bde665be8a 100644 --- a/pos_payment_change/views/view_pos_order.xml +++ b/pos_payment_change/views/view_pos_order.xml @@ -1,10 +1,9 @@ - + - @@ -12,9 +11,13 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). diff --git a/pos_payment_change/wizards/pos_payment_change_wizard.py b/pos_payment_change/wizards/pos_payment_change_wizard.py index 96edfb46af..e53d200e70 100644 --- a/pos_payment_change/wizards/pos_payment_change_wizard.py +++ b/pos_payment_change/wizards/pos_payment_change_wizard.py @@ -11,9 +11,7 @@ class PosPaymentChangeWizard(models.TransientModel): _description = "PoS Payment Change Wizard" # Column Section - order_id = fields.Many2one( - comodel_name="pos.order", string="Order", readonly=True - ) + order_id = fields.Many2one(comodel_name="pos.order", string="Order", readonly=True) old_line_ids = fields.One2many( comodel_name="pos.payment.change.wizard.old.line", @@ -38,16 +36,23 @@ def default_get(self, fields): order = PosOrder.browse(self._context.get("active_id")) old_lines_vals = [] for statement_line in order.statement_ids: - old_lines_vals.append((0, 0, { - "old_journal_id": statement_line.statement_id.journal_id.id, - "amount": statement_line.amount - } - )) - res.update({ - "order_id": order.id, - "amount_total": order.amount_total, - "old_line_ids": old_lines_vals, - }) + old_lines_vals.append( + ( + 0, + 0, + { + "old_journal_id": statement_line.statement_id.journal_id.id, + "amount": statement_line.amount, + }, + ) + ) + res.update( + { + "order_id": order.id, + "amount_total": order.amount_total, + "old_line_ids": old_lines_vals, + } + ) return res # View section @@ -71,11 +76,14 @@ def button_change_payment(self): ) # Change payment - new_payments = [{ - "journal": line.new_journal_id.id, - "amount": line.amount, - "payment_date": fields.Date.context_today(self), - } for line in self.new_line_ids] + new_payments = [ + { + "journal": line.new_journal_id.id, + "amount": line.amount, + "payment_date": fields.Date.context_today(self), + } + for line in self.new_line_ids + ] orders = order.change_payment(new_payments) @@ -87,12 +95,10 @@ def button_change_payment(self): if len(orders) == 1: # if policy is 'update', only close the pop up - action = {'type': 'ir.actions.act_window_close'} + action = {"type": "ir.actions.act_window_close"} else: # otherwise (refund policy), displays the 3 orders - action = self.env.ref( - "point_of_sale.action_pos_pos_form" - ).read()[0] - action['domain'] = [('id', 'in', orders.ids)] + action = self.env.ref("point_of_sale.action_pos_pos_form").read()[0] + action["domain"] = [("id", "in", orders.ids)] return action diff --git a/pos_payment_change/wizards/pos_payment_change_wizard_new_line.py b/pos_payment_change/wizards/pos_payment_change_wizard_new_line.py index d234d1d0e6..080d8ab325 100644 --- a/pos_payment_change/wizards/pos_payment_change_wizard_new_line.py +++ b/pos_payment_change/wizards/pos_payment_change_wizard_new_line.py @@ -10,7 +10,8 @@ class PosPaymentChangeWizardLine(models.TransientModel): _description = "PoS Payment Change Wizard New Line" wizard_id = fields.Many2one( - comodel_name="pos.payment.change.wizard", required=True, + comodel_name="pos.payment.change.wizard", + required=True, ) new_journal_id = fields.Many2one( @@ -21,24 +22,26 @@ class PosPaymentChangeWizardLine(models.TransientModel): ) company_currency_id = fields.Many2one( - comodel_name='res.currency', store=True, - related='new_journal_id.currency_id', - string="Company Currency", readonly=True, - help='Utility field to express amount currency' + comodel_name="res.currency", + store=True, + related="new_journal_id.currency_id", + string="Company Currency", + readonly=True, + help="Utility field to express amount currency", ) amount = fields.Monetary( string="Amount", - required=True, default=0.0, - currency_field='company_currency_id' + required=True, + default=0.0, + currency_field="company_currency_id", ) @api.model def _domain_new_journal_id(self): PosOrder = self.env["pos.order"] order = PosOrder.browse(self.env.context.get("active_id")) - return [("id", "in", order.mapped( - "session_id.statement_ids.journal_id").ids)] + return [("id", "in", order.mapped("session_id.statement_ids.journal_id").ids)] # View Section @api.model @@ -48,9 +51,8 @@ def default_get(self, fields): return res balance = self._context.get("amount_total", 0.0) for line in self.wizard_id.resolve_2many_commands( - "new_line_ids", - self._context["new_line_ids"], - fields=["amount"]): + "new_line_ids", self._context["new_line_ids"], fields=["amount"] + ): balance -= line.get("amount") - res.update({'amount': balance}) + res.update({"amount": balance}) return res diff --git a/pos_payment_change/wizards/pos_payment_change_wizard_old_line.py b/pos_payment_change/wizards/pos_payment_change_wizard_old_line.py index 8829fd1f82..e2237b8f68 100644 --- a/pos_payment_change/wizards/pos_payment_change_wizard_old_line.py +++ b/pos_payment_change/wizards/pos_payment_change_wizard_old_line.py @@ -10,7 +10,8 @@ class PosPaymentChangeWizardOldLine(models.TransientModel): _description = "PoS Payment Change Wizard Old Line" wizard_id = fields.Many2one( - comodel_name="pos.payment.change.wizard", required=True, + comodel_name="pos.payment.change.wizard", + required=True, ) old_journal_id = fields.Many2one( @@ -21,15 +22,18 @@ class PosPaymentChangeWizardOldLine(models.TransientModel): ) company_currency_id = fields.Many2one( - comodel_name='res.currency', store=True, - related='old_journal_id.currency_id', - string="Company Currency", readonly=True, - help='Utility field to express amount currency' + comodel_name="res.currency", + store=True, + related="old_journal_id.currency_id", + string="Company Currency", + readonly=True, + help="Utility field to express amount currency", ) amount = fields.Monetary( string="Amount", required=True, - readonly=True, default=0.0, - currency_field='company_currency_id' + readonly=True, + default=0.0, + currency_field="company_currency_id", ) diff --git a/pos_payment_change/wizards/view_pos_payment_change_wizard.xml b/pos_payment_change/wizards/view_pos_payment_change_wizard.xml index e888fef112..1eb7e6d883 100644 --- a/pos_payment_change/wizards/view_pos_payment_change_wizard.xml +++ b/pos_payment_change/wizards/view_pos_payment_change_wizard.xml @@ -1,10 +1,9 @@ - + - @@ -13,25 +12,35 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
- + - - + + - + - - + +
-
From 9fc45fd03833bb3715bdb469e8b4664d3eb72657 Mon Sep 17 00:00:00 2001 From: fshah Date: Tue, 25 May 2021 17:11:45 +0530 Subject: [PATCH 12/35] [MIG] Migrate module pos_payment_change to v14. --- pos_payment_change/README.rst | 19 ++--- pos_payment_change/__manifest__.py | 3 +- .../i18n/pos_payment_change.pot | 53 ++++++++----- pos_payment_change/models/pos_order.py | 17 ++-- pos_payment_change/readme/CONTRIBUTORS.rst | 1 + .../security/ir.model.access.csv | 4 + .../static/description/index.html | 15 ++-- pos_payment_change/tests/test_module.py | 78 ++++++++++--------- .../wizards/pos_payment_change_wizard.py | 12 +-- .../pos_payment_change_wizard_new_line.py | 18 ++--- .../pos_payment_change_wizard_old_line.py | 8 +- .../view_pos_payment_change_wizard.xml | 5 +- 12 files changed, 127 insertions(+), 106 deletions(-) create mode 100644 pos_payment_change/security/ir.model.access.csv diff --git a/pos_payment_change/README.rst b/pos_payment_change/README.rst index 600e2ec741..85f0b37898 100644 --- a/pos_payment_change/README.rst +++ b/pos_payment_change/README.rst @@ -14,13 +14,13 @@ Point Of Sale - Change Payments :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fpos-lightgray.png?logo=github - :target: https://github.com/OCA/pos/tree/12.0/pos_payment_change + :target: https://github.com/OCA/pos/tree/14.0/pos_payment_change :alt: OCA/pos .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/pos-12-0/pos-12-0-pos_payment_change + :target: https://translation.odoo-community.org/projects/pos-14-0/pos-14-0-pos_payment_change :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/184/12.0 + :target: https://runbot.odoo-community.org/runbot/184/14.0 :alt: Try me on Runbot |badge1| |badge2| |badge3| |badge4| |badge5| @@ -52,7 +52,7 @@ Two options are available: * 'Update Payments': Odoo will change payment lines. -.. figure:: https://raw.githubusercontent.com/OCA/pos/12.0/pos_payment_change/static/description/pos_config_form.png +.. figure:: https://raw.githubusercontent.com/OCA/pos/14.0/pos_payment_change/static/description/pos_config_form.png **Note** @@ -71,12 +71,12 @@ Usage * Click on the button 'Change Payments' -.. figure:: https://raw.githubusercontent.com/OCA/pos/12.0/pos_payment_change/static/description/pos_order_form.png +.. figure:: https://raw.githubusercontent.com/OCA/pos/14.0/pos_payment_change/static/description/pos_order_form.png * In the pop up wizard, select the real payment(s) that have been used to pay the order -.. figure:: https://raw.githubusercontent.com/OCA/pos/12.0/pos_payment_change/static/description/pos_payment_change_wizard_form.png +.. figure:: https://raw.githubusercontent.com/OCA/pos/14.0/pos_payment_change/static/description/pos_payment_change_wizard_form.png * Then click on the button 'Change Payments' @@ -85,7 +85,7 @@ Usage If the option 'Refund and Resale' is selected, changing the payments will display the three PoS orders. the oringal one, the refund one, and the new one. -.. figure:: https://raw.githubusercontent.com/OCA/pos/12.0/pos_payment_change/static/description/pos_order_tree.png +.. figure:: https://raw.githubusercontent.com/OCA/pos/14.0/pos_payment_change/static/description/pos_order_tree.png Bug Tracker =========== @@ -93,7 +93,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -110,6 +110,7 @@ Contributors * Sylvain LE GAL * Julien WESTE +* Foram Shah Other credits ~~~~~~~~~~~~~ @@ -140,6 +141,6 @@ Current `maintainer `__: |maintainer-legalsylvain| -This module is part of the `OCA/pos `_ project on GitHub. +This module is part of the `OCA/pos `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/pos_payment_change/__manifest__.py b/pos_payment_change/__manifest__.py index c0865707f9..08665d2800 100644 --- a/pos_payment_change/__manifest__.py +++ b/pos_payment_change/__manifest__.py @@ -3,7 +3,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { "name": "Point Of Sale - Change Payments", - "version": "12.0.1.0.2", + "version": "14.0.1.0.0", "summary": "Allow cashier to change order payments, as long as" " the session is not closed.", "category": "Point Of Sale", @@ -14,6 +14,7 @@ "maintainers": ["legalsylvain"], "development_status": "Beta", "data": [ + "security/ir.model.access.csv", "wizards/view_pos_payment_change_wizard.xml", "views/view_pos_config.xml", "views/view_pos_order.xml", diff --git a/pos_payment_change/i18n/pos_payment_change.pot b/pos_payment_change/i18n/pos_payment_change.pot index 84a54550f2..9e0978f581 100644 --- a/pos_payment_change/i18n/pos_payment_change.pot +++ b/pos_payment_change/i18n/pos_payment_change.pot @@ -1,12 +1,12 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: -# * pos_payment_change +# * pos_payment_change # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 12.0\n" +"Project-Id-Version: Odoo Server 14.0\n" "Report-Msgid-Bugs-To: \n" -"Last-Translator: <>\n" +"Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -14,7 +14,7 @@ msgstr "" "Plural-Forms: \n" #. module: pos_payment_change -#: code:addons/pos_payment_change/models/pos_order.py:79 +#: code:addons/pos_payment_change/models/pos_order.py:0 #, python-format msgid " (Refund Order: %s ; Resale Order: %s)" msgstr "" @@ -63,9 +63,10 @@ msgid "Created on" msgstr "" #. module: pos_payment_change -#: code:addons/pos_payment_change/wizards/pos_payment_change_wizard.py:69 +#: code:addons/pos_payment_change/wizards/pos_payment_change_wizard.py:0 #, python-format -msgid "Differences between the two values for the POS Order '%s':\n" +msgid "" +"Differences between the two values for the POS Order '%s':\n" "\n" " * Total of all the new payments %s;\n" " * Total of the POS Order %s;\n" @@ -74,6 +75,8 @@ msgid "Differences between the two values for the POS Order '%s':\n" msgstr "" #. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_config__display_name +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_order__display_name #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__display_name #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__display_name #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__display_name @@ -81,6 +84,8 @@ msgid "Display Name" msgstr "" #. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_config__id +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_order__id #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__id #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__id #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__id @@ -88,12 +93,8 @@ msgid "ID" msgstr "" #. module: pos_payment_change -#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__new_journal_id -#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__old_journal_id -msgid "Journal" -msgstr "" - -#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_config____last_update +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_order____last_update #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard____last_update #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line____last_update #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line____last_update @@ -136,13 +137,20 @@ msgstr "" #. module: pos_payment_change #: model:ir.model.fields,help:pos_payment_change.field_pos_config__payment_change_policy -msgid "Payment Change Policy when users want to change the payment lines of a given PoS Order.\n" +msgid "" +"Payment Change Policy when users want to change the payment lines of a given PoS Order.\n" "* 'Refund and Resale': Odoo will refund the current Pos Order to cancel it, and create a new PoS Order with the correct payment lines.\n" "* 'Update Payments': Odoo will change payment lines.\n" "\n" "Note : In some countries the 'Update Payments' Option is not allowed by law, because orders history shouldn't not be altered." msgstr "" +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__new_payment_method_id +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__old_payment_method_id +msgid "Payment Method" +msgstr "" + #. module: pos_payment_change #: model:ir.model,name:pos_payment_change.model_pos_payment_change_wizard msgid "PoS Payment Change Wizard" @@ -169,12 +177,12 @@ msgid "Point of Sale Orders" msgstr "" #. module: pos_payment_change -#: selection:pos.config,payment_change_policy:0 +#: model:ir.model.fields.selection,name:pos_payment_change.selection__pos_config__payment_change_policy__refund msgid "Refund and Resale" msgstr "" #. module: pos_payment_change -#: code:addons/pos_payment_change/models/pos_order.py:43 +#: code:addons/pos_payment_change/models/pos_order.py:0 #, python-format msgid "The payments of the Order %s (Ref: %s) has been changed by %s at %s." msgstr "" @@ -186,13 +194,15 @@ msgid "Total" msgstr "" #. module: pos_payment_change -#: code:addons/pos_payment_change/models/pos_config.py:43 +#: code:addons/pos_payment_change/models/pos_config.py:0 #, python-format -msgid "Unable to use the 'Update Payments' options for companies that have unalterable accounting." +msgid "" +"Unable to use the 'Update Payments' options for companies that have " +"unalterable accounting." msgstr "" #. module: pos_payment_change -#: selection:pos.config,payment_change_policy:0 +#: model:ir.model.fields.selection,name:pos_payment_change.selection__pos_config__payment_change_policy__update msgid "Update Payments" msgstr "" @@ -209,8 +219,9 @@ msgid "Wizard" msgstr "" #. module: pos_payment_change -#: code:addons/pos_payment_change/models/pos_order.py:97 +#: code:addons/pos_payment_change/models/pos_order.py:0 #, python-format -msgid "You can not change payments of the POS '%s' because the associated session '%s' has been closed!" +msgid "" +"You can not change payments of the POS '%s' because the associated session " +"'%s' has been closed!" msgstr "" - diff --git a/pos_payment_change/models/pos_order.py b/pos_payment_change/models/pos_order.py index f7f121d96f..c1b6fe5348 100644 --- a/pos_payment_change/models/pos_order.py +++ b/pos_payment_change/models/pos_order.py @@ -5,7 +5,7 @@ from datetime import datetime -from odoo import _, api, fields, models +from odoo import _, fields, models from odoo.exceptions import Warning as UserError from odoo.tools import float_is_zero @@ -13,7 +13,6 @@ class PosOrder(models.Model): _inherit = "pos.order" - @api.multi def change_payment(self, payment_lines): """ Change payment of a given order. @@ -47,7 +46,7 @@ def change_payment(self, payment_lines): ) if self.config_id.payment_change_policy == "update": - self.statement_ids.with_context().unlink() + self.payment_ids.with_context().unlink() # Create new payment for line in payment_lines: @@ -58,22 +57,23 @@ def change_payment(self, payment_lines): # with same payment method as the original one refund_result = self.refund() refund_order = self.browse(refund_result["res_id"]) - - for statement in self.statement_ids: + for payment in self.payment_ids: refund_order.add_payment( { - "journal": statement.journal_id.id, - "amount": -statement.amount, + "pos_order_id": refund_order.id, + "payment_method_id": payment.payment_method_id.id, + "amount": -payment.amount, "payment_date": fields.Date.context_today(self), } ) + refund_order.action_pos_order_paid() # Resale order and mark it as paid # with the new payment resale_order = self.copy(default={"pos_reference": self.pos_reference}) - for line in payment_lines: + line.update({"pos_order_id": resale_order.id}) resale_order.add_payment(line) resale_order.action_pos_order_paid() @@ -86,7 +86,6 @@ def change_payment(self, payment_lines): order.note = "%s\n%s" % (order.note or "", comment) return orders - @api.multi def _check_payment_change_allowed(self): """Return True if the user can change the payment of a POS, depending of the state of the current session.""" diff --git a/pos_payment_change/readme/CONTRIBUTORS.rst b/pos_payment_change/readme/CONTRIBUTORS.rst index 7754037b21..49812a4137 100644 --- a/pos_payment_change/readme/CONTRIBUTORS.rst +++ b/pos_payment_change/readme/CONTRIBUTORS.rst @@ -1,2 +1,3 @@ * Sylvain LE GAL * Julien WESTE +* Foram Shah diff --git a/pos_payment_change/security/ir.model.access.csv b/pos_payment_change/security/ir.model.access.csv new file mode 100644 index 0000000000..913b1232b5 --- /dev/null +++ b/pos_payment_change/security/ir.model.access.csv @@ -0,0 +1,4 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_pos_payment_change_wizard,access_pos_payment_change_wizard,model_pos_payment_change_wizard,base.group_user,1,1,1,1 +access_pos_payment_change_wizard_new_line,access_pos_payment_change_wizard_new_line,model_pos_payment_change_wizard_new_line,base.group_user,1,1,1,1 +access_pos_payment_change_wizard_old_line,access_pos_payment_change_wizard_old_line,model_pos_payment_change_wizard_old_line,base.group_user,1,1,1,1 diff --git a/pos_payment_change/static/description/index.html b/pos_payment_change/static/description/index.html index b2179e428b..c56ddde124 100644 --- a/pos_payment_change/static/description/index.html +++ b/pos_payment_change/static/description/index.html @@ -367,7 +367,7 @@

Point Of Sale - Change Payments

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

Beta License: AGPL-3 OCA/pos Translate me on Weblate Try me on Runbot

+

Beta License: AGPL-3 OCA/pos Translate me on Weblate Try me on Runbot

This module extends the functionnality of the Odoo Point of Sale to allow the cashier to change the payments of a PoS order.

This feature is usefull when the user realized that he did a mistake, @@ -403,7 +403,7 @@

Configuration

  • ‘Update Payments’: Odoo will change payment lines.
  • -https://raw.githubusercontent.com/OCA/pos/12.0/pos_payment_change/static/description/pos_config_form.png +https://raw.githubusercontent.com/OCA/pos/14.0/pos_payment_change/static/description/pos_config_form.png

    Note In some countries the ‘Update Payments’ Option @@ -420,14 +420,14 @@

    Usage

  • Click on the button ‘Change Payments’
  • -https://raw.githubusercontent.com/OCA/pos/12.0/pos_payment_change/static/description/pos_order_form.png +https://raw.githubusercontent.com/OCA/pos/14.0/pos_payment_change/static/description/pos_order_form.png
    • In the pop up wizard, select the real payment(s) that have been used to pay the order
    -https://raw.githubusercontent.com/OCA/pos/12.0/pos_payment_change/static/description/pos_payment_change_wizard_form.png +https://raw.githubusercontent.com/OCA/pos/14.0/pos_payment_change/static/description/pos_payment_change_wizard_form.png
    • Then click on the button ‘Change Payments’
    • @@ -436,7 +436,7 @@

      Usage

      If the option ‘Refund and Resale’ is selected, changing the payments will display the three PoS orders. the oringal one, the refund one, and the new one.

      -https://raw.githubusercontent.com/OCA/pos/12.0/pos_payment_change/static/description/pos_order_tree.png +https://raw.githubusercontent.com/OCA/pos/14.0/pos_payment_change/static/description/pos_order_tree.png
      @@ -444,7 +444,7 @@

      Bug Tracker

      Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed -feedback.

      +feedback.

      Do not contact contributors directly about support or help with technical issues.

      @@ -460,6 +460,7 @@

      Contributors

      @@ -479,7 +480,7 @@

      Maintainers

      promote its widespread use.

      Current maintainer:

      legalsylvain

      -

      This module is part of the OCA/pos project on GitHub.

      +

      This module is part of the OCA/pos project on GitHub.

      You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

      diff --git a/pos_payment_change/tests/test_module.py b/pos_payment_change/tests/test_module.py index 6dcc56f629..05bb086b9e 100644 --- a/pos_payment_change/tests/test_module.py +++ b/pos_payment_change/tests/test_module.py @@ -14,7 +14,8 @@ def setUp(self): super().setUp() self.PosSession = self.env["pos.session"] self.PosOrder = self.env["pos.order"] - self.AccountJournal = self.env["account.journal"] + self.PosPaymentMethod = self.env["pos.payment.method"] + self.PosPayment = self.env["pos.payment"] self.PosMakePayment = self.env["pos.make.payment"] self.PosPaymentChangeWizard = self.env["pos.payment.change.wizard"] self.PosPaymentChangeWizardNewLine = self.env[ @@ -24,37 +25,30 @@ def setUp(self): self.pos_config = self.env.ref("point_of_sale.pos_config_main").copy() def _initialize_journals_open_session(self): - - self.check_journal = self.AccountJournal.create( + account_id = self.env.company.account_default_pos_receivable_account_id + self.bank_payment_method = self.PosPaymentMethod.create( { - "name": "Demo Check Journal", - "type": "bank", - "journal_user": True, + "name": "Bank", + "receivable_account_id": account_id.id, } ) - self.cash_journal = self.AccountJournal.create( + self.cash_payment_method = self.PosPaymentMethod.create( { - "name": "Demo Cash Journal", - "type": "cash", - "journal_user": True, + "name": "Cash", + "is_cash_count": True, + "receivable_account_id": account_id.id, } ) # create new session and open it - self.pos_config.journal_ids = [ - self.check_journal.id, - self.cash_journal.id, + self.pos_config.payment_method_ids = [ + self.bank_payment_method.id, + self.cash_payment_method.id, ] self.pos_config.open_session_cb() self.session = self.pos_config.current_session_id - self.check_statement = self.session.statement_ids.filtered( - lambda x: x.journal_id == self.check_journal - ) - self.cash_statement = self.session.statement_ids.filtered( - lambda x: x.journal_id == self.cash_journal - ) - def _sale(self, journal_1, price_1, journal_2=False, price_2=0.0): + def _sale(self, payment_method_1, price_1, payment_method_2=False, price_2=0.0): price = price_1 + price_2 line_vals = { "name": "OL/0001", @@ -76,41 +70,41 @@ def _sale(self, journal_1, price_1, journal_2=False, price_2=0.0): ) order.add_payment( { + "pos_order_id": order.id, "amount": price_1, "payment_date": fields.Date.today(), - "payment_name": "Demo", - "journal": journal_1.id, + "payment_method_id": payment_method_1.id, } ) - if journal_2: + if payment_method_2: order.add_payment( { + "pos_order_id": order.id, "amount": price_2, "payment_date": fields.Date.today(), - "payment_name": "Demo", - "journal": journal_2.id, + "payment_method_id": payment_method_2.id, } ) order.action_pos_order_paid() return order def _change_payment( - self, order, journal_1, amount_1, journal_2=False, amount_2=0.0 + self, order, payment_method_1, amount_1, payment_method_2=False, amount_2=0.0 ): # Switch to check journal wizard = self.PosPaymentChangeWizard.with_context(active_id=order.id).create({}) self.PosPaymentChangeWizardNewLine.with_context(active_id=order.id).create( { "wizard_id": wizard.id, - "new_journal_id": journal_1.id, + "new_payment_method_id": payment_method_1.id, "amount": amount_1, } ) - if journal_2: + if payment_method_2: self.PosPaymentChangeWizardNewLine.with_context(active_id=order.id).create( { "wizard_id": wizard.id, - "new_journal_id": journal_2.id, + "new_payment_method_id": payment_method_2.id, "amount": amount_2, } ) @@ -122,25 +116,35 @@ def test_01_payment_change_policy_update(self): self._initialize_journals_open_session() # Make a sale with 35 in cash journal and 65 in check - order = self._sale(self.cash_journal, 35, self.check_journal, 65) + order = self._sale(self.cash_payment_method, 35, self.bank_payment_method, 65) order_qty = len(self.PosOrder.search([])) with self.assertRaises(UserError): # Should not work if total is not correct - self._change_payment(order, self.cash_journal, 10, self.check_journal, 10) + self._change_payment( + order, self.cash_payment_method, 10, self.cash_payment_method, 10 + ) - self._change_payment(order, self.cash_journal, 10, self.check_journal, 90) + self._change_payment( + order, self.cash_payment_method, 10, self.bank_payment_method, 90 + ) + self.bank_payment = self.session.order_ids.mapped("payment_ids").filtered( + lambda x: x.payment_method_id == self.bank_payment_method + ) + self.cash_payment = self.session.order_ids.mapped("payment_ids").filtered( + lambda x: x.payment_method_id == self.cash_payment_method + ) # check Session self.assertEqual( - self.cash_statement.balance_end, + self.cash_payment.amount, 10, "Bad recompute of the balance for the statement cash", ) self.assertEqual( - self.check_statement.balance_end, + self.bank_payment.amount, 90, "Bad recompute of the balance for the statement check", ) @@ -157,11 +161,13 @@ def test_02_payment_change_policy_refund(self): self._initialize_journals_open_session() # Make a sale with 35 in cash journal and 65 in check - order = self._sale(self.cash_journal, 35, self.check_journal, 65) + order = self._sale(self.cash_payment_method, 35, self.bank_payment_method, 65) order_qty = len(self.PosOrder.search([])) - self._change_payment(order, self.cash_journal, 50, self.check_journal, 50) + self._change_payment( + order, self.cash_payment_method, 50, self.bank_payment_method, 50 + ) # Check Order quantity self.assertEqual( diff --git a/pos_payment_change/wizards/pos_payment_change_wizard.py b/pos_payment_change/wizards/pos_payment_change_wizard.py index e53d200e70..e99748273f 100644 --- a/pos_payment_change/wizards/pos_payment_change_wizard.py +++ b/pos_payment_change/wizards/pos_payment_change_wizard.py @@ -3,7 +3,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo import _, api, fields, models -from odoo.exceptions import Warning as UserError +from odoo.exceptions import UserError class PosPaymentChangeWizard(models.TransientModel): @@ -35,14 +35,14 @@ def default_get(self, fields): res = super().default_get(fields) order = PosOrder.browse(self._context.get("active_id")) old_lines_vals = [] - for statement_line in order.statement_ids: + for payment in order.payment_ids: old_lines_vals.append( ( 0, 0, { - "old_journal_id": statement_line.statement_id.journal_id.id, - "amount": statement_line.amount, + "old_payment_method_id": payment.payment_method_id.id, + "amount": payment.amount, }, ) ) @@ -56,7 +56,6 @@ def default_get(self, fields): return res # View section - @api.multi def button_change_payment(self): self.ensure_one() order = self.order_id @@ -78,7 +77,8 @@ def button_change_payment(self): # Change payment new_payments = [ { - "journal": line.new_journal_id.id, + "pos_order_id": order.id, + "payment_method_id": line.new_payment_method_id.id, "amount": line.amount, "payment_date": fields.Date.context_today(self), } diff --git a/pos_payment_change/wizards/pos_payment_change_wizard_new_line.py b/pos_payment_change/wizards/pos_payment_change_wizard_new_line.py index 080d8ab325..2d0b21a31f 100644 --- a/pos_payment_change/wizards/pos_payment_change_wizard_new_line.py +++ b/pos_payment_change/wizards/pos_payment_change_wizard_new_line.py @@ -14,17 +14,17 @@ class PosPaymentChangeWizardLine(models.TransientModel): required=True, ) - new_journal_id = fields.Many2one( - comodel_name="account.journal", - string="Journal", + new_payment_method_id = fields.Many2one( + comodel_name="pos.payment.method", + string="Payment Method", required=True, - domain=lambda s: s._domain_new_journal_id(), + domain=lambda s: s._domain_new_payment_method_id(), ) company_currency_id = fields.Many2one( comodel_name="res.currency", store=True, - related="new_journal_id.currency_id", + related="new_payment_method_id.company_id.currency_id", string="Company Currency", readonly=True, help="Utility field to express amount currency", @@ -38,10 +38,10 @@ class PosPaymentChangeWizardLine(models.TransientModel): ) @api.model - def _domain_new_journal_id(self): + def _domain_new_payment_method_id(self): PosOrder = self.env["pos.order"] order = PosOrder.browse(self.env.context.get("active_id")) - return [("id", "in", order.mapped("session_id.statement_ids.journal_id").ids)] + return [("id", "in", order.mapped("session_id.payment_method_ids").ids)] # View Section @api.model @@ -50,9 +50,7 @@ def default_get(self, fields): if "new_line_ids" not in self._context: return res balance = self._context.get("amount_total", 0.0) - for line in self.wizard_id.resolve_2many_commands( - "new_line_ids", self._context["new_line_ids"], fields=["amount"] - ): + for line in self.wizard_id.old_line_ids: balance -= line.get("amount") res.update({"amount": balance}) return res diff --git a/pos_payment_change/wizards/pos_payment_change_wizard_old_line.py b/pos_payment_change/wizards/pos_payment_change_wizard_old_line.py index e2237b8f68..383f2dc14e 100644 --- a/pos_payment_change/wizards/pos_payment_change_wizard_old_line.py +++ b/pos_payment_change/wizards/pos_payment_change_wizard_old_line.py @@ -14,9 +14,9 @@ class PosPaymentChangeWizardOldLine(models.TransientModel): required=True, ) - old_journal_id = fields.Many2one( - comodel_name="account.journal", - string="Journal", + old_payment_method_id = fields.Many2one( + comodel_name="pos.payment.method", + string="Payment Method", required=True, readonly=True, ) @@ -24,7 +24,7 @@ class PosPaymentChangeWizardOldLine(models.TransientModel): company_currency_id = fields.Many2one( comodel_name="res.currency", store=True, - related="old_journal_id.currency_id", + related="old_payment_method_id.company_id.currency_id", string="Company Currency", readonly=True, help="Utility field to express amount currency", diff --git a/pos_payment_change/wizards/view_pos_payment_change_wizard.xml b/pos_payment_change/wizards/view_pos_payment_change_wizard.xml index 1eb7e6d883..8640065fef 100644 --- a/pos_payment_change/wizards/view_pos_payment_change_wizard.xml +++ b/pos_payment_change/wizards/view_pos_payment_change_wizard.xml @@ -15,7 +15,7 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - + @@ -27,7 +27,7 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). > @@ -50,7 +50,6 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). Change Payments pos.payment.change.wizard - form form new From a02f31372e9cd491075f4f0e072f64c20a27e274 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bidoul?= Date: Fri, 24 Dec 2021 12:56:56 +0100 Subject: [PATCH 13/35] [FIX] pos_payment_change: fix test A cash payment method must have a cash journal. --- pos_payment_change/tests/test_module.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pos_payment_change/tests/test_module.py b/pos_payment_change/tests/test_module.py index 05bb086b9e..14f8deb1cd 100644 --- a/pos_payment_change/tests/test_module.py +++ b/pos_payment_change/tests/test_module.py @@ -37,6 +37,12 @@ def _initialize_journals_open_session(self): "name": "Cash", "is_cash_count": True, "receivable_account_id": account_id.id, + "cash_journal_id": self.env["account.journal"] + .search( + [("type", "=", "cash"), ("company_id", "=", self.env.company.id)], + limit=1, + ) + .id, } ) From e4b67c6391484bb5bf582f98b4379d8cba743bfb Mon Sep 17 00:00:00 2001 From: manu Date: Mon, 5 Dec 2022 13:48:31 +0100 Subject: [PATCH 14/35] [MIG]pos_payment_change: Migration to 15.0 --- pos_payment_change/README.rst | 19 ++++++------ pos_payment_change/__manifest__.py | 2 +- pos_payment_change/i18n/de.po | 29 ++++++++++-------- pos_payment_change/i18n/es.po | 26 ++++++++-------- pos_payment_change/i18n/fr.po | 28 ++++++++--------- .../i18n/pos_payment_change.pot | 24 +++++++-------- pos_payment_change/models/pos_order.py | 30 +++++++++---------- pos_payment_change/readme/CONTRIBUTORS.rst | 1 + .../static/description/index.html | 15 +++++----- pos_payment_change/tests/test_module.py | 2 +- .../wizards/pos_payment_change_wizard.py | 12 ++++---- .../pos_payment_change_wizard_new_line.py | 1 - .../pos_payment_change_wizard_old_line.py | 1 - 13 files changed, 95 insertions(+), 95 deletions(-) diff --git a/pos_payment_change/README.rst b/pos_payment_change/README.rst index 85f0b37898..33f03994e1 100644 --- a/pos_payment_change/README.rst +++ b/pos_payment_change/README.rst @@ -14,13 +14,13 @@ Point Of Sale - Change Payments :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fpos-lightgray.png?logo=github - :target: https://github.com/OCA/pos/tree/14.0/pos_payment_change + :target: https://github.com/OCA/pos/tree/15.0/pos_payment_change :alt: OCA/pos .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/pos-14-0/pos-14-0-pos_payment_change + :target: https://translation.odoo-community.org/projects/pos-15-0/pos-15-0-pos_payment_change :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/184/14.0 + :target: https://runbot.odoo-community.org/runbot/184/15.0 :alt: Try me on Runbot |badge1| |badge2| |badge3| |badge4| |badge5| @@ -52,7 +52,7 @@ Two options are available: * 'Update Payments': Odoo will change payment lines. -.. figure:: https://raw.githubusercontent.com/OCA/pos/14.0/pos_payment_change/static/description/pos_config_form.png +.. figure:: https://raw.githubusercontent.com/OCA/pos/15.0/pos_payment_change/static/description/pos_config_form.png **Note** @@ -71,12 +71,12 @@ Usage * Click on the button 'Change Payments' -.. figure:: https://raw.githubusercontent.com/OCA/pos/14.0/pos_payment_change/static/description/pos_order_form.png +.. figure:: https://raw.githubusercontent.com/OCA/pos/15.0/pos_payment_change/static/description/pos_order_form.png * In the pop up wizard, select the real payment(s) that have been used to pay the order -.. figure:: https://raw.githubusercontent.com/OCA/pos/14.0/pos_payment_change/static/description/pos_payment_change_wizard_form.png +.. figure:: https://raw.githubusercontent.com/OCA/pos/15.0/pos_payment_change/static/description/pos_payment_change_wizard_form.png * Then click on the button 'Change Payments' @@ -85,7 +85,7 @@ Usage If the option 'Refund and Resale' is selected, changing the payments will display the three PoS orders. the oringal one, the refund one, and the new one. -.. figure:: https://raw.githubusercontent.com/OCA/pos/14.0/pos_payment_change/static/description/pos_order_tree.png +.. figure:: https://raw.githubusercontent.com/OCA/pos/15.0/pos_payment_change/static/description/pos_order_tree.png Bug Tracker =========== @@ -93,7 +93,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -111,6 +111,7 @@ Contributors * Sylvain LE GAL * Julien WESTE * Foram Shah +* Manuel Regidor Other credits ~~~~~~~~~~~~~ @@ -141,6 +142,6 @@ Current `maintainer `__: |maintainer-legalsylvain| -This module is part of the `OCA/pos `_ project on GitHub. +This module is part of the `OCA/pos `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/pos_payment_change/__manifest__.py b/pos_payment_change/__manifest__.py index 08665d2800..d160447462 100644 --- a/pos_payment_change/__manifest__.py +++ b/pos_payment_change/__manifest__.py @@ -3,7 +3,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { "name": "Point Of Sale - Change Payments", - "version": "14.0.1.0.0", + "version": "15.0.1.0.0", "summary": "Allow cashier to change order payments, as long as" " the session is not closed.", "category": "Point Of Sale", diff --git a/pos_payment_change/i18n/de.po b/pos_payment_change/i18n/de.po index 20c98513d4..994a9b0b12 100644 --- a/pos_payment_change/i18n/de.po +++ b/pos_payment_change/i18n/de.po @@ -19,8 +19,8 @@ msgstr "" #. module: pos_payment_change #: code:addons/pos_payment_change/models/pos_order.py:79 #, python-format -msgid " (Refund Order: %s ; Resale Order: %s)" -msgstr " (Rückerstattungsauftrag: %s ; Wiederverkaufsauftrag: %s)" +msgid " (Refund Order: %(refund_order)s ; Resale Order: %(resale_order)s)" +msgstr " (Rückerstattungsauftrag: %(refund_order)s ; Wiederverkaufsauftrag: %(resale_order)s)" #. module: pos_payment_change #: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_config_form @@ -68,17 +68,18 @@ msgstr "Erstellt am" #. module: pos_payment_change #: code:addons/pos_payment_change/wizards/pos_payment_change_wizard.py:69 #, python-format -msgid "Differences between the two values for the POS Order '%s':\n" +msgid "" +"Differences between the two values for the POS Order '%(name)s':" "\n" -" * Total of all the new payments %s;\n" -" * Total of the POS Order %s;\n" +" * Total of all the new payments %(total)s;" +" * Total of the POS Order %(amount_total)s;" "\n" "Please change the payments." msgstr "" -"Differenzen zwischen den beiden Werten für den POS-Auftrag '%s':\n" +"Differenzen zwischen den beiden Werten für den POS-Auftrag '%(name)s':\n" "\n" -" * Summe aller neuen Zahlungen %s;\n" -" * Summe des POS-Auftrags %s;\n" +" * Summe aller neuen Zahlungen %(total)s;\n" +" * Summe des POS-Auftrags %(amount_total)s;\n" "\n" "Bitte ändern Sie die Zahlungen." @@ -194,8 +195,8 @@ msgstr "Rückerstattung und Wiederverkauf" #. module: pos_payment_change #: code:addons/pos_payment_change/models/pos_order.py:43 #, python-format -msgid "The payments of the Order %s (Ref: %s) has been changed by %s at %s." -msgstr "Die Zahlungen des Auftrags %s (Ref: %s) wurden von %s bei %s geändert." +msgid "The payments of the Order %(order)s (Ref: %(ref)s have been changed by %(user_name)s on %(today)s" +msgstr "Die Zahlungen des Auftrags %(order)s (Ref: %(ref)s) wurden von %(user_name)s bei %(today)s geändert." #. module: pos_payment_change #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__amount_total @@ -231,7 +232,9 @@ msgstr "Assistent" #. module: pos_payment_change #: code:addons/pos_payment_change/models/pos_order.py:97 #, python-format -msgid "You can not change payments of the POS '%s' because the associated session '%s' has been closed!" +msgid "" +"You can not change payments of the POS '%(name)s' because the associated session " +"'%(session)s' has been closed!" msgstr "" -"Sie können Zahlungen der Kasse '%s' nicht ändern, da die zugehörige Sitzung " -"'%s' geschlossen wurde!" +"Sie können Zahlungen der Kasse '%(name)s' nicht ändern, da die zugehörige Sitzung " +"'%(session)s' geschlossen wurde!" diff --git a/pos_payment_change/i18n/es.po b/pos_payment_change/i18n/es.po index 651be7cc33..f5ef49c96f 100644 --- a/pos_payment_change/i18n/es.po +++ b/pos_payment_change/i18n/es.po @@ -19,8 +19,8 @@ msgstr "" #. module: pos_payment_change #: code:addons/pos_payment_change/models/pos_order.py:79 #, python-format -msgid " (Refund Order: %s ; Resale Order: %s)" -msgstr " (Orden de reembolso: %s ; Orden de reventa: %s)" +msgid " (Refund Order: %(refund_order)s ; Resale Order: %(resale_order)s)" +msgstr " (Orden de reembolso: %(refund_order)s ; Orden de reventa: %(resale_order)s)" #. module: pos_payment_change #: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_config_form @@ -69,17 +69,17 @@ msgstr "Creado el" #: code:addons/pos_payment_change/wizards/pos_payment_change_wizard.py:69 #, python-format msgid "" -"Differences between the two values for the POS Order '%s':\n" +"Differences between the two values for the POS Order '%(name)s':" "\n" -" * Total of all the new payments %s;\n" -" * Total of the POS Order %s;\n" +" * Total of all the new payments %(total)s;" +" * Total of the POS Order %(amount_total)s;" "\n" "Please change the payments." msgstr "" -"Diferencias entre los dos valores para la orden PdV '%s':\n" +"Diferencias entre los dos valores para la orden PdV '%(name)s':\n" "\n" -" * Total de todos los nuevos pagos %s;\n" -" * Total del pedido del punto de venta %s;\n" +" * Total de todos los nuevos pagos %(total)s;\n" +" * Total del pedido del punto de venta %(amount_total)s;\n" "\n" "Por favor cambie los pagos." @@ -199,8 +199,8 @@ msgstr "Reembolso y reventa" #. module: pos_payment_change #: code:addons/pos_payment_change/models/pos_order.py:43 #, python-format -msgid "The payments of the Order %s (Ref: %s) has been changed by %s at %s." -msgstr "Los pagos de la orden %s (Ref: %s) han sido modificados por %s en %s." +msgid "The payments of the Order %(order)s (Ref: %(ref)s have been changed by %(user_name)s on %(today)s" +msgstr "Los pagos de la orden %(order)s (Ref: %(ref)s) han sido modificados por %(user_name)s en %(today)s." #. module: pos_payment_change #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__amount_total @@ -239,8 +239,8 @@ msgstr "Asistente" #: code:addons/pos_payment_change/models/pos_order.py:97 #, python-format msgid "" -"You can not change payments of the POS '%s' because the associated session " -"'%s' has been closed!" +"You can not change payments of the POS '%(name)s' because the associated session " +"'%(session)s' has been closed!" msgstr "" -"¡No puede cambiar los pagos del PdV '%s' porque la sesión asociada '%s' se " +"¡No puede cambiar los pagos del PdV '%(name)s' porque la sesión asociada '%(session)s' se " "ha cerrado!" diff --git a/pos_payment_change/i18n/fr.po b/pos_payment_change/i18n/fr.po index eebb932426..22631e44ef 100644 --- a/pos_payment_change/i18n/fr.po +++ b/pos_payment_change/i18n/fr.po @@ -19,8 +19,8 @@ msgstr "" #. module: pos_payment_change #: code:addons/pos_payment_change/models/pos_order.py:79 #, python-format -msgid " (Refund Order: %s ; Resale Order: %s)" -msgstr " (Remboursement: %s ; Revente : %s)" +msgid " (Refund Order: %(refund_order)s ; Resale Order: %(resale_order)s)" +msgstr " (Remboursement: %(refund_order)s ; Revente : %(resale_order)s)" #. module: pos_payment_change #: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_config_form @@ -69,17 +69,17 @@ msgstr "Créé le" #: code:addons/pos_payment_change/wizards/pos_payment_change_wizard.py:69 #, python-format msgid "" -"Differences between the two values for the POS Order '%s':\n" +"Differences between the two values for the POS Order '%(name)s':" "\n" -" * Total of all the new payments %s;\n" -" * Total of the POS Order %s;\n" +" * Total of all the new payments %(total)s;" +" * Total of the POS Order %(amount_total)s;" "\n" "Please change the payments." msgstr "" -"Différences entre les deux valeurs pour la vente '%s':\n" +"Différences entre les deux valeurs pour la vente '%(name)s':\n" "\n" -" * Total des nouveaux paiements %s;\n" -" * Total de la vente %s;\n" +" * Total des nouveaux paiements %(total)s;\n" +" * Total de la vente %(amount_total)s;\n" "\n" "Veuillez changer les paiements." @@ -201,8 +201,8 @@ msgstr "Retourner et revendre" #. module: pos_payment_change #: code:addons/pos_payment_change/models/pos_order.py:43 #, python-format -msgid "The payments of the Order %s (Ref: %s) has been changed by %s at %s." -msgstr "Les paiements de la commande %s (Réf: %s) ont été changés par %s à %s." +msgid "The payments of the Order %(order)s (Ref: %(ref)s have been changed by %(user_name)s on %(today)s" +msgstr "Les paiements de la commande %(order)s (Réf: %(ref)s) ont été changés par %(user_name)s à %(today)s." #. module: pos_payment_change #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__amount_total @@ -241,8 +241,8 @@ msgstr "Assistant" #: code:addons/pos_payment_change/models/pos_order.py:97 #, python-format msgid "" -"You can not change payments of the POS '%s' because the associated session " -"'%s' has been closed!" +"You can not change payments of the POS '%(name)s' because the associated session " +"'%(session)s' has been closed!" msgstr "" -"Vous ne pouvez pas changer les paiements de la Vente '%s' car la session " -"associée '%s' a été clôturé !" +"Vous ne pouvez pas changer les paiements de la Vente '%(name)s' car la session " +"associée '%(session)s' a été clôturé !" diff --git a/pos_payment_change/i18n/pos_payment_change.pot b/pos_payment_change/i18n/pos_payment_change.pot index 9e0978f581..295c79832e 100644 --- a/pos_payment_change/i18n/pos_payment_change.pot +++ b/pos_payment_change/i18n/pos_payment_change.pot @@ -4,7 +4,7 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 14.0\n" +"Project-Id-Version: Odoo Server 15.0\n" "Report-Msgid-Bugs-To: \n" "Last-Translator: \n" "Language-Team: \n" @@ -16,7 +16,7 @@ msgstr "" #. module: pos_payment_change #: code:addons/pos_payment_change/models/pos_order.py:0 #, python-format -msgid " (Refund Order: %s ; Resale Order: %s)" +msgid " (Refund Order: %(refund_order)s ; Resale Order: %(resale_order)s)" msgstr "" #. module: pos_payment_change @@ -66,17 +66,15 @@ msgstr "" #: code:addons/pos_payment_change/wizards/pos_payment_change_wizard.py:0 #, python-format msgid "" -"Differences between the two values for the POS Order '%s':\n" +"Differences between the two values for the POS Order '%(name)s':\n" "\n" -" * Total of all the new payments %s;\n" -" * Total of the POS Order %s;\n" +" * Total of all the new payments %(total)s;\n" +" * Total of the POS Order %(amount_total)s;\n" "\n" "Please change the payments." msgstr "" #. module: pos_payment_change -#: model:ir.model.fields,field_description:pos_payment_change.field_pos_config__display_name -#: model:ir.model.fields,field_description:pos_payment_change.field_pos_order__display_name #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__display_name #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__display_name #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__display_name @@ -84,8 +82,6 @@ msgid "Display Name" msgstr "" #. module: pos_payment_change -#: model:ir.model.fields,field_description:pos_payment_change.field_pos_config__id -#: model:ir.model.fields,field_description:pos_payment_change.field_pos_order__id #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__id #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__id #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__id @@ -93,8 +89,6 @@ msgid "ID" msgstr "" #. module: pos_payment_change -#: model:ir.model.fields,field_description:pos_payment_change.field_pos_config____last_update -#: model:ir.model.fields,field_description:pos_payment_change.field_pos_order____last_update #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard____last_update #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line____last_update #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line____last_update @@ -184,7 +178,9 @@ msgstr "" #. module: pos_payment_change #: code:addons/pos_payment_change/models/pos_order.py:0 #, python-format -msgid "The payments of the Order %s (Ref: %s) has been changed by %s at %s." +msgid "" +"The payments of the Order %(order)s (Ref: %(ref)s have been changed by " +"%(user_name)s on %(today)s" msgstr "" #. module: pos_payment_change @@ -222,6 +218,6 @@ msgstr "" #: code:addons/pos_payment_change/models/pos_order.py:0 #, python-format msgid "" -"You can not change payments of the POS '%s' because the associated session " -"'%s' has been closed!" +"You can not change payments of the POS '%(name)s' because the associated " +"session '%(session)s' has been closed!" msgstr "" diff --git a/pos_payment_change/models/pos_order.py b/pos_payment_change/models/pos_order.py index c1b6fe5348..bfa89ff20f 100644 --- a/pos_payment_change/models/pos_order.py +++ b/pos_payment_change/models/pos_order.py @@ -35,14 +35,12 @@ def change_payment(self, payment_lines): self._check_payment_change_allowed() comment = _( - "The payments of the Order %s (Ref: %s) has been changed" - " by %s at %s." - % ( - self.name, - self.pos_reference, - self.env.user.name, - datetime.today(), - ) + "The payments of the Order %(order)s (Ref: %(ref)s have" + " been changed by %(user_name)s on %(today)s", + order=self.name, + ref=self.pos_reference, + user_name=self.env.user.name, + today=datetime.today(), ) if self.config_id.payment_change_policy == "update": @@ -79,9 +77,11 @@ def change_payment(self, payment_lines): orders += refund_order + resale_order comment += _( - " (Refund Order: %s ; Resale Order: %s)" - % (refund_order.name, resale_order.name) + " (Refund Order: %(refund_order)s ; Resale Order: %(resale_order)s)", + refund_order=refund_order.name, + resale_order=resale_order.name, ) + for order in orders: order.note = "%s\n%s" % (order.note or "", comment) return orders @@ -93,11 +93,9 @@ def _check_payment_change_allowed(self): if len(closed_orders): raise UserError( _( - "You can not change payments of the POS '%s' because" - " the associated session '%s' has been closed!" - % ( - ", ".join(closed_orders.mapped("name")), - ", ".join(closed_orders.mapped("session_id.name")), - ) + "You can not change payments of the POS '%(name)s' because" + " the associated session '%(session)s' has been closed!", + name=", ".join(closed_orders.mapped("name")), + session=", ".join(closed_orders.mapped("session_id.name")), ) ) diff --git a/pos_payment_change/readme/CONTRIBUTORS.rst b/pos_payment_change/readme/CONTRIBUTORS.rst index 49812a4137..300d09239b 100644 --- a/pos_payment_change/readme/CONTRIBUTORS.rst +++ b/pos_payment_change/readme/CONTRIBUTORS.rst @@ -1,3 +1,4 @@ * Sylvain LE GAL * Julien WESTE * Foram Shah +* Manuel Regidor diff --git a/pos_payment_change/static/description/index.html b/pos_payment_change/static/description/index.html index c56ddde124..5019e263fe 100644 --- a/pos_payment_change/static/description/index.html +++ b/pos_payment_change/static/description/index.html @@ -367,7 +367,7 @@

      Point Of Sale - Change Payments

      !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

      Beta License: AGPL-3 OCA/pos Translate me on Weblate Try me on Runbot

      +

      Beta License: AGPL-3 OCA/pos Translate me on Weblate Try me on Runbot

      This module extends the functionnality of the Odoo Point of Sale to allow the cashier to change the payments of a PoS order.

      This feature is usefull when the user realized that he did a mistake, @@ -403,7 +403,7 @@

      Configuration

    • ‘Update Payments’: Odoo will change payment lines.
    -https://raw.githubusercontent.com/OCA/pos/14.0/pos_payment_change/static/description/pos_config_form.png +https://raw.githubusercontent.com/OCA/pos/15.0/pos_payment_change/static/description/pos_config_form.png

    Note In some countries the ‘Update Payments’ Option @@ -420,14 +420,14 @@

    Usage

  • Click on the button ‘Change Payments’
  • -https://raw.githubusercontent.com/OCA/pos/14.0/pos_payment_change/static/description/pos_order_form.png +https://raw.githubusercontent.com/OCA/pos/15.0/pos_payment_change/static/description/pos_order_form.png
    • In the pop up wizard, select the real payment(s) that have been used to pay the order
    -https://raw.githubusercontent.com/OCA/pos/14.0/pos_payment_change/static/description/pos_payment_change_wizard_form.png +https://raw.githubusercontent.com/OCA/pos/15.0/pos_payment_change/static/description/pos_payment_change_wizard_form.png
    • Then click on the button ‘Change Payments’
    • @@ -436,7 +436,7 @@

      Usage

      If the option ‘Refund and Resale’ is selected, changing the payments will display the three PoS orders. the oringal one, the refund one, and the new one.

      -https://raw.githubusercontent.com/OCA/pos/14.0/pos_payment_change/static/description/pos_order_tree.png +https://raw.githubusercontent.com/OCA/pos/15.0/pos_payment_change/static/description/pos_order_tree.png
      @@ -444,7 +444,7 @@

      Bug Tracker

      Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed -feedback.

      +feedback.

      Do not contact contributors directly about support or help with technical issues.

      @@ -461,6 +461,7 @@

      Contributors

    • Sylvain LE GAL <https://twitter.com/legalsylvain>
    • Julien WESTE
    • Foram Shah <foram.shah@initos.com>
    • +
    • Manuel Regidor <manuel.regidor@sygel.es>
    @@ -480,7 +481,7 @@

    Maintainers

    promote its widespread use.

    Current maintainer:

    legalsylvain

    -

    This module is part of the OCA/pos project on GitHub.

    +

    This module is part of the OCA/pos project on GitHub.

    You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

    diff --git a/pos_payment_change/tests/test_module.py b/pos_payment_change/tests/test_module.py index 14f8deb1cd..9ff46e2e1f 100644 --- a/pos_payment_change/tests/test_module.py +++ b/pos_payment_change/tests/test_module.py @@ -37,7 +37,7 @@ def _initialize_journals_open_session(self): "name": "Cash", "is_cash_count": True, "receivable_account_id": account_id.id, - "cash_journal_id": self.env["account.journal"] + "journal_id": self.env["account.journal"] .search( [("type", "=", "cash"), ("company_id", "=", self.env.company.id)], limit=1, diff --git a/pos_payment_change/wizards/pos_payment_change_wizard.py b/pos_payment_change/wizards/pos_payment_change_wizard.py index e99748273f..79c323ed9d 100644 --- a/pos_payment_change/wizards/pos_payment_change_wizard.py +++ b/pos_payment_change/wizards/pos_payment_change_wizard.py @@ -66,11 +66,13 @@ def button_change_payment(self): raise UserError( _( "Differences between the two values for the POS" - " Order '%s':\n\n" - " * Total of all the new payments %s;\n" - " * Total of the POS Order %s;\n\n" - "Please change the payments." - % (order.name, total, order.amount_total) + " Order '%(name)s':\n\n" + " * Total of all the new payments %(total)s;\n" + " * Total of the POS Order %(amount_total)s;\n\n" + "Please change the payments.", + name=order.name, + total=total, + amount_total=order.amount_total, ) ) diff --git a/pos_payment_change/wizards/pos_payment_change_wizard_new_line.py b/pos_payment_change/wizards/pos_payment_change_wizard_new_line.py index 2d0b21a31f..8fcfefc032 100644 --- a/pos_payment_change/wizards/pos_payment_change_wizard_new_line.py +++ b/pos_payment_change/wizards/pos_payment_change_wizard_new_line.py @@ -31,7 +31,6 @@ class PosPaymentChangeWizardLine(models.TransientModel): ) amount = fields.Monetary( - string="Amount", required=True, default=0.0, currency_field="company_currency_id", diff --git a/pos_payment_change/wizards/pos_payment_change_wizard_old_line.py b/pos_payment_change/wizards/pos_payment_change_wizard_old_line.py index 383f2dc14e..911357dc01 100644 --- a/pos_payment_change/wizards/pos_payment_change_wizard_old_line.py +++ b/pos_payment_change/wizards/pos_payment_change_wizard_old_line.py @@ -31,7 +31,6 @@ class PosPaymentChangeWizardOldLine(models.TransientModel): ) amount = fields.Monetary( - string="Amount", required=True, readonly=True, default=0.0, From fce608ff2b3d004701d70f54a967f9a9d0a7f4ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julen=20Z=C3=A1rate=20Ruiz?= Date: Mon, 20 Feb 2023 23:48:13 +0100 Subject: [PATCH 15/35] [WIP] pos_payment_change: Migration to 16.0 --- pos_payment_change/README.rst | 16 ++++++++-------- pos_payment_change/__manifest__.py | 2 +- pos_payment_change/static/description/index.html | 14 +++++++------- pos_payment_change/tests/test_module.py | 16 +++++++++++++++- 4 files changed, 31 insertions(+), 17 deletions(-) diff --git a/pos_payment_change/README.rst b/pos_payment_change/README.rst index 33f03994e1..f131f00135 100644 --- a/pos_payment_change/README.rst +++ b/pos_payment_change/README.rst @@ -14,13 +14,13 @@ Point Of Sale - Change Payments :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fpos-lightgray.png?logo=github - :target: https://github.com/OCA/pos/tree/15.0/pos_payment_change + :target: https://github.com/OCA/pos/tree/16.0/pos_payment_change :alt: OCA/pos .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png :target: https://translation.odoo-community.org/projects/pos-15-0/pos-15-0-pos_payment_change :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/184/15.0 + :target: https://runbot.odoo-community.org/runbot/184/16.0 :alt: Try me on Runbot |badge1| |badge2| |badge3| |badge4| |badge5| @@ -52,7 +52,7 @@ Two options are available: * 'Update Payments': Odoo will change payment lines. -.. figure:: https://raw.githubusercontent.com/OCA/pos/15.0/pos_payment_change/static/description/pos_config_form.png +.. figure:: https://raw.githubusercontent.com/OCA/pos/16.0/pos_payment_change/static/description/pos_config_form.png **Note** @@ -71,12 +71,12 @@ Usage * Click on the button 'Change Payments' -.. figure:: https://raw.githubusercontent.com/OCA/pos/15.0/pos_payment_change/static/description/pos_order_form.png +.. figure:: https://raw.githubusercontent.com/OCA/pos/16.0/pos_payment_change/static/description/pos_order_form.png * In the pop up wizard, select the real payment(s) that have been used to pay the order -.. figure:: https://raw.githubusercontent.com/OCA/pos/15.0/pos_payment_change/static/description/pos_payment_change_wizard_form.png +.. figure:: https://raw.githubusercontent.com/OCA/pos/16.0/pos_payment_change/static/description/pos_payment_change_wizard_form.png * Then click on the button 'Change Payments' @@ -85,7 +85,7 @@ Usage If the option 'Refund and Resale' is selected, changing the payments will display the three PoS orders. the oringal one, the refund one, and the new one. -.. figure:: https://raw.githubusercontent.com/OCA/pos/15.0/pos_payment_change/static/description/pos_order_tree.png +.. figure:: https://raw.githubusercontent.com/OCA/pos/16.0/pos_payment_change/static/description/pos_order_tree.png Bug Tracker =========== @@ -93,7 +93,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -142,6 +142,6 @@ Current `maintainer `__: |maintainer-legalsylvain| -This module is part of the `OCA/pos `_ project on GitHub. +This module is part of the `OCA/pos `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/pos_payment_change/__manifest__.py b/pos_payment_change/__manifest__.py index d160447462..094688efd5 100644 --- a/pos_payment_change/__manifest__.py +++ b/pos_payment_change/__manifest__.py @@ -3,7 +3,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { "name": "Point Of Sale - Change Payments", - "version": "15.0.1.0.0", + "version": "16.0.1.0.0", "summary": "Allow cashier to change order payments, as long as" " the session is not closed.", "category": "Point Of Sale", diff --git a/pos_payment_change/static/description/index.html b/pos_payment_change/static/description/index.html index 5019e263fe..cb6a49fef1 100644 --- a/pos_payment_change/static/description/index.html +++ b/pos_payment_change/static/description/index.html @@ -367,7 +367,7 @@

    Point Of Sale - Change Payments

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

    Beta License: AGPL-3 OCA/pos Translate me on Weblate Try me on Runbot

    +

    Beta License: AGPL-3 OCA/pos Translate me on Weblate Try me on Runbot

    This module extends the functionnality of the Odoo Point of Sale to allow the cashier to change the payments of a PoS order.

    This feature is usefull when the user realized that he did a mistake, @@ -403,7 +403,7 @@

    Configuration

  • ‘Update Payments’: Odoo will change payment lines.
  • -https://raw.githubusercontent.com/OCA/pos/15.0/pos_payment_change/static/description/pos_config_form.png +https://raw.githubusercontent.com/OCA/pos/16.0/pos_payment_change/static/description/pos_config_form.png

    Note In some countries the ‘Update Payments’ Option @@ -420,14 +420,14 @@

    Usage

  • Click on the button ‘Change Payments’
  • -https://raw.githubusercontent.com/OCA/pos/15.0/pos_payment_change/static/description/pos_order_form.png +https://raw.githubusercontent.com/OCA/pos/16.0/pos_payment_change/static/description/pos_order_form.png
    • In the pop up wizard, select the real payment(s) that have been used to pay the order
    -https://raw.githubusercontent.com/OCA/pos/15.0/pos_payment_change/static/description/pos_payment_change_wizard_form.png +https://raw.githubusercontent.com/OCA/pos/16.0/pos_payment_change/static/description/pos_payment_change_wizard_form.png
    -

    Configuration

    +

    Configuration

      -
    • Go to Point of Sale.
    • -
    • Choose the view list.
    • +
    • Go to Point of Sale > Configuration > Settings
    • Edit your point of sale, and select a value for the field ‘Payment Change Policy’.
    @@ -405,7 +410,7 @@

    Configuration

  • ‘Update Payments’: Odoo will change payment lines.
  • -https://raw.githubusercontent.com/OCA/pos/16.0/pos_payment_change/static/description/pos_config_form.png +https://raw.githubusercontent.com/OCA/pos/16.0/pos_payment_change/static/description/res_config_settings_form.png

    Note In some countries the ‘Update Payments’ Option @@ -416,7 +421,7 @@

    Configuration

    to select the value ‘Update Payments’.

    -

    Usage

    +

    Usage

    • Go to a PoS Order
    • Click on the button ‘Change Payments’
    • @@ -442,7 +447,7 @@

      Usage

    -

    Bug Tracker

    +

    Bug Tracker

    Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed @@ -450,15 +455,15 @@

    Bug Tracker

    Do not contact contributors directly about support or help with technical issues.

    -

    Credits

    +

    Credits

    -

    Authors

    +

    Authors

    • GRAP
    -

    Contributors

    +

    Contributors

    -

    Other credits

    +

    Other credits

    The development of this module has been financially supported by:

    • GRAP, Groupement Régional Alimentaire de proximité (www.grap.coop)
    • @@ -475,9 +480,11 @@

      Other credits

    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    -Odoo Community Association + +Odoo Community Association +

    OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.

    @@ -488,5 +495,6 @@

    Maintainers

    + diff --git a/pos_payment_change/static/description/pos_config_form.png b/pos_payment_change/static/description/pos_config_form.png deleted file mode 100644 index 8723af042552d7c7f7706ab900366d34f0afa4b7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20384 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 diff --git a/pos_payment_change/static/description/res_config_settings_form.png b/pos_payment_change/static/description/res_config_settings_form.png new file mode 100644 index 0000000000000000000000000000000000000000..be8a10b6bc72d10ece1deea380ea13674527987f GIT binary patch literal 67916 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 literal 0 HcmV?d00001 diff --git a/pos_payment_change/views/view_pos_config.xml b/pos_payment_change/views/view_pos_config.xml deleted file mode 100644 index 6ec422b38b..0000000000 --- a/pos_payment_change/views/view_pos_config.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - pos.config - - - -
    -
    - Payment Change Policy -
    - -
    -
    -
    -
    -
    -
    - -
    diff --git a/pos_payment_change/views/view_res_config_settings.xml b/pos_payment_change/views/view_res_config_settings.xml new file mode 100644 index 0000000000..b6f46bfacf --- /dev/null +++ b/pos_payment_change/views/view_res_config_settings.xml @@ -0,0 +1,45 @@ + + + + + + res.config.settings + + + +
    +
    +
    +
    + +
    +
    +
    +
    From c34fdf8916e2782151ee7254bf61e6b12c1665ba Mon Sep 17 00:00:00 2001 From: Su Date: Fri, 29 May 2026 10:29:28 +0000 Subject: [PATCH 29/35] Added translation using Weblate (Portuguese (Portugal)) Translated using Weblate (Portuguese (Portugal)) Currently translated at 100.0% (33 of 33 strings) Translation: pos-16.0/pos-16.0-pos_payment_change Translate-URL: https://translation.odoo-community.org/projects/pos-16-0/pos-16-0-pos_payment_change/pt_PT/ --- pos_payment_change/i18n/pt_PT.po | 253 +++++++++++++++++++++++++++++++ 1 file changed, 253 insertions(+) create mode 100644 pos_payment_change/i18n/pt_PT.po diff --git a/pos_payment_change/i18n/pt_PT.po b/pos_payment_change/i18n/pt_PT.po new file mode 100644 index 0000000000..41dc5f463f --- /dev/null +++ b/pos_payment_change/i18n/pt_PT.po @@ -0,0 +1,253 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * pos_payment_change +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2026-05-29 10:30+0000\n" +"Last-Translator: Su \n" +"Language-Team: none\n" +"Language: pt_PT\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 5.15.2\n" + +#. module: pos_payment_change +#. odoo-python +#: code:addons/pos_payment_change/models/pos_order.py:0 +#, python-format +msgid " (Refund Order: %(refund_order)s ; Resale Order: %(resale_order)s)" +msgstr "" +" (Ordem de Reembolso: %(refund_order)s ; Ordem de Revenda: %(resale_order)s)" + +#. module: pos_payment_change +#: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_config_form +msgid "Payment Change Policy" +msgstr "Política de Alteração de Pagamentos" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__amount +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__amount +msgid "Amount" +msgstr "Montante" + +#. module: pos_payment_change +#: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_payment_change_wizard_form +msgid "Cancel" +msgstr "Cancelar" + +#. module: pos_payment_change +#: model:ir.actions.act_window,name:pos_payment_change.action_pos_payment_change_wizard +#: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_order_form +#: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_payment_change_wizard_form +msgid "Change Payments" +msgstr "Alterar Pagamentos" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__company_currency_id +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__company_currency_id +msgid "Company Currency" +msgstr "Moeda da Empresa" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__create_uid +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__create_uid +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__create_uid +msgid "Created by" +msgstr "Criado por" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__create_date +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__create_date +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__create_date +msgid "Created on" +msgstr "Criado em" + +#. module: pos_payment_change +#. odoo-python +#: code:addons/pos_payment_change/wizards/pos_payment_change_wizard.py:0 +#, python-format +msgid "" +"Differences between the two values for the POS Order '%(name)s':\n" +"\n" +" * Total of all the new payments %(total)s;\n" +" * Total of the POS Order %(amount_total)s;\n" +"\n" +"Please change the payments." +msgstr "" +"Diferenças entre os dois valores para a Ordem do TPV '%(name)s':\n" +"\n" +" * Total de todos os novos pagamentos %(total)s;\n" +" * Total da Ordem do TPV %(amount_total)s;\n" +"\n" +"Por favor, altere os pagamentos." + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__display_name +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__display_name +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__display_name +msgid "Display Name" +msgstr "Nome a Apresentar" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__id +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__id +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__id +msgid "ID" +msgstr "ID" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard____last_update +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line____last_update +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line____last_update +msgid "Last Modified on" +msgstr "Última Modificação em" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__write_uid +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__write_uid +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__write_uid +msgid "Last Updated by" +msgstr "Última Atualização por" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__write_date +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__write_date +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__write_date +msgid "Last Updated on" +msgstr "Última Atualização em" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__new_line_ids +msgid "New Payment Lines" +msgstr "Novas Linhas de Pagamento" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__old_line_ids +msgid "Old Payment Lines" +msgstr "Linhas de Pagamento Anteriores" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__order_id +msgid "Order" +msgstr "Ordem" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_config__payment_change_policy +msgid "Payment Change Policy" +msgstr "Política de Alteração de Pagamentos" + +#. module: pos_payment_change +#: model:ir.model.fields,help:pos_payment_change.field_pos_config__payment_change_policy +msgid "" +"Payment Change Policy when users want to change the payment lines of a given PoS Order.\n" +"* 'Refund and Resale': Odoo will refund the current Pos Order to cancel it, and create a new PoS Order with the correct payment lines.\n" +"* 'Update Payments': Odoo will change payment lines.\n" +"\n" +"Note : In some countries the 'Update Payments' Option is not allowed by law, because orders history shouldn't not be altered." +msgstr "" +"Política de Alteração de Pagamentos quando os utilizadores querem alterar as " +"linhas de pagamento de uma dada Ordem do TPV.\n" +"* 'Reembolso e Revenda': O Odoo reembolsará a Ordem do TPV atual para a " +"cancelar, e criará uma nova Ordem do TPV com as linhas de pagamento " +"corretas.\n" +"* 'Atualizar Pagamentos': O Odoo alterará as linhas de pagamento.\n" +"\n" +"Nota: Em alguns países a opção 'Atualizar Pagamentos' não é permitida por " +"lei, porque o histórico das ordens não deve ser alterado." + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__new_payment_method_id +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__old_payment_method_id +msgid "Payment Method" +msgstr "Método de Pagamento" + +#. module: pos_payment_change +#: model:ir.model,name:pos_payment_change.model_pos_payment_change_wizard +msgid "PoS Payment Change Wizard" +msgstr "Assistente de Alteração de Pagamentos do TPV" + +#. module: pos_payment_change +#: model:ir.model,name:pos_payment_change.model_pos_payment_change_wizard_new_line +msgid "PoS Payment Change Wizard New Line" +msgstr "Assistente de Alteração de Pagamentos do TPV - Nova Linha" + +#. module: pos_payment_change +#: model:ir.model,name:pos_payment_change.model_pos_payment_change_wizard_old_line +msgid "PoS Payment Change Wizard Old Line" +msgstr "Assistente de Alteração de Pagamentos do TPV - Linha Anterior" + +#. module: pos_payment_change +#: model:ir.model,name:pos_payment_change.model_pos_config +msgid "Point of Sale Configuration" +msgstr "Configuração do Ponto de Venda" + +#. module: pos_payment_change +#: model:ir.model,name:pos_payment_change.model_pos_order +msgid "Point of Sale Orders" +msgstr "Ordens do Ponto de Venda" + +#. module: pos_payment_change +#: model:ir.model.fields.selection,name:pos_payment_change.selection__pos_config__payment_change_policy__refund +msgid "Refund and Resale" +msgstr "Reembolso e Revenda" + +#. module: pos_payment_change +#. odoo-python +#: code:addons/pos_payment_change/models/pos_order.py:0 +#, python-format +msgid "" +"The payments of the Order %(order)s (Ref: %(ref)s have been changed by " +"%(user_name)s on %(today)s" +msgstr "" +"Os pagamentos da Ordem %(order)s (Ref: %(ref)s foram alterados por %" +"(user_name)s em %(today)s" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__amount_total +#: model_terms:ir.ui.view,arch_db:pos_payment_change.view_pos_payment_change_wizard_form +msgid "Total" +msgstr "Total" + +#. module: pos_payment_change +#. odoo-python +#: code:addons/pos_payment_change/models/pos_config.py:0 +#, python-format +msgid "" +"Unable to use the 'Update Payments' options for companies that have " +"unalterable accounting." +msgstr "" +"Não é possível utilizar a opção 'Atualizar Pagamentos' para empresas com " +"contabilidade inalterável." + +#. module: pos_payment_change +#: model:ir.model.fields.selection,name:pos_payment_change.selection__pos_config__payment_change_policy__update +msgid "Update Payments" +msgstr "Atualizar Pagamentos" + +#. module: pos_payment_change +#: model:ir.model.fields,help:pos_payment_change.field_pos_payment_change_wizard_new_line__company_currency_id +#: model:ir.model.fields,help:pos_payment_change.field_pos_payment_change_wizard_old_line__company_currency_id +msgid "Utility field to express amount currency" +msgstr "Campo utilitário para expressar a moeda do montante" + +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__wizard_id +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line__wizard_id +msgid "Wizard" +msgstr "Assistente" + +#. module: pos_payment_change +#. odoo-python +#: code:addons/pos_payment_change/models/pos_order.py:0 +#, python-format +msgid "" +"You can not change payments of the POS '%(name)s' because the associated " +"session '%(session)s' has been closed!" +msgstr "" +"Não é possível alterar os pagamentos do TPV '%(name)s' porque a sessão " +"associada '%(session)s' foi fechada!" From b476e4c7935ba6e7bd7f9e26c9d38e5123898ac4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Mart=C3=ADnez?= Date: Wed, 17 Jun 2026 16:54:03 +0200 Subject: [PATCH 30/35] [IMP] pos_payment_change: pre-commit auto fixes --- pos_payment_change/README.rst | 93 +++++++++---------- pos_payment_change/pyproject.toml | 3 + pos_payment_change/readme/CONFIGURE.md | 19 ++++ pos_payment_change/readme/CONFIGURE.rst | 23 ----- pos_payment_change/readme/CONTRIBUTORS.md | 4 + pos_payment_change/readme/CONTRIBUTORS.rst | 4 - pos_payment_change/readme/CREDITS.md | 4 + pos_payment_change/readme/CREDITS.rst | 4 - .../{DESCRIPTION.rst => DESCRIPTION.md} | 4 +- pos_payment_change/readme/USAGE.md | 19 ++++ pos_payment_change/readme/USAGE.rst | 19 ---- .../static/description/index.html | 84 +++++++---------- 12 files changed, 132 insertions(+), 148 deletions(-) create mode 100644 pos_payment_change/pyproject.toml create mode 100644 pos_payment_change/readme/CONFIGURE.md delete mode 100644 pos_payment_change/readme/CONFIGURE.rst create mode 100644 pos_payment_change/readme/CONTRIBUTORS.md delete mode 100644 pos_payment_change/readme/CONTRIBUTORS.rst create mode 100644 pos_payment_change/readme/CREDITS.md delete mode 100644 pos_payment_change/readme/CREDITS.rst rename pos_payment_change/readme/{DESCRIPTION.rst => DESCRIPTION.md} (83%) create mode 100644 pos_payment_change/readme/USAGE.md delete mode 100644 pos_payment_change/readme/USAGE.rst diff --git a/pos_payment_change/README.rst b/pos_payment_change/README.rst index d2e39fa254..2c06443133 100644 --- a/pos_payment_change/README.rst +++ b/pos_payment_change/README.rst @@ -1,7 +1,3 @@ -.. image:: https://odoo-community.org/readme-banner-image - :target: https://odoo-community.org/get-involved?utm_source=readme - :alt: Odoo Community Association - =============================== Point Of Sale - Change Payments =============================== @@ -11,23 +7,23 @@ Point Of Sale - Change Payments !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:f92dd72ac053a86a8837e2a670cfa091391cadb66e6e3b45553b3b34f8d76400 + !! source digest: sha256:1c6e8c040d05dda8166904f53fc0ab8ba31c3e0fc1d9c158284f6dbd75c966c4 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fpos-lightgray.png?logo=github - :target: https://github.com/OCA/pos/tree/16.0/pos_payment_change + :target: https://github.com/OCA/pos/tree/17.0/pos_payment_change :alt: OCA/pos .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/pos-16-0/pos-16-0-pos_payment_change + :target: https://translation.odoo-community.org/projects/pos-17-0/pos-17-0-pos_payment_change :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/builds?repo=OCA/pos&target_branch=16.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/pos&target_branch=17.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| @@ -36,8 +32,8 @@ This module extends the functionnality of the Odoo Point of Sale to allow the cashier to change the payments of a PoS order. This feature is usefull when the user realized that he did a mistake, -just after he marked the order as paid, or during the close of the session, -Only if entries has not been generated. +just after he marked the order as paid, or during the close of the +session, Only if entries has not been generated. **Table of contents** @@ -47,52 +43,54 @@ Only if entries has not been generated. Configuration ============= -* Go to Point of Sale > Configuration > Settings -* Edit your point of sale, and select a value for the field - 'Payment Change Policy'. +- Go to Point of Sale > Configuration > Settings +- Edit your point of sale, and select a value for the field 'Payment + Change Policy'. Two options are available: -* 'Refund and Resale': Odoo will refund the current - Pos Order to cancel it, and create a new PoS Order - with the correct payment lines - -* 'Update Payments': Odoo will change payment lines. - -.. figure:: https://raw.githubusercontent.com/OCA/pos/16.0/pos_payment_change/static/description/res_config_settings_form.png +- 'Refund and Resale': Odoo will refund the current Pos Order to cancel + it, and create a new PoS Order with the correct payment lines +- 'Update Payments': Odoo will change payment lines. +|pos_config_form| -**Note** -In some countries the 'Update Payments' Option -is not allowed by law, because orders history shouldn't not be altered. +**Note** In some countries the 'Update Payments' Option is not allowed +by law, because orders history shouldn't not be altered. For that purpose, a constrains is present to check the value of this field. If the module ``l10n_fr_certification`` is installed and if the current company has an inalterable accounting, it will not be possible to select the value 'Update Payments'. +.. |pos_config_form| image:: https://raw.githubusercontent.com/OCA/pos/17.0/pos_payment_change/static/description/res_config_settings_form.png + Usage ===== -* Go to a PoS Order +- Go to a PoS Order +- Click on the button 'Change Payments' -* Click on the button 'Change Payments' +|pos_order_form| -.. figure:: https://raw.githubusercontent.com/OCA/pos/16.0/pos_payment_change/static/description/pos_order_form.png +- In the pop up wizard, select the real payment(s) that have been used + to pay the order -* In the pop up wizard, select the real payment(s) that have been - used to pay the order +|pos_payment_change_wizard_form| -.. figure:: https://raw.githubusercontent.com/OCA/pos/16.0/pos_payment_change/static/description/pos_payment_change_wizard_form.png - -* Then click on the button 'Change Payments' +- Then click on the button 'Change Payments' **Note** -If the option 'Refund and Resale' is selected, changing the payments will -display the three PoS orders. the oringal one, the refund one, and the new one. +If the option 'Refund and Resale' is selected, changing the payments +will display the three PoS orders. the oringal one, the refund one, and +the new one. + +|pos_order_tree| -.. figure:: https://raw.githubusercontent.com/OCA/pos/16.0/pos_payment_change/static/description/pos_order_tree.png +.. |pos_order_form| image:: https://raw.githubusercontent.com/OCA/pos/17.0/pos_payment_change/static/description/pos_order_form.png +.. |pos_payment_change_wizard_form| image:: https://raw.githubusercontent.com/OCA/pos/17.0/pos_payment_change/static/description/pos_payment_change_wizard_form.png +.. |pos_order_tree| image:: https://raw.githubusercontent.com/OCA/pos/17.0/pos_payment_change/static/description/pos_order_tree.png Bug Tracker =========== @@ -100,7 +98,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -108,28 +106,29 @@ Credits ======= Authors -~~~~~~~ +------- * GRAP Contributors -~~~~~~~~~~~~ +------------ -* Sylvain LE GAL -* Julien WESTE -* Foram Shah -* Manuel Regidor +- Sylvain LE GAL +- Julien WESTE +- Foram Shah +- Manuel Regidor Other credits -~~~~~~~~~~~~~ +------------- The development of this module has been financially supported by: -* GRAP, Groupement Régional Alimentaire de proximité (www.grap.coop) -* Vracoop (www.vracoop.fr) +- GRAP, Groupement Régional Alimentaire de proximité + (`www.grap.coop `__) +- Vracoop (`www.vracoop.fr `__) Maintainers -~~~~~~~~~~~ +----------- This module is maintained by the OCA. @@ -149,6 +148,6 @@ Current `maintainer `__: |maintainer-legalsylvain| -This module is part of the `OCA/pos `_ project on GitHub. +This module is part of the `OCA/pos `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/pos_payment_change/pyproject.toml b/pos_payment_change/pyproject.toml new file mode 100644 index 0000000000..4231d0cccb --- /dev/null +++ b/pos_payment_change/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/pos_payment_change/readme/CONFIGURE.md b/pos_payment_change/readme/CONFIGURE.md new file mode 100644 index 0000000000..6151ecdd0e --- /dev/null +++ b/pos_payment_change/readme/CONFIGURE.md @@ -0,0 +1,19 @@ +- Go to Point of Sale > Configuration > Settings +- Edit your point of sale, and select a value for the field + 'Payment Change Policy'. + +Two options are available: + +- 'Refund and Resale': Odoo will refund the current Pos Order to cancel + it, and create a new PoS Order with the correct payment lines +- 'Update Payments': Odoo will change payment lines. + +![pos_config_form](../static/description/res_config_settings_form.png) + +**Note** In some countries the 'Update Payments' Option is not allowed +by law, because orders history shouldn't not be altered. + +For that purpose, a constrains is present to check the value of this +field. If the module `l10n_fr_certification` is installed and if the +current company has an inalterable accounting, it will not be possible +to select the value 'Update Payments'. diff --git a/pos_payment_change/readme/CONFIGURE.rst b/pos_payment_change/readme/CONFIGURE.rst deleted file mode 100644 index 0a435c912a..0000000000 --- a/pos_payment_change/readme/CONFIGURE.rst +++ /dev/null @@ -1,23 +0,0 @@ -* Go to Point of Sale > Configuration > Settings -* Edit your point of sale, and select a value for the field - 'Payment Change Policy'. - -Two options are available: - -* 'Refund and Resale': Odoo will refund the current - Pos Order to cancel it, and create a new PoS Order - with the correct payment lines - -* 'Update Payments': Odoo will change payment lines. - -.. figure:: ../static/description/res_config_settings_form.png - - -**Note** -In some countries the 'Update Payments' Option -is not allowed by law, because orders history shouldn't not be altered. - -For that purpose, a constrains is present to check the value of this -field. If the module ``l10n_fr_certification`` is installed and if the -current company has an inalterable accounting, it will not be possible -to select the value 'Update Payments'. diff --git a/pos_payment_change/readme/CONTRIBUTORS.md b/pos_payment_change/readme/CONTRIBUTORS.md new file mode 100644 index 0000000000..6be98ff3a6 --- /dev/null +++ b/pos_payment_change/readme/CONTRIBUTORS.md @@ -0,0 +1,4 @@ +- Sylvain LE GAL \<\> +- Julien WESTE +- Foram Shah \<\> +- Manuel Regidor \<\> diff --git a/pos_payment_change/readme/CONTRIBUTORS.rst b/pos_payment_change/readme/CONTRIBUTORS.rst deleted file mode 100644 index 300d09239b..0000000000 --- a/pos_payment_change/readme/CONTRIBUTORS.rst +++ /dev/null @@ -1,4 +0,0 @@ -* Sylvain LE GAL -* Julien WESTE -* Foram Shah -* Manuel Regidor diff --git a/pos_payment_change/readme/CREDITS.md b/pos_payment_change/readme/CREDITS.md new file mode 100644 index 0000000000..7c8befb9ce --- /dev/null +++ b/pos_payment_change/readme/CREDITS.md @@ -0,0 +1,4 @@ +The development of this module has been financially supported by: + +- GRAP, Groupement Régional Alimentaire de proximité (www.grap.coop) +- Vracoop (www.vracoop.fr) diff --git a/pos_payment_change/readme/CREDITS.rst b/pos_payment_change/readme/CREDITS.rst deleted file mode 100644 index 4832a8457f..0000000000 --- a/pos_payment_change/readme/CREDITS.rst +++ /dev/null @@ -1,4 +0,0 @@ -The development of this module has been financially supported by: - -* GRAP, Groupement Régional Alimentaire de proximité (www.grap.coop) -* Vracoop (www.vracoop.fr) diff --git a/pos_payment_change/readme/DESCRIPTION.rst b/pos_payment_change/readme/DESCRIPTION.md similarity index 83% rename from pos_payment_change/readme/DESCRIPTION.rst rename to pos_payment_change/readme/DESCRIPTION.md index f725ca719c..03f8336b2a 100644 --- a/pos_payment_change/readme/DESCRIPTION.rst +++ b/pos_payment_change/readme/DESCRIPTION.md @@ -2,5 +2,5 @@ This module extends the functionnality of the Odoo Point of Sale to allow the cashier to change the payments of a PoS order. This feature is usefull when the user realized that he did a mistake, -just after he marked the order as paid, or during the close of the session, -Only if entries has not been generated. +just after he marked the order as paid, or during the close of the +session, Only if entries has not been generated. diff --git a/pos_payment_change/readme/USAGE.md b/pos_payment_change/readme/USAGE.md new file mode 100644 index 0000000000..6b1c096b46 --- /dev/null +++ b/pos_payment_change/readme/USAGE.md @@ -0,0 +1,19 @@ +- Go to a PoS Order +- Click on the button 'Change Payments' + +![pos_order_form](../static/description/pos_order_form.png) + +- In the pop up wizard, select the real payment(s) that have been used + to pay the order + +![pos_payment_change_wizard_form](../static/description/pos_payment_change_wizard_form.png) + +- Then click on the button 'Change Payments' + +**Note** + +If the option 'Refund and Resale' is selected, changing the payments +will display the three PoS orders. the oringal one, the refund one, and +the new one. + +![pos_order_tree](../static/description/pos_order_tree.png) diff --git a/pos_payment_change/readme/USAGE.rst b/pos_payment_change/readme/USAGE.rst deleted file mode 100644 index 604022c883..0000000000 --- a/pos_payment_change/readme/USAGE.rst +++ /dev/null @@ -1,19 +0,0 @@ -* Go to a PoS Order - -* Click on the button 'Change Payments' - -.. figure:: ../static/description/pos_order_form.png - -* In the pop up wizard, select the real payment(s) that have been - used to pay the order - -.. figure:: ../static/description/pos_payment_change_wizard_form.png - -* Then click on the button 'Change Payments' - -**Note** - -If the option 'Refund and Resale' is selected, changing the payments will -display the three PoS orders. the oringal one, the refund one, and the new one. - -.. figure:: ../static/description/pos_order_tree.png diff --git a/pos_payment_change/static/description/index.html b/pos_payment_change/static/description/index.html index 44fedb44b4..8ba5327830 100644 --- a/pos_payment_change/static/description/index.html +++ b/pos_payment_change/static/description/index.html @@ -3,7 +3,7 @@ -README.rst +Point Of Sale - Change Payments -
    +
    +

    Point Of Sale - Change Payments

    - -
    -Odoo Community Association - -
    -

    Point Of Sale - Change Payments

    -

    Beta License: AGPL-3 OCA/pos Translate me on Weblate Try me on Runboat

    +

    Beta License: AGPL-3 OCA/pos Translate me on Weblate Try me on Runboat

    This module extends the functionnality of the Odoo Point of Sale to allow the cashier to change the payments of a PoS order.

    This feature is usefull when the user realized that he did a mistake, -just after he marked the order as paid, or during the close of the session, -Only if entries has not been generated.

    +just after he marked the order as paid, or during the close of the +session, Only if entries has not been generated.

    Table of contents

      @@ -396,74 +391,65 @@

      Point Of Sale - Change Payments

    -

    Configuration

    +

    Configuration

    • Go to Point of Sale > Configuration > Settings
    • -
    • Edit your point of sale, and select a value for the field -‘Payment Change Policy’.
    • +
    • Edit your point of sale, and select a value for the field ‘Payment +Change Policy’.

    Two options are available:

      -
    • ‘Refund and Resale’: Odoo will refund the current -Pos Order to cancel it, and create a new PoS Order -with the correct payment lines
    • +
    • ‘Refund and Resale’: Odoo will refund the current Pos Order to cancel +it, and create a new PoS Order with the correct payment lines
    • ‘Update Payments’: Odoo will change payment lines.
    -
    -https://raw.githubusercontent.com/OCA/pos/16.0/pos_payment_change/static/description/res_config_settings_form.png -
    -

    Note -In some countries the ‘Update Payments’ Option -is not allowed by law, because orders history shouldn’t not be altered.

    +

    pos_config_form

    +

    Note In some countries the ‘Update Payments’ Option is not allowed +by law, because orders history shouldn’t not be altered.

    For that purpose, a constrains is present to check the value of this field. If the module l10n_fr_certification is installed and if the current company has an inalterable accounting, it will not be possible to select the value ‘Update Payments’.

    -

    Usage

    +

    Usage

    • Go to a PoS Order
    • Click on the button ‘Change Payments’
    -
    -https://raw.githubusercontent.com/OCA/pos/16.0/pos_payment_change/static/description/pos_order_form.png -
    +

    pos_order_form

      -
    • In the pop up wizard, select the real payment(s) that have been -used to pay the order
    • +
    • In the pop up wizard, select the real payment(s) that have been used +to pay the order
    -
    -https://raw.githubusercontent.com/OCA/pos/16.0/pos_payment_change/static/description/pos_payment_change_wizard_form.png -
    +

    pos_payment_change_wizard_form

    • Then click on the button ‘Change Payments’

    Note

    -

    If the option ‘Refund and Resale’ is selected, changing the payments will -display the three PoS orders. the oringal one, the refund one, and the new one.

    -
    -https://raw.githubusercontent.com/OCA/pos/16.0/pos_payment_change/static/description/pos_order_tree.png -
    +

    If the option ‘Refund and Resale’ is selected, changing the payments +will display the three PoS orders. the oringal one, the refund one, and +the new one.

    +

    pos_order_tree

    -

    Bug Tracker

    +

    Bug Tracker

    Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -feedback.

    +feedback.

    Do not contact contributors directly about support or help with technical issues.

    -

    Credits

    +

    Credits

    -

    Authors

    +

    Authors

    • GRAP
    -

    Contributors

    +

    Contributors

    -

    Other credits

    +

    Other credits

    The development of this module has been financially supported by:

      -
    • GRAP, Groupement Régional Alimentaire de proximité (www.grap.coop)
    • -
    • Vracoop (www.vracoop.fr)
    • +
    • GRAP, Groupement Régional Alimentaire de proximité +(www.grap.coop)
    • +
    • Vracoop (www.vracoop.fr)
    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    Odoo Community Association @@ -490,11 +477,10 @@

    Maintainers

    promote its widespread use.

    Current maintainer:

    legalsylvain

    -

    This module is part of the OCA/pos project on GitHub.

    +

    This module is part of the OCA/pos project on GitHub.

    You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

    -
    From 940b5a3744590cef1f7998151728fa031b97e156 Mon Sep 17 00:00:00 2001 From: Eugene Molotov Date: Thu, 13 Mar 2025 17:48:48 +0500 Subject: [PATCH 31/35] [MIG] pos_payment_change: Migration to 17.0 [FIX] pos_payment_change: rebase test on TestPoSCommon [FIX] pos_payment_change: in tests replace Marc Demo to user with explicit rights [FIX] pos_payment_change: add compatibility with pos_order_copy Co-authored-by: Eugene Molotov [UPD] Update pos_payment_change.pot [BOT] post-merge updates --- pos_payment_change/README.rst | 44 +++--- pos_payment_change/__manifest__.py | 2 +- pos_payment_change/i18n/de.po | 17 -- pos_payment_change/i18n/es.po | 15 -- .../i18n/pos_payment_change.pot | 14 +- pos_payment_change/models/pos_order.py | 11 +- .../static/description/index.html | 32 ++-- pos_payment_change/tests/__init__.py | 2 +- ...t_module.py => test_pos_payment_change.py} | 148 +++++++----------- pos_payment_change/views/view_pos_order.xml | 2 +- .../views/view_res_config_settings.xml | 46 ++---- .../wizards/pos_payment_change_wizard.py | 23 ++- .../pos_payment_change_wizard_new_line.py | 12 +- .../view_pos_payment_change_wizard.xml | 16 +- 14 files changed, 163 insertions(+), 221 deletions(-) rename pos_payment_change/tests/{test_module.py => test_pos_payment_change.py} (57%) diff --git a/pos_payment_change/README.rst b/pos_payment_change/README.rst index 2c06443133..9da41c8076 100644 --- a/pos_payment_change/README.rst +++ b/pos_payment_change/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + =============================== Point Of Sale - Change Payments =============================== @@ -7,13 +11,13 @@ Point Of Sale - Change Payments !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:1c6e8c040d05dda8166904f53fc0ab8ba31c3e0fc1d9c158284f6dbd75c966c4 + !! source digest: sha256:bd65942d8b04bf96c6479713390736e81e44935e7df4cd0a3a9c94237b229c28 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fpos-lightgray.png?logo=github @@ -43,15 +47,15 @@ session, Only if entries has not been generated. Configuration ============= -- Go to Point of Sale > Configuration > Settings -- Edit your point of sale, and select a value for the field 'Payment - Change Policy'. +- Go to Point of Sale > Configuration > Settings +- Edit your point of sale, and select a value for the field 'Payment + Change Policy'. Two options are available: -- 'Refund and Resale': Odoo will refund the current Pos Order to cancel - it, and create a new PoS Order with the correct payment lines -- 'Update Payments': Odoo will change payment lines. +- 'Refund and Resale': Odoo will refund the current Pos Order to cancel + it, and create a new PoS Order with the correct payment lines +- 'Update Payments': Odoo will change payment lines. |pos_config_form| @@ -68,17 +72,17 @@ to select the value 'Update Payments'. Usage ===== -- Go to a PoS Order -- Click on the button 'Change Payments' +- Go to a PoS Order +- Click on the button 'Change Payments' |pos_order_form| -- In the pop up wizard, select the real payment(s) that have been used - to pay the order +- In the pop up wizard, select the real payment(s) that have been used + to pay the order |pos_payment_change_wizard_form| -- Then click on the button 'Change Payments' +- Then click on the button 'Change Payments' **Note** @@ -113,19 +117,19 @@ Authors Contributors ------------ -- Sylvain LE GAL -- Julien WESTE -- Foram Shah -- Manuel Regidor +- Sylvain LE GAL +- Julien WESTE +- Foram Shah +- Manuel Regidor Other credits ------------- The development of this module has been financially supported by: -- GRAP, Groupement Régional Alimentaire de proximité - (`www.grap.coop `__) -- Vracoop (`www.vracoop.fr `__) +- GRAP, Groupement Régional Alimentaire de proximité + (`www.grap.coop `__) +- Vracoop (`www.vracoop.fr `__) Maintainers ----------- diff --git a/pos_payment_change/__manifest__.py b/pos_payment_change/__manifest__.py index bbaf176030..465177140f 100644 --- a/pos_payment_change/__manifest__.py +++ b/pos_payment_change/__manifest__.py @@ -3,7 +3,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { "name": "Point Of Sale - Change Payments", - "version": "16.0.1.0.4", + "version": "17.0.1.0.0", "summary": "Allow cashier to change order payments, as long as" " the session is not closed.", "category": "Point Of Sale", diff --git a/pos_payment_change/i18n/de.po b/pos_payment_change/i18n/de.po index 351fb77ef7..16893fa83c 100644 --- a/pos_payment_change/i18n/de.po +++ b/pos_payment_change/i18n/de.po @@ -249,20 +249,3 @@ msgid "" msgstr "" "Sie können Zahlungen der Kasse '%(name)s' nicht ändern, da die zugehörige " "Sitzung '%(session)s' geschlossen wurde!" - -#, python-format -#~ msgid "" -#~ "Differences between the two values for the POS Order '%(name)s':\n" -#~ " * Total of all the new payments %(total)s; * Total of the POS Order " -#~ "%(amount_total)s;\n" -#~ "Please change the payments." -#~ msgstr "" -#~ "Differenzen zwischen den beiden Werten für den POS-Auftrag '%(name)s':\n" -#~ "\n" -#~ " * Summe aller neuen Zahlungen %(total)s;\n" -#~ " * Summe des POS-Auftrags %(amount_total)s;\n" -#~ "\n" -#~ "Bitte ändern Sie die Zahlungen." - -#~ msgid "Journal" -#~ msgstr "Journal" diff --git a/pos_payment_change/i18n/es.po b/pos_payment_change/i18n/es.po index e69ed67ab5..8212e50d46 100644 --- a/pos_payment_change/i18n/es.po +++ b/pos_payment_change/i18n/es.po @@ -254,18 +254,3 @@ msgid "" msgstr "" "¡No puede cambiar los pagos del TPV '%(name)s' porque la sesión asociada " "'%(session)s' se ha cerrado!" - -#, python-format -#~ msgid "" -#~ "Differences between the two values for the POS Order '%(name)s':\n" -#~ " * Total of all the new payments %(total)s; * Total of the POS Order " -#~ "%(amount_total)s;\n" -#~ "Please change the payments." -#~ msgstr "" -#~ "Diferencias entre los dos valores para el pedido de TPV '%(name)s':\n" -#~ " * Total de todos los nuevos pagos %(total)s;\n" -#~ " * Total del pedido del punto de venta %(amount_total)s;\n" -#~ "Por favor cambie los pagos." - -#~ msgid "Journal" -#~ msgstr "Diario" diff --git a/pos_payment_change/i18n/pos_payment_change.pot b/pos_payment_change/i18n/pos_payment_change.pot index 5ec6986c9e..de6f3d6bcd 100644 --- a/pos_payment_change/i18n/pos_payment_change.pot +++ b/pos_payment_change/i18n/pos_payment_change.pot @@ -4,7 +4,7 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 16.0\n" +"Project-Id-Version: Odoo Server 17.0\n" "Report-Msgid-Bugs-To: \n" "Last-Translator: \n" "Language-Team: \n" @@ -102,13 +102,6 @@ msgstr "" msgid "ID" msgstr "" -#. module: pos_payment_change -#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard____last_update -#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line____last_update -#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_line____last_update -msgid "Last Modified on" -msgstr "" - #. module: pos_payment_change #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard__write_uid #: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__write_uid @@ -176,6 +169,11 @@ msgstr "" msgid "Payment Method" msgstr "" +#. module: pos_payment_change +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_new_line__available_payment_method_ids +msgid "Payment Methods" +msgstr "" + #. module: pos_payment_change #: model:ir.model,name:pos_payment_change.model_pos_payment_change_wizard msgid "PoS Payment Change Wizard" diff --git a/pos_payment_change/models/pos_order.py b/pos_payment_change/models/pos_order.py index 2a5de9da57..5435c4191d 100644 --- a/pos_payment_change/models/pos_order.py +++ b/pos_payment_change/models/pos_order.py @@ -69,7 +69,7 @@ def change_payment(self, payment_lines): # Resale order and mark it as paid # with the new payment - resale_order = self.copy(default={"pos_reference": self.pos_reference}) + resale_order = self.copy(default=self._prepare_resale_order_vals()) for line in payment_lines: line.update({"pos_order_id": resale_order.id}) resale_order.add_payment(line) @@ -83,7 +83,7 @@ def change_payment(self, payment_lines): ) for order in orders: - order.note = "%s\n%s" % (order.note or "", comment) + order.note = "{}\n{}".format(order.note or "", comment) return orders def _check_payment_change_allowed(self): @@ -99,3 +99,10 @@ def _check_payment_change_allowed(self): session=", ".join(closed_orders.mapped("session_id.name")), ) ) + + def _prepare_resale_order_vals(self): + self.ensure_one() + return { + "pos_reference": self.pos_reference, + "session_id": self.session_id.id, + } diff --git a/pos_payment_change/static/description/index.html b/pos_payment_change/static/description/index.html index 8ba5327830..62f2acd207 100644 --- a/pos_payment_change/static/description/index.html +++ b/pos_payment_change/static/description/index.html @@ -3,7 +3,7 @@ -Point Of Sale - Change Payments +README.rst -
    -

    Point Of Sale - Change Payments

    +
    + + +Odoo Community Association + +
    +

    Point Of Sale - Change Payments

    -

    Beta License: AGPL-3 OCA/pos Translate me on Weblate Try me on Runboat

    +

    Beta License: AGPL-3 OCA/pos Translate me on Weblate Try me on Runboat

    This module extends the functionnality of the Odoo Point of Sale to allow the cashier to change the payments of a PoS order.

    This feature is usefull when the user realized that he did a mistake, @@ -391,7 +396,7 @@

    Point Of Sale - Change Payments

    -

    Configuration

    +

    Configuration

    • Go to Point of Sale > Configuration > Settings
    • Edit your point of sale, and select a value for the field ‘Payment @@ -412,7 +417,7 @@

      Configuration

      to select the value ‘Update Payments’.

    -

    Usage

    +

    Usage

    • Go to a PoS Order
    • Click on the button ‘Change Payments’
    • @@ -433,7 +438,7 @@

      Usage

      pos_order_tree

    -

    Bug Tracker

    +

    Bug Tracker

    Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed @@ -441,15 +446,15 @@

    Bug Tracker

    Do not contact contributors directly about support or help with technical issues.

    -

    Credits

    +

    Credits

    -

    Authors

    +

    Authors

    • GRAP
    -

    Contributors

    +

    Contributors

    -

    Other credits

    +

    Other credits

    The development of this module has been financially supported by:

    • GRAP, Groupement Régional Alimentaire de proximité @@ -467,7 +472,7 @@

      Other credits

    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    Odoo Community Association @@ -482,5 +487,6 @@

    Maintainers

    +
    diff --git a/pos_payment_change/tests/__init__.py b/pos_payment_change/tests/__init__.py index d9b96c4fa5..c2983ad535 100644 --- a/pos_payment_change/tests/__init__.py +++ b/pos_payment_change/tests/__init__.py @@ -1 +1 @@ -from . import test_module +from . import test_pos_payment_change diff --git a/pos_payment_change/tests/test_module.py b/pos_payment_change/tests/test_pos_payment_change.py similarity index 57% rename from pos_payment_change/tests/test_module.py rename to pos_payment_change/tests/test_pos_payment_change.py index 53a7162cbc..40eec8f358 100644 --- a/pos_payment_change/tests/test_module.py +++ b/pos_payment_change/tests/test_pos_payment_change.py @@ -2,68 +2,37 @@ # @author: Sylvain LE GAL (https://twitter.com/legalsylvain) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo import fields +from odoo import Command, fields from odoo.exceptions import UserError -from odoo.tests.common import TransactionCase - - -class TestModule(TransactionCase): - """Tests for 'Point of Sale - Change Payment' Module""" - - def setUp(self): - super().setUp() - self.PosSession = self.env["pos.session"] - self.PosOrder = self.env["pos.order"] - self.PosPaymentMethod = self.env["pos.payment.method"] - self.PosPayment = self.env["pos.payment"] - self.PosMakePayment = self.env["pos.make.payment"] - self.PosPaymentChangeWizard = self.env["pos.payment.change.wizard"] - self.PosPaymentChangeWizardNewLine = self.env[ - "pos.payment.change.wizard.new.line" - ] - self.product = self.env.ref("product.product_product_3") - self.pos_config = self.env.ref("point_of_sale.pos_config_main").copy() +from odoo.tests import new_test_user, tagged +from odoo.tests.common import users +from odoo.tools import mute_logger - def _initialize_journals_open_session(self): - account_id = self.env.company.account_default_pos_receivable_account_id - self.bank_payment_method = self.PosPaymentMethod.create( - { - "name": "Bank", - "receivable_account_id": account_id.id, - } - ) - self.cash_payment_method = self.PosPaymentMethod.create( - { - "name": "Cash", - "is_cash_count": True, - "receivable_account_id": account_id.id, - "journal_id": self.env["account.journal"] - .search( - [("type", "=", "cash"), ("company_id", "=", self.env.company.id)], - limit=1, - ) - .id, - } - ) +from odoo.addons.point_of_sale.tests.common import TestPoSCommon + + +@tagged("post_install", "-at_install") +class TestPosPaymentChange(TestPoSCommon): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.PosOrder = cls.env["pos.order"] + cls.product = cls.create_product("Test POS Product", cls.categ_basic, 10) + cls.pos_config = cls.basic_config + cls.bank_payment_method = cls.bank_pm1 + cls.cash_payment_method = cls.cash_pm1 # create new session and open it - self.pos_config.payment_method_ids = [ - self.bank_payment_method.id, - self.cash_payment_method.id, - ] - self.pos_config.open_ui() - self.session = self.pos_config.current_session_id + cls.pos_config.open_ui() + cls.session = cls.pos_config.current_session_id + new_test_user( + cls.env, + login="test-pos-manager", + groups="point_of_sale.group_pos_manager", + ) def _sale(self, payment_method_1, price_1, payment_method_2=False, price_2=0.0): price = price_1 + price_2 - line_vals = { - "name": "OL/0001", - "product_id": self.product.id, - "qty": 1.0, - "price_unit": price, - "price_subtotal": price, - "price_subtotal_incl": price, - } order = self.PosOrder.create( { "session_id": self.session.id, @@ -71,7 +40,18 @@ def _sale(self, payment_method_1, price_1, payment_method_2=False, price_2=0.0): "amount_total": price, "amount_paid": price, "amount_return": 0, - "lines": [[0, False, line_vals]], + "lines": [ + Command.create( + { + "name": "OL/0001", + "product_id": self.product.id, + "qty": 1.0, + "price_unit": price, + "price_subtotal": price, + "price_subtotal_incl": price, + } + ) + ], } ) order.add_payment( @@ -98,29 +78,35 @@ def _change_payment( self, order, payment_method_1, amount_1, payment_method_2=False, amount_2=0.0 ): # Switch to check journal - wizard = self.PosPaymentChangeWizard.with_context(active_id=order.id).create({}) - self.PosPaymentChangeWizardNewLine.with_context(active_id=order.id).create( - { - "wizard_id": wizard.id, - "new_payment_method_id": payment_method_1.id, - "amount": amount_1, - } - ) - if payment_method_2: - self.PosPaymentChangeWizardNewLine.with_context(active_id=order.id).create( + new_line_vals = [ + Command.create( { - "wizard_id": wizard.id, - "new_payment_method_id": payment_method_2.id, - "amount": amount_2, + "new_payment_method_id": payment_method_1.id, + "amount": amount_1, } ) + ] + if payment_method_2: + new_line_vals += [ + Command.create( + { + "new_payment_method_id": payment_method_2.id, + "amount": amount_2, + } + ) + ] + wizard = ( + self.env["pos.payment.change.wizard"] + .with_context(active_id=order.id) + .create({"new_line_ids": new_line_vals}) + ) wizard.button_change_payment() # Test Section + @mute_logger("odoo.models.unlink") def test_01_payment_change_policy_update(self): self.pos_config.payment_change_policy = "update" - self._initialize_journals_open_session() # Make a sale with 35 in cash journal and 65 in check order = self._sale(self.cash_payment_method, 35, self.bank_payment_method, 65) @@ -165,7 +151,6 @@ def test_01_payment_change_policy_update(self): def test_02_payment_change_policy_refund(self): self.pos_config.payment_change_policy = "refund" - self._initialize_journals_open_session() # Make a sale with 35 in cash journal and 65 in check order = self._sale(self.cash_payment_method, 35, self.bank_payment_method, 65) @@ -185,7 +170,6 @@ def test_02_payment_change_policy_refund(self): def test_03_payment_change_closed_orders(self): self.pos_config.payment_change_policy = "update" - self._initialize_journals_open_session() # Make a sale with 35 in cash journal and 65 in check order = self._sale(self.cash_payment_method, 35, self.bank_payment_method, 65) @@ -196,25 +180,9 @@ def test_03_payment_change_closed_orders(self): order, self.cash_payment_method, 10, self.bank_payment_method, 90 ) + @users("test-pos-manager") def test_04_payment_change_security(self): self.pos_config.payment_change_policy = "refund" - self._initialize_journals_open_session() order = self._sale(self.cash_payment_method, 35, self.bank_payment_method, 65) - # the demo user should be able to do this - user_demo = self.env.ref("base.user_demo") - wizard = ( - self.PosPaymentChangeWizard.with_user(user_demo) - .with_context(active_id=order.id) - .create({}) - ) - self.PosPaymentChangeWizardNewLine.with_user(user_demo).with_context( - active_id=order.id - ).create( - { - "wizard_id": wizard.id, - "new_payment_method_id": self.cash_payment_method.id, - "amount": 100.0, - } - ) - wizard.button_change_payment() + self._change_payment(order, self.cash_payment_method, 100) diff --git a/pos_payment_change/views/view_pos_order.xml b/pos_payment_change/views/view_pos_order.xml index bde665be8a..32fdc66544 100644 --- a/pos_payment_change/views/view_pos_order.xml +++ b/pos_payment_change/views/view_pos_order.xml @@ -16,7 +16,7 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). context="{'pos_session_id' : session_id}" string="Change Payments" type="action" - states="paid,invoiced" + invisible="state not in ('paid', 'invoiced')" /> diff --git a/pos_payment_change/views/view_res_config_settings.xml b/pos_payment_change/views/view_res_config_settings.xml index b6f46bfacf..35e4b7a527 100644 --- a/pos_payment_change/views/view_res_config_settings.xml +++ b/pos_payment_change/views/view_res_config_settings.xml @@ -10,36 +10,24 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). res.config.settings - -
    -
    -
    - - +
    + Payment Change Policy when users want to change the payment lines of a given PoS Order. +
      +
    • 'Refund and Resale': Odoo will refund the current Pos Order to cancel it, and create a new PoS Order with the correct payment lines. +
    • +
    • 'Update Payments': Odoo will change payment lines. +
    • +
    + Note : In some countries the 'Update Payments' option is not allowed by law, because orders history shouldn't not be altered. +
    + + diff --git a/pos_payment_change/wizards/pos_payment_change_wizard.py b/pos_payment_change/wizards/pos_payment_change_wizard.py index a68514086f..2b58beba98 100644 --- a/pos_payment_change/wizards/pos_payment_change_wizard.py +++ b/pos_payment_change/wizards/pos_payment_change_wizard.py @@ -2,7 +2,7 @@ # @author: Sylvain LE GAL (https://twitter.com/legalsylvain) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo import _, api, fields, models +from odoo import Command, _, api, fields, models from odoo.exceptions import UserError from odoo.tools import float_compare @@ -35,18 +35,15 @@ def default_get(self, fields): PosOrder = self.env["pos.order"] res = super().default_get(fields) order = PosOrder.browse(self._context.get("active_id")) - old_lines_vals = [] - for payment in order.payment_ids: - old_lines_vals.append( - ( - 0, - 0, - { - "old_payment_method_id": payment.payment_method_id.id, - "amount": payment.amount, - }, - ) + old_lines_vals = [ + Command.create( + { + "old_payment_method_id": payment.payment_method_id.id, + "amount": payment.amount, + }, ) + for payment in order.payment_ids + ] res.update( { "order_id": order.id, @@ -99,7 +96,7 @@ def button_change_payment(self): if len(orders) == 1: # if policy is 'update', only close the pop up - action = {"type": "ir.actions.act_window_close"} + return {"type": "ir.actions.act_window_close"} else: # otherwise (refund policy), displays the 3 orders action = self.env["ir.actions.act_window"]._for_xml_id( diff --git a/pos_payment_change/wizards/pos_payment_change_wizard_new_line.py b/pos_payment_change/wizards/pos_payment_change_wizard_new_line.py index 72b571a1ac..2c274948fc 100644 --- a/pos_payment_change/wizards/pos_payment_change_wizard_new_line.py +++ b/pos_payment_change/wizards/pos_payment_change_wizard_new_line.py @@ -19,7 +19,11 @@ class PosPaymentChangeWizardLine(models.TransientModel): comodel_name="pos.payment.method", string="Payment Method", required=True, - domain=lambda s: s._domain_new_payment_method_id(), + domain="[('id', 'in', available_payment_method_ids)]", + ) + available_payment_method_ids = fields.Many2many( + comodel_name="pos.payment.method", + related="wizard_id.order_id.session_id.payment_method_ids", ) company_currency_id = fields.Many2one( @@ -37,12 +41,6 @@ class PosPaymentChangeWizardLine(models.TransientModel): currency_field="company_currency_id", ) - @api.model - def _domain_new_payment_method_id(self): - PosOrder = self.env["pos.order"] - order = PosOrder.browse(self.env.context.get("active_id")) - return [("id", "in", order.mapped("session_id.payment_method_ids").ids)] - # View Section @api.model def default_get(self, fields): diff --git a/pos_payment_change/wizards/view_pos_payment_change_wizard.xml b/pos_payment_change/wizards/view_pos_payment_change_wizard.xml index e947a8254e..800e98cf28 100644 --- a/pos_payment_change/wizards/view_pos_payment_change_wizard.xml +++ b/pos_payment_change/wizards/view_pos_payment_change_wizard.xml @@ -10,24 +10,32 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). pos.payment.change.wizard
    - + - + From 7913f5d053b264ff67f537ce9967081f4a03a62d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Mart=C3=ADnez?= Date: Mon, 22 Jun 2026 17:42:27 +0200 Subject: [PATCH 32/35] [IMP] pos_payment_change: pre-commit auto fixes --- pos_payment_change/views/view_pos_order.xml | 1 - pos_payment_change/views/view_res_config_settings.xml | 9 ++++----- .../wizards/view_pos_payment_change_wizard.xml | 2 -- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/pos_payment_change/views/view_pos_order.xml b/pos_payment_change/views/view_pos_order.xml index 32fdc66544..cf7ac7239b 100644 --- a/pos_payment_change/views/view_pos_order.xml +++ b/pos_payment_change/views/view_pos_order.xml @@ -5,7 +5,6 @@ Copyright (C) 2015-Today GRAP (http://www.grap.coop) License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). --> - pos.order diff --git a/pos_payment_change/views/view_res_config_settings.xml b/pos_payment_change/views/view_res_config_settings.xml index 35e4b7a527..009830a22d 100644 --- a/pos_payment_change/views/view_res_config_settings.xml +++ b/pos_payment_change/views/view_res_config_settings.xml @@ -5,7 +5,6 @@ Copyright (C) 2020-Today GRAP (http://www.grap.coop) License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). --> - res.config.settings @@ -18,12 +17,12 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
    Payment Change Policy when users want to change the payment lines of a given PoS Order.
      -
    • 'Refund and Resale': Odoo will refund the current Pos Order to cancel it, and create a new PoS Order with the correct payment lines. +
    • 'Refund and Resale': Odoo will refund the current Pos Order to cancel it, and create a new PoS Order with the correct payment lines.
    • -
    • 'Update Payments': Odoo will change payment lines. +
    • 'Update Payments': Odoo will change payment lines.
    • -
    + Note : In some countries the 'Update Payments' option is not allowed by law, because orders history shouldn't not be altered.
    diff --git a/pos_payment_change/wizards/view_pos_payment_change_wizard.xml b/pos_payment_change/wizards/view_pos_payment_change_wizard.xml index 800e98cf28..bc7d70e4ab 100644 --- a/pos_payment_change/wizards/view_pos_payment_change_wizard.xml +++ b/pos_payment_change/wizards/view_pos_payment_change_wizard.xml @@ -5,7 +5,6 @@ Copyright (C) 2015-Today GRAP (http://www.grap.coop) License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). --> - pos.payment.change.wizard @@ -58,5 +57,4 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). form new - From c5d89d5ecd91a34695db282241c3c66c9fbc7c0a Mon Sep 17 00:00:00 2001 From: Abraham Anes Date: Sun, 9 Nov 2025 23:15:06 +0100 Subject: [PATCH 33/35] [MIG] pos_payment_change: Migration to 18.0 Co-authored-by: Abraham Anes --- pos_payment_change/README.rst | 67 ++--- pos_payment_change/__manifest__.py | 2 +- pos_payment_change/models/__init__.py | 1 + pos_payment_change/models/pos_config.py | 4 +- pos_payment_change/models/pos_order.py | 38 ++- pos_payment_change/models/pos_payment.py | 12 + pos_payment_change/readme/DESCRIPTION.md | 6 +- .../static/description/index.html | 49 ++-- .../tests/test_pos_payment_change.py | 273 ++++++++++++++---- pos_payment_change/views/view_pos_order.xml | 2 +- .../wizards/pos_payment_change_wizard.py | 9 +- .../pos_payment_change_wizard_new_line.py | 5 +- .../pos_payment_change_wizard_old_line.py | 4 +- .../view_pos_payment_change_wizard.xml | 10 +- 14 files changed, 331 insertions(+), 151 deletions(-) create mode 100644 pos_payment_change/models/pos_payment.py diff --git a/pos_payment_change/README.rst b/pos_payment_change/README.rst index 9da41c8076..2529711207 100644 --- a/pos_payment_change/README.rst +++ b/pos_payment_change/README.rst @@ -1,7 +1,3 @@ -.. image:: https://odoo-community.org/readme-banner-image - :target: https://odoo-community.org/get-involved?utm_source=readme - :alt: Odoo Community Association - =============================== Point Of Sale - Change Payments =============================== @@ -17,27 +13,26 @@ Point Of Sale - Change Payments .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fpos-lightgray.png?logo=github - :target: https://github.com/OCA/pos/tree/17.0/pos_payment_change + :target: https://github.com/OCA/pos/tree/18.0/pos_payment_change :alt: OCA/pos .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/pos-17-0/pos-17-0-pos_payment_change + :target: https://translation.odoo-community.org/projects/pos-18-0/pos-18-0-pos_payment_change :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/builds?repo=OCA/pos&target_branch=17.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/pos&target_branch=18.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| This module extends the functionnality of the Odoo Point of Sale to -allow the cashier to change the payments of a PoS order. +allow the cashier to change the payments of a invoiced PoS order. -This feature is usefull when the user realized that he did a mistake, -just after he marked the order as paid, or during the close of the -session, Only if entries has not been generated. +This feature is usefull when the user realized that he did a mistake +after invoice. **Table of contents** @@ -47,15 +42,15 @@ session, Only if entries has not been generated. Configuration ============= -- Go to Point of Sale > Configuration > Settings -- Edit your point of sale, and select a value for the field 'Payment - Change Policy'. +- Go to Point of Sale > Configuration > Settings +- Edit your point of sale, and select a value for the field 'Payment + Change Policy'. Two options are available: -- 'Refund and Resale': Odoo will refund the current Pos Order to cancel - it, and create a new PoS Order with the correct payment lines -- 'Update Payments': Odoo will change payment lines. +- 'Refund and Resale': Odoo will refund the current Pos Order to cancel + it, and create a new PoS Order with the correct payment lines +- 'Update Payments': Odoo will change payment lines. |pos_config_form| @@ -67,22 +62,22 @@ field. If the module ``l10n_fr_certification`` is installed and if the current company has an inalterable accounting, it will not be possible to select the value 'Update Payments'. -.. |pos_config_form| image:: https://raw.githubusercontent.com/OCA/pos/17.0/pos_payment_change/static/description/res_config_settings_form.png +.. |pos_config_form| image:: https://raw.githubusercontent.com/OCA/pos/18.0/pos_payment_change/static/description/res_config_settings_form.png Usage ===== -- Go to a PoS Order -- Click on the button 'Change Payments' +- Go to a PoS Order +- Click on the button 'Change Payments' |pos_order_form| -- In the pop up wizard, select the real payment(s) that have been used - to pay the order +- In the pop up wizard, select the real payment(s) that have been used + to pay the order |pos_payment_change_wizard_form| -- Then click on the button 'Change Payments' +- Then click on the button 'Change Payments' **Note** @@ -92,9 +87,9 @@ the new one. |pos_order_tree| -.. |pos_order_form| image:: https://raw.githubusercontent.com/OCA/pos/17.0/pos_payment_change/static/description/pos_order_form.png -.. |pos_payment_change_wizard_form| image:: https://raw.githubusercontent.com/OCA/pos/17.0/pos_payment_change/static/description/pos_payment_change_wizard_form.png -.. |pos_order_tree| image:: https://raw.githubusercontent.com/OCA/pos/17.0/pos_payment_change/static/description/pos_order_tree.png +.. |pos_order_form| image:: https://raw.githubusercontent.com/OCA/pos/18.0/pos_payment_change/static/description/pos_order_form.png +.. |pos_payment_change_wizard_form| image:: https://raw.githubusercontent.com/OCA/pos/18.0/pos_payment_change/static/description/pos_payment_change_wizard_form.png +.. |pos_order_tree| image:: https://raw.githubusercontent.com/OCA/pos/18.0/pos_payment_change/static/description/pos_order_tree.png Bug Tracker =========== @@ -102,7 +97,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -117,19 +112,19 @@ Authors Contributors ------------ -- Sylvain LE GAL -- Julien WESTE -- Foram Shah -- Manuel Regidor +- Sylvain LE GAL +- Julien WESTE +- Foram Shah +- Manuel Regidor Other credits ------------- The development of this module has been financially supported by: -- GRAP, Groupement Régional Alimentaire de proximité - (`www.grap.coop `__) -- Vracoop (`www.vracoop.fr `__) +- GRAP, Groupement Régional Alimentaire de proximité + (`www.grap.coop `__) +- Vracoop (`www.vracoop.fr `__) Maintainers ----------- @@ -152,6 +147,6 @@ Current `maintainer `__: |maintainer-legalsylvain| -This module is part of the `OCA/pos `_ project on GitHub. +This module is part of the `OCA/pos `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/pos_payment_change/__manifest__.py b/pos_payment_change/__manifest__.py index 465177140f..23a247c648 100644 --- a/pos_payment_change/__manifest__.py +++ b/pos_payment_change/__manifest__.py @@ -3,7 +3,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { "name": "Point Of Sale - Change Payments", - "version": "17.0.1.0.0", + "version": "18.0.1.0.0", "summary": "Allow cashier to change order payments, as long as" " the session is not closed.", "category": "Point Of Sale", diff --git a/pos_payment_change/models/__init__.py b/pos_payment_change/models/__init__.py index 3d75627c44..b2f3b28373 100644 --- a/pos_payment_change/models/__init__.py +++ b/pos_payment_change/models/__init__.py @@ -1,3 +1,4 @@ from . import pos_config from . import pos_order +from . import pos_payment from . import res_config_settings diff --git a/pos_payment_change/models/pos_config.py b/pos_payment_change/models/pos_config.py index 2997e8c6de..2f4659dad3 100644 --- a/pos_payment_change/models/pos_config.py +++ b/pos_payment_change/models/pos_config.py @@ -2,7 +2,7 @@ # @author: Sylvain LE GAL (https://twitter.com/legalsylvain) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo import _, api, fields, models +from odoo import api, fields, models from odoo.exceptions import ValidationError @@ -44,7 +44,7 @@ def _check_payment_change_policy(self): for config in self.filtered(lambda x: x.payment_change_policy == "update"): if config.company_id._is_accounting_unalterable(): raise ValidationError( - _( + self.env._( "Unable to use the 'Update Payments' options" " for companies that have unalterable accounting." ) diff --git a/pos_payment_change/models/pos_order.py b/pos_payment_change/models/pos_order.py index 5435c4191d..f318076f7b 100644 --- a/pos_payment_change/models/pos_order.py +++ b/pos_payment_change/models/pos_order.py @@ -5,7 +5,7 @@ from datetime import datetime -from odoo import _, fields, models +from odoo import fields, models from odoo.exceptions import UserError from odoo.tools import float_is_zero @@ -13,6 +13,8 @@ class PosOrder(models.Model): _inherit = "pos.order" + payment_change_policy = fields.Selection(related="config_id.payment_change_policy") + def change_payment(self, payment_lines): """ Change payment of a given order. @@ -33,8 +35,7 @@ def change_payment(self, payment_lines): ] self._check_payment_change_allowed() - - comment = _( + comment = self.env._( "The payments of the Order %(order)s (Ref: %(ref)s have" " been changed by %(user_name)s on %(today)s", order=self.name, @@ -44,12 +45,21 @@ def change_payment(self, payment_lines): ) if self.config_id.payment_change_policy == "update": - self.payment_ids.with_context().unlink() + payments = self.payment_ids + account_moves = payments.account_move_id + if account_moves: + account_moves.button_draft() + account_moves.unlink() + payments.unlink() # Create new payment for line in payment_lines: - self.add_payment(line) + self.with_context( + skip_pos_payment_invoiced_check_amount=True + ).add_payment(line) + if self.state == "invoiced": + self._apply_invoice_payments(self.session_id.state == "closed") elif self.config_id.payment_change_policy == "refund": # Refund order and mark it as paid # with same payment method as the original one @@ -65,25 +75,29 @@ def change_payment(self, payment_lines): } ) - refund_order.action_pos_order_paid() - + if self.state == "invoiced": + refund_order._generate_pos_order_invoice() + else: + refund_order.action_pos_order_paid() # Resale order and mark it as paid # with the new payment resale_order = self.copy(default=self._prepare_resale_order_vals()) for line in payment_lines: line.update({"pos_order_id": resale_order.id}) resale_order.add_payment(line) - resale_order.action_pos_order_paid() - + if self.state == "invoiced": + resale_order._generate_pos_order_invoice() + else: + resale_order.action_pos_order_paid() orders += refund_order + resale_order - comment += _( + comment += self.env._( " (Refund Order: %(refund_order)s ; Resale Order: %(resale_order)s)", refund_order=refund_order.name, resale_order=resale_order.name, ) for order in orders: - order.note = "{}\n{}".format(order.note or "", comment) + order.general_note = "{}\n{}".format(order.general_note or "", comment) return orders def _check_payment_change_allowed(self): @@ -92,7 +106,7 @@ def _check_payment_change_allowed(self): closed_orders = self.filtered(lambda x: x.session_id.state == "closed") if len(closed_orders): raise UserError( - _( + self.env._( "You can not change payments of the POS '%(name)s' because" " the associated session '%(session)s' has been closed!", name=", ".join(closed_orders.mapped("name")), diff --git a/pos_payment_change/models/pos_payment.py b/pos_payment_change/models/pos_payment.py new file mode 100644 index 0000000000..bde7790fd3 --- /dev/null +++ b/pos_payment_change/models/pos_payment.py @@ -0,0 +1,12 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import models + + +class PosPayment(models.Model): + _inherit = "pos.payment" + + def _check_amount(self): + if self.env.context.get("skip_pos_payment_invoiced_check_amount"): + self -= self.filtered(lambda x: x.state == "invoiced") + return super()._check_amount() diff --git a/pos_payment_change/readme/DESCRIPTION.md b/pos_payment_change/readme/DESCRIPTION.md index 03f8336b2a..86879e5c48 100644 --- a/pos_payment_change/readme/DESCRIPTION.md +++ b/pos_payment_change/readme/DESCRIPTION.md @@ -1,6 +1,4 @@ This module extends the functionnality of the Odoo Point of Sale to -allow the cashier to change the payments of a PoS order. +allow the cashier to change the payments of a invoiced PoS order. -This feature is usefull when the user realized that he did a mistake, -just after he marked the order as paid, or during the close of the -session, Only if entries has not been generated. +This feature is usefull when the user realized that he did a mistake after invoice. diff --git a/pos_payment_change/static/description/index.html b/pos_payment_change/static/description/index.html index 62f2acd207..53e09548bb 100644 --- a/pos_payment_change/static/description/index.html +++ b/pos_payment_change/static/description/index.html @@ -3,7 +3,7 @@ -README.rst +Point Of Sale - Change Payments -
    +
    +

    Point Of Sale - Change Payments

    - - -Odoo Community Association - -
    -

    Point Of Sale - Change Payments

    -

    Beta License: AGPL-3 OCA/pos Translate me on Weblate Try me on Runboat

    +

    Beta License: AGPL-3 OCA/pos Translate me on Weblate Try me on Runboat

    This module extends the functionnality of the Odoo Point of Sale to -allow the cashier to change the payments of a PoS order.

    -

    This feature is usefull when the user realized that he did a mistake, -just after he marked the order as paid, or during the close of the -session, Only if entries has not been generated.

    +allow the cashier to change the payments of a invoiced PoS order.

    +

    This feature is usefull when the user realized that he did a mistake +after invoice.

    Table of contents

      @@ -396,7 +390,7 @@

      Point Of Sale - Change Payments

    -

    Configuration

    +

    Configuration

    • Go to Point of Sale > Configuration > Settings
    • Edit your point of sale, and select a value for the field ‘Payment @@ -408,7 +402,7 @@

      Configuration

      it, and create a new PoS Order with the correct payment lines
    • ‘Update Payments’: Odoo will change payment lines.
    -

    pos_config_form

    +

    pos_config_form

    Note In some countries the ‘Update Payments’ Option is not allowed by law, because orders history shouldn’t not be altered.

    For that purpose, a constrains is present to check the value of this @@ -417,17 +411,17 @@

    Configuration

    to select the value ‘Update Payments’.

    -

    Usage

    +

    Usage

    • Go to a PoS Order
    • Click on the button ‘Change Payments’
    -

    pos_order_form

    +

    pos_order_form

    • In the pop up wizard, select the real payment(s) that have been used to pay the order
    -

    pos_payment_change_wizard_form

    +

    pos_payment_change_wizard_form

    • Then click on the button ‘Change Payments’
    @@ -435,26 +429,26 @@

    Usage

    If the option ‘Refund and Resale’ is selected, changing the payments will display the three PoS orders. the oringal one, the refund one, and the new one.

    -

    pos_order_tree

    +

    pos_order_tree

    -

    Bug Tracker

    +

    Bug Tracker

    Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -feedback.

    +feedback.

    Do not contact contributors directly about support or help with technical issues.

    -

    Credits

    +

    Credits

    -

    Authors

    +

    Authors

    • GRAP
    -

    Contributors

    +

    Contributors

    -

    Other credits

    +

    Other credits

    The development of this module has been financially supported by:

    • GRAP, Groupement Régional Alimentaire de proximité @@ -472,7 +466,7 @@

      Other credits

    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    Odoo Community Association @@ -482,11 +476,10 @@

    Maintainers

    promote its widespread use.

    Current maintainer:

    legalsylvain

    -

    This module is part of the OCA/pos project on GitHub.

    +

    This module is part of the OCA/pos project on GitHub.

    You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

    -
    diff --git a/pos_payment_change/tests/test_pos_payment_change.py b/pos_payment_change/tests/test_pos_payment_change.py index 40eec8f358..7f5770c3db 100644 --- a/pos_payment_change/tests/test_pos_payment_change.py +++ b/pos_payment_change/tests/test_pos_payment_change.py @@ -103,86 +103,245 @@ def _change_payment( wizard.button_change_payment() # Test Section - @mute_logger("odoo.models.unlink") - def test_01_payment_change_policy_update(self): + def test_03_payment_change_closed_orders(self): self.pos_config.payment_change_policy = "update" # Make a sale with 35 in cash journal and 65 in check order = self._sale(self.cash_payment_method, 35, self.bank_payment_method, 65) - order_qty = len(self.PosOrder.search([])) + self.session.state = "closed" with self.assertRaises(UserError): - # Should not work if total is not correct self._change_payment( - order, self.cash_payment_method, 10, self.cash_payment_method, 10 + order, self.cash_payment_method, 10, self.bank_payment_method, 90 ) - self._change_payment( - order, self.cash_payment_method, 10, self.bank_payment_method, 90 - ) + @users("test-pos-manager") + def test_04_payment_change_security_01(self): + self.pos_config.payment_change_policy = "refund" + order = self._sale(self.cash_payment_method, 35, self.bank_payment_method, 65) - self.bank_payment = self.session.order_ids.mapped("payment_ids").filtered( - lambda x: x.payment_method_id == self.bank_payment_method - ) - self.cash_payment = self.session.order_ids.mapped("payment_ids").filtered( + self.assertEqual(order.state, "paid") + self.assertEqual(len(order.payment_ids), 2) + self.assertEqual(order.amount_paid, 100) + self._change_payment(order, self.cash_payment_method, 100) + refund = order.mapped("lines.refund_orderline_ids.order_id") + self.assertEqual(refund.state, "paid") + self.assertEqual(len(refund.payment_ids), 2) + self.assertEqual(refund.amount_paid, -100) + cash_refund_payment = refund.payment_ids.filtered( lambda x: x.payment_method_id == self.cash_payment_method ) - # check Session - self.assertEqual( - self.cash_payment.amount, - 10, - "Bad recompute of the balance for the statement cash", + self.assertEqual(cash_refund_payment.amount, -35) + bank_refund_payment = refund.payment_ids.filtered( + lambda x: x.payment_method_id == self.bank_payment_method ) - - self.assertEqual( - self.bank_payment.amount, - 90, - "Bad recompute of the balance for the statement check", + self.assertEqual(bank_refund_payment.amount, -65) + resale_order = self.env["pos.order"].search( + [ + ("pos_reference", "=", order.pos_reference), + ("session_id", "=", order.session_id.id), + ("id", "not in", (order + refund).ids), + ] ) - - # Check Order quantity + self.assertEqual(resale_order.state, "paid") + self.assertEqual(resale_order.amount_paid, 100) + self.assertEqual(len(resale_order.payment_ids), 1) self.assertEqual( - order_qty, - len(self.PosOrder.search([])), - "In 'Update' mode, changing payment should not create" " other PoS Orders", + resale_order.payment_ids.payment_method_id, self.cash_payment_method ) - def test_02_payment_change_policy_refund(self): + @users("test-pos-manager") + def test_04_payment_change_security_02(self): self.pos_config.payment_change_policy = "refund" - - # Make a sale with 35 in cash journal and 65 in check - order = self._sale(self.cash_payment_method, 35, self.bank_payment_method, 65) - - order_qty = len(self.PosOrder.search([])) - - self._change_payment( - order, self.cash_payment_method, 50, self.bank_payment_method, 50 + order = self._sale(self.cash_payment_method, 100) + self.assertEqual(order.state, "paid") + self.assertEqual(len(order.payment_ids), 1) + self.assertEqual(order.amount_paid, 100) + self._change_payment(order, self.bank_payment_method, 100) + refund = order.mapped("lines.refund_orderline_ids.order_id") + self.assertEqual(refund.state, "paid") + self.assertEqual(len(refund.payment_ids), 1) + self.assertEqual(refund.amount_paid, -100) + self.assertEqual(refund.payment_ids.payment_method_id, self.cash_payment_method) + resale_order = self.env["pos.order"].search( + [ + ("pos_reference", "=", order.pos_reference), + ("session_id", "=", order.session_id.id), + ("id", "not in", (order + refund).ids), + ] ) - - # Check Order quantity + self.assertEqual(resale_order.state, "paid") + self.assertEqual(resale_order.amount_paid, 100) + self.assertEqual(len(resale_order.payment_ids), 1) self.assertEqual( - order_qty + 2, - len(self.PosOrder.search([])), - "In 'Refund' mode, changing payment should generate" " two new PoS Orders", + resale_order.payment_ids.payment_method_id, self.bank_payment_method ) - def test_03_payment_change_closed_orders(self): + @mute_logger("odoo.models.unlink") + def test_05_payment_change_update_invoiced_orders(self): self.pos_config.payment_change_policy = "update" + customer = self.env["res.partner"].create({"name": "Test customer"}) + price = 100 + order = self.PosOrder.create( + { + "session_id": self.session.id, + "partner_id": customer.id, + "amount_tax": 0, + "amount_total": price, + "amount_paid": price, + "amount_return": 0, + "to_invoice": True, + "lines": [ + Command.create( + { + "name": "OL/0001", + "product_id": self.product.id, + "qty": 1.0, + "price_unit": price, + "price_subtotal": price, + "price_subtotal_incl": price, + } + ) + ], + } + ) + order.add_payment( + { + "pos_order_id": order.id, + "amount": price, + "payment_date": "2026-01-01", + "payment_method_id": self.cash_payment_method.id, + } + ) + order.action_pos_order_invoice() + self.assertEqual(order.state, "invoiced") + invoice = order.account_move + self.assertEqual(len(order.payment_ids), 1) + old_move = order.payment_ids.account_move_id + # Change payment (from cash to bank) + self._change_payment(order, self.bank_payment_method, 100) + self.assertEqual(len(order.payment_ids), 1) + payment = order.payment_ids + self.assertEqual(payment.payment_method_id, self.bank_payment_method) + self.assertEqual(payment.amount, 100) + self.assertEqual(payment.payment_date.date(), fields.Date.today()) + self.assertFalse(old_move.exists()) + self.assertEqual(order.state, "invoiced") + self.assertEqual(invoice.state, "posted") + self.assertEqual(invoice.payment_state, "paid") + new_move = order.payment_ids.account_move_id + self.assertEqual(new_move.state, "posted") + self.assertEqual(new_move.date, fields.Date.today()) + # Change payment_again (80 cash, 20 bank) + self._change_payment( + order, self.cash_payment_method, 80, self.bank_payment_method, 20 + ) + self.assertFalse(new_move.exists()) + self.assertEqual(len(order.payment_ids), 2) + cash_payment = order.payment_ids.filtered( + lambda x: x.payment_method_id == self.cash_payment_method + ) + self.assertEqual(cash_payment.amount, 80) + cash_payment_move = cash_payment.account_move_id + self.assertEqual(cash_payment_move.state, "posted") + self.assertEqual(cash_payment_move.amount_total, 80) + bank_payment = order.payment_ids.filtered( + lambda x: x.payment_method_id == self.bank_payment_method + ) + self.assertEqual(bank_payment.amount, 20) + bank_payment_move = bank_payment.account_move_id + self.assertEqual(bank_payment_move.state, "posted") + self.assertEqual(bank_payment_move.amount_total, 20) + self.assertEqual(invoice.state, "posted") + self.assertEqual(invoice.payment_state, "paid") - # Make a sale with 35 in cash journal and 65 in check - order = self._sale(self.cash_payment_method, 35, self.bank_payment_method, 65) - - self.session.state = "closed" - - with self.assertRaises(UserError): - self._change_payment( - order, self.cash_payment_method, 10, self.bank_payment_method, 90 - ) - - @users("test-pos-manager") - def test_04_payment_change_security(self): + @mute_logger("odoo.models.unlink") + def test_06_payment_change_refund_invoiced_orders(self): self.pos_config.payment_change_policy = "refund" - order = self._sale(self.cash_payment_method, 35, self.bank_payment_method, 65) - - self._change_payment(order, self.cash_payment_method, 100) + customer = self.env["res.partner"].create({"name": "Test customer"}) + price = 100 + order = self.PosOrder.create( + { + "session_id": self.session.id, + "partner_id": customer.id, + "amount_tax": 0, + "amount_total": price, + "amount_paid": price, + "amount_return": 0, + "to_invoice": True, + "lines": [ + Command.create( + { + "name": "OL/0001", + "product_id": self.product.id, + "qty": 1.0, + "price_unit": price, + "price_subtotal": price, + "price_subtotal_incl": price, + } + ) + ], + } + ) + order.add_payment( + { + "pos_order_id": order.id, + "amount": price, + "payment_date": "2026-01-01", + "payment_method_id": self.cash_payment_method.id, + } + ) + order.action_pos_order_invoice() + self.assertEqual(order.state, "invoiced") + invoice = order.account_move + self.assertEqual(len(order.payment_ids), 1) + old_move = order.payment_ids.account_move_id + # Change payment (from cash to bank) + self._change_payment(order, self.bank_payment_method, 100) + self.assertEqual(order.amount_paid, 100) + self.assertEqual(len(order.payment_ids), 1) + payment = order.payment_ids + self.assertEqual(payment.payment_method_id, self.cash_payment_method) + self.assertEqual(payment.amount, 100) + self.assertEqual( + payment.payment_date.date(), fields.Date.from_string("2026-01-01") + ) + self.assertTrue(old_move.exists()) + self.assertEqual(old_move.state, "posted") + self.assertEqual(order.state, "invoiced") + self.assertEqual(invoice.state, "posted") + self.assertEqual(invoice.payment_state, "paid") + refund = order.mapped("lines.refund_orderline_ids.order_id") + self.assertEqual(refund.state, "invoiced") + self.assertEqual(len(refund.payment_ids), 1) + refund_payment = refund.payment_ids + self.assertTrue(refund_payment.account_move_id) + self.assertEqual(refund_payment.account_move_id.state, "posted") + self.assertEqual(refund_payment.payment_method_id, self.cash_payment_method) + self.assertEqual(refund_payment.amount, -100) + self.assertEqual(refund.amount_paid, -100) + self.assertEqual(refund.state, "invoiced") + refund_invoice = refund.account_move + self.assertEqual(refund_invoice.move_type, "out_refund") + self.assertEqual(refund_invoice.state, "posted") + self.assertEqual(refund_invoice.payment_state, "reversed") + resale_order = self.env["pos.order"].search( + [ + ("pos_reference", "=", order.pos_reference), + ("session_id", "=", order.session_id.id), + ("id", "not in", (order + refund).ids), + ] + ) + self.assertEqual(resale_order.state, "invoiced") + self.assertEqual(resale_order.amount_paid, 100) + self.assertEqual(len(resale_order.payment_ids), 1) + resale_payment = resale_order.payment_ids + self.assertTrue(resale_payment.account_move_id) + self.assertEqual(resale_payment.account_move_id.state, "posted") + self.assertEqual(resale_payment.payment_method_id, self.bank_payment_method) + self.assertEqual(resale_payment.amount, 100) + extra_invoice = resale_order.account_move + self.assertEqual(extra_invoice.move_type, "out_invoice") + self.assertEqual(extra_invoice.state, "posted") + self.assertEqual(extra_invoice.payment_state, "paid") diff --git a/pos_payment_change/views/view_pos_order.xml b/pos_payment_change/views/view_pos_order.xml index cf7ac7239b..450fcf19c2 100644 --- a/pos_payment_change/views/view_pos_order.xml +++ b/pos_payment_change/views/view_pos_order.xml @@ -15,7 +15,7 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). context="{'pos_session_id' : session_id}" string="Change Payments" type="action" - invisible="state not in ('paid', 'invoiced')" + invisible="(payment_change_policy=='update' and state!='invoiced') or (payment_change_policy=='refund' and state not in ('paid', 'invoiced'))" /> diff --git a/pos_payment_change/wizards/pos_payment_change_wizard.py b/pos_payment_change/wizards/pos_payment_change_wizard.py index 2b58beba98..58b218849a 100644 --- a/pos_payment_change/wizards/pos_payment_change_wizard.py +++ b/pos_payment_change/wizards/pos_payment_change_wizard.py @@ -2,7 +2,7 @@ # @author: Sylvain LE GAL (https://twitter.com/legalsylvain) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo import Command, _, api, fields, models +from odoo import Command, api, fields, models from odoo.exceptions import UserError from odoo.tools import float_compare @@ -38,6 +38,7 @@ def default_get(self, fields): old_lines_vals = [ Command.create( { + "payment_date": payment.payment_date, "old_payment_method_id": payment.payment_method_id.id, "amount": payment.amount, }, @@ -64,12 +65,12 @@ def button_change_payment(self): float_compare( total, self.amount_total, - precision_rounding=self.order_id.currency_id.rounding, + precision_rounding=order.currency_id.rounding, ) != 0 ): raise UserError( - _( + self.env._( "Differences between the two values for the POS" " Order '%(name)s':\n\n" " * Total of all the new payments %(total)s;\n" @@ -87,7 +88,7 @@ def button_change_payment(self): "pos_order_id": order.id, "payment_method_id": line.new_payment_method_id.id, "amount": line.amount, - "payment_date": fields.Date.context_today(self), + "payment_date": line.payment_date, } for line in self.new_line_ids ] diff --git a/pos_payment_change/wizards/pos_payment_change_wizard_new_line.py b/pos_payment_change/wizards/pos_payment_change_wizard_new_line.py index 2c274948fc..fb2cf25782 100644 --- a/pos_payment_change/wizards/pos_payment_change_wizard_new_line.py +++ b/pos_payment_change/wizards/pos_payment_change_wizard_new_line.py @@ -14,7 +14,10 @@ class PosPaymentChangeWizardLine(models.TransientModel): required=True, ondelete="cascade", ) - + payment_date = fields.Datetime( + required=True, + default=lambda self: fields.Datetime.now(), + ) new_payment_method_id = fields.Many2one( comodel_name="pos.payment.method", string="Payment Method", diff --git a/pos_payment_change/wizards/pos_payment_change_wizard_old_line.py b/pos_payment_change/wizards/pos_payment_change_wizard_old_line.py index 088dce680e..b3f42af1b7 100644 --- a/pos_payment_change/wizards/pos_payment_change_wizard_old_line.py +++ b/pos_payment_change/wizards/pos_payment_change_wizard_old_line.py @@ -14,7 +14,9 @@ class PosPaymentChangeWizardOldLine(models.TransientModel): required=True, ondelete="cascade", ) - + payment_date = fields.Datetime( + readonly=True, + ) old_payment_method_id = fields.Many2one( comodel_name="pos.payment.method", string="Payment Method", diff --git a/pos_payment_change/wizards/view_pos_payment_change_wizard.xml b/pos_payment_change/wizards/view_pos_payment_change_wizard.xml index bc7d70e4ab..f8e9c54e2f 100644 --- a/pos_payment_change/wizards/view_pos_payment_change_wizard.xml +++ b/pos_payment_change/wizards/view_pos_payment_change_wizard.xml @@ -14,11 +14,12 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).