tests/test_fe_form.py: se implementa prueba cude.
se implementa prueba para cude de nota debito segun ejemplo en pagina 614, pero el sha384 de la composicion difiere del generado tanto de facho como el sitio web que dan para generarlo. FossilOrigin-Name: 51b29990f6eaf4fc4f85dc51873957f41d9ba047889e4e4fe2ea4f0b1285e88c
This commit is contained in:
parent
4cc29bda4f
commit
a7eb945962
@ -13,6 +13,7 @@ import hashlib
|
||||
from contextlib import contextmanager
|
||||
from .data.dian import codelist
|
||||
from . import form
|
||||
from collections import defaultdict
|
||||
|
||||
AMBIENTE_PRUEBAS = codelist.TipoAmbiente.by_name('Pruebas')['code']
|
||||
AMBIENTE_PRODUCCION = codelist.TipoAmbiente.by_name('Producción')['code']
|
||||
@ -97,7 +98,7 @@ class DianXMLExtensionCUDFE(FachoXMLExtension):
|
||||
raise NotImplementedError()
|
||||
|
||||
def build(self, fachoxml):
|
||||
cufe = self._generate_cufe(fachoxml)
|
||||
cufe = self._generate_cufe()
|
||||
fachoxml.set_element('./cbc:UUID', cufe,
|
||||
schemeID=self.tipo_ambiente,
|
||||
schemeName=self.schemeName())
|
||||
@ -122,7 +123,7 @@ class DianXMLExtensionCUDFE(FachoXMLExtension):
|
||||
# PAG 601
|
||||
build_vars['ValorBruto'] = invoice.invoice_legal_monetary_total.line_extension_amount
|
||||
build_vars['ValorTotalPagar'] = invoice.invoice_legal_monetary_total.payable_amount
|
||||
ValorImpuestoPara = {}
|
||||
ValorImpuestoPara = defaultdict(lambda: form.Amount(0.0))
|
||||
build_vars['CodImpuesto1'] = 1
|
||||
build_vars['CodImpuesto2'] = 4
|
||||
build_vars['CodImpuesto3'] = 3
|
||||
@ -139,9 +140,8 @@ class DianXMLExtensionCUDFE(FachoXMLExtension):
|
||||
|
||||
return build_vars
|
||||
|
||||
def _generate_cufe(self, fachoxml):
|
||||
formatVars = self.formatVars()
|
||||
cufe = "".join(formatVars)
|
||||
def _generate_cufe(self):
|
||||
cufe = "".join(self.formatVars())
|
||||
|
||||
# crear hash...
|
||||
h = hashlib.sha384()
|
||||
|
@ -91,6 +91,7 @@ class Amount:
|
||||
def is_same_currency(self, other):
|
||||
return self.currency == other.currency
|
||||
|
||||
|
||||
@dataclass
|
||||
class Item:
|
||||
description: str
|
||||
@ -348,12 +349,19 @@ class AllowanceCharge:
|
||||
|
||||
class NationalSalesInvoiceDocumentType(str):
|
||||
def __str__(self):
|
||||
# 6.1.3
|
||||
return '01'
|
||||
|
||||
class CreditNoteDocumentType(str):
|
||||
def __str__(self):
|
||||
# 6.1.3
|
||||
return '91'
|
||||
|
||||
class DebitNoteDocumentType(str):
|
||||
def __str__(self):
|
||||
# 6.1.3
|
||||
return '92'
|
||||
|
||||
class Invoice:
|
||||
def __init__(self, type_code: str):
|
||||
if str(type_code) not in codelist.TipoDocumento:
|
||||
@ -475,3 +483,12 @@ class CreditNote(Invoice):
|
||||
if not isinstance(invoice_document_reference, BillingReference):
|
||||
raise TypeError('invoice_document_reference invalid type')
|
||||
self.invoice_billing_reference = invoice_document_reference
|
||||
|
||||
|
||||
class DebitNote(Invoice):
|
||||
def __init__(self, invoice_document_reference: BillingReference):
|
||||
super().__init__(DebitNoteDocumentType())
|
||||
|
||||
if not isinstance(invoice_document_reference, BillingReference):
|
||||
raise TypeError('invoice_document_reference invalid type')
|
||||
self.invoice_billing_reference = invoice_document_reference
|
||||
|
@ -17,7 +17,7 @@ class DIANDebitNoteXML(fe.FeXML):
|
||||
ublextension = self.fragment('/fe:DebitNote/ext:UBLExtensions/ext:UBLExtension', append=True)
|
||||
extcontent = ublextension.find_or_create_element('/ext:UBLExtension/ext:ExtensionContent')
|
||||
self.attach_invoice(invoice)
|
||||
|
||||
|
||||
def set_supplier(fexml, invoice):
|
||||
fexml.placeholder_for('/fe:DebitNote/cac:AccountingSupplierParty')
|
||||
#DIAN 1.7.-2020: DAJ02
|
||||
@ -101,7 +101,7 @@ class DIANDebitNoteXML(fe.FeXML):
|
||||
invoice.invoice_customer.tax_scheme.code)
|
||||
#DIAN 1.7.-2020: DAJ41
|
||||
fexml.set_element('/fe:DebitNote/cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cac:TaxScheme/cbc:Name',
|
||||
invoice.invoice_customer.tax_scheme.name)
|
||||
invoice.invoice_customer.tax_scheme.name)
|
||||
#DIAN 1.7.-2020: DAJ42
|
||||
fexml.placeholder_for('/fe:DebitNote/cac:AccountingSupplierParty/cac:Party/cac:PartyLegalEntity')
|
||||
#DIAN 1.7.-2020: DAJ43
|
||||
@ -229,7 +229,7 @@ class DIANDebitNoteXML(fe.FeXML):
|
||||
#DIAN 1.7.-2020: CAK51, CAK55
|
||||
fexml.set_element('/fe:DebitNote/cac:AccountingCustomerParty/cac:Party/cac:Contact/cbc:ElectronicMail',
|
||||
invoice.invoice_customer.email)
|
||||
|
||||
|
||||
|
||||
def set_payment_mean(fexml, invoice):
|
||||
payment_mean = invoice.invoice_payment_mean
|
||||
@ -275,10 +275,10 @@ class DIANDebitNoteXML(fe.FeXML):
|
||||
schemeName='CUFE-SHA384')
|
||||
fexml.set_element('/fe:DebitNote/cac:BillingReference/cac:InvoiceDocumentReference/cbc:IssueDate',
|
||||
invoice.invoice_billing_reference.date)
|
||||
|
||||
|
||||
|
||||
|
||||
def set_invoice_totals(fexml, invoice):
|
||||
tax_amount_for = defaultdict(lambda: defaultdict(lambda: 0.0))
|
||||
tax_amount_for = defaultdict(lambda: defaultdict(lambda: Amount(0.0)))
|
||||
percent_for = defaultdict(lambda: None)
|
||||
|
||||
#requeridos para CUDE
|
||||
|
@ -416,7 +416,7 @@ class DIANInvoiceXML(fe.FeXML):
|
||||
return fexml._set_invoice_document_reference(reference)
|
||||
|
||||
def set_invoice_totals(fexml, invoice):
|
||||
tax_amount_for = defaultdict(lambda: defaultdict(lambda: 0.0))
|
||||
tax_amount_for = defaultdict(lambda: defaultdict(lambda: Amount(0.0)))
|
||||
percent_for = defaultdict(lambda: None)
|
||||
|
||||
#requeridos para CUFE
|
||||
|
@ -12,7 +12,39 @@ import zipfile
|
||||
|
||||
import facho.fe.form as form
|
||||
from facho import fe
|
||||
from facho.fe.form_xml import DIANInvoiceXML, DIANCreditNoteXML
|
||||
from facho.fe.form_xml import DIANInvoiceXML, DIANCreditNoteXML, DIANDebitNoteXML
|
||||
|
||||
@pytest.fixture
|
||||
def simple_debit_note_without_lines():
|
||||
inv = form.DebitNote(form.InvoiceDocumentReference('1234', 'xx', datetime.now()))
|
||||
inv.set_period(datetime.now(), datetime.now())
|
||||
inv.set_issue(datetime.now())
|
||||
inv.set_ident('ABC123')
|
||||
inv.set_operation_type('10')
|
||||
inv.set_payment_mean(form.PaymentMean(form.PaymentMean.DEBIT, '41', datetime.now(), '1234'))
|
||||
inv.set_supplier(form.Party(
|
||||
name = 'facho-supplier',
|
||||
ident = form.PartyIdentification('123','', '31'),
|
||||
responsability_code = form.Responsability(['O-07']),
|
||||
responsability_regime_code = '48',
|
||||
organization_code = '1',
|
||||
address = form.Address(
|
||||
'', '', form.City('05001', 'Medellín'),
|
||||
form.Country('CO', 'Colombia'),
|
||||
form.CountrySubentity('05', 'Antioquia'))
|
||||
))
|
||||
inv.set_customer(form.Party(
|
||||
name = 'facho-customer',
|
||||
ident = form.PartyIdentification('321', '', '31'),
|
||||
responsability_code = form.Responsability(['O-07']),
|
||||
responsability_regime_code = '48',
|
||||
organization_code = '1',
|
||||
address = form.Address(
|
||||
'', '', form.City('05001', 'Medellín'),
|
||||
form.Country('CO', 'Colombia'),
|
||||
form.CountrySubentity('05', 'Antioquia'))
|
||||
))
|
||||
return inv
|
||||
|
||||
@pytest.fixture
|
||||
def simple_credit_note_without_lines():
|
||||
@ -312,3 +344,54 @@ def test_credit_note_cude(simple_credit_note_without_lines):
|
||||
cude = xml_invoice.get_element_text('/fe:CreditNote/cbc:UUID')
|
||||
# pag 612
|
||||
assert cude == '907e4444decc9e59c160a2fb3b6659b33dc5b632a5008922b9a62f83f757b1c448e47f5867f2b50dbdb96f48c7681168'
|
||||
|
||||
|
||||
# pag 614
|
||||
def test_debit_note_cude(simple_debit_note_without_lines):
|
||||
simple_invoice = simple_debit_note_without_lines
|
||||
simple_invoice.invoice_ident = 'ND1001'
|
||||
simple_invoice.invoice_issue = datetime.strptime('2019-01-18 10:58:00-05:00', '%Y-%m-%d %H:%M:%S%z')
|
||||
simple_invoice.invoice_supplier.ident = form.PartyIdentification('900197264', '5', '31')
|
||||
simple_invoice.invoice_customer.ident = form.PartyIdentification('10254102', '5', '31')
|
||||
simple_invoice.add_invoice_line(form.InvoiceLine(
|
||||
quantity = 1,
|
||||
description = 'producto',
|
||||
item = form.StandardItem('test', 111),
|
||||
price = form.Price(form.Amount(30_000), '01', ''),
|
||||
tax = form.TaxTotal(
|
||||
subtotals = [
|
||||
form.TaxSubTotal(
|
||||
tax_scheme_ident = '04',
|
||||
percent = 8.0
|
||||
)])
|
||||
))
|
||||
|
||||
simple_invoice.calculate()
|
||||
xml_invoice = DIANDebitNoteXML(simple_invoice)
|
||||
|
||||
cude_extension = fe.DianXMLExtensionCUDE(
|
||||
simple_invoice,
|
||||
'10201',
|
||||
tipo_ambiente = fe.AMBIENTE_PRUEBAS,
|
||||
)
|
||||
build_vars = cude_extension.buildVars()
|
||||
assert build_vars['NumFac'] == 'ND1001'
|
||||
assert build_vars['FecFac'] == '2019-01-18'
|
||||
assert build_vars['HoraFac'] == '10:58:00-05:00'
|
||||
assert build_vars['ValorBruto'] == form.Amount(30_000)
|
||||
assert build_vars['NitOFE'] == '900197264'
|
||||
assert build_vars['NumAdq'] == '10254102'
|
||||
assert build_vars['ValorImpuestoPara'][1] == form.Amount(0)
|
||||
assert build_vars['ValorImpuestoPara'][4] == form.Amount(2400)
|
||||
assert build_vars['ValorImpuestoPara'][3] == form.Amount(0)
|
||||
assert build_vars['ValorTotalPagar'] == form.Amount(32400)
|
||||
assert build_vars['Software-PIN'] == '10201'
|
||||
assert build_vars['TipoAmb'] == 2
|
||||
|
||||
|
||||
cude_composicion = "".join(cude_extension.formatVars())
|
||||
assert cude_composicion == 'ND10012019-01-1810:58:00-05:0030000.00010.00042400.00030.0032400.0090019726410254102102012'
|
||||
|
||||
xml_invoice.add_extension(cude_extension)
|
||||
cude = xml_invoice.get_element_text('/fe:DebitNote/cbc:UUID')
|
||||
assert cude == 'b9483dc2a17167feedf37b6bd67c4204e7b601933e0e389cffbd545e4d0ec370b403cbb41ff656776cb6cb5d8348ecd4'
|
||||
|
Loading…
Reference in New Issue
Block a user