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'))