facho/fe/form.py (DianResolucion0001Validator): centraliza la validacion de facturas
FossilOrigin-Name: fa0f09a8340c2f8b6d6e11ca6d5c1ff430701b31676bb1024e45f66726b157a2
This commit is contained in:
parent
34032e8a45
commit
33cc210ad4
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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')
|
||||||
|
Loading…
Reference in New Issue
Block a user