nuevo atribute Price.quantity para cantidad base y se separa de InvoiceLine.quantity

FossilOrigin-Name: 4ed8ab2f9ce5505b59f75c9a0ac9f01d7ba5b9512856f4da8ea0b40fe4acfef0
This commit is contained in:
bit4bit 2020-11-11 01:08:48 +00:00
parent 67156ec9a6
commit f648188834
4 changed files with 38 additions and 8 deletions

View File

@ -71,6 +71,12 @@ class Amount:
rounding=decimal.ROUND_HALF_EVEN ))
self.currency = currency
def fromNumber(self, val):
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))
def __round__(self, prec):
return round(self.amount, prec)
@ -88,17 +94,27 @@ class Amount:
raise AmountCurrencyError()
return round(self.amount, DECIMAL_PRECISION) == round(other.amount, DECIMAL_PRECISION)
def __add__(self, other):
def _cast(self, val):
if type(val) in [int, float]:
return self.fromNumber(val)
if isinstance(val, Amount):
return val
raise TypeError("cant cast to amount")
def __add__(self, rother):
other = self._cast(rother)
if not self.is_same_currency(other):
raise AmountCurrencyError()
return Amount(self.amount + other.amount, self.currency)
def __sub__(self, other):
def __sub__(self, rother):
other = self._cast(rother)
if not self.is_same_currency(other):
raise AmountCurrencyError()
return Amount(self.amount - other.amount, self.currency)
def __mul__(self, other):
def __mul__(self, rother):
other = self._cast(rother)
if not self.is_same_currency(other):
raise AmountCurrencyError()
return Amount(self.amount * other.amount, self.currency)
@ -125,18 +141,16 @@ class Quantity:
self.code = code
def __mul__(self, other):
if isinstance(other, Amount):
return Amount(self.value) * other
return self.value * other
def __lt__(self, other):
if isinstance(other, Amount):
return Amount(self.value) < other
return self.value < other
def __str__(self):
return str(self.value)
def __repr__(self):
return str(self)
@dataclass
class Item:
@ -323,11 +337,15 @@ class Price:
amount: Amount
type_code: str
type: str
quantity: int = 1
def __post_init__(self):
if self.type_code not in codelist.CodigoPrecioReferencia:
raise ValueError("type_code [%s] not found" % (self.type_code))
if not isinstance(self.quantity, int):
raise ValueError("quantity must be int")
self.amount *= self.quantity
@dataclass
class PaymentMean:

View File

@ -540,7 +540,7 @@ class DIANInvoiceXML(fe.FeXML):
line.set_element('./cac:Price/cbc:PriceAmount', invoice_line.price.amount, currencyID=invoice_line.price.amount.currency.code)
#DIAN 1.7.-2020: FBB04
line.set_element('./cac:Price/cbc:BaseQuantity',
invoice_line.quantity,
invoice_line.price.quantity,
unitCode=invoice_line.quantity.code)

View File

@ -20,3 +20,14 @@ def test_amount_equals():
assert price1 == price2
assert price1 == form.Amount(100) + form.Amount(10)
assert price1 == form.Amount(10) * form.Amount(10) + form.Amount(10)
assert form.Amount(110) == (form.Amount(1.10) * form.Amount(100))
def test_round():
# Entre 0 y 5 Mantener el dígito menos significativo
assert form.Amount(1.133).round(2) == form.Amount(1.13)
# Entre 6 y 9 Incrementar el dígito menos significativo
assert form.Amount(1.166).round(2) == form.Amount(1.17)
# 5, y el segundo dígito siguiente al dígito menos significativo es cero o par Mantener el dígito menos significativo
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)

View File

@ -170,6 +170,7 @@ def test_invoice_cufe(simple_invoice_without_lines):
assert cufe == '8bb918b19ba22a694f1da11c643b5e9de39adf60311cf179179e9b33381030bcd4c3c3f156c506ed5908f9276f5bd9b4'
def test_credit_note_cude(simple_credit_note_without_lines):
simple_invoice = simple_credit_note_without_lines
simple_invoice.invoice_ident = '8110007871'