details: https://code.tryton.org/tryton/commit/07a0ab59f30e
branch: default
user: Cédric Krier <[email protected]>
date: Fri Jan 23 23:49:58 2026 +0100
description:
Search unit of measure with enough digits for the quantity in UBL
invoice and credit note
Closes #14541
diffstat:
modules/edocument_ubl/edocument.py | 54 +++++++++++++++++++++++++++++++++----
modules/edocument_ubl/message.xml | 3 +-
2 files changed, 50 insertions(+), 7 deletions(-)
diffs (126 lines):
diff -r ba15a67c6c7d -r 07a0ab59f30e modules/edocument_ubl/edocument.py
--- a/modules/edocument_ubl/edocument.py Fri Jan 30 11:20:26 2026 +0100
+++ b/modules/edocument_ubl/edocument.py Fri Jan 23 23:49:58 2026 +0100
@@ -18,7 +18,7 @@
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 @@
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 @@
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 -r ba15a67c6c7d -r 07a0ab59f30e modules/edocument_ubl/message.xml
--- a/modules/edocument_ubl/message.xml Fri Jan 30 11:20:26 2026 +0100
+++ b/modules/edocument_ubl/message.xml Fri Jan 23 23:49:58 2026 +0100
@@ -17,7 +17,8 @@
<field name="text">Could not find a currency with code
"%(code)s".</field>
</record>
<record model="ir.message" id="msg_unit_not_found">
- <field name="text">Could not find a unit with UNECE code
"%(code)s".</field>
+ <field name="text">Could not find a unit with UNECE code
"%(code)s" and at least %(digits)s digit.</field>
+ <field name="text_plural">Could not find a unit with UNECE code
"%(code)s" and at least %(digits)s digits.</field>
</record>
<record model="ir.message" id="msg_tax_not_found">
<field name="text">Could not find tax for: