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 contextlib import contextmanager
from .data.dian import codelist from .data.dian import codelist
from . import form from . import form
from collections import defaultdict
AMBIENTE_PRUEBAS = codelist.TipoAmbiente.by_name('Pruebas')['code'] AMBIENTE_PRUEBAS = codelist.TipoAmbiente.by_name('Pruebas')['code']
AMBIENTE_PRODUCCION = codelist.TipoAmbiente.by_name('Producción')['code'] AMBIENTE_PRODUCCION = codelist.TipoAmbiente.by_name('Producción')['code']
@ -97,7 +98,7 @@ class DianXMLExtensionCUDFE(FachoXMLExtension):
raise NotImplementedError() raise NotImplementedError()
def build(self, fachoxml): def build(self, fachoxml):
cufe = self._generate_cufe(fachoxml) cufe = self._generate_cufe()
fachoxml.set_element('./cbc:UUID', cufe, fachoxml.set_element('./cbc:UUID', cufe,
schemeID=self.tipo_ambiente, schemeID=self.tipo_ambiente,
schemeName=self.schemeName()) schemeName=self.schemeName())
@ -122,7 +123,7 @@ class DianXMLExtensionCUDFE(FachoXMLExtension):
# PAG 601 # PAG 601
build_vars['ValorBruto'] = invoice.invoice_legal_monetary_total.line_extension_amount build_vars['ValorBruto'] = invoice.invoice_legal_monetary_total.line_extension_amount
build_vars['ValorTotalPagar'] = invoice.invoice_legal_monetary_total.payable_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['CodImpuesto1'] = 1
build_vars['CodImpuesto2'] = 4 build_vars['CodImpuesto2'] = 4
build_vars['CodImpuesto3'] = 3 build_vars['CodImpuesto3'] = 3
@ -139,9 +140,8 @@ class DianXMLExtensionCUDFE(FachoXMLExtension):
return build_vars return build_vars
def _generate_cufe(self, fachoxml): def _generate_cufe(self):
formatVars = self.formatVars() cufe = "".join(self.formatVars())
cufe = "".join(formatVars)
# crear hash... # crear hash...
h = hashlib.sha384() h = hashlib.sha384()

View File

@ -91,6 +91,7 @@ class Amount:
def is_same_currency(self, other): def is_same_currency(self, other):
return self.currency == other.currency return self.currency == other.currency
@dataclass @dataclass
class Item: class Item:
description: str description: str
@ -348,12 +349,19 @@ class AllowanceCharge:
class NationalSalesInvoiceDocumentType(str): class NationalSalesInvoiceDocumentType(str):
def __str__(self): def __str__(self):
# 6.1.3
return '01' return '01'
class CreditNoteDocumentType(str): class CreditNoteDocumentType(str):
def __str__(self): def __str__(self):
# 6.1.3
return '91' return '91'
class DebitNoteDocumentType(str):
def __str__(self):
# 6.1.3
return '92'
class Invoice: class Invoice:
def __init__(self, type_code: str): def __init__(self, type_code: str):
if str(type_code) not in codelist.TipoDocumento: if str(type_code) not in codelist.TipoDocumento:
@ -475,3 +483,12 @@ class CreditNote(Invoice):
if not isinstance(invoice_document_reference, BillingReference): if not isinstance(invoice_document_reference, BillingReference):
raise TypeError('invoice_document_reference invalid type') raise TypeError('invoice_document_reference invalid type')
self.invoice_billing_reference = invoice_document_reference 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

@ -278,7 +278,7 @@ class DIANDebitNoteXML(fe.FeXML):
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: Amount(0.0)))
percent_for = defaultdict(lambda: None) percent_for = defaultdict(lambda: None)
#requeridos para CUDE #requeridos para CUDE

View File

@ -416,7 +416,7 @@ class DIANInvoiceXML(fe.FeXML):
return fexml._set_invoice_document_reference(reference) 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: Amount(0.0)))
percent_for = defaultdict(lambda: None) percent_for = defaultdict(lambda: None)
#requeridos para CUFE #requeridos para CUFE

View File

@ -12,7 +12,39 @@ import zipfile
import facho.fe.form as form import facho.fe.form as form
from facho import fe 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 @pytest.fixture
def simple_credit_note_without_lines(): 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') cude = xml_invoice.get_element_text('/fe:CreditNote/cbc:UUID')
# pag 612 # pag 612
assert cude == '907e4444decc9e59c160a2fb3b6659b33dc5b632a5008922b9a62f83f757b1c448e47f5867f2b50dbdb96f48c7681168' 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'