From 41846feed77b7417d1c364221bdb05340f13fc2d Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Mon, 27 Apr 2020 08:07:56 +0200 Subject: [PATCH 01/21] [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 a0e7dc782074be94046f5681b3fd7832c33635f6 Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Mon, 27 Apr 2020 12:50:19 +0200 Subject: [PATCH 02/21] [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 72785481111fb5cac9ade962e1c01597047386fe Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Mon, 18 May 2020 19:32:28 +0200 Subject: [PATCH 03/21] [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 18555d0cb627b28644dd7e8688b305790237458e Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Wed, 3 Jun 2020 12:25:17 +0200 Subject: [PATCH 04/21] 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 07ff79adfdbe4294b73673d274e430bddfac62e1 Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Fri, 12 Jun 2020 23:34:58 +0200 Subject: [PATCH 05/21] [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 d0c2422c056376ecf4743b462f54f62310e351c9 Mon Sep 17 00:00:00 2001 From: Daniel Martinez Vila Date: Mon, 27 Jul 2020 09:32:40 +0000 Subject: [PATCH 06/21] Added translation using Weblate (Spanish) --- pos_payment_change/i18n/es.po | 204 ++++++++++++++++++++++++++++++++++ 1 file changed, 204 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..1ab239b46e --- /dev/null +++ b/pos_payment_change/i18n/es.po @@ -0,0 +1,204 @@ +# 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" +"Last-Translator: Automatically generated\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" + +#. module: pos_payment_change +#: code:addons/pos_payment_change/models/pos_order.py:79 +#, 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_new_line__amount +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_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_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_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: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 "" + +#. 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 "" + +#. 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 "" + +#. 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_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 +#: 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_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" +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,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_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_old_line +msgid "PoS Payment Change Wizard Old 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_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:97 +#, python-format +msgid "You can not change payments of the POS '%s' because the associated session '%s' has been closed!" +msgstr "" From 84b82b938da824017e0a6d62670ed3aadd96d65a Mon Sep 17 00:00:00 2001 From: Daniel Martinez Vila Date: Mon, 27 Jul 2020 09:33:09 +0000 Subject: [PATCH 07/21] 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 | 77 ++++++++++++++++++++++------------- 1 file changed, 49 insertions(+), 28 deletions(-) diff --git a/pos_payment_change/i18n/es.po b/pos_payment_change/i18n/es.po index 1ab239b46e..20eb42153e 100644 --- a/pos_payment_change/i18n/es.po +++ b/pos_payment_change/i18n/es.po @@ -6,56 +6,58 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 12.0\n" "Report-Msgid-Bugs-To: \n" -"Last-Translator: Automatically generated\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 "" +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 "" +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 "" +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 "" +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 "" +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 "" +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 "" +msgstr "Creado el" #. module: pos_payment_change #: code:addons/pos_payment_change/wizards/pos_payment_change_wizard.py:69 @@ -67,67 +69,73 @@ msgid "Differences between the two values for 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 "" +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 "" +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 "" +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 "" +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 "" +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 "" +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 "" +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 "" +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 "" +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 "" +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 @@ -137,68 +145,81 @@ msgid "Payment Change Policy when users want to change the payment lines of a gi "\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 "" +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 "" +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 "" +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 "" +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 "" +msgstr "Pedidos de Punto de Venta" #. module: pos_payment_change #: selection:pos.config,payment_change_policy:0 msgid "Refund and Resale" -msgstr "" +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 "" +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 "" +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 "" +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 "" +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 4facd60f1eb8643ab3faa0a39e46559f2baea04a Mon Sep 17 00:00:00 2001 From: Florent THOMAS Date: Tue, 28 Jul 2020 21:30:22 +0200 Subject: [PATCH 08/21] 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 976caa92f4f14c370c0f4643c9a0b436fe8a20bd Mon Sep 17 00:00:00 2001 From: Florent THOMAS Date: Thu, 10 Sep 2020 08:57:32 +0200 Subject: [PATCH 09/21] 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 f3eb510c7898233a47734c4ade8e48f64941affb Mon Sep 17 00:00:00 2001 From: Daniel Martinez Vila Date: Mon, 26 Oct 2020 09:09:58 +0000 Subject: [PATCH 10/21] 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 551edc9b10866780b5c38cd7ca0c29fbf8adddc5 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 11/21] Added translation using Weblate (German) --- pos_payment_change/i18n/de.po | 216 ++++++++++++++++++++++++++++++++++ 1 file changed, 216 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..ec8fdaee05 --- /dev/null +++ b/pos_payment_change/i18n/de.po @@ -0,0 +1,216 @@ +# 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" +"Last-Translator: Automatically generated\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" + +#. module: pos_payment_change +#: code:addons/pos_payment_change/models/pos_order.py:79 +#, 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_new_line__amount +#: model:ir.model.fields,field_description:pos_payment_change.field_pos_payment_change_wizard_old_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_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 +#: 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_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: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 "" + +#. 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 "" + +#. 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 "" + +#. 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_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 +#: 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_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" +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,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_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_old_line +msgid "PoS Payment Change Wizard Old 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,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 +msgid "Wizard" +msgstr "" + +#. 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 "" From 8283dba803273562ee6e1d0afbb020ce74976ede Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Volksdorf?= Date: Thu, 8 Apr 2021 07:51:30 +0000 Subject: [PATCH 12/21] 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 | 81 ++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 30 deletions(-) diff --git a/pos_payment_change/i18n/de.po b/pos_payment_change/i18n/de.po index ec8fdaee05..20c98513d4 100644 --- a/pos_payment_change/i18n/de.po +++ b/pos_payment_change/i18n/de.po @@ -6,62 +6,64 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 12.0\n" "Report-Msgid-Bugs-To: \n" -"Last-Translator: Automatically generated\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 "" +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 "" +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 "" +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 "" +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 "" +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 "" +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 "" +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 "" +msgstr "Erstellt am" #. module: pos_payment_change #: code:addons/pos_payment_change/wizards/pos_payment_change_wizard.py:69 @@ -73,67 +75,73 @@ msgid "Differences between the two values for 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 "" +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 "" +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 "" +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 "" +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 "" +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 "" +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 "" +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 "" +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 "" +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 "" +msgstr "Richtlinie für Zahlungsänderungen" #. module: pos_payment_change #: model:ir.model.fields,help:pos_payment_change.field_pos_config__payment_change_policy @@ -143,74 +151,87 @@ msgid "Payment Change Policy when users want to change the payment lines of a gi "\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 "" +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 "" +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 "" +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 "" +msgstr "Konfiguration der Verkaufsstelle" #. module: pos_payment_change #: model:ir.model,name:pos_payment_change.model_pos_order msgid "Point of Sale Orders" -msgstr "" +msgstr "Bestellungen am Point of Sale" #. module: pos_payment_change #: selection:pos.config,payment_change_policy:0 msgid "Refund and Resale" -msgstr "" +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 "" +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 "" +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 "" +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 "" +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 "" +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 1086773d28d341d52105c0ca6e5796f7309cf073 Mon Sep 17 00:00:00 2001 From: fshah Date: Mon, 24 May 2021 16:45:11 +0530 Subject: [PATCH 13/21] [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 dd1f953c54d55580fb578668ef58334752205355 Mon Sep 17 00:00:00 2001 From: fshah Date: Tue, 25 May 2021 17:11:45 +0530 Subject: [PATCH 14/21] [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 006d6e62246e4892a82365649116248dd6b29d08 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 15/21] [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 02922130fcd0257d26d6b9b84c99923e6c24fe80 Mon Sep 17 00:00:00 2001 From: manu Date: Mon, 5 Dec 2022 13:48:31 +0100 Subject: [PATCH 16/21] [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 a08b3486d0c03b45525a4b1b156165c2c5e8cf86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julen=20Z=C3=A1rate=20Ruiz?= Date: Mon, 20 Feb 2023 23:10:14 +0100 Subject: [PATCH 17/21] [IMP] pos_payment_change: pre-commit stuff --- setup/pos_payment_change/odoo/addons/pos_payment_change | 1 + setup/pos_payment_change/setup.py | 6 ++++++ 2 files changed, 7 insertions(+) create mode 120000 setup/pos_payment_change/odoo/addons/pos_payment_change create mode 100644 setup/pos_payment_change/setup.py diff --git a/setup/pos_payment_change/odoo/addons/pos_payment_change b/setup/pos_payment_change/odoo/addons/pos_payment_change new file mode 120000 index 0000000000..6758108b45 --- /dev/null +++ b/setup/pos_payment_change/odoo/addons/pos_payment_change @@ -0,0 +1 @@ +../../../../pos_payment_change \ No newline at end of file diff --git a/setup/pos_payment_change/setup.py b/setup/pos_payment_change/setup.py new file mode 100644 index 0000000000..28c57bb640 --- /dev/null +++ b/setup/pos_payment_change/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) From c7b097d083e6bbc170484d0f46e46124c9fde487 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 18/21] [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