diff --git a/modules/edocument_ubl/edocument.py b/modules/edocument_ubl/edocument.py
index 8151564713..9f5cd29148 100644
--- a/modules/edocument_ubl/edocument.py
+++ b/modules/edocument_ubl/edocument.py
@@ -18,7 +18,7 @@ import genshi.template
from genshi.template.astutil import ASTCodeGenerator, ASTTransformer
from lxml import etree
-from trytond.i18n import gettext
+from trytond.i18n import gettext, ngettext
from trytond.model import Model
from trytond.modules.product import round_price
from trytond.pool import Pool, PoolMeta
@@ -392,26 +392,48 @@ class Invoice(Model):
if (invoiced_quantity := invoice_line.find('./{*}InvoicedQuantity')
) is not None:
line.quantity = float(invoiced_quantity.text)
+ digits = -Decimal(invoiced_quantity.text).as_tuple().exponent
if (unit_code := invoiced_quantity.get('unitCode')) not in {
None, 'ZZ', 'XZZ'}:
try:
line.unit, = UoM.search([
('unece_code', '=', unit_code),
- ], limit=1)
+ ('digits', '>=', digits),
+ ],
+ order=[('digits', 'ASC')],
+ limit=1)
except ValueError:
- raise InvoiceError(gettext(
+ raise InvoiceError(ngettext(
'edocument_ubl.msg_unit_not_found',
- code=unit_code))
+ digits,
+ code=unit_code,
+ digits=digits))
else:
line.unit = None
else:
line.quantity = 1
line.unit = None
+ digits = 0
line.product = cls._parse_2_item(
invoice_line.find('./{*}Item'), supplier=supplier)
if line.product:
line.on_change_product()
+ if line.unit and line.unit.digits < digits:
+ # Search the unit with enough digits
+ try:
+ line.unit, = UoM.search([
+ ('category', '=', line.unit.category),
+ ('digits', '>=', digits),
+ ['OR',
+ ('factor', '=', line.unit.factor),
+ ('rate', '=', line.unit.rate),
+ ],
+ ],
+ order=[('digits', 'ASC')],
+ limit=1)
+ except ValueError:
+ pass
line.description = '\n'.join(e.text for e in chain(
invoice_line.iterfind('./{*}Item/{*}Name'),
@@ -640,26 +662,46 @@ class Invoice(Model):
if (credited_quantity := credit_note_line.find('./{*}CreditedQuantity')
) is not None:
line.quantity = -float(credited_quantity.text)
+ digits = -Decimal(credited_quantity.text).as_tuple().exponent
if (unit_code := credited_quantity.get('unitCode')) not in {
None, 'ZZ', 'XZZ'}:
try:
line.unit, = UoM.search([
('unece_code', '=', unit_code),
+ ('digits', '>=', digits),
], limit=1)
except ValueError:
- raise InvoiceError(gettext(
+ raise InvoiceError(ngettext(
'edocument_ubl.msg_unit_not_found',
- code=unit_code))
+ digits,
+ code=unit_code,
+ digits=digits))
else:
line.unit = None
else:
line.quantity = -1
line.unit = None
+ digits = 0
line.product = cls._parse_2_item(
credit_note_line.find('./{*}Item'), supplier=supplier)
if line.product:
line.on_change_product()
+ if line.unit and line.unit.digits < digits:
+ # Search the unit with enough digits
+ try:
+ line.unit, = UoM.search([
+ ('category', '=', line.unit.category),
+ ('digits', '>=', digits),
+ ['OR',
+ ('factor', '=', line.unit.factor),
+ ('rate', '=', line.unit.rate),
+ ],
+ ],
+ order=[('digits', 'ASC')],
+ limit=1)
+ except ValueError:
+ pass
line.description = '\n'.join(e.text for e in chain(
credit_note_line.iterfind('./{*}Item/{*}Name'),
diff --git a/modules/edocument_ubl/message.xml b/modules/edocument_ubl/message.xml
index 1db8108fab..531d66d632 100644
--- a/modules/edocument_ubl/message.xml
+++ b/modules/edocument_ubl/message.xml
@@ -17,7 +17,8 @@ this repository contains the full copyright notices and license terms. -->
Could not find a currency with code "%(code)s".
- Could not find a unit with UNECE code "%(code)s".
+ Could not find a unit with UNECE code "%(code)s" and at least %(digits)s digit.
+ Could not find a unit with UNECE code "%(code)s" and at least %(digits)s digits.
Could not find tax for: