facho/fe/form.py (DianResolucion0001Validator): centraliza la validacion de facturas

FossilOrigin-Name: fa0f09a8340c2f8b6d6e11ca6d5c1ff430701b31676bb1024e45f66726b157a2
This commit is contained in:
bit4bit@riseup.net 2020-05-23 20:18:02 +00:00
parent 34032e8a45
commit 33cc210ad4
3 changed files with 47 additions and 48 deletions

View File

@ -1,4 +1,4 @@
from .fe import DianXMLExtensionSigner
from .fe import FeXML from .fe import FeXML
from .fe import NAMESPACES from .fe import NAMESPACES
from .fe import DianXMLExtensionSigner
from .fe import DianZIP from .fe import DianZIP

View File

@ -10,26 +10,8 @@ from datetime import datetime
from .data import dian from .data import dian
from . import fe from . import fe
class DataError(Exception):
def __init__(self, errors):
self._errors = errors
class DataValidator:
# valida y retorna errores [(key, error)..]
def validate(self) -> []:
raise NotImplementedError()
def try_validate(self):
errors = self.validate()
if errors:
raise DataError(errors)
@dataclass @dataclass
class Party(DataValidator): class Party:
name: str name: str
ident: str ident: str
responsability_code: str responsability_code: str
@ -42,20 +24,6 @@ class Party(DataValidator):
legal_company_ident: str = '' legal_company_ident: str = ''
legal_address: str = '' legal_address: str = ''
def validate(self):
errors = []
try:
dian.TipoResponsabilidad[self.responsability_code]
except KeyError:
errors.append(('responsability_code', 'not found'))
try:
dian.TipoOrganizacion[self.organization_code]
except KeyError:
errors.append(('organization_code', 'not found'))
return errors
@dataclass @dataclass
@ -117,7 +85,7 @@ class LegalMonetaryTotal:
payable_amount: float = 0.0 payable_amount: float = 0.0
class Invoice(DataValidator): class Invoice:
def __init__(self): def __init__(self):
self.invoice_period_start = None self.invoice_period_start = None
self.invoice_period_end = None self.invoice_period_end = None
@ -128,7 +96,6 @@ class Invoice(DataValidator):
self.invoice_customer = None self.invoice_customer = None
self.invoice_supplier = None self.invoice_supplier = None
self.invoice_lines = [] self.invoice_lines = []
self.errors = []
def set_period(self, startdate, enddate): def set_period(self, startdate, enddate):
self.invoice_period_start = startdate self.invoice_period_start = startdate
@ -149,14 +116,11 @@ class Invoice(DataValidator):
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 validate(self): def validate(self, validator):
errors_customer = [('customer.%s' % (field), err) for field, err in self.invoice_customer.validate()] validator.validate_customer(self.invoice_customer)
errors_supplier = [('supplier.%s' % (field), err) for field, err in self.invoice_customer.validate()] validator.validate_supplier(self.invoice_supplier)
self.errors = errors_customer + errors_supplier for invline in self.invoice_lines:
validator.validate_invoice_line(self, invline)
def valid(self):
self.validate()
return not self.errors
def _calculate_legal_monetary_total(self): def _calculate_legal_monetary_total(self):
for invline in self.invoice_lines: for invline in self.invoice_lines:
@ -173,6 +137,36 @@ class Invoice(DataValidator):
for invline in self.invoice_lines: for invline in self.invoice_lines:
invline.calculate() invline.calculate()
class DianResolucion0001Validator:
def __init__(self):
self.errors = []
def _validate_party(self, party):
try:
dian.TipoResponsabilidad[party.responsability_code]
except KeyError:
self.errors.append(('responsability_code', 'not found'))
try:
dian.TipoOrganizacion[party.organization_code]
except KeyError:
self.errors.append(('organization_code', 'not found'))
def validate_customer(self, customer):
self._validate_party(customer)
def validate_supplier(self, supplier):
self._validate_party(supplier)
def validate_invoice_line(self, invoice, line):
pass
def valid(self):
return not self.errors
class DIANInvoiceXML(fe.FeXML): class DIANInvoiceXML(fe.FeXML):
def __init__(self, invoice, TipoAmbiente = 'Pruebas'): def __init__(self, invoice, TipoAmbiente = 'Pruebas'):
@ -184,7 +178,6 @@ class DIANInvoiceXML(fe.FeXML):
en caso de fallar validacion retorna None""" en caso de fallar validacion retorna None"""
fexml = self fexml = self
invoice.try_validate()
invoice.calculate() invoice.calculate()
cufe = self._generate_cufe(invoice, TipoAmbiente) cufe = self._generate_cufe(invoice, TipoAmbiente)

View File

@ -52,7 +52,9 @@ def simple_invoice():
def test_invoicesimple_build(simple_invoice): def test_invoicesimple_build(simple_invoice):
assert simple_invoice.valid() == True invoice_validator = form.DianResolucion0001Validator()
simple_invoice.validate(invoice_validator)
assert invoice_validator.valid() == True
xml = form.DIANInvoiceXML(simple_invoice) xml = form.DIANInvoiceXML(simple_invoice)
supplier_name = xml.get_element_text('/fe:Invoice/fe:AccountingSupplierParty/fe:Party/cac:PartyName/cbc:Name') supplier_name = xml.get_element_text('/fe:Invoice/fe:AccountingSupplierParty/fe:Party/cac:PartyName/cbc:Name')
@ -69,14 +71,18 @@ def test_invoicesimple_build(simple_invoice):
def test_invoicesimple_build_with_cufe(simple_invoice): def test_invoicesimple_build_with_cufe(simple_invoice):
assert simple_invoice.valid() == True invoice_validator = form.DianResolucion0001Validator()
simple_invoice.validate(invoice_validator)
assert invoice_validator.valid() == True
xml = form.DIANInvoiceXML(simple_invoice) xml = form.DIANInvoiceXML(simple_invoice)
cufe = xml.get_element_text('/fe:Invoice/cbc:UUID') cufe = xml.get_element_text('/fe:Invoice/cbc:UUID')
assert cufe != '' assert cufe != ''
def test_invoicesimple_xml_signed(simple_invoice): def test_invoicesimple_xml_signed(simple_invoice):
assert simple_invoice.valid() == True invoice_validator = form.DianResolucion0001Validator()
simple_invoice.validate(invoice_validator)
assert invoice_validator.valid() == True
xml = form.DIANInvoiceXML(simple_invoice) xml = form.DIANInvoiceXML(simple_invoice)
signer = fe.DianXMLExtensionSigner('./tests/example.p12') signer = fe.DianXMLExtensionSigner('./tests/example.p12')