diff --git a/facho/facho.py b/facho/facho.py index c49e423..712bb7b 100644 --- a/facho/facho.py +++ b/facho/facho.py @@ -213,6 +213,12 @@ class FachoXML: self.builder.set_attribute(elem, k, v) return elem + def set_attributes(self, xpath, **attrs): + xpath = self._normalize_xpath(xpath) + elem = self.get_element(xpath) + for k, v in attrs.items(): + self.builder.set_attribute(elem, k, v) + def get_element(self, xpath): xpath = self.fragment_prefix + self._normalize_xpath(xpath) return self.builder.xpath(self.root, xpath) diff --git a/facho/fe/__init__.py b/facho/fe/__init__.py index 4e8b758..9a42e32 100644 --- a/facho/fe/__init__.py +++ b/facho/fe/__init__.py @@ -5,4 +5,5 @@ from .fe import DianXMLExtensionSoftwareSecurityCode from .fe import DianXMLExtensionCUFE from .fe import DianXMLExtensionInvoiceAuthorization from .fe import DianXMLExtensionSoftwareProvider +from .fe import DianXMLExtensionAuthorizationProvider from .fe import DianZIP diff --git a/facho/fe/fe.py b/facho/fe/fe.py index 40133b4..b6e1531 100644 --- a/facho/fe/fe.py +++ b/facho/fe/fe.py @@ -12,6 +12,12 @@ import hashlib from contextlib import contextmanager from .data.dian import codelist +SCHEME_AGENCY_ATTRS = { + 'schemeAgencyName': 'CO, DIAN (Direccion de Impuestos y Aduanas Nacionales)', + 'schemeAgencyID': '195' +} + + NAMESPACES = { 'fe': 'http://www.dian.gov.co/contratos/facturaelectronica/v1', 'cac': 'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2', @@ -123,8 +129,10 @@ class DianXMLExtensionSoftwareProvider(FachoXMLExtension): def build(self, fexml): software_provider = fexml.fragment('/fe:Invoice/ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent/sts:DianExtensions/sts:SoftwareProvider') - software_provider.set_element('/sts:SoftwareProvider/sts:ProviderID', self.nit) - software_provider.set_element('/sts:SoftwareProvider/sts:SoftwareID', self.id_software) + software_provider.set_element('/sts:SoftwareProvider/sts:ProviderID', self.nit, + **SCHEME_AGENCY_ATTRS) + software_provider.set_element('/sts:SoftwareProvider/sts:SoftwareID', self.id_software, + **SCHEME_AGENCY_ATTRS) return '', [] @@ -142,6 +150,7 @@ class DianXMLExtensionSoftwareSecurityCode(FachoXMLExtension): m = hashlib.sha384() m.update(code.encode('utf-8')) fexml.set_element(dian_path, m.hexdigest()) + fexml.set_attributes(dian_path, **SCHEME_AGENCY_ATTRS) return '', [] @@ -234,6 +243,19 @@ class DianXMLExtensionSigner(FachoXMLExtension): return '', [] +class DianXMLExtensionAuthorizationProvider(FachoXMLExtension): + # RESOLUCION 0004: pagina 176 + + def build(self, fexml): + dian_path = '/fe:Invoice/ext:UBLExtensions/ext:ExtensionContent/sts:DianExtensions/sts:AuthorizationProvider/sts:AuthorizationProviderID' + fexml.set_element(dian_path, '800197268') + + attrs = {'schemeID': '4', 'schemeName': '31'} + attrs.update(SCHEME_AGENCY_ATTRS) + fexml.set_attributes(dian_path, **attrs) + return '', [] + + class DianXMLExtensionInvoiceAuthorization(FachoXMLExtension): # RESOLUCION 0004: pagina 106 diff --git a/facho/fe/form.py b/facho/fe/form.py index 84b0eac..4cbcaa1 100644 --- a/facho/fe/form.py +++ b/facho/fe/form.py @@ -228,7 +228,8 @@ class DIANInvoiceXML(fe.FeXML): invoice.invoice_supplier.address.street) fexml.set_element('/fe:Invoice/cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID', - invoice.invoice_supplier.ident) + invoice.invoice_supplier.ident, + **fe.SCHEME_AGENCY_ATTRS) fexml.set_element('/fe:Invoice/cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cbc:TaxLevelCode', invoice.invoice_supplier.responsability_code) @@ -251,7 +252,8 @@ class DIANInvoiceXML(fe.FeXML): fexml.set_element('/fe:Invoice/cac:AccountingCustomerParty/cac:Party/cac:PhysicalLocation/cac:Address/cac:AddressLine/cbc:Line', invoice.invoice_customer.address.street) fexml.set_element('/fe:Invoice/cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID', - invoice.invoice_customer.ident) + invoice.invoice_customer.ident, + **fe.SCHEME_AGENCY_ATTRS) fexml.set_element('/fe:Invoice/cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cbc:TaxLevelCode', invoice.invoice_customer.responsability_code) fexml.find_or_create_element('/fe:Invoice/cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cac:TaxScheme') diff --git a/tests/test_fe.py b/tests/test_fe.py index 5db990d..8910bc8 100644 --- a/tests/test_fe.py +++ b/tests/test_fe.py @@ -78,3 +78,16 @@ def test_dian_extension_software_provider(): give_nit = xml.get_element_text('/fe:Invoice/ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent/sts:DianExtensions/sts:SoftwareProvider/sts:ProviderID') assert nit == give_nit + +def test_dian_extension_authorization_provider(): + auth_provider_extension = fe.DianXMLExtensionAuthorizationProvider() + xml = fe.FeXML('Invoice', + 'http://www.dian.gov.co/contratos/facturaelectronica/v1') + xml.add_extension(auth_provider_extension) + dian_nit = xml.get_element_text('/fe:Invoice/ext:UBLExtensions/ext:ExtensionContent/sts:DianExtensions/sts:AuthorizationProvider/sts:AuthorizationProviderID') + assert dian_nit == '800197268' + + + + +