diff --git a/account_cash_discount_payment/README.rst b/account_cash_discount_payment/README.rst new file mode 100644 index 000000000000..b507efd34ba8 --- /dev/null +++ b/account_cash_discount_payment/README.rst @@ -0,0 +1,86 @@ +============================= +Account Cash Discount Payment +============================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:c0408e84ad8124462c5bc0080d916702eb7bd1cae225aac98233e1e357295e40 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Faccount--payment-lightgray.png?logo=github + :target: https://github.com/OCA/account-payment/tree/14.0/account_cash_discount_payment + :alt: OCA/account-payment +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/account-payment-14-0/account-payment-14-0-account_cash_discount_payment + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/account-payment&target_branch=14.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Extends Account Cash Discount Base and Payment Order modules to let you +add invoices on payment order considering the cash discount on it. +When an invoice with cash discount is added to a payment order, +the amount proposed on payment line will be the residual amount discount deducted, +provided that the due date has not expired. + +This module also offers to search by discount due date to add invoices on +payment order and add discount amount on payment line. + +**Table of contents** + +.. contents:: + :local: + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* ACSONE SA/NV + +Contributors +~~~~~~~~~~~~ + +* Christelle De Coninck (ACSONE) +* Stéphane Bidoul (ACSONE) +* Adrien Peiffer (ACSONE) +* Benjamin Willig (ACSONE) + +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. + +This module is part of the `OCA/account-payment `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/account_cash_discount_payment/__init__.py b/account_cash_discount_payment/__init__.py new file mode 100644 index 000000000000..aee8895e7a31 --- /dev/null +++ b/account_cash_discount_payment/__init__.py @@ -0,0 +1,2 @@ +from . import models +from . import wizards diff --git a/account_cash_discount_payment/__manifest__.py b/account_cash_discount_payment/__manifest__.py new file mode 100644 index 000000000000..8cef877f054d --- /dev/null +++ b/account_cash_discount_payment/__manifest__.py @@ -0,0 +1,17 @@ +# Copyright 2018 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "Account Cash Discount Payment", + "version": "15.0.1.0.0", + "author": "ACSONE SA/NV," "Odoo Community Association (OCA)", + "website": "https://github.com/OCA/account-payment", + "license": "AGPL-3", + "category": "Accounting", + "depends": ["account_cash_discount_base", "account_payment_order_grouped_output"], + "data": [ + "views/account_move_line.xml", + "views/account_payment_line.xml", + "wizards/account_payment_line_create.xml", + ], +} diff --git a/account_cash_discount_payment/i18n/account_cash_discount_payment.pot b/account_cash_discount_payment/i18n/account_cash_discount_payment.pot new file mode 100644 index 000000000000..603112949e59 --- /dev/null +++ b/account_cash_discount_payment/i18n/account_cash_discount_payment.pot @@ -0,0 +1,153 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_cash_discount_payment +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \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: account_cash_discount_payment +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line_create__cash_discount_date +msgid "Cash Discount Date" +msgstr "" + +#. module: account_cash_discount_payment +#: model_terms:ir.ui.view,arch_db:account_cash_discount_payment.account_payment_line_tree_view +msgid "Disable discount" +msgstr "" + +#. module: account_cash_discount_payment +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_move_line__discount_amount +msgid "Discount Amount" +msgstr "" + +#. module: account_cash_discount_payment +#: code:addons/account_cash_discount_payment/wizards/account_payment_line_create.py:0 +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_move_line__discount_due_date +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line__discount_due_date +#: model:ir.model.fields.selection,name:account_cash_discount_payment.selection__account_payment_line_create__date_type__discount_due_date +#, python-format +msgid "Discount Due Date" +msgstr "" + +#. module: account_cash_discount_payment +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line__discount_amount +msgid "Discount amount (minus related refunds amount)" +msgstr "" + +#. module: account_cash_discount_payment +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_move__display_name +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_move_line__display_name +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line__display_name +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line_create__display_name +msgid "Display Name" +msgstr "" + +#. module: account_cash_discount_payment +#: model_terms:ir.ui.view,arch_db:account_cash_discount_payment.account_payment_line_tree_view +msgid "Enable discount" +msgstr "" + +#. module: account_cash_discount_payment +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_move__id +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_move_line__id +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line__id +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line_create__id +msgid "ID" +msgstr "" + +#. module: account_cash_discount_payment +#: model:ir.model,name:account_cash_discount_payment.model_account_move +msgid "Journal Entry" +msgstr "" + +#. module: account_cash_discount_payment +#: model:ir.model,name:account_cash_discount_payment.model_account_move_line +msgid "Journal Item" +msgstr "" + +#. module: account_cash_discount_payment +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_move____last_update +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_move_line____last_update +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line____last_update +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line_create____last_update +msgid "Last Modified on" +msgstr "" + +#. module: account_cash_discount_payment +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line__pay_with_discount +msgid "Pay With Discount" +msgstr "" + +#. module: account_cash_discount_payment +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line__pay_with_discount_allowed +msgid "Pay With Discount Allowed" +msgstr "" + +#. module: account_cash_discount_payment +#: model:ir.model,name:account_cash_discount_payment.model_account_payment_line +msgid "Payment Lines" +msgstr "" + +#. module: account_cash_discount_payment +#: model:ir.model.fields,help:account_cash_discount_payment.field_account_payment_line_create__cash_discount_date +msgid "" +"Search lines with a discount due date which is posterior to the selected " +"date." +msgstr "" + +#. module: account_cash_discount_payment +#: model_terms:ir.ui.view,arch_db:account_cash_discount_payment.account_payment_line_tree_view +msgid "Toggle Discount" +msgstr "" + +#. module: account_cash_discount_payment +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line__toggle_pay_with_discount_allowed +msgid "Toggle Pay With Discount Allowed" +msgstr "" + +#. module: account_cash_discount_payment +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line_create__date_type +msgid "Type of Date Filter" +msgstr "" + +#. module: account_cash_discount_payment +#: code:addons/account_cash_discount_payment/models/account_payment_line.py:0 +#, python-format +msgid "Warning!" +msgstr "" + +#. module: account_cash_discount_payment +#: model:ir.model,name:account_cash_discount_payment.model_account_payment_line_create +msgid "Wizard to create payment lines" +msgstr "" + +#. module: account_cash_discount_payment +#: code:addons/account_cash_discount_payment/models/account_payment_line.py:0 +#, python-format +msgid "" +"You can change the pay with discount value only if there is a linked invoice" +" with a discount and if the payment order is not done. (Payment Order: %s)" +msgstr "" + +#. module: account_cash_discount_payment +#: code:addons/account_cash_discount_payment/models/account_payment_line.py:0 +#, python-format +msgid "" +"You can't pay with a discount if the payment line is not linked to an " +"invoice which has a discount." +msgstr "" + +#. module: account_cash_discount_payment +#: code:addons/account_cash_discount_payment/models/account_payment_line.py:0 +#, python-format +msgid "" +"You can't pay with a discount if you don't pay all the invoice at once." +msgstr "" diff --git a/account_cash_discount_payment/i18n/es.po b/account_cash_discount_payment/i18n/es.po new file mode 100644 index 000000000000..8fccd53e6db3 --- /dev/null +++ b/account_cash_discount_payment/i18n/es.po @@ -0,0 +1,164 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_cash_discount_payment +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-12-18 00:18+0000\n" +"Last-Translator: Ivorra78 \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 4.17\n" + +#. module: account_cash_discount_payment +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line_create__cash_discount_date +msgid "Cash Discount Date" +msgstr "Fecha de descuento por pronto pago" + +#. module: account_cash_discount_payment +#: model_terms:ir.ui.view,arch_db:account_cash_discount_payment.account_payment_line_tree_view +msgid "Disable discount" +msgstr "Deshabilitar descuento" + +#. module: account_cash_discount_payment +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_move_line__discount_amount +msgid "Discount Amount" +msgstr "Importe descuento" + +#. module: account_cash_discount_payment +#: code:addons/account_cash_discount_payment/wizards/account_payment_line_create.py:0 +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_move_line__discount_due_date +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line__discount_due_date +#: model:ir.model.fields.selection,name:account_cash_discount_payment.selection__account_payment_line_create__date_type__discount_due_date +#, python-format +msgid "Discount Due Date" +msgstr "Fecha de Vencimiento del Descuento" + +#. module: account_cash_discount_payment +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line__discount_amount +msgid "Discount amount (minus related refunds amount)" +msgstr "" +"Importe del descuento (menos el importe de las devoluciones correspondientes)" + +#. module: account_cash_discount_payment +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_move__display_name +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_move_line__display_name +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line__display_name +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line_create__display_name +msgid "Display Name" +msgstr "Nombre a Mostrar" + +#. module: account_cash_discount_payment +#: model_terms:ir.ui.view,arch_db:account_cash_discount_payment.account_payment_line_tree_view +msgid "Enable discount" +msgstr "Habilitar descuento" + +#. module: account_cash_discount_payment +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_move__id +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_move_line__id +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line__id +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line_create__id +msgid "ID" +msgstr "ID (identificación)" + +#. module: account_cash_discount_payment +#: model:ir.model,name:account_cash_discount_payment.model_account_move +msgid "Journal Entry" +msgstr "Entrada en Diario" + +#. module: account_cash_discount_payment +#: model:ir.model,name:account_cash_discount_payment.model_account_move_line +msgid "Journal Item" +msgstr "Artículo del Diario" + +#. module: account_cash_discount_payment +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_move____last_update +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_move_line____last_update +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line____last_update +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line_create____last_update +msgid "Last Modified on" +msgstr "Última Modificación el" + +#. module: account_cash_discount_payment +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line__pay_with_discount +msgid "Pay With Discount" +msgstr "Pagar con Descuento" + +#. module: account_cash_discount_payment +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line__pay_with_discount_allowed +msgid "Pay With Discount Allowed" +msgstr "Pago con Descuento Permitido" + +#. module: account_cash_discount_payment +#: model:ir.model,name:account_cash_discount_payment.model_account_payment_line +msgid "Payment Lines" +msgstr "Líneas de pago" + +#. module: account_cash_discount_payment +#: model:ir.model.fields,help:account_cash_discount_payment.field_account_payment_line_create__cash_discount_date +msgid "" +"Search lines with a discount due date which is posterior to the selected " +"date." +msgstr "" +"Buscar líneas cuya fecha de vencimiento del descuento sea posterior a la " +"fecha seleccionada." + +#. module: account_cash_discount_payment +#: model_terms:ir.ui.view,arch_db:account_cash_discount_payment.account_payment_line_tree_view +msgid "Toggle Discount" +msgstr "Alternar Descuento" + +#. module: account_cash_discount_payment +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line__toggle_pay_with_discount_allowed +msgid "Toggle Pay With Discount Allowed" +msgstr "Alternar Pago con Descuento Permitido" + +#. module: account_cash_discount_payment +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line_create__date_type +msgid "Type of Date Filter" +msgstr "Tipo de filtro por fecha" + +#. module: account_cash_discount_payment +#: code:addons/account_cash_discount_payment/models/account_payment_line.py:0 +#, python-format +msgid "Warning!" +msgstr "¡Aviso!" + +#. module: account_cash_discount_payment +#: model:ir.model,name:account_cash_discount_payment.model_account_payment_line_create +msgid "Wizard to create payment lines" +msgstr "Asistente para crear líneas de pago" + +#. module: account_cash_discount_payment +#: code:addons/account_cash_discount_payment/models/account_payment_line.py:0 +#, python-format +msgid "" +"You can change the pay with discount value only if there is a linked invoice" +" with a discount and if the payment order is not done. (Payment Order: %s)" +msgstr "" +"Puede modificar el valor de pago con descuento sólo si existe una factura " +"vinculada con descuento y si la orden de pago no está realizada. (Orden de " +"pago: %s)" + +#. module: account_cash_discount_payment +#: code:addons/account_cash_discount_payment/models/account_payment_line.py:0 +#, python-format +msgid "" +"You can't pay with a discount if the payment line is not linked to an " +"invoice which has a discount." +msgstr "" +"No se puede pagar con descuento si la línea de pago no está vinculada a una " +"factura que tenga descuento." + +#. module: account_cash_discount_payment +#: code:addons/account_cash_discount_payment/models/account_payment_line.py:0 +#, python-format +msgid "" +"You can't pay with a discount if you don't pay all the invoice at once." +msgstr "No puedes pagar con descuento si no pagas toda la factura de una vez." diff --git a/account_cash_discount_payment/i18n/fr.po b/account_cash_discount_payment/i18n/fr.po new file mode 100644 index 000000000000..1509d43d2713 --- /dev/null +++ b/account_cash_discount_payment/i18n/fr.po @@ -0,0 +1,155 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_cash_discount_payment +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 13.0+e\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-08-17 10:35+0000\n" +"PO-Revision-Date: 2020-08-17 10:35+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" +"Plural-Forms: \n" + +#. module: account_cash_discount_payment +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line_create__cash_discount_date +msgid "Cash Discount Date" +msgstr "Dernière date d'escompte" + +#. module: account_cash_discount_payment +#: model_terms:ir.ui.view,arch_db:account_cash_discount_payment.account_payment_line_tree_view +msgid "Disable discount" +msgstr "Désactiver l'escompte" + +#. module: account_cash_discount_payment +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_move_line__discount_amount +msgid "Discount Amount" +msgstr "Montant de l'escompte" + +#. module: account_cash_discount_payment +#: code:addons/account_cash_discount_payment/wizards/account_payment_line_create.py:0 +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_move_line__discount_due_date +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line__discount_due_date +#: model:ir.model.fields.selection,name:account_cash_discount_payment.selection__account_payment_line_create__date_type__discount_due_date +#, python-format +msgid "Discount Due Date" +msgstr "Date d'échéance de l'escompte" + +#. module: account_cash_discount_payment +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line__discount_amount +msgid "Discount amount (minus related refunds amount)" +msgstr "" + +#. module: account_cash_discount_payment +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_move__display_name +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_move_line__display_name +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line__display_name +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line_create__display_name +msgid "Display Name" +msgstr "" + +#. module: account_cash_discount_payment +#: model_terms:ir.ui.view,arch_db:account_cash_discount_payment.account_payment_line_tree_view +msgid "Enable discount" +msgstr "Activer l'escompte" + +#. module: account_cash_discount_payment +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_move__id +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_move_line__id +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line__id +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line_create__id +msgid "ID" +msgstr "" + +#. module: account_cash_discount_payment +#: model:ir.model,name:account_cash_discount_payment.model_account_move +msgid "Journal Entry" +msgstr "" + +#. module: account_cash_discount_payment +#: model:ir.model,name:account_cash_discount_payment.model_account_move_line +msgid "Journal Item" +msgstr "" + +#. module: account_cash_discount_payment +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_move____last_update +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_move_line____last_update +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line____last_update +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line_create____last_update +msgid "Last Modified on" +msgstr "" + +#. module: account_cash_discount_payment +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line__pay_with_discount +msgid "Pay With Discount" +msgstr "Payer avec l'escompte" + +#. module: account_cash_discount_payment +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line__pay_with_discount_allowed +msgid "Pay With Discount Allowed" +msgstr "" + +#. module: account_cash_discount_payment +#: model:ir.model,name:account_cash_discount_payment.model_account_payment_line +msgid "Payment Lines" +msgstr "" + +#. module: account_cash_discount_payment +#: model:ir.model.fields,help:account_cash_discount_payment.field_account_payment_line_create__cash_discount_date +msgid "" +"Search lines with a discount due date which is posterior to the selected " +"date." +msgstr "" + +#. module: account_cash_discount_payment +#: model_terms:ir.ui.view,arch_db:account_cash_discount_payment.account_payment_line_tree_view +msgid "Toggle Discount" +msgstr "" + +#. module: account_cash_discount_payment +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line__toggle_pay_with_discount_allowed +msgid "Toggle Pay With Discount Allowed" +msgstr "" + +#. module: account_cash_discount_payment +#: model:ir.model.fields,field_description:account_cash_discount_payment.field_account_payment_line_create__date_type +msgid "Type of Date Filter" +msgstr "" + +#. module: account_cash_discount_payment +#: code:addons/account_cash_discount_payment/models/account_payment_line.py:0 +#, python-format +msgid "Warning!" +msgstr "" + +#. module: account_cash_discount_payment +#: model:ir.model,name:account_cash_discount_payment.model_account_payment_line_create +msgid "Wizard to create payment lines" +msgstr "" + +#. module: account_cash_discount_payment +#: code:addons/account_cash_discount_payment/models/account_payment_line.py:0 +#, python-format +msgid "" +"You can change the pay with discount value only if there is a linked invoice " +"with a discount and if the payment order is not done. (Payment Order: %s)" +msgstr "" + +#. module: account_cash_discount_payment +#: code:addons/account_cash_discount_payment/models/account_payment_line.py:0 +#, python-format +msgid "" +"You can't pay with a discount if the payment line is not linked to an " +"invoice which has a discount." +msgstr "" + +#. module: account_cash_discount_payment +#: code:addons/account_cash_discount_payment/models/account_payment_line.py:0 +#, python-format +msgid "You can't pay with a discount if you don't pay all the invoice at once." +msgstr "" diff --git a/account_cash_discount_payment/models/__init__.py b/account_cash_discount_payment/models/__init__.py new file mode 100644 index 000000000000..b4f312acf98f --- /dev/null +++ b/account_cash_discount_payment/models/__init__.py @@ -0,0 +1,3 @@ +from . import account_move +from . import account_move_line +from . import account_payment_line diff --git a/account_cash_discount_payment/models/account_move.py b/account_cash_discount_payment/models/account_move.py new file mode 100644 index 000000000000..bc3916e073c0 --- /dev/null +++ b/account_cash_discount_payment/models/account_move.py @@ -0,0 +1,33 @@ +# Copyright 2018 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models +from odoo.tools import float_compare + + +class AccountMove(models.Model): + + _inherit = "account.move" + + def _can_pay_invoice_with_discount(self, check_due_date=True): + self.ensure_one() + today = fields.Date.today() + rounding = self.currency_id.rounding + if not self.has_discount: + return False + + if check_due_date: + date_check_valid = self.discount_due_date >= today + else: + date_check_valid = True + + refunds_amount_total = self._get_refunds_amount_total()["total"] + return ( + date_check_valid + and float_compare( + self.amount_residual, + self.amount_total - refunds_amount_total, + precision_rounding=rounding, + ) + == 0 + ) diff --git a/account_cash_discount_payment/models/account_move_line.py b/account_cash_discount_payment/models/account_move_line.py new file mode 100644 index 000000000000..0e6ba2979c57 --- /dev/null +++ b/account_cash_discount_payment/models/account_move_line.py @@ -0,0 +1,30 @@ +# Copyright 2018 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class AccountMoveLine(models.Model): + + _inherit = "account.move.line" + + discount_due_date = fields.Date( + related="move_id.discount_due_date", + readonly=True, + ) + discount_amount = fields.Monetary( + related="move_id.discount_amount", + readonly=True, + ) + + def _prepare_payment_line_vals(self, payment_order): + self.ensure_one() + values = super(AccountMoveLine, self)._prepare_payment_line_vals(payment_order) + + move = self.move_id + if move and move.discount_due_date and move.has_discount: + pay_with_discount = move._can_pay_invoice_with_discount() + values["pay_with_discount"] = pay_with_discount + if pay_with_discount: + values["amount_currency"] = move.residual_with_discount + return values diff --git a/account_cash_discount_payment/models/account_payment_line.py b/account_cash_discount_payment/models/account_payment_line.py new file mode 100644 index 000000000000..43916683208a --- /dev/null +++ b/account_cash_discount_payment/models/account_payment_line.py @@ -0,0 +1,151 @@ +# Copyright 2018 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import _, api, fields, models +from odoo.exceptions import UserError, ValidationError +from odoo.tools import float_compare + + +class PaymentLine(models.Model): + + _inherit = "account.payment.line" + + pay_with_discount = fields.Boolean( + default=False, + ) + pay_with_discount_allowed = fields.Boolean( + compute="_compute_pay_with_discount_allowed", + ) + toggle_pay_with_discount_allowed = fields.Boolean( + compute="_compute_toggle_pay_with_discount_allowed", + ) + discount_due_date = fields.Date( + related="move_line_id.move_id.discount_due_date", + readonly=True, + ) + discount_amount = fields.Monetary( + related="move_line_id.move_id.real_discount_amount", + readonly=True, + ) + + def _compute_pay_with_discount_allowed(self): + """ + Discount can be used only when the invoice has not already + been paid partially or if the invoice has been reconciled only with + refunds + """ + for rec in self: + allowed = False + move_line = rec.move_line_id + if move_line and move_line.move_id.has_discount: + invoice = move_line.move_id + allowed = invoice._can_pay_invoice_with_discount(check_due_date=False) + rec.pay_with_discount_allowed = allowed + + def _compute_toggle_pay_with_discount_allowed(self): + for rec in self: + rec.toggle_pay_with_discount_allowed = ( + rec.pay_with_discount_allowed + and rec.order_id.state not in ("uploaded", "cancelled") + ) + + @api.constrains( + "pay_with_discount", + "move_line_id", + ) + def _check_pay_with_discount(self): + for rec in self: + if not rec.pay_with_discount: + continue + if not rec.pay_with_discount_allowed: + raise ValidationError( + _( + "You can't pay with a discount if the payment line is " + "not linked to an invoice which has a discount." + ) + ) + + @api.onchange( + "discount_amount", + "move_line_id", + "pay_with_discount", + ) + def _onchange_pay_with_discount(self): + """ + This onchange should be executed completely only when the payment line + is linked to a move line which is linked to an invoice which has a + discount. + + If the above condition is ok, the amount will change based on the + invoice total and invoice discount amount. + """ + self._check_pay_with_discount() + invoice = self.move_line_id.move_id + currency = self.currency_id + # When pay_with_discount is changed to False, we do not want to lose + # the amount if the user changed it manually (related to the + # _onchange_amount_with_discount which enable or disable the value + # depending on the amount) + change_base_amount = ( + float_compare( + self.amount_currency, + invoice.residual_with_discount, + precision_rounding=currency.rounding, + ) + == 0 + ) + if self.pay_with_discount: + self.amount_currency = invoice.residual_with_discount + elif change_base_amount: + self.amount_currency = invoice.amount_residual + + @api.onchange( + "amount_currency", + ) + def _onchange_amount_with_discount(self): + """ + This method will disable the pay_with_discount flag if the amount has + been changed and if it doesn't equal to the invoice total amount with + discount. + """ + if not self.pay_with_discount_allowed or not self.pay_with_discount: + return + invoice = self.move_line_id.move_id + currency = self.currency_id + can_pay_with_discount = ( + float_compare( + self.amount_currency, + invoice.residual_with_discount, + precision_rounding=currency.rounding, + ) + == 0 + ) + if not can_pay_with_discount: + self.pay_with_discount = False + return { + "warning": { + "title": _("Warning!"), + "message": _( + "You can't pay with a discount if " + "you don't pay all the invoice at once." + ), + } + } + + def _check_toggle_pay_with_discount_allowed(self): + for rec in self: + if not rec.toggle_pay_with_discount_allowed: + raise UserError( + _( + "You can change the pay with discount value only if " + "there is a linked invoice with a discount and if the " + "payment order is not done. (Payment Order: %s)" + ) + % (rec.order_id.name) + ) + + def toggle_pay_with_discount(self): + self.ensure_one() + self._check_toggle_pay_with_discount_allowed() + self.pay_with_discount = not self.pay_with_discount + self._onchange_pay_with_discount() diff --git a/account_cash_discount_payment/readme/CONTRIBUTORS.rst b/account_cash_discount_payment/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000000..d3152ca72627 --- /dev/null +++ b/account_cash_discount_payment/readme/CONTRIBUTORS.rst @@ -0,0 +1,4 @@ +* Christelle De Coninck (ACSONE) +* Stéphane Bidoul (ACSONE) +* Adrien Peiffer (ACSONE) +* Benjamin Willig (ACSONE) diff --git a/account_cash_discount_payment/readme/DESCRIPTION.rst b/account_cash_discount_payment/readme/DESCRIPTION.rst new file mode 100644 index 000000000000..6838f2204c17 --- /dev/null +++ b/account_cash_discount_payment/readme/DESCRIPTION.rst @@ -0,0 +1,8 @@ +Extends Account Cash Discount Base and Payment Order modules to let you +add invoices on payment order considering the cash discount on it. +When an invoice with cash discount is added to a payment order, +the amount proposed on payment line will be the residual amount discount deducted, +provided that the due date has not expired. + +This module also offers to search by discount due date to add invoices on +payment order and add discount amount on payment line. diff --git a/account_cash_discount_payment/static/description/icon.png b/account_cash_discount_payment/static/description/icon.png new file mode 100644 index 000000000000..3a0328b516c4 Binary files /dev/null and b/account_cash_discount_payment/static/description/icon.png differ diff --git a/account_cash_discount_payment/static/description/index.html b/account_cash_discount_payment/static/description/index.html new file mode 100644 index 000000000000..bc80b00af2f9 --- /dev/null +++ b/account_cash_discount_payment/static/description/index.html @@ -0,0 +1,430 @@ + + + + + + +Account Cash Discount Payment + + + +
+

Account Cash Discount Payment

+ + +

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

+

Extends Account Cash Discount Base and Payment Order modules to let you +add invoices on payment order considering the cash discount on it. +When an invoice with cash discount is added to a payment order, +the amount proposed on payment line will be the residual amount discount deducted, +provided that the due date has not expired.

+

This module also offers to search by discount due date to add invoices on +payment order and add discount amount on payment line.

+

Table of contents

+ +
+

Bug Tracker

+

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

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • ACSONE SA/NV
  • +
+
+
+

Contributors

+ +
+
+

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.

+

This module is part of the OCA/account-payment project on GitHub.

+

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

+
+
+
+ + diff --git a/account_cash_discount_payment/tests/__init__.py b/account_cash_discount_payment/tests/__init__.py new file mode 100644 index 000000000000..8292aa01dd12 --- /dev/null +++ b/account_cash_discount_payment/tests/__init__.py @@ -0,0 +1,2 @@ +from . import common +from . import test_account_cash_discount_payment diff --git a/account_cash_discount_payment/tests/common.py b/account_cash_discount_payment/tests/common.py new file mode 100644 index 000000000000..e133ecc1b968 --- /dev/null +++ b/account_cash_discount_payment/tests/common.py @@ -0,0 +1,61 @@ +# Copyright 2018 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo.tests.common import Form + +from odoo.addons.account_cash_discount_base.tests.common import ( + TestAccountCashDiscountCommon, +) + + +class TestAccountCashDiscountPaymentCommon(TestAccountCashDiscountCommon): + @classmethod + def setUpClass(cls): + super(TestAccountCashDiscountPaymentCommon, cls).setUpClass() + cls.PaymentLineCreate = cls.env["account.payment.line.create"] + cls.PaymentOrder = cls.env["account.payment.order"] + + cls.payment_mode_out = cls.env.ref( + "account_payment_mode.payment_mode_outbound_ct1" + ) + cls.bank_ing = cls.env.ref("base.bank_ing") + cls.partner_bank_ing = cls.env.ref("base_iban.bank_iban_main_partner") + + cls.bank_ing_journal = cls.Journal.create( + { + "name": "ING Bank", + "code": "ING-B", + "type": "bank", + "bank_id": cls.bank_ing.id, + } + ) + + def create_supplier_invoice( + self, date, payment_mode, amount, discount_percent, taxes + ): + + invoice_form = Form( + self.AccountMove.with_context( + default_move_type="in_invoice", + default_company_id=self.company.id, + default_journal_id=self.purchase_journal.id, + default_payment_mode_id=payment_mode.id, + default_ref="reference", + ) + ) + invoice_form.partner_id = self.partner_agrolait + invoice_form.invoice_date = date + invoice_form.discount_due_date = date + invoice_form.discount_percent = discount_percent + + with invoice_form.invoice_line_ids.new() as line_form: + line_form.name = "test" + line_form.quantity = 1 + line_form.account_id = self.exp_account + line_form.price_unit = amount + line_form.tax_ids.clear() + for tax in taxes: + line_form.tax_ids.add(tax) + + invoice = invoice_form.save() + return invoice diff --git a/account_cash_discount_payment/tests/test_account_cash_discount_payment.py b/account_cash_discount_payment/tests/test_account_cash_discount_payment.py new file mode 100644 index 000000000000..3c563f596e70 --- /dev/null +++ b/account_cash_discount_payment/tests/test_account_cash_discount_payment.py @@ -0,0 +1,79 @@ +# Copyright 2018 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo.exceptions import ValidationError +from odoo.fields import Date + +from .common import TestAccountCashDiscountPaymentCommon + + +class TestAccountCashDiscountPayment(TestAccountCashDiscountPaymentCommon): + def test_invoice_payment_discount(self): + invoice_date = Date.today() + invoice = self.create_supplier_invoice( + invoice_date, self.payment_mode_out, 2000, 25, [] + ) + invoice.action_post() + + payment_order = self.PaymentOrder.create( + {"payment_mode_id": self.payment_mode_out.id, "payment_type": "outbound"} + ) + + payment_line_wizard = self.PaymentLineCreate.with_context( + active_model=payment_order._name, + active_id=payment_order.id, + ).create( + { + "cash_discount_date": invoice_date, + "date_type": "discount_due_date", + "target_move": "posted", + "journal_ids": [(6, 0, [self.purchase_journal.id])], + } + ) + self.assertEqual(payment_line_wizard.order_id, payment_order) + + payment_line_wizard.populate() + move_lines = payment_line_wizard.move_line_ids + self.assertEqual(len(move_lines), 1) + + move_line = move_lines[0] + self.assertAlmostEqual(move_line.discount_amount, 500, 2) + + payment_line_wizard.create_payment_lines() + + self.assertEqual(len(payment_order.payment_line_ids), 1) + payment_line = payment_order.payment_line_ids[0] + self.assertTrue(payment_line.pay_with_discount) + self.assertAlmostEqual(payment_line.amount_currency, 1500) + + # Change the amount of the line and trigger the onchange amount method + # and verify there is a warning + payment_line.amount_currency = 125 + onchange_res = payment_line._onchange_amount_with_discount() + self.assertTrue("warning" in onchange_res) + self.assertFalse(payment_line.pay_with_discount) + + # Change it back to use the discount + payment_line.pay_with_discount = True + payment_line._onchange_pay_with_discount() + self.assertAlmostEqual(payment_line.amount_currency, 1500) + payment_line.invalidate_cache() + + # Check pay_with_discount_constraint + with self.assertRaises(ValidationError), self.env.cr.savepoint(): + payment_line.move_line_id = False + + # Change pay_with_discount and check if discount amount is coherent + # with the invoice + payment_line.pay_with_discount = False + payment_line._onchange_pay_with_discount() + self.assertEqual(payment_line.amount_currency, invoice.amount_total) + + payment_line.pay_with_discount = True + payment_line._onchange_pay_with_discount() + self.assertEqual( + payment_line.amount_currency, invoice.amount_total - invoice.discount_amount + ) + + self.assertAlmostEqual(payment_line.discount_amount, 500, 2) + self.assertAlmostEqual(payment_line.amount_currency, 1500, 2) diff --git a/account_cash_discount_payment/views/account_move_line.xml b/account_cash_discount_payment/views/account_move_line.xml new file mode 100644 index 000000000000..59c94b521043 --- /dev/null +++ b/account_cash_discount_payment/views/account_move_line.xml @@ -0,0 +1,24 @@ + + + + + account.move.line.tree (in account_cash_discount_payment) + account.move.line + + + + + + + + + diff --git a/account_cash_discount_payment/views/account_payment_line.xml b/account_cash_discount_payment/views/account_payment_line.xml new file mode 100644 index 000000000000..757f308c82ff --- /dev/null +++ b/account_cash_discount_payment/views/account_payment_line.xml @@ -0,0 +1,73 @@ + + + + + account.payment.line.form (account_cash_discount_payment) + account.payment.line + + + + + + + + + + + + + account.payment.line.tree (account_cash_discount_payment) + account.payment.line + + + + + + + + + + +