nuevo tipo nota credito.
* facho/fe/form.py(NationalSalesInvoice): para facturas de venta nacional. * facho/fe/form.py(CreditNote): para nota creditos. FossilOrigin-Name: 0590af5ac99b2476943dfeacb11ba8cd801012e409b2b594479229df75ddb484
This commit is contained in:
parent
1c4d9bee75
commit
8707319036
@ -271,6 +271,14 @@ class BillingReference:
|
|||||||
self.uuid = uuid
|
self.uuid = uuid
|
||||||
self.date = date
|
self.date = date
|
||||||
|
|
||||||
|
class CreditNoteDocumentReference(BillingReference):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class DebitNoteDocumentReference(BillingReference):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class InvoiceDocumentReference(BillingReference):
|
||||||
|
pass
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class InvoiceLine:
|
class InvoiceLine:
|
||||||
@ -338,9 +346,19 @@ class AllowanceCharge:
|
|||||||
self.charge_indicator = False
|
self.charge_indicator = False
|
||||||
|
|
||||||
|
|
||||||
|
class NationalSalesInvoiceDocumentType(str):
|
||||||
|
def __str__(self):
|
||||||
|
return '01'
|
||||||
|
|
||||||
|
class CreditNoteDocumentType(str):
|
||||||
|
def __str__(self):
|
||||||
|
return '91'
|
||||||
|
|
||||||
class Invoice:
|
class Invoice:
|
||||||
def __init__(self):
|
def __init__(self, type_code: str):
|
||||||
|
if str(type_code) not in codelist.TipoDocumento:
|
||||||
|
raise ValueError("type_code [%s] not found")
|
||||||
|
|
||||||
self.invoice_period_start = None
|
self.invoice_period_start = None
|
||||||
self.invoice_period_end = None
|
self.invoice_period_end = None
|
||||||
self.invoice_issue = None
|
self.invoice_issue = None
|
||||||
@ -355,6 +373,8 @@ class Invoice:
|
|||||||
self.invoice_allowance_charge = []
|
self.invoice_allowance_charge = []
|
||||||
self.invoice_prepaid_payment = []
|
self.invoice_prepaid_payment = []
|
||||||
self.invoice_billing_reference = None
|
self.invoice_billing_reference = None
|
||||||
|
self.invoice_type_code = str(type_code)
|
||||||
|
|
||||||
|
|
||||||
def set_period(self, startdate, enddate):
|
def set_period(self, startdate, enddate):
|
||||||
self.invoice_period_start = startdate
|
self.invoice_period_start = startdate
|
||||||
@ -441,3 +461,15 @@ class Invoice:
|
|||||||
for invline in self.invoice_lines:
|
for invline in self.invoice_lines:
|
||||||
invline.calculate()
|
invline.calculate()
|
||||||
self._calculate_legal_monetary_total()
|
self._calculate_legal_monetary_total()
|
||||||
|
|
||||||
|
|
||||||
|
class NationalSalesInvoice(Invoice):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(NationalSalesInvoiceDocumentType())
|
||||||
|
|
||||||
|
|
||||||
|
class CreditNote(Invoice):
|
||||||
|
def __init__(self, invoice_document_reference: BillingReference):
|
||||||
|
if not isinstance(invoice_document_reference, BillingReference):
|
||||||
|
raise TypeError('invoice_document_reference invalid type')
|
||||||
|
self.invoice_billing_reference = invoice_document_reference
|
||||||
|
@ -15,9 +15,6 @@ class DIANCreditNoteXML(DIANInvoiceXML):
|
|||||||
|
|
||||||
def tag_document(fexml):
|
def tag_document(fexml):
|
||||||
return 'CreditNote'
|
return 'CreditNote'
|
||||||
|
|
||||||
def tag_document_concilied(fexml):
|
def tag_document_concilied(fexml):
|
||||||
return 'Credited'
|
return 'Credited'
|
||||||
|
|
||||||
def document_type_code(fexml):
|
|
||||||
return codelist.TipoDocumento.by_name('Nota Crédito')['code']
|
|
||||||
|
@ -30,11 +30,11 @@ class DIANInvoiceXML(fe.FeXML):
|
|||||||
#DIAN 1.7.-2020: FAJ06
|
#DIAN 1.7.-2020: FAJ06
|
||||||
fexml.set_element('./cac:AccountingSupplierParty/cac:Party/cac:PartyName/cbc:Name',
|
fexml.set_element('./cac:AccountingSupplierParty/cac:Party/cac:PartyName/cbc:Name',
|
||||||
invoice.invoice_supplier.name)
|
invoice.invoice_supplier.name)
|
||||||
|
|
||||||
#DIAN 1.7.-2020: CAJ07, CAJ08
|
#DIAN 1.7.-2020: CAJ07, CAJ08
|
||||||
#DIAN 1.7.-2020: FAJ07
|
#DIAN 1.7.-2020: FAJ07
|
||||||
fexml.placeholder_for('./cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address')
|
fexml.placeholder_for('./cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address')
|
||||||
|
|
||||||
#DIAN 1.7.-2020: FAJ08
|
#DIAN 1.7.-2020: FAJ08
|
||||||
#DIAN 1.7.-2020: CAJ09
|
#DIAN 1.7.-2020: CAJ09
|
||||||
fexml.set_element('./cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:ID',
|
fexml.set_element('./cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:ID',
|
||||||
@ -47,7 +47,7 @@ class DIANInvoiceXML(fe.FeXML):
|
|||||||
#DIAN 1.7.-2020: CAJ11
|
#DIAN 1.7.-2020: CAJ11
|
||||||
fexml.set_element('./cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:CountrySubentity',
|
fexml.set_element('./cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:CountrySubentity',
|
||||||
invoice.invoice_supplier.address.countrysubentity.name)
|
invoice.invoice_supplier.address.countrysubentity.name)
|
||||||
|
|
||||||
#DIAN 1.7.-2020: FAJ12
|
#DIAN 1.7.-2020: FAJ12
|
||||||
#DIAN 1.7.-2020: CAJ12
|
#DIAN 1.7.-2020: CAJ12
|
||||||
fexml.set_element('./cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:CountrySubentityCode',
|
fexml.set_element('./cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:CountrySubentityCode',
|
||||||
@ -384,19 +384,36 @@ class DIANInvoiceXML(fe.FeXML):
|
|||||||
invoice.invoice_legal_monetary_total.payable_amount)
|
invoice.invoice_legal_monetary_total.payable_amount)
|
||||||
|
|
||||||
|
|
||||||
def set_billing_reference(fexml, invoice):
|
def _set_invoice_document_reference(fexml, reference):
|
||||||
if invoice.invoice_billing_reference is None:
|
fexml._do_set_billing_reference(reference, 'cac:InvoiceDocumentReference')
|
||||||
return
|
|
||||||
|
|
||||||
fexml.placeholder_for('./cac:BillingReference')
|
def _set_credit_note_document_reference(fexml, reference):
|
||||||
fexml.placeholder_for('./cac:BillingReference/cac:InvoiceDocumentReference')
|
fexml._do_set_billing_reference(reference, 'cac:CreditNoteDocumentReference')
|
||||||
fexml.set_element('./cac:BillingReference/cac:InvoiceDocumentReference/cbc:ID',
|
|
||||||
invoice.invoice_billing_reference.ident)
|
def _set_debit_note_document_reference(fexml, reference):
|
||||||
|
fexml._do_set_billing_reference(reference, 'cac:DebitNoteDocumentReference')
|
||||||
|
|
||||||
|
def _do_set_billing_reference(fexml, reference, tag_document):
|
||||||
|
fexml.set_element('./cac:BillingReference/%s/cbc:ID' %(tag_document),
|
||||||
|
reference.ident)
|
||||||
fexml.set_element('./cac:BillingReference/cac:InvoiceDocumentReference/cbc:UUID',
|
fexml.set_element('./cac:BillingReference/cac:InvoiceDocumentReference/cbc:UUID',
|
||||||
invoice.invoice_billing_reference.uuid,
|
reference.uuid,
|
||||||
schemeName='CUFE-SHA384')
|
schemeName='CUFE-SHA384')
|
||||||
fexml.set_element('./cac:BillingReference/cac:InvoiceDocumentReference/cbc:IssueDate',
|
fexml.set_element('./cac:BillingReference/cac:InvoiceDocumentReference/cbc:IssueDate',
|
||||||
invoice.invoice_billing_reference.date)
|
reference.date)
|
||||||
|
|
||||||
|
def set_billing_reference(fexml, invoice):
|
||||||
|
reference = invoice.invoice_billing_reference
|
||||||
|
if reference is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
if isinstance(reference, DebitNoteDocumentReference):
|
||||||
|
return fexml._set_debit_note_document_reference(reference)
|
||||||
|
if isinstance(reference, CreditNoteDocumentReference):
|
||||||
|
return fexml._set_credit_note_document_reference(reference)
|
||||||
|
|
||||||
|
if isinstance(reference, InvoiceDocumentReference):
|
||||||
|
return fexml._set_invoice_document_reference(reference)
|
||||||
|
|
||||||
def set_invoice_totals(fexml, invoice):
|
def set_invoice_totals(fexml, invoice):
|
||||||
tax_amount_for = defaultdict(lambda: defaultdict(lambda: 0.0))
|
tax_amount_for = defaultdict(lambda: defaultdict(lambda: 0.0))
|
||||||
@ -469,10 +486,6 @@ class DIANInvoiceXML(fe.FeXML):
|
|||||||
def tag_document_concilied(fexml):
|
def tag_document_concilied(fexml):
|
||||||
return 'Invoiced'
|
return 'Invoiced'
|
||||||
|
|
||||||
# abstract method
|
|
||||||
def document_type_code(fexml):
|
|
||||||
return codelist.TipoDocumento.by_name('Factura de Venta Nacional')['code']
|
|
||||||
|
|
||||||
def set_invoice_lines(fexml, invoice):
|
def set_invoice_lines(fexml, invoice):
|
||||||
next_append = False
|
next_append = False
|
||||||
for index, invoice_line in enumerate(invoice.invoice_lines):
|
for index, invoice_line in enumerate(invoice.invoice_lines):
|
||||||
@ -519,14 +532,15 @@ class DIANInvoiceXML(fe.FeXML):
|
|||||||
fexml.set_element('./cbc:IssueDate', invoice.invoice_issue.strftime('%Y-%m-%d'))
|
fexml.set_element('./cbc:IssueDate', invoice.invoice_issue.strftime('%Y-%m-%d'))
|
||||||
#DIAN 1.7.-2020: FAD10
|
#DIAN 1.7.-2020: FAD10
|
||||||
fexml.set_element('./cbc:IssueTime', invoice.invoice_issue.strftime('%H:%M:%S-05:00'))
|
fexml.set_element('./cbc:IssueTime', invoice.invoice_issue.strftime('%H:%M:%S-05:00'))
|
||||||
fexml.set_element('./cbc:%sTypeCode' % (fexml.tag_document()), fexml.document_type_code(),
|
fexml.set_element('./cbc:%sTypeCode' % (fexml.tag_document()),
|
||||||
listAgencyID='195',
|
invoice.invoice_type_code,
|
||||||
listAgencyName='No matching global declaration available for the validation root',
|
listAgencyID='195',
|
||||||
listURI='http://www.dian.gov.co')
|
listAgencyName='No matching global declaration available for the validation root',
|
||||||
|
listURI='http://www.dian.gov.co')
|
||||||
fexml.set_element('./cbc:LineCountNumeric', len(invoice.invoice_lines))
|
fexml.set_element('./cbc:LineCountNumeric', len(invoice.invoice_lines))
|
||||||
fexml.set_element('./cac:%sPeriod/cbc:StartDate' % (fexml.tag_document()),
|
fexml.set_element('./cac:%sPeriod/cbc:StartDate' % (fexml.tag_document()),
|
||||||
invoice.invoice_period_start.strftime('%Y-%m-%d'))
|
invoice.invoice_period_start.strftime('%Y-%m-%d'))
|
||||||
|
|
||||||
fexml.set_element('./cac:%sPeriod/cbc:EndDate' % (fexml.tag_document()),
|
fexml.set_element('./cac:%sPeriod/cbc:EndDate' % (fexml.tag_document()),
|
||||||
invoice.invoice_period_end.strftime('%Y-%m-%d'))
|
invoice.invoice_period_end.strftime('%Y-%m-%d'))
|
||||||
|
|
||||||
@ -545,10 +559,3 @@ class DIANInvoiceXML(fe.FeXML):
|
|||||||
def customize(fexml, invoice):
|
def customize(fexml, invoice):
|
||||||
"""adiciona etiquetas a FEXML y retorna FEXML
|
"""adiciona etiquetas a FEXML y retorna FEXML
|
||||||
en caso de fallar validacion retorna None"""
|
en caso de fallar validacion retorna None"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ from facho.fe.form_xml import DIANInvoiceXML
|
|||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def simple_invoice_without_lines():
|
def simple_invoice_without_lines():
|
||||||
inv = form.Invoice()
|
inv = form.NationalSalesInvoice()
|
||||||
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')
|
||||||
@ -48,7 +48,7 @@ def simple_invoice_without_lines():
|
|||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def simple_invoice():
|
def simple_invoice():
|
||||||
inv = form.Invoice()
|
inv = form.NationalSalesInvoice()
|
||||||
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')
|
||||||
|
@ -14,7 +14,7 @@ import facho.fe.form as form
|
|||||||
from facho import fe
|
from facho import fe
|
||||||
|
|
||||||
def test_invoice_legalmonetary():
|
def test_invoice_legalmonetary():
|
||||||
inv = form.Invoice()
|
inv = form.NationalSalesInvoice()
|
||||||
inv.add_invoice_line(form.InvoiceLine(
|
inv.add_invoice_line(form.InvoiceLine(
|
||||||
quantity = 1,
|
quantity = 1,
|
||||||
description = 'producto facho',
|
description = 'producto facho',
|
||||||
@ -40,7 +40,7 @@ def test_invoice_legalmonetary():
|
|||||||
|
|
||||||
|
|
||||||
def test_FAU10():
|
def test_FAU10():
|
||||||
inv = form.Invoice()
|
inv = form.NationalSalesInvoice()
|
||||||
inv.add_invoice_line(form.InvoiceLine(
|
inv.add_invoice_line(form.InvoiceLine(
|
||||||
quantity = 1,
|
quantity = 1,
|
||||||
description = 'producto facho',
|
description = 'producto facho',
|
||||||
@ -68,7 +68,7 @@ def test_FAU10():
|
|||||||
|
|
||||||
|
|
||||||
def test_FAU14():
|
def test_FAU14():
|
||||||
inv = form.Invoice()
|
inv = form.NationalSalesInvoice()
|
||||||
inv.add_invoice_line(form.InvoiceLine(
|
inv.add_invoice_line(form.InvoiceLine(
|
||||||
quantity = 1,
|
quantity = 1,
|
||||||
description = 'producto facho',
|
description = 'producto facho',
|
||||||
|
Loading…
Reference in New Issue
Block a user