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
This commit is contained in:
@@ -86,7 +86,10 @@ class Invoice(Model):
|
||||
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'))
|
||||
|
||||
@@ -70,10 +70,10 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<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 @@ this repository contains the full copyright notices and license terms. -->
|
||||
</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>
|
||||
@@ -111,7 +111,7 @@ this repository contains the full copyright notices and license terms. -->
|
||||
</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>
|
||||
|
||||
@@ -70,10 +70,10 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<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 @@ this repository contains the full copyright notices and license terms. -->
|
||||
</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>
|
||||
@@ -111,7 +111,7 @@ this repository contains the full copyright notices and license terms. -->
|
||||
</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>
|
||||
|
||||
@@ -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 @@ class Invoice(Model):
|
||||
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'))
|
||||
|
||||
@@ -48,7 +48,7 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<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 @@ this repository contains the full copyright notices and license terms. -->
|
||||
</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">
|
||||
|
||||
Reference in New Issue
Block a user