facho/fe/form.py: se adiciona payment mean
FossilOrigin-Name: 8558260e0c61be0923ff4a4264584afc29191c3572f5dd41ad1d02e749bed8f5
This commit is contained in:
parent
90cf2917d1
commit
b109c9f8db
@ -61,7 +61,10 @@ class CodeList:
|
|||||||
|
|
||||||
__all__ = ['TipoOrganizacion',
|
__all__ = ['TipoOrganizacion',
|
||||||
'TipoResponsabilidad',
|
'TipoResponsabilidad',
|
||||||
'TipoAmbiente']
|
'TipoAmbiente',
|
||||||
|
'TipoDocumento',
|
||||||
|
'CodigoPrecioReferencia',
|
||||||
|
'MediosPago']
|
||||||
|
|
||||||
def path_for_codelist(name):
|
def path_for_codelist(name):
|
||||||
return os.path.join(DATA_DIR, name)
|
return os.path.join(DATA_DIR, name)
|
||||||
@ -71,3 +74,4 @@ TipoResponsabilidad = CodeList(path_for_codelist('TipoResponsabilidad-2.1.gc'),
|
|||||||
TipoAmbiente = CodeList(path_for_codelist('TipoAmbiente-2.1.gc'), 'code', 'name')
|
TipoAmbiente = CodeList(path_for_codelist('TipoAmbiente-2.1.gc'), 'code', 'name')
|
||||||
TipoDocumento = CodeList(path_for_codelist('TipoDocumento-2.1.gc'), 'code', 'name')
|
TipoDocumento = CodeList(path_for_codelist('TipoDocumento-2.1.gc'), 'code', 'name')
|
||||||
CodigoPrecioReferencia = CodeList(path_for_codelist('CodigoPrecioReferencia-2.1.gc'), 'code', 'name')
|
CodigoPrecioReferencia = CodeList(path_for_codelist('CodigoPrecioReferencia-2.1.gc'), 'code', 'name')
|
||||||
|
MediosPago = CodeList(path_for_codelist('MediosPago-2.1.gc'), 'code', 'name')
|
||||||
|
@ -77,13 +77,32 @@ class TaxTotal:
|
|||||||
subtax.calculate(invline)
|
subtax.calculate(invline)
|
||||||
self.tax_amount += subtax.tax_amount
|
self.tax_amount += subtax.tax_amount
|
||||||
self.taxable_amount += subtax.taxable_amount
|
self.taxable_amount += subtax.taxable_amount
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Price:
|
class Price:
|
||||||
amount: float
|
amount: float
|
||||||
type_code: str
|
type_code: str
|
||||||
type: str
|
type: str
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class PaymentMean:
|
||||||
|
id: str
|
||||||
|
code :str
|
||||||
|
due_at: datetime
|
||||||
|
payment_id: str
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Payment:
|
||||||
|
amount: float
|
||||||
|
at: datetime
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class PrePaidPayment(Payment):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class InvoiceLine:
|
class InvoiceLine:
|
||||||
@ -93,7 +112,7 @@ class InvoiceLine:
|
|||||||
item: Item
|
item: Item
|
||||||
price: Price
|
price: Price
|
||||||
tax: TaxTotal
|
tax: TaxTotal
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def total_amount(self):
|
def total_amount(self):
|
||||||
return self.quantity * self.price.amount
|
return self.quantity * self.price.amount
|
||||||
@ -136,6 +155,8 @@ class Invoice:
|
|||||||
self.invoice_legal_monetary_total = LegalMonetaryTotal(0, 0, 0, 0, 0)
|
self.invoice_legal_monetary_total = LegalMonetaryTotal(0, 0, 0, 0, 0)
|
||||||
self.invoice_customer = None
|
self.invoice_customer = None
|
||||||
self.invoice_supplier = None
|
self.invoice_supplier = None
|
||||||
|
self.invoice_payment_mean = None
|
||||||
|
self.invoice_payments = []
|
||||||
self.invoice_lines = []
|
self.invoice_lines = []
|
||||||
|
|
||||||
def set_period(self, startdate, enddate):
|
def set_period(self, startdate, enddate):
|
||||||
@ -154,12 +175,18 @@ class Invoice:
|
|||||||
def set_customer(self, party: Party):
|
def set_customer(self, party: Party):
|
||||||
self.invoice_customer = party
|
self.invoice_customer = party
|
||||||
|
|
||||||
|
def set_payment_mean_debit(self, payment_id, code, due_at):
|
||||||
|
self.invoice_payment_mean = PaymentMean('01', code, due_at, payment_id)
|
||||||
|
|
||||||
def add_invoice_line(self, line: InvoiceLine):
|
def add_invoice_line(self, line: InvoiceLine):
|
||||||
self.invoice_lines.append(line)
|
self.invoice_lines.append(line)
|
||||||
|
|
||||||
def accept(self, visitor):
|
def accept(self, visitor):
|
||||||
|
visitor.visit_payment_mean(self.invoice_payment_mean)
|
||||||
visitor.visit_customer(self.invoice_customer)
|
visitor.visit_customer(self.invoice_customer)
|
||||||
visitor.visit_supplier(self.invoice_supplier)
|
visitor.visit_supplier(self.invoice_supplier)
|
||||||
|
for payment in self.invoice_payments:
|
||||||
|
visitor.visit_payment(payment)
|
||||||
for invline in self.invoice_lines:
|
for invline in self.invoice_lines:
|
||||||
visitor.visit_invoice_line(invline)
|
visitor.visit_invoice_line(invline)
|
||||||
|
|
||||||
@ -203,12 +230,22 @@ class DianResolucion0001Validator:
|
|||||||
invoice.accept(self)
|
invoice.accept(self)
|
||||||
return not self.errors
|
return not self.errors
|
||||||
|
|
||||||
|
def visit_payment_mean(self, mean):
|
||||||
|
try:
|
||||||
|
codelist.MediosPago[mean.code]
|
||||||
|
except KeyError:
|
||||||
|
self.errors.append(('payment_mean', 'code',
|
||||||
|
'not found %s' % (mean.code)))
|
||||||
|
|
||||||
def visit_customer(self, customer):
|
def visit_customer(self, customer):
|
||||||
self._validate_party('customer', customer)
|
self._validate_party('customer', customer)
|
||||||
|
|
||||||
def visit_supplier(self, supplier):
|
def visit_supplier(self, supplier):
|
||||||
self._validate_party('supplier', supplier)
|
self._validate_party('supplier', supplier)
|
||||||
|
|
||||||
|
def visit_payment(self, payment):
|
||||||
|
pass
|
||||||
|
|
||||||
def visit_invoice_line(self, line):
|
def visit_invoice_line(self, line):
|
||||||
try:
|
try:
|
||||||
codelist.CodigoPrecioReferencia[line.price.type_code]
|
codelist.CodigoPrecioReferencia[line.price.type_code]
|
||||||
@ -276,6 +313,13 @@ class DIANInvoiceXML(fe.FeXML):
|
|||||||
fexml.set_element('/fe:Invoice/cac:AccountingCustomerParty/cac:Party/cac:PartyLegalEntity/cac:RegistrationAddress/cac:Country/cbc:IdentificationCode', invoice.invoice_customer.address.country.code)
|
fexml.set_element('/fe:Invoice/cac:AccountingCustomerParty/cac:Party/cac:PartyLegalEntity/cac:RegistrationAddress/cac:Country/cbc:IdentificationCode', invoice.invoice_customer.address.country.code)
|
||||||
fexml.set_element('/fe:Invoice/cac:AccountingCustomerParty/cac:Party/cac:PartyLegalEntity/cac:RegistrationAddress/cac:Country/cbc:Name', invoice.invoice_customer.address.country.name)
|
fexml.set_element('/fe:Invoice/cac:AccountingCustomerParty/cac:Party/cac:PartyLegalEntity/cac:RegistrationAddress/cac:Country/cbc:Name', invoice.invoice_customer.address.country.name)
|
||||||
|
|
||||||
|
def set_payment_mean(fexml, invoice):
|
||||||
|
payment_mean = invoice.invoice_payment_mean
|
||||||
|
fexml.set_element('/fe:Invoice/cac:PaymentMeans/cbc:ID', payment_mean.id)
|
||||||
|
fexml.set_element('/fe:Invoice/cac:PaymentMeans/cbc:PaymentMeansCode', payment_mean.code)
|
||||||
|
fexml.set_element('/fe:Invoice/cac:PaymentMeans/cbc:PaymentDueDate', payment_mean.due_at.strftime('%Y-%m-%d'))
|
||||||
|
fexml.set_element('/fe:Invoice/cac:PaymentMeans/cbc:PaymentID', payment_mean.payment_id)
|
||||||
|
|
||||||
def set_legal_monetary(fexml, invoice):
|
def set_legal_monetary(fexml, invoice):
|
||||||
fexml.set_element('/fe:Invoice/cac:LegalMonetaryTotal/cbc:LineExtensionAmount',
|
fexml.set_element('/fe:Invoice/cac:LegalMonetaryTotal/cbc:LineExtensionAmount',
|
||||||
invoice.invoice_legal_monetary_total.line_extension_amount,
|
invoice.invoice_legal_monetary_total.line_extension_amount,
|
||||||
@ -346,6 +390,6 @@ class DIANInvoiceXML(fe.FeXML):
|
|||||||
fexml.set_customer(invoice)
|
fexml.set_customer(invoice)
|
||||||
fexml.set_legal_monetary(invoice)
|
fexml.set_legal_monetary(invoice)
|
||||||
fexml.set_invoice_lines(invoice)
|
fexml.set_invoice_lines(invoice)
|
||||||
|
fexml.set_payment_mean(invoice)
|
||||||
|
|
||||||
return fexml
|
return fexml
|
||||||
|
@ -20,6 +20,7 @@ def simple_invoice_without_lines():
|
|||||||
inv.set_period(datetime.now(), datetime.now())
|
inv.set_period(datetime.now(), datetime.now())
|
||||||
inv.set_issue(datetime.now())
|
inv.set_issue(datetime.now())
|
||||||
inv.set_ident('ABC123')
|
inv.set_ident('ABC123')
|
||||||
|
inv.set_payment_mean_debit('1234', '41', datetime.now())
|
||||||
inv.set_supplier(form.Party(
|
inv.set_supplier(form.Party(
|
||||||
name = 'facho-supplier',
|
name = 'facho-supplier',
|
||||||
ident = 123,
|
ident = 123,
|
||||||
@ -42,6 +43,7 @@ def simple_invoice():
|
|||||||
inv.set_period(datetime.now(), datetime.now())
|
inv.set_period(datetime.now(), datetime.now())
|
||||||
inv.set_issue(datetime.now())
|
inv.set_issue(datetime.now())
|
||||||
inv.set_ident('ABC123')
|
inv.set_ident('ABC123')
|
||||||
|
inv.set_payment_mean_debit('1234', '41', datetime.now())
|
||||||
inv.set_supplier(form.Party(
|
inv.set_supplier(form.Party(
|
||||||
name = 'facho-supplier',
|
name = 'facho-supplier',
|
||||||
ident = 123,
|
ident = 123,
|
||||||
@ -204,3 +206,8 @@ def test_invoice_cufe(simple_invoice_without_lines):
|
|||||||
# RESOLUCION 004: pagina 689
|
# RESOLUCION 004: pagina 689
|
||||||
assert cufe == '8bb918b19ba22a694f1da11c643b5e9de39adf60311cf179179e9b33381030bcd4c3c3f156c506ed5908f9276f5bd9b4'
|
assert cufe == '8bb918b19ba22a694f1da11c643b5e9de39adf60311cf179179e9b33381030bcd4c3c3f156c506ed5908f9276f5bd9b4'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test_invoice_payment_mean(monkeypatch, simple_invoice):
|
||||||
|
invoice_validator = form.DianResolucion0001Validator()
|
||||||
|
assert invoice_validator.validate(simple_invoice) == True
|
||||||
|
Loading…
Reference in New Issue
Block a user