From 7157a5d8d6b8e0c707b92eee2cdf2068624c6e5f Mon Sep 17 00:00:00 2001 From: Mathias Behrle Date: Wed, 29 Jan 2025 11:33:19 +0100 Subject: [PATCH 1/4] Explain the reason for evtl. tax mismatch. --- document.py | 23 ++++++++++++++++++----- locale/de.po | 3 +++ message.xml | 3 +++ 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/document.py b/document.py index 3445df8..75a2003 100644 --- a/document.py +++ b/document.py @@ -100,12 +100,15 @@ class Incoming(metaclass=PoolMeta): UserError: if calculated values dont match with xml-values """ + pool = Pool() + Configuration = pool.get('account.configuration.tax_rounding') + configuration = Configuration(1) + totals = self.parsed_data.get('total', None) if not totals: raise UserError(gettext( 'msg_convert_error.msg_convert_error', msg='no totals-section in xml-data')) - for xfield, inv_field in [ ('taxbase', 'untaxed_amount'), ('taxtotal', 'tax_amount'), @@ -114,15 +117,25 @@ class Incoming(metaclass=PoolMeta): inv_val = getattr(invoice, inv_field) if xml_val != inv_val: - raise UserError(gettext( - 'document_incoming_invoice_xml.msg_convert_error', - msg=' '.join([ + rounding = configuration.tax_rounding + field_name = 'tax_rounding' + selection_values = configuration.fields_get( + [field_name])[field_name]['selection'] + rounding_cfg = [ + i[1] for i in selection_values if i[0] == rounding][0] + msg = ' '.join([ inv_field + ' mismatch', 'from-xml=' + Report.format_currency( xml_val, None, invoice.currency), 'calculated=' + Report.format_currency( inv_val, None, invoice.currency) - ]))) + ]) + msg += '\n\n' + gettext( + 'document_incoming_invoice_xml.msg_tax_amount_mismatch', + rounding=rounding_cfg) + raise UserError(gettext( + 'document_incoming_invoice_xml.msg_convert_error', + msg=msg)) def _readxml_xpath(self, tags): """ generate xpath diff --git a/locale/de.po b/locale/de.po index 67a498c..84ba775 100644 --- a/locale/de.po +++ b/locale/de.po @@ -46,6 +46,9 @@ msgctxt "model:ir.message,text:msg_unused_linevalues" msgid "The following data was not used to generate the invoice line:" msgstr "Die folgenden Daten wurden für die Erzeugung der Rechnungszeile nicht verwendet:" +msgctxt "model:ir.message,text:msg_tax_amount_mismatch" +msgid "You have configured tax rounding method '%(rounding)s' in the account configuration. Maybe try with a different method" +msgstr "In Rechnungswesen/Einstellungen ist die Steuerrundungsmethode '%(rounding)s' eingetragen. Versuchen Sie es u.U. mit einer anderen Methode' ################################### # document.incoming.configuration # diff --git a/message.xml b/message.xml index e65f1a2..0b743d1 100644 --- a/message.xml +++ b/message.xml @@ -35,6 +35,9 @@ The following data was not used to generate the invoice line: + + You have configured tax rounding method '%(rounding)s' in the account configuration. Maybe try with a different method + From 9a83b244775791a613182c254a9ebe8378bfb001 Mon Sep 17 00:00:00 2001 From: Frederik Jaeckel Date: Wed, 29 Jan 2025 10:50:13 +0100 Subject: [PATCH 2/4] round incoming unit_price and quantity to match digits of fields --- document.py | 14 +++++++++----- tests/parsed_data.py | 24 ++++++++++++------------ 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/document.py b/document.py index 3445df8..39b1f00 100644 --- a/document.py +++ b/document.py @@ -20,6 +20,7 @@ from trytond.i18n import gettext from trytond.model import fields from trytond.pyson import Eval from trytond.protocols.jsonrpc import JSONEncoder +from trytond.modules.product import round_price xml_types = [ @@ -719,12 +720,15 @@ class Incoming(metaclass=PoolMeta): if units: xml_uom = units[0] + unitprice = line_data.get('unit_net_price', {}).pop('amount', None) line = Line( invoice=invoice, type='line', unit=xml_uom, - quantity=line_data.get('quantity', {}).pop('billed', None), - unit_price=line_data.get('unit_net_price', {}).pop('amount', None)) + quantity=xml_uom.round( + line_data.get('quantity', {}).pop('billed', None)), + unit_price=round_price(unitprice) + if unitprice is not None else Decimal('0.0')) line_no = line_data.pop('line_no', None) # description @@ -963,9 +967,9 @@ class Incoming(metaclass=PoolMeta): result['quantity'] = self._readxml_read_listdata( xmldata, xpath_line, [ 'ram:SpecifiedLineTradeDelivery'], [ - ('ram:BilledQuantity', 'billed', Decimal), - ('ram:ChargeFreeQuantity', 'chargefree', Decimal), - ('ram:PackageQuantity', 'package', Decimal), + ('ram:BilledQuantity', 'billed', float), + ('ram:ChargeFreeQuantity', 'chargefree', float), + ('ram:PackageQuantity', 'package', float), ])[0] result['quantity']['unit_code'] = self._readxml_getattrib( xmldata, xpath_quantity + ['ram:BilledQuantity'], 'unitCode') diff --git a/tests/parsed_data.py b/tests/parsed_data.py index 0e5315f..351052d 100644 --- a/tests/parsed_data.py +++ b/tests/parsed_data.py @@ -23,7 +23,7 @@ parsed_data_ci_invoice = { 'total': {'amount': Decimal('1350.00')}, 'line_no': '1', 'quantity': { - 'billed': Decimal('1.0'), + 'billed': 1.0, 'unit_code': 'KGM'}, 'unit_net_price': {'amount': Decimal('1350.00')}, }, { @@ -34,7 +34,7 @@ parsed_data_ci_invoice = { 'total': {'amount': Decimal('1200.00')}, 'line_no': '2', 'quantity': { - 'billed': Decimal('1.5'), + 'billed': 1.5, 'unit_code': 'KGM'}, 'unit_net_price': {'amount': Decimal('800.00')}, }, { @@ -42,7 +42,7 @@ parsed_data_ci_invoice = { 'total': {'amount': Decimal('300.00')}, 'line_no': '3', 'quantity': { - 'billed': Decimal('2.0'), + 'billed': 2.0, 'unit_code': 'MTR'}, 'unit_net_price': {'amount': Decimal('150.00')}}], 'note_list': [{ @@ -101,7 +101,7 @@ parsed_data_facturx_en16931 = { 'description': 'Description of Product 1', 'unit_net_price': {'amount': Decimal('1350.00')}, 'quantity': { - 'billed': Decimal('1.0'), 'unit_code': 'KGM'}, + 'billed': 1.0, 'unit_code': 'KGM'}, 'taxes': [{ 'type': 'VAT', 'category_code': 'S', @@ -127,7 +127,7 @@ parsed_data_facturx_en16931 = { 'amount': Decimal('950.00'), 'basequantity': Decimal('1.0')}, 'quantity': { - 'billed': Decimal('1.5'), + 'billed': 1.5, 'unit_code': 'KGM'}, 'taxes': [{ 'type': 'VAT', @@ -141,7 +141,7 @@ parsed_data_facturx_en16931 = { 'description': 'Description of Product 3', 'unit_net_price': {'amount': Decimal('150.00')}, 'quantity': { - 'billed': Decimal('2.0'), + 'billed': 2.0, 'unit_code': 'MTR'}, 'taxes': [{ 'type': 'VAT', @@ -213,7 +213,7 @@ parsed_data_facturx_basic = { 'line_no': '1', 'name': 'Name of Product 1', 'unit_net_price': {'amount': Decimal('1350.00')}, - 'quantity': {'billed': Decimal('1.0'), 'unit_code': 'KGM'}, + 'quantity': {'billed': 1.0, 'unit_code': 'KGM'}, 'taxes': [{ 'type': 'VAT', 'category_code': 'S', @@ -231,7 +231,7 @@ parsed_data_facturx_basic = { 'amount': Decimal('950.00'), 'basequantity': Decimal('1.0')}, 'quantity': { - 'billed': Decimal('1.5'), + 'billed': 1.5, 'unit_code': 'KGM'}, 'taxes': [{ 'type': 'VAT', @@ -243,7 +243,7 @@ parsed_data_facturx_basic = { 'name': 'Name of Product 3', 'unit_net_price': {'amount': Decimal('150.00')}, 'quantity': { - 'billed': Decimal('2.0'), + 'billed': 2.0, 'unit_code': 'MTR'}, 'taxes': [{ 'type': 'VAT', @@ -328,7 +328,7 @@ parsed_data_facturx_extended = { 'name': 'Name of Product 1', 'description': 'Description of Product 1', 'unit_net_price': {'amount': Decimal('1350.00')}, - 'quantity': {'billed': Decimal('1.0'), 'unit_code': 'KGM'}, + 'quantity': {'billed': 1.0, 'unit_code': 'KGM'}, 'taxes': [{ 'type': 'VAT', 'category_code': 'S', @@ -379,7 +379,7 @@ parsed_data_facturx_extended = { 'amount': Decimal('950.00'), 'basequantity': Decimal('1.0')}, 'quantity': { - 'billed': Decimal('1.5'), + 'billed': 1.5, 'unit_code': 'KGM', 'package': Decimal('1.5')}, 'taxes': [{ @@ -392,7 +392,7 @@ parsed_data_facturx_extended = { 'name': 'Name of Product 3', 'description': 'Description of Product 3', 'unit_net_price': {'amount': Decimal('150.00')}, - 'quantity': {'billed': Decimal('2.0'), 'unit_code': 'MTR'}, + 'quantity': {'billed': 2.0, 'unit_code': 'MTR'}, 'taxes': [{ 'type': 'VAT', 'category_code': 'S', From 2bf95fb2458ef1ab42f084059526781984fea3be Mon Sep 17 00:00:00 2001 From: Frederik Jaeckel Date: Wed, 29 Jan 2025 10:53:32 +0100 Subject: [PATCH 3/4] Version 7.0.4 --- README.rst | 4 ++++ tryton.cfg | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 2af1f47..15cf365 100644 --- a/README.rst +++ b/README.rst @@ -15,6 +15,10 @@ Requires Changes ======= +*7.0.4 - 29.01.2025* + +- add: Round unit_price + quantity to match the decimal places of the fields. + *7.0.3 - 27.01.2025* - filter product-categories in configuration diff --git a/tryton.cfg b/tryton.cfg index 8dd8cc3..2d37146 100644 --- a/tryton.cfg +++ b/tryton.cfg @@ -1,5 +1,5 @@ [tryton] -version=7.0.3 +version=7.0.4 depends: document_incoming_invoice edocument_unece From 970fb9caaf41f9bfd85844ab0604e721d882b581 Mon Sep 17 00:00:00 2001 From: Mathias Behrle Date: Wed, 29 Jan 2025 11:33:19 +0100 Subject: [PATCH 4/4] Explain the reason for evtl. tax mismatch. --- document.py | 23 ++++++++++++++++++----- locale/de.po | 3 +++ message.xml | 3 +++ 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/document.py b/document.py index 39b1f00..a3bf0c9 100644 --- a/document.py +++ b/document.py @@ -101,12 +101,15 @@ class Incoming(metaclass=PoolMeta): UserError: if calculated values dont match with xml-values """ + pool = Pool() + Configuration = pool.get('account.configuration.tax_rounding') + configuration = Configuration(1) + totals = self.parsed_data.get('total', None) if not totals: raise UserError(gettext( 'msg_convert_error.msg_convert_error', msg='no totals-section in xml-data')) - for xfield, inv_field in [ ('taxbase', 'untaxed_amount'), ('taxtotal', 'tax_amount'), @@ -115,15 +118,25 @@ class Incoming(metaclass=PoolMeta): inv_val = getattr(invoice, inv_field) if xml_val != inv_val: - raise UserError(gettext( - 'document_incoming_invoice_xml.msg_convert_error', - msg=' '.join([ + rounding = configuration.tax_rounding + field_name = 'tax_rounding' + selection_values = configuration.fields_get( + [field_name])[field_name]['selection'] + rounding_cfg = [ + i[1] for i in selection_values if i[0] == rounding][0] + msg = ' '.join([ inv_field + ' mismatch', 'from-xml=' + Report.format_currency( xml_val, None, invoice.currency), 'calculated=' + Report.format_currency( inv_val, None, invoice.currency) - ]))) + ]) + msg += '\n\n' + gettext( + 'document_incoming_invoice_xml.msg_tax_amount_mismatch', + rounding=rounding_cfg) + raise UserError(gettext( + 'document_incoming_invoice_xml.msg_convert_error', + msg=msg)) def _readxml_xpath(self, tags): """ generate xpath diff --git a/locale/de.po b/locale/de.po index 67a498c..84ba775 100644 --- a/locale/de.po +++ b/locale/de.po @@ -46,6 +46,9 @@ msgctxt "model:ir.message,text:msg_unused_linevalues" msgid "The following data was not used to generate the invoice line:" msgstr "Die folgenden Daten wurden für die Erzeugung der Rechnungszeile nicht verwendet:" +msgctxt "model:ir.message,text:msg_tax_amount_mismatch" +msgid "You have configured tax rounding method '%(rounding)s' in the account configuration. Maybe try with a different method" +msgstr "In Rechnungswesen/Einstellungen ist die Steuerrundungsmethode '%(rounding)s' eingetragen. Versuchen Sie es u.U. mit einer anderen Methode' ################################### # document.incoming.configuration # diff --git a/message.xml b/message.xml index e65f1a2..0b743d1 100644 --- a/message.xml +++ b/message.xml @@ -35,6 +35,9 @@ The following data was not used to generate the invoice line: + + You have configured tax rounding method '%(rounding)s' in the account configuration. Maybe try with a different method +