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:
bit4bit@riseup.net 2020-10-30 03:27:11 +00:00
parent 4cc29bda4f
commit a7eb945962
5 changed files with 113 additions and 13 deletions

View File

@ -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()

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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'