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