From bcf5120d82252505be52da827a226abb2b30756f Mon Sep 17 00:00:00 2001 From: bit4bit Date: Wed, 11 Nov 2020 01:58:01 +0000 Subject: [PATCH] Amount implementa truncate_as_string para forzar truncado de Decimal FossilOrigin-Name: e65c80a4d6956aff8cd80f3ee35cad827ffbd5c965a1fb651ab07424e6b22f31 --- facho/fe/fe.py | 20 ++++++++++---------- facho/fe/form/__init__.py | 14 +++++++------- tests/test_amount.py | 9 +++++++++ 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/facho/fe/fe.py b/facho/fe/fe.py index c07b483..5452d33 100644 --- a/facho/fe/fe.py +++ b/facho/fe/fe.py @@ -185,14 +185,14 @@ class DianXMLExtensionCUFE(DianXMLExtensionCUDFE): '%s' % build_vars['NumFac'], '%s' % build_vars['FecFac'], '%s' % build_vars['HoraFac'], - form.Amount(build_vars['ValorBruto']).format('%.02f'), + form.Amount(build_vars['ValorBruto']).truncate_as_string(2), CodImpuesto1, - form.Amount(build_vars['ValorImpuestoPara'].get(CodImpuesto1, 0.0)).format('%.02f'), + build_vars['ValorImpuestoPara'].get(CodImpuesto1, form.Amount(0.0)).truncate_as_string(2), CodImpuesto2, - form.Amount(build_vars['ValorImpuestoPara'].get(CodImpuesto2, 0.0)).format('%.02f'), + build_vars['ValorImpuestoPara'].get(CodImpuesto2, form.Amount(0.0)).truncate_as_string(2), CodImpuesto3, - form.Amount(build_vars['ValorImpuestoPara'].get(CodImpuesto3, 0.0)).format('%.02f'), - form.Amount(build_vars['ValorTotalPagar']).format('%.02f'), + build_vars['ValorImpuestoPara'].get(CodImpuesto3, form.Amount(0.0)).truncate_as_string(2), + build_vars['ValorTotalPagar'].truncate_as_string(2), '%s' % build_vars['NitOFE'], '%s' % build_vars['NumAdq'], '%s' % build_vars['ClTec'], @@ -222,14 +222,14 @@ class DianXMLExtensionCUDE(DianXMLExtensionCUDFE): '%s' % build_vars['NumFac'], '%s' % build_vars['FecFac'], '%s' % build_vars['HoraFac'], - form.Amount(build_vars['ValorBruto']).format('%.02f'), + form.Amount(build_vars['ValorBruto']).truncate_as_string(2), CodImpuesto1, - form.Amount(build_vars['ValorImpuestoPara'].get(CodImpuesto1, 0.0)).format('%.02f'), + form.Amount(build_vars['ValorImpuestoPara'].get(CodImpuesto1, 0.0)).truncate_as_string(2), CodImpuesto2, - form.Amount(build_vars['ValorImpuestoPara'].get(CodImpuesto2, 0.0)).format('%.02f'), + form.Amount(build_vars['ValorImpuestoPara'].get(CodImpuesto2, 0.0)).truncate_as_string(2), CodImpuesto3, - form.Amount(build_vars['ValorImpuestoPara'].get(CodImpuesto3, 0.0)).format('%.02f'), - form.Amount(build_vars['ValorTotalPagar']).format('%.02f'), + form.Amount(build_vars['ValorImpuestoPara'].get(CodImpuesto3, 0.0)).truncate_as_string(2), + form.Amount(build_vars['ValorTotalPagar']).truncate_as_string(2), '%s' % build_vars['NitOFE'], '%s' % build_vars['NumAdq'], '%s' % build_vars['Software-PIN'], diff --git a/facho/fe/form/__init__.py b/facho/fe/form/__init__.py index 69add30..6ff78b3 100644 --- a/facho/fe/form/__init__.py +++ b/facho/fe/form/__init__.py @@ -53,7 +53,7 @@ class AmountCollection(Collection): return total class Amount: - def __init__(self, amount: int or float or Amount, currency: Currency = Currency('COP')): + def __init__(self, amount: int or float or str or Amount, currency: Currency = Currency('COP')): #DIAN 1.7.-2020: 1.2.3.1 if isinstance(amount, Amount): @@ -63,7 +63,7 @@ class Amount: self.amount = amount.amount self.currency = amount.currency else: - if amount < 0: + if float(amount) < 0: raise ValueError('amount must be positive >= 0') self.amount = Decimal(amount, decimal.Context(prec=DECIMAL_PRECISION, @@ -75,14 +75,13 @@ class Amount: return Amount(val, currency=self.currency) def round(self, prec): - #return Amount(self.amount.quantize(Decimal('1.' + '0' * prec), rounding=decimal.ROUND_HALF_EVEN)) - return Amount(round(self.amount, prec)) + return Amount(round(self.amount, prec), currency=self.currency) def __round__(self, prec): return round(self.amount, prec) def __str__(self): - return '%.06f' % self.amount + return str(self.float()) def __lt__(self, other): if not self.is_same_currency(other): @@ -122,8 +121,9 @@ class Amount: def is_same_currency(self, other): return self.currency == other.currency - def format(self, formatter): - return formatter % self.float() + def truncate_as_string(self, prec): + parts = str(self.float()).split('.', 1) + return '%s.%s' % (parts[0], parts[1][0:prec].ljust(prec,'0')) def float(self): return float(round(self.amount, DECIMAL_PRECISION)) diff --git a/tests/test_amount.py b/tests/test_amount.py index fdc99fe..fe671ba 100644 --- a/tests/test_amount.py +++ b/tests/test_amount.py @@ -31,3 +31,12 @@ def test_round(): assert str(form.Amount(1.1560).round(2)) == str(form.Amount(1.15)) # 5, y el segundo dígito siguiente al dígito menos significativo es impar Incrementar el dígito menos significativo assert form.Amount(1.1569).round(2) == form.Amount(1.157) + +def test_amount_truncate(): + assert form.Amount(1.1569).truncate_as_string(2) == '1.15' + assert form.Amount(587.0700).truncate_as_string(2) == '587.07' + assert form.Amount(14705.8800).truncate_as_string(2) == '14705.88' + assert form.Amount(9423.7000).truncate_as_string(2) == '9423.70' + assert form.Amount(10084.03).truncate_as_string(2) == '10084.03' + assert form.Amount(10000.02245).truncate_as_string(2) == '10000.02' + assert form.Amount(10000.02357).truncate_as_string(2) == '10000.02'