Actualizar para envío de Nómina Ajuste
FossilOrigin-Name: 98e5f9522b428c2e401b9fb5ba2f8a96157415ada89aef70d7b7900674a461b8
This commit is contained in:
		| @@ -34,6 +34,7 @@ POLICY_NAME = u'Política de firma para facturas electrónicas de la República | |||||||
| NAMESPACES = { | NAMESPACES = { | ||||||
|     'atd': 'urn:oasis:names:specification:ubl:schema:xsd:AttachedDocument-2', |     'atd': 'urn:oasis:names:specification:ubl:schema:xsd:AttachedDocument-2', | ||||||
|     'nomina': 'dian:gov:co:facturaelectronica:NominaIndividual', |     'nomina': 'dian:gov:co:facturaelectronica:NominaIndividual', | ||||||
|  |     'nominaajuste': 'dian:gov:co:facturaelectronica:NominaIndividualDeAjuste',     | ||||||
|     'fe': 'http://www.dian.gov.co/contratos/facturaelectronica/v1', |     'fe': 'http://www.dian.gov.co/contratos/facturaelectronica/v1', | ||||||
|     'xs': 'http://www.w3.org/2001/XMLSchema-instance',     |     'xs': 'http://www.w3.org/2001/XMLSchema-instance',     | ||||||
|     'cac': 'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2', |     'cac': 'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2', | ||||||
|   | |||||||
| @@ -150,7 +150,6 @@ class Proveedor: | |||||||
|             raise RuntimeError('fail to get InformacionGeneral/@Ambiente') |             raise RuntimeError('fail to get InformacionGeneral/@Ambiente') | ||||||
|          |          | ||||||
|         scopexml.set_element('./CodigoQR', codigo_qr) |         scopexml.set_element('./CodigoQR', codigo_qr) | ||||||
|         scopexml.set_element('./Novedad', "false")         |  | ||||||
|  |  | ||||||
|         # NIE020 |         # NIE020 | ||||||
|         software_code = self._software_security_code(fexml, scopexml) |         software_code = self._software_security_code(fexml, scopexml) | ||||||
| @@ -183,6 +182,7 @@ class Metadata: | |||||||
|     proveedor: Proveedor |     proveedor: Proveedor | ||||||
|  |  | ||||||
|     def apply(self, novedad, numero_secuencia_xml, lugar_generacion_xml, proveedor_xml): |     def apply(self, novedad, numero_secuencia_xml, lugar_generacion_xml, proveedor_xml): | ||||||
|  |         if novedad: | ||||||
|             self.novedad.apply(novedad) |             self.novedad.apply(novedad) | ||||||
|         self.secuencia.apply(numero_secuencia_xml) |         self.secuencia.apply(numero_secuencia_xml) | ||||||
|         self.lugar_generacion.apply(lugar_generacion_xml, './LugarGeneracionXML') |         self.lugar_generacion.apply(lugar_generacion_xml, './LugarGeneracionXML') | ||||||
| @@ -190,6 +190,7 @@ class Metadata: | |||||||
|  |  | ||||||
|     def post_apply(self, fexml, scopexml, novedad, numero_secuencia_xml, lugar_generacion_xml, proveedor_xml): |     def post_apply(self, fexml, scopexml, novedad, numero_secuencia_xml, lugar_generacion_xml, proveedor_xml): | ||||||
|         self.proveedor.post_apply(fexml, scopexml, proveedor_xml) |         self.proveedor.post_apply(fexml, scopexml, proveedor_xml) | ||||||
|  |         if novedad: | ||||||
|             self.novedad.post_apply(fexml, scopexml, proveedor_xml)         |             self.novedad.post_apply(fexml, scopexml, proveedor_xml)         | ||||||
|          |          | ||||||
| @dataclass | @dataclass | ||||||
| @@ -237,11 +238,35 @@ class InformacionGeneral: | |||||||
|         def __str__(self): |         def __str__(self): | ||||||
|             self.valor             |             self.valor             | ||||||
|  |  | ||||||
|  |     # TABLA 5.5.7 | ||||||
|  |     @dataclass | ||||||
|  |     class TIPO_XML: | ||||||
|  |         valor: str | ||||||
|  |  | ||||||
|  |         @classmethod | ||||||
|  |         def same(cls, value): | ||||||
|  |             return cls.valor == str(value) | ||||||
|  |  | ||||||
|  |     @dataclass | ||||||
|  |     class TIPO_XML_NORMAL(TIPO_XML): | ||||||
|  |         valor: str = '102' | ||||||
|  |  | ||||||
|  |         def __str__(self): | ||||||
|  |             self.valor             | ||||||
|  |  | ||||||
|  |     @dataclass | ||||||
|  |     class TIPO_XML_AJUSTES(TIPO_XML): | ||||||
|  |         valor: str = '103' | ||||||
|  |  | ||||||
|  |         def __str__(self): | ||||||
|  |             self.valor | ||||||
|  |  | ||||||
|     fecha_generacion: typing.Union[str, Fecha] |     fecha_generacion: typing.Union[str, Fecha] | ||||||
|     hora_generacion: str |     hora_generacion: str | ||||||
|     periodo_nomina: PeriodoNomina |     periodo_nomina: PeriodoNomina | ||||||
|     tipo_moneda: TipoMoneda |     tipo_moneda: TipoMoneda | ||||||
|     tipo_ambiente: TIPO_AMBIENTE |     tipo_ambiente: TIPO_AMBIENTE | ||||||
|  |     tipo_xml: TIPO_XML | ||||||
|     software_pin: str |     software_pin: str | ||||||
|  |  | ||||||
|     def __post_init__(self): |     def __post_init__(self): | ||||||
| @@ -256,7 +281,7 @@ class InformacionGeneral: | |||||||
|                                 # NIE202 |                                 # NIE202 | ||||||
|                                 # TABLA 5.5.2 |                                 # TABLA 5.5.2 | ||||||
|                                 # TODO(bit4bit) solo NominaIndividual |                                 # TODO(bit4bit) solo NominaIndividual | ||||||
|                                 TipoXML = '102', |                                 TipoXML = self.tipo_xml.valor, | ||||||
|                                 # NIE024 |                                 # NIE024 | ||||||
|                                 CUNE = None, |                                 CUNE = None, | ||||||
|                                 # NIE025 |                                 # NIE025 | ||||||
| @@ -315,15 +340,16 @@ class DianXMLExtensionSigner(fe.DianXMLExtensionSigner): | |||||||
|  |  | ||||||
|  |  | ||||||
| class DIANNominaXML: | class DIANNominaXML: | ||||||
|     def __init__(self, tag_document, xpath_ajuste=None,schemaLocation=None): |     def __init__(self, tag_document, xpath_ajuste=None, schemaLocation=None, namespace_ajuste=None): | ||||||
|         self.informacion_general_version = None |         self.informacion_general_version = None | ||||||
|  |  | ||||||
|         self.tag_document = tag_document |         self.tag_document = tag_document | ||||||
|  |  | ||||||
|  |         if namespace_ajuste: | ||||||
|  |             self.fexml = fe.FeXML(tag_document, namespace_ajuste) | ||||||
|  |         else: | ||||||
|             self.fexml = fe.FeXML(tag_document, 'dian:gov:co:facturaelectronica:NominaIndividual') |             self.fexml = fe.FeXML(tag_document, 'dian:gov:co:facturaelectronica:NominaIndividual') | ||||||
|  |  | ||||||
|         schemaLocation = "dian:gov:co:facturaelectronica:NominaIndividual NominaIndividualElectronicaXSD.xsd" |  | ||||||
|  |  | ||||||
|         if schemaLocation is not None: |  | ||||||
|         self.fexml.root.set("SchemaLocation", "") |         self.fexml.root.set("SchemaLocation", "") | ||||||
|         self.fexml.root.set("schemaLocation", schemaLocation) |         self.fexml.root.set("schemaLocation", schemaLocation) | ||||||
|  |  | ||||||
| @@ -337,6 +363,7 @@ class DIANNominaXML: | |||||||
|             self.root_fragment = self.fexml.fragment(xpath_ajuste) |             self.root_fragment = self.fexml.fragment(xpath_ajuste) | ||||||
|         self.root_fragment.placeholder_for('./ReemplazandoPredecesor', optional=True) |         self.root_fragment.placeholder_for('./ReemplazandoPredecesor', optional=True) | ||||||
|         self.root_fragment.placeholder_for('./EliminandoPredecesor', optional=True) |         self.root_fragment.placeholder_for('./EliminandoPredecesor', optional=True) | ||||||
|  |         if not namespace_ajuste: | ||||||
|             self.root_fragment.placeholder_for('./Novedad', optional=False) |             self.root_fragment.placeholder_for('./Novedad', optional=False) | ||||||
|         self.root_fragment.placeholder_for('./Periodo') |         self.root_fragment.placeholder_for('./Periodo') | ||||||
|         self.root_fragment.placeholder_for('./NumeroSecuenciaXML') |         self.root_fragment.placeholder_for('./NumeroSecuenciaXML') | ||||||
| @@ -350,8 +377,10 @@ class DIANNominaXML: | |||||||
|         self.root_fragment.placeholder_for('./FechasPagos') |         self.root_fragment.placeholder_for('./FechasPagos') | ||||||
|         self.root_fragment.placeholder_for('./Devengados/Basico') |         self.root_fragment.placeholder_for('./Devengados/Basico') | ||||||
|         self.root_fragment.placeholder_for('./Devengados/Transporte', optional=True) |         self.root_fragment.placeholder_for('./Devengados/Transporte', optional=True) | ||||||
|  |         if not namespace_ajuste: | ||||||
|             self.novedad = self.root_fragment.fragment('./Novedad') |             self.novedad = self.root_fragment.fragment('./Novedad') | ||||||
|  |         else: | ||||||
|  |             self.novedad = None | ||||||
|         self.informacion_general_xml = self.root_fragment.fragment('./InformacionGeneral') |         self.informacion_general_xml = self.root_fragment.fragment('./InformacionGeneral') | ||||||
|         self.periodo_xml = self.root_fragment.fragment('./Periodo') |         self.periodo_xml = self.root_fragment.fragment('./Periodo') | ||||||
|         self.fecha_pagos_xml = self.root_fragment.fragment('./FechasPagos') |         self.fecha_pagos_xml = self.root_fragment.fragment('./FechasPagos') | ||||||
| @@ -371,6 +400,7 @@ class DIANNominaXML: | |||||||
|         if not isinstance(metadata, Metadata): |         if not isinstance(metadata, Metadata): | ||||||
|             raise ValueError('se espera tipo Metadata') |             raise ValueError('se espera tipo Metadata') | ||||||
|         self.metadata = metadata |         self.metadata = metadata | ||||||
|  |                  | ||||||
|         self.metadata.apply(self.novedad, self.numero_secuencia_xml, self.lugar_generacion_xml, self.proveedor_xml) |         self.metadata.apply(self.novedad, self.numero_secuencia_xml, self.lugar_generacion_xml, self.proveedor_xml) | ||||||
|          |          | ||||||
|     def asignar_informacion_general(self, general): |     def asignar_informacion_general(self, general): | ||||||
| @@ -548,7 +578,7 @@ class DIANNominaXML: | |||||||
| class DIANNominaIndividual(DIANNominaXML): | class DIANNominaIndividual(DIANNominaXML): | ||||||
|  |  | ||||||
|     def __init__(self): |     def __init__(self): | ||||||
|         schema = "dian:gov:co:facturaelectronica:NominaIndividual" |         schema = "dian:gov:co:facturaelectronica:NominaIndividual NominaIndividualElectronicaXSD.xsd" | ||||||
|  |  | ||||||
|         super().__init__('NominaIndividual', schemaLocation=schema) |         super().__init__('NominaIndividual', schemaLocation=schema) | ||||||
|         self.informacion_general_version = 'V1.0: Documento Soporte de Pago de Nómina Electrónica' |         self.informacion_general_version = 'V1.0: Documento Soporte de Pago de Nómina Electrónica' | ||||||
| @@ -564,6 +594,8 @@ class DIANNominaIndividualDeAjuste(DIANNominaXML): | |||||||
|             fecha_generacion: str |             fecha_generacion: str | ||||||
|  |  | ||||||
|             def apply(self, fragment): |             def apply(self, fragment): | ||||||
|  |                 # NIAE214 | ||||||
|  |                 fragment.set_element('./TipoNota', '1')                 | ||||||
|                 fragment.set_element('./Reemplazar/ReemplazandoPredecesor', None, |                 fragment.set_element('./Reemplazar/ReemplazandoPredecesor', None, | ||||||
|                                      # NIAE090 |                                      # NIAE090 | ||||||
|                                      NumeroPred = self.numero, |                                      NumeroPred = self.numero, | ||||||
| @@ -574,9 +606,11 @@ class DIANNominaIndividualDeAjuste(DIANNominaXML): | |||||||
|                                      ) |                                      ) | ||||||
|  |  | ||||||
|         def __init__(self): |         def __init__(self): | ||||||
|             super().__init__('NominaIndividualDeAjuste', './Reemplazar') |             schema = "dian:gov:co:facturaelectronica:NominaIndividualDeAjuste NominaIndividualDeAjusteElectronicaXSD.xsd" | ||||||
|             # NIAE214 |              | ||||||
|             self.root_fragment.set_element('./TipoNota', '1') |             super().__init__('NominaIndividualDeAjuste', './Reemplazar', schemaLocation=schema, namespace_ajuste='dian:gov:co:facturaelectronica:NominaIndividualDeAjuste') | ||||||
|  |              | ||||||
|  |             self.informacion_general_version = 'V1.0: Nota de Ajuste de Documento Soporte de Pago de Nómina Electrónica' | ||||||
|  |  | ||||||
|         def asignar_predecesor(self, predecesor): |         def asignar_predecesor(self, predecesor): | ||||||
|             if not isinstance(predecesor, self.Predecesor): |             if not isinstance(predecesor, self.Predecesor): | ||||||
| @@ -593,6 +627,7 @@ class DIANNominaIndividualDeAjuste(DIANNominaXML): | |||||||
|             fecha_generacion: str |             fecha_generacion: str | ||||||
|  |  | ||||||
|             def apply(self, fragment): |             def apply(self, fragment): | ||||||
|  |                 fragment.set_element('./TipoNota', '2') | ||||||
|                 fragment.set_element('./Eliminar/EliminandoPredecesor', None, |                 fragment.set_element('./Eliminar/EliminandoPredecesor', None, | ||||||
|                                      # NIAE090 |                                      # NIAE090 | ||||||
|                                      NumeroPred = self.numero, |                                      NumeroPred = self.numero, | ||||||
| @@ -603,9 +638,9 @@ class DIANNominaIndividualDeAjuste(DIANNominaXML): | |||||||
|                                      ) |                                      ) | ||||||
|  |  | ||||||
|         def __init__(self): |         def __init__(self): | ||||||
|             super().__init__('NominaIndividualDeAjuste', './Eliminar') |             schema = "dian:gov:co:facturaelectronica:NominaIndividualDeAjuste NominaIndividualDeAjusteElectronicaXSD.xsd"             | ||||||
|  |             super().__init__('NominaIndividualDeAjuste', './Eliminar', schemaLocation=schema, namespace_ajuste='dian:gov:co:facturaelectronica:NominaIndividualDeAjuste') | ||||||
|  |  | ||||||
|             self.root_fragment.set_element('./TipoNota', '2') |  | ||||||
|             self.informacion_general_version = "V1.0: Nota de Ajuste de Documento Soporte de Pago de Nómina Electrónica" |             self.informacion_general_version = "V1.0: Nota de Ajuste de Documento Soporte de Pago de Nómina Electrónica" | ||||||
|  |  | ||||||
|         def asignar_predecesor(self, predecesor): |         def asignar_predecesor(self, predecesor): | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user