From 0f06ca91423c57e78d679bed6bdf7cdbeaa56f90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Mon, 19 Feb 2024 12:43:52 +0100 Subject: [PATCH] Raise a warning when validating invoice with non default taxes Closes #3818 --- modules/account_invoice/CHANGELOG | 1 + modules/account_invoice/exceptions.py | 4 ++ modules/account_invoice/invoice.py | 38 +++++++++++++++++-- modules/account_invoice/message.xml | 3 ++ .../scenario_invoice_alternate_currency.rst | 12 ++++++ .../tests/scenario_invoice_tax_deductible.rst | 11 ++++++ 6 files changed, 65 insertions(+), 4 deletions(-) diff --git a/modules/account_invoice/CHANGELOG b/modules/account_invoice/CHANGELOG index e50eaa1681..c0036a19c9 100644 --- a/modules/account_invoice/CHANGELOG +++ b/modules/account_invoice/CHANGELOG @@ -1,3 +1,4 @@ +* Raise a warning when validating invoice with non default taxes * Book currency exchange amount in dedicated account Version 7.0.0 - 2023-10-30 diff --git a/modules/account_invoice/exceptions.py b/modules/account_invoice/exceptions.py index 3aacd58b94..c714c4d89d 100644 --- a/modules/account_invoice/exceptions.py +++ b/modules/account_invoice/exceptions.py @@ -41,6 +41,10 @@ class InvoiceFutureWarning(UserWarning): pass +class InvoiceTaxesWarning(UserWarning): + pass + + class InvoiceSimilarWarning(UserWarning): pass diff --git a/modules/account_invoice/invoice.py b/modules/account_invoice/invoice.py index 7f85767dda..711488231e 100644 --- a/modules/account_invoice/invoice.py +++ b/modules/account_invoice/invoice.py @@ -37,8 +37,8 @@ from trytond.wizard import ( from .exceptions import ( InvoiceFutureWarning, InvoiceNumberError, InvoicePaymentTermDateWarning, - InvoiceSimilarWarning, InvoiceTaxValidationError, InvoiceValidationError, - PayInvoiceError) + InvoiceSimilarWarning, InvoiceTaxesWarning, InvoiceTaxValidationError, + InvoiceValidationError, PayInvoiceError) if config.getboolean('account_invoice', 'filestore', default=False): file_id = 'invoice_report_cache_id' @@ -1777,10 +1777,12 @@ class Invoice(Workflow, ModelSQL, ModelView, TaxableMixin, InvoiceReportMixin): pool = Pool() Move = pool.get('account.move') + cls._check_taxes(invoices) + cls._check_similar(invoices) + invoices_in = cls.browse([i for i in invoices if i.type == 'in']) cls.set_number(invoices_in) cls._store_cache(invoices) - cls._check_similar(invoices) moves = [] for invoice in invoices_in: move = invoice.get_move() @@ -1837,7 +1839,9 @@ class Invoice(Workflow, ModelSQL, ModelView, TaxableMixin, InvoiceReportMixin): raise InvoiceFutureWarning(warning_key, gettext('account_invoice.msg_invoice_date_future', invoices=names)) - cls._check_similar([i for i in invoices if i.state != 'validated']) + to_check = [i for i in invoices if i.state != 'validated'] + cls._check_taxes(to_check) + cls._check_similar(to_check) cls._post(invoices) @classmethod @@ -1876,6 +1880,32 @@ class Invoice(Workflow, ModelSQL, ModelView, TaxableMixin, InvoiceReportMixin): queue_batch=context.get('queue_batch', True)): cls.__queue__.process(reconciled) + @classmethod + def _check_taxes(cls, invoices): + pool = Pool() + Line = pool.get('account.invoice.line') + Warning = pool.get('res.user.warning') + for invoice in invoices: + different_lines = [] + for line in invoice.lines: + test_line = Line(line.id) + test_line.on_change_product() + if (test_line.taxes != line.taxes + or test_line.taxes_deductible_rate + != line.taxes_deductible_rate): + different_lines.append(line) + if different_lines: + warning_key = Warning.format( + 'invoice_taxes', [invoice]) + if Warning.check(warning_key): + lines = ', '.join(l.rec_name for l in different_lines[:5]) + if len(different_lines) > 5: + lines += '...' + raise InvoiceTaxesWarning(warning_key, + gettext('account_invoice.msg_invoice_default_taxes', + invoice=invoice.rec_name, + lines=lines)) + @classmethod def _check_similar(cls, invoices, type='in'): pool = Pool() diff --git a/modules/account_invoice/message.xml b/modules/account_invoice/message.xml index 7aedd813f9..9120aec352 100644 --- a/modules/account_invoice/message.xml +++ b/modules/account_invoice/message.xml @@ -78,6 +78,9 @@ this repository contains the full copyright notices and license terms. --> The invoices "%(invoices)s" have an invoice date in the future. + + The invoice "%(invoice)s" does not have the default taxes for %(lines)s. + The invoice "%(invoice)s" is similar to invoice "%(similar)s". diff --git a/modules/account_invoice/tests/scenario_invoice_alternate_currency.rst b/modules/account_invoice/tests/scenario_invoice_alternate_currency.rst index a412fdaa33..ebaf643e34 100644 --- a/modules/account_invoice/tests/scenario_invoice_alternate_currency.rst +++ b/modules/account_invoice/tests/scenario_invoice_alternate_currency.rst @@ -10,6 +10,7 @@ Imports:: >>> from proteus import Model >>> from trytond.modules.account.tests.tools import ( ... create_chart, create_fiscalyear, create_tax, get_accounts) + >>> from trytond.modules.account_invoice.exceptions import InvoiceTaxesWarning >>> from trytond.modules.account_invoice.tests.tools import ( ... set_fiscalyear_invoice_sequences) >>> from trytond.modules.company.tests.tools import create_company, get_company @@ -23,6 +24,8 @@ Activate modules:: >>> config = activate_modules('account_invoice') + >>> Warning = Model.get('res.user.warning') + Create company:: >>> currency = get_currency('USD') @@ -178,6 +181,15 @@ Create invoice with alternate currency and negative taxes:: Decimal('-40.00') >>> invoice.total_amount Decimal('360.00') + >>> try: + ... invoice.click('post') + ... except InvoiceTaxesWarning as warning: + ... _, (key, *_) = warning.args + ... raise + Traceback (most recent call last): + ... + InvoiceTaxesWarning: ... + >>> Warning(user=config.user, name=key).save() >>> invoice.click('post') >>> invoice.state 'posted' diff --git a/modules/account_invoice/tests/scenario_invoice_tax_deductible.rst b/modules/account_invoice/tests/scenario_invoice_tax_deductible.rst index 13804f4fed..cafba570d2 100644 --- a/modules/account_invoice/tests/scenario_invoice_tax_deductible.rst +++ b/modules/account_invoice/tests/scenario_invoice_tax_deductible.rst @@ -10,6 +10,7 @@ Imports:: >>> from proteus import Model >>> from trytond.modules.account.tests.tools import ( ... create_chart, create_fiscalyear, create_tax, get_accounts) + >>> from trytond.modules.account_invoice.exceptions import InvoiceTaxesWarning >>> from trytond.modules.account_invoice.tests.tools import ( ... set_fiscalyear_invoice_sequences) >>> from trytond.modules.company.tests.tools import create_company, get_company @@ -26,6 +27,7 @@ Activate modules:: >>> ProductCategory = Model.get('product.category') >>> ProductTemplate = Model.get('product.template') >>> ProductUom = Model.get('product.uom') + >>> Warning = Model.get('res.user.warning') Create company:: @@ -90,6 +92,15 @@ Post a supplier invoice with 0% deductible:: Decimal('550.00') >>> invoice.untaxed_amount, invoice.tax_amount, invoice.total_amount (Decimal('550.00'), Decimal('0.00'), Decimal('550.00')) + >>> try: + ... invoice.click('post') + ... except InvoiceTaxesWarning as warning: + ... _, (key, *_) = warning.args + ... raise + Traceback (most recent call last): + ... + InvoiceTaxesWarning: ... + >>> Warning(user=config.user, name=key).save() >>> invoice.click('post') >>> invoice.untaxed_amount, invoice.tax_amount, invoice.total_amount (Decimal('550.00'), Decimal('0.00'), Decimal('550.00'))