details: https://code.tryton.org/tryton/commit/d00988aac0dc
branch: 7.8
user: Cédric Krier <[email protected]>
date: Tue Jan 20 09:19:12 2026 +0100
description:
Format float and computed Decimal using fixed-point notation
This avoid the usage of scientific notation.
For float we must convert them to Decimal to get a precision large
enough to
show all coefficient digits.
For computed Decimal (which are thus not rounded) we must normalized
them first
to avoid trailing 0.
Closes #14522
(grafted from fccb90d0a3f4acd15e749e8aa4ff9a397053988c)
diffstat:
modules/edocument_ubl/edocument.py | 5 ++++-
modules/edocument_ubl/template/2/CreditNote.xml | 8
++++----
modules/edocument_ubl/template/2/Invoice.xml | 8
++++----
modules/edocument_uncefact/edocument.py | 5 ++++-
modules/edocument_uncefact/template/16B-CII/CrossIndustryInvoice.xml | 4 ++--
5 files changed, 18 insertions(+), 12 deletions(-)
diffs (126 lines):
diff -r 6a34531050a9 -r d00988aac0dc modules/edocument_ubl/edocument.py
--- a/modules/edocument_ubl/edocument.py Mon Jan 19 11:43:28 2026 +0100
+++ b/modules/edocument_ubl/edocument.py Tue Jan 20 09:19:12 2026 +0100
@@ -86,7 +86,10 @@
tmpl = self._get_template(template)
if not tmpl:
raise NotImplementedError
- return (tmpl.generate(this=self, specification=specification)
+ return (tmpl.generate(
+ this=self,
+ specification=specification,
+ Decimal=Decimal)
.filter(remove_comment)
.render()
.encode('utf-8'))
diff -r 6a34531050a9 -r d00988aac0dc
modules/edocument_ubl/template/2/CreditNote.xml
--- a/modules/edocument_ubl/template/2/CreditNote.xml Mon Jan 19 11:43:28
2026 +0100
+++ b/modules/edocument_ubl/template/2/CreditNote.xml Tue Jan 20 09:19:12
2026 +0100
@@ -70,10 +70,10 @@
<cac:TaxSubtotal py:for="line in lines">
<cbc:TaxableAmount py:attrs="{'currencyID':
this.invoice.currency.code}">${-line.base}</cbc:TaxableAmount>
<cbc:TaxAmount py:attrs="{'currencyID':
this.invoice.currency.code}">${-line.amount}</cbc:TaxAmount>
- <cbc:Percent py:if="line.tax.type == 'percentage' and not
(specification or '').startswith('peppol')">${line.tax.rate * 100}</cbc:Percent>
+ <cbc:Percent py:if="line.tax.type == 'percentage' and not
(specification or '').startswith('peppol')">${format((line.tax.rate *
100).normalize(), 'f')}</cbc:Percent>
<cac:TaxCategory>
<cbc:ID
py:if="line.tax.unece_category_code">${line.tax.unece_category_code}</cbc:ID>
- <cbc:Percent py:if="line.tax.type == 'percentage'">${line.tax.rate
* 100}</cbc:Percent>
+ <cbc:Percent py:if="line.tax.type ==
'percentage'">${format((line.tax.rate * 100).normalize(), 'f')}</cbc:Percent>
<cac:TaxScheme py:if="line.tax.unece_code">
<cbc:ID>${line.tax.unece_code}</cbc:ID>
</cac:TaxScheme>
@@ -91,7 +91,7 @@
</cac:LegalMonetaryTotal>
<cac:CreditNoteLine py:for="line_id, line in enumerate(this.lines, 1)">
<cbc:ID>${line_id}</cbc:ID>
- <cbc:CreditedQuantity py:attrs="{'unitCode': line.unit.unece_code if
line.unit and line.unit.unece_code else
'ZZ'}">${-line.quantity}</cbc:CreditedQuantity>
+ <cbc:CreditedQuantity py:attrs="{'unitCode': line.unit.unece_code if
line.unit and line.unit.unece_code else
'ZZ'}">${format(-Decimal(str(line.quantity)), 'f')}</cbc:CreditedQuantity>
<cbc:LineExtensionAmount py:attrs="{'currencyID':
this.invoice.currency.code}">${-line.amount}</cbc:LineExtensionAmount>
<cac:Item>
<cbc:Description
py:if="line.description">${line.description}</cbc:Description>
@@ -108,7 +108,7 @@
</py:if>
<cac:ClassifiedTaxCategory py:for="tax in line.taxes">
<cbc:ID
py:if="tax.unece_category_code">${tax.unece_category_code}</cbc:ID>
- <cbc:Percent py:if="tax.type == 'percentage'">${tax.rate *
100}</cbc:Percent>
+ <cbc:Percent py:if="tax.type == 'percentage'">${format((tax.rate *
100).normalize(), 'f')}</cbc:Percent>
<cac:TaxScheme py:if="tax.unece_code">
<cbc:ID>${tax.unece_code}</cbc:ID>
</cac:TaxScheme>
diff -r 6a34531050a9 -r d00988aac0dc
modules/edocument_ubl/template/2/Invoice.xml
--- a/modules/edocument_ubl/template/2/Invoice.xml Mon Jan 19 11:43:28
2026 +0100
+++ b/modules/edocument_ubl/template/2/Invoice.xml Tue Jan 20 09:19:12
2026 +0100
@@ -70,10 +70,10 @@
<cac:TaxSubtotal py:for="line in lines">
<cbc:TaxableAmount py:attrs="{'currencyID':
this.invoice.currency.code}">${line.base}</cbc:TaxableAmount>
<cbc:TaxAmount py:attrs="{'currencyID':
this.invoice.currency.code}">${line.amount}</cbc:TaxAmount>
- <cbc:Percent py:if="line.tax.type == 'percentage' and not
(specification or '').startswith('peppol')">${line.tax.rate * 100}</cbc:Percent>
+ <cbc:Percent py:if="line.tax.type == 'percentage' and not
(specification or '').startswith('peppol')">${format((line.tax.rate *
100).normalize(), 'f')}</cbc:Percent>
<cac:TaxCategory>
<cbc:ID
py:if="line.tax.unece_category_code">${line.tax.unece_category_code}</cbc:ID>
- <cbc:Percent py:if="line.tax.type == 'percentage'">${line.tax.rate
* 100}</cbc:Percent>
+ <cbc:Percent py:if="line.tax.type ==
'percentage'">${format((line.tax.rate * 100).normalize(), 'f')}</cbc:Percent>
<cac:TaxScheme py:if="line.tax.unece_code">
<cbc:ID>${line.tax.unece_code}</cbc:ID>
</cac:TaxScheme>
@@ -91,7 +91,7 @@
</cac:LegalMonetaryTotal>
<cac:InvoiceLine py:for="line_id, line in enumerate(this.lines, 1)">
<cbc:ID>${line_id}</cbc:ID>
- <cbc:InvoicedQuantity py:attrs="{'unitCode': line.unit.unece_code if
line.unit and line.unit.unece_code else
'ZZ'}">${line.quantity}</cbc:InvoicedQuantity>
+ <cbc:InvoicedQuantity py:attrs="{'unitCode': line.unit.unece_code if
line.unit and line.unit.unece_code else
'ZZ'}">${format(Decimal(str(line.quantity)), 'f')}</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount py:attrs="{'currencyID':
this.invoice.currency.code}">${line.amount}</cbc:LineExtensionAmount>
<cac:Item>
<cbc:Description
py:if="line.description">${line.description}</cbc:Description>
@@ -108,7 +108,7 @@
</py:if>
<cac:ClassifiedTaxCategory py:for="tax in line.taxes">
<cbc:ID
py:if="tax.unece_category_code">${tax.unece_category_code}</cbc:ID>
- <cbc:Percent py:if="tax.type == 'percentage'">${tax.rate *
100}</cbc:Percent>
+ <cbc:Percent py:if="tax.type == 'percentage'">${format((tax.rate *
100).normalize(), 'f')}</cbc:Percent>
<cac:TaxScheme py:if="tax.unece_code">
<cbc:ID>${tax.unece_code}</cbc:ID>
</cac:TaxScheme>
diff -r 6a34531050a9 -r d00988aac0dc modules/edocument_uncefact/edocument.py
--- a/modules/edocument_uncefact/edocument.py Mon Jan 19 11:43:28 2026 +0100
+++ b/modules/edocument_uncefact/edocument.py Tue Jan 20 09:19:12 2026 +0100
@@ -2,6 +2,7 @@
# this repository contains the full copyright notices and license terms.
import functools
import os
+from decimal import Decimal
import genshi
import genshi.template
@@ -78,7 +79,9 @@
tmpl = self._get_template(template)
if not tmpl:
raise NotImplementedError
- return (tmpl.generate(this=self)
+ return (tmpl.generate(
+ this=self,
+ Decimal=Decimal)
.filter(remove_comment)
.render()
.encode('utf-8'))
diff -r 6a34531050a9 -r d00988aac0dc
modules/edocument_uncefact/template/16B-CII/CrossIndustryInvoice.xml
--- a/modules/edocument_uncefact/template/16B-CII/CrossIndustryInvoice.xml
Mon Jan 19 11:43:28 2026 +0100
+++ b/modules/edocument_uncefact/template/16B-CII/CrossIndustryInvoice.xml
Tue Jan 20 09:19:12 2026 +0100
@@ -48,7 +48,7 @@
<ram:ExemptionReason
py:if="tax.legal_notice">${tax.legal_notice}</ram:ExemptionReason>
<ram:BasisAmount py:if="base">${base *
this.type_sign}</ram:BasisAmount>
<ram:CategoryCode
py:if="tax.unece_category_code">${tax.unece_category_code}</ram:CategoryCode>
- <ram:RateApplicablePercent py:if="tax.type ==
'percentage'">${tax.rate * 100}</ram:RateApplicablePercent>
+ <ram:RateApplicablePercent py:if="tax.type ==
'percentage'">${format((tax.rate * 100).normalize(),
'f')}</ram:RateApplicablePercent>
</ram:ApplicableTradeTax>
</py:def>
<rsm:ExchangedDocumentContext>
@@ -76,7 +76,7 @@
</ram:NetPriceProductTradePrice>
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
- <ram:BilledQuantity py:attrs="{'unitCode':
line.unit.unece_code} if line.unit and line.unit.unece_code else
{}">${line.quantity * this.type_sign}</ram:BilledQuantity>
+ <ram:BilledQuantity py:attrs="{'unitCode':
line.unit.unece_code} if line.unit and line.unit.unece_code else
{}">${format(Decimal(str(line.quantity * this.type_sign)),
'f')}</ram:BilledQuantity>
</ram:SpecifiedLineTradeDelivery>
<ram:SpecifiedLineTradeSettlement>
<py:for each="tax in line.invoice_taxes">