Compare commits
	
		
			1 Commits
		
	
	
		
			documento_
			...
			quantity-f
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 1f75ac46f4 | 
| @@ -94,14 +94,6 @@ Ready to contribute? Here's how to set up `facho` for local development. | |||||||
|  |  | ||||||
| 7. Submit a pull request through the GitHub website. | 7. Submit a pull request through the GitHub website. | ||||||
|  |  | ||||||
| Using docker |  | ||||||
| ------------ |  | ||||||
|  |  | ||||||
| 1. make -f Makefile.dev build |  | ||||||
| 2. make -f Makefile.dev dev-shell |  | ||||||
| 3. make -f Makefile.dev python3.8 setup.py develop |  | ||||||
| 4. make -f Makefile.dev python3.8 setup.py test |  | ||||||
|  |  | ||||||
| Pull Request Guidelines | Pull Request Guidelines | ||||||
| ----------------------- | ----------------------- | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										40
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										40
									
								
								Dockerfile
									
									
									
									
									
								
							| @@ -1,40 +0,0 @@ | |||||||
| # DERIVADO DE https://alextereshenkov.github.io/run-python-tests-with-tox-in-docker.html |  | ||||||
| FROM ubuntu:24.04 |  | ||||||
|  |  | ||||||
| RUN apt-get -qq update |  | ||||||
|  |  | ||||||
| RUN apt install software-properties-common -y \ |  | ||||||
|     && add-apt-repository ppa:deadsnakes/ppa |  | ||||||
|  |  | ||||||
| RUN apt-get install -y --no-install-recommends \ |  | ||||||
|   python3.7 python3.7-distutils python3.7-dev \ |  | ||||||
|   python3.8 python3.8-distutils python3.8-dev \ |  | ||||||
|   python3.9 python3.9-distutils python3.9-dev \ |  | ||||||
|   python3.10 python3.10-distutils python3.10-dev \ |  | ||||||
|   wget \ |  | ||||||
|   ca-certificates |  | ||||||
|  |  | ||||||
| RUN wget https://bootstrap.pypa.io/get-pip.py \ |  | ||||||
|   && python3.7 get-pip.py pip==22.2.2 \ |  | ||||||
|   && python3.8 get-pip.py pip==22.2.2 \ |  | ||||||
|   && python3.9 get-pip.py pip==22.2.2 \ |  | ||||||
|   && python3.10 get-pip.py pip==22.2.2 \ |  | ||||||
|   && rm get-pip.py |  | ||||||
|  |  | ||||||
| RUN apt-get install -y --no-install-recommends \ |  | ||||||
|         libxml2-dev \ |  | ||||||
|         libxmlsec1-dev \ |  | ||||||
|         build-essential \ |  | ||||||
|         zip |  | ||||||
|  |  | ||||||
| RUN python3.7 --version |  | ||||||
| RUN python3.8 --version |  | ||||||
| RUN python3.9 --version |  | ||||||
| RUN python3.10 --version |  | ||||||
|  |  | ||||||
| RUN pip3.7 install setuptools setuptools-rust |  | ||||||
| RUN pip3.8 install setuptools setuptools-rust |  | ||||||
| RUN pip3.9 install setuptools setuptools-rust |  | ||||||
| RUN pip3.10 install setuptools setuptools-rust |  | ||||||
|  |  | ||||||
| RUN pip3 install tox pytest |  | ||||||
							
								
								
									
										21
									
								
								Makefile.dev
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								Makefile.dev
									
									
									
									
									
								
							| @@ -1,21 +0,0 @@ | |||||||
| # Entorno de desarrollo |  | ||||||
| # |  | ||||||
| # solo es necesario una vez: |  | ||||||
| #  * make -f Makefile.dev dev-setup |  | ||||||
| # |  | ||||||
| # luego se pueden ejecutar las pruebas: |  | ||||||
| #  * make -f Makefile.dev test |  | ||||||
|  |  | ||||||
| .PHONY: dev-setup dev-shell py-develop test tox |  | ||||||
|  |  | ||||||
| dev-setup: |  | ||||||
| 	docker build -t facho . |  | ||||||
|  |  | ||||||
| dev-shell: |  | ||||||
| 	docker run --rm -ti -v "$(PWD):/app" -w /app --name facho-cli facho bash |  | ||||||
|  |  | ||||||
| test: |  | ||||||
| 	docker run -t -v $(PWD):/app -w /app facho sh -c 'cd /app; python3.7 setup.py test' |  | ||||||
|  |  | ||||||
| tox: |  | ||||||
| 	docker run -it -v $(PWD)/:/app -w /app facho tox |  | ||||||
							
								
								
									
										20
									
								
								README.rst
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								README.rst
									
									
									
									
									
								
							| @@ -2,6 +2,8 @@ | |||||||
| facho | facho | ||||||
| ===== | ===== | ||||||
|  |  | ||||||
|  | !!INESTABLE NO RECOMENDAMOS USO PARA PRODUCION!! | ||||||
|  |  | ||||||
| Libreria para facturacion electronica colombia. | Libreria para facturacion electronica colombia. | ||||||
|  |  | ||||||
| - facho/facho.py: abstracion para manipulacion del XML | - facho/facho.py: abstracion para manipulacion del XML | ||||||
| @@ -22,7 +24,7 @@ usando pip:: | |||||||
| CLI | CLI | ||||||
| === | === | ||||||
|  |  | ||||||
| tambien se provee linea de comandos **facho** para generacion, firmado y envio de documentos:: | tambien se provee linea de comandos **facho** para firmado y envio de documentos:: | ||||||
|   facho --help |   facho --help | ||||||
|  |  | ||||||
| CONTRIBUIR | CONTRIBUIR | ||||||
| @@ -30,13 +32,17 @@ CONTRIBUIR | |||||||
|  |  | ||||||
| ver **CONTRIBUTING.rst** | ver **CONTRIBUTING.rst** | ||||||
|  |  | ||||||
| USO |  | ||||||
| === |  | ||||||
|  |  | ||||||
| ver **USAGE.rst** |  | ||||||
|  |  | ||||||
|  |  | ||||||
| DIAN HABILITACION | DIAN HABILITACION | ||||||
| ================= | ================= | ||||||
|  |  | ||||||
| guia oficial actualizada al 2020-04-20: https://www.dian.gov.co/fizcalizacioncontrol/herramienconsulta/FacturaElectronica/Facturaci%C3%B3n_Gratuita_DIAN/Documents/Guia_usuario_08052019.pdf#search=numeracion | guia oficial actualizada al 2020-04-20: https://www.dian.gov.co/fizcalizacioncontrol/herramienconsulta/FacturaElectronica/Facturaci%C3%B3n_Gratuita_DIAN/Documents/Guia_usuario_08052019.pdf#search=numeracion | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ERROR X509SerialNumber | ||||||
|  | ====================== | ||||||
|  |  | ||||||
|  |  | ||||||
|  | lxml.etree.DocumentInvalid: Element '{http://www.w3.org/2000/09/xmldsig#}X509SerialNumber': '632837201711293159666920255411738137494572618415' is not a valid value of the atomic type 'xs:integer' | ||||||
|  |  | ||||||
|  | Actualmente el xmlschema usado por xmlsig para el campo X509SerialNumber es tipo | ||||||
|  | integer ahi que parchar manualmente a tipo string, en el archivo site-packages/xmlsig/data/xmldsig-core-schema.xsd. | ||||||
|   | |||||||
							
								
								
									
										24
									
								
								USAGE.rst
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								USAGE.rst
									
									
									
									
									
								
							| @@ -1,24 +0,0 @@ | |||||||
| uso de la libreria |  | ||||||
| ================== |  | ||||||
|  |  | ||||||
| **facho** es tanto una libreria para modelar y generar los documentos xml requeridos para la facturacion, |  | ||||||
| asi como una herramienta de **consola** para facilitar algunas actividades como: generaciones de xml |  | ||||||
| apartir de una especificacion en python, comprimir y enviar archivos según el SOAP vigente. |  | ||||||
|  |  | ||||||
| **facho** es diseñado para ser usado en conjunto con el documento **docs/DIAN/Anexo_Tecnico_Factura_Electronica_Vr1_7_2020.pdf**, ya que en gran medida sigue la terminologia presente en este. |  | ||||||
|  |  | ||||||
|  |  | ||||||
| Para ejemplos ver **examples/** . |  | ||||||
|  |  | ||||||
| En terminos generales seria modelar la factura usando **facho/fe/form.py**, instanciar las extensiones requeridas ver **facho/fe/fe.py** y |  | ||||||
| una vez generado el objeto invoice y las extensiones requeridas se procede a crear el XML, ejemplo: |  | ||||||
|  |  | ||||||
| ~~~python |  | ||||||
| .... |  | ||||||
| xml = form_xml.DIANInvoiceXML(invoice) |  | ||||||
| extensions = module.extensions(invoice) |  | ||||||
| for extension in extensions: |  | ||||||
|   xml.add_extension(extension) |  | ||||||
|  |  | ||||||
| form_xml.DIANWriteSigned(xml, "factura.xml", "llave privada", "frase") |  | ||||||
| ~~~ |  | ||||||
										
											Binary file not shown.
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -1,13 +0,0 @@ | |||||||
| # notas |  | ||||||
|  |  | ||||||
| * se extrae documento tecnico de resolucion usando **pdfarranger** |  | ||||||
|  |  | ||||||
| ## CUNE |  | ||||||
|  |  | ||||||
|  ver 8.1.1.1 del archivo **Resolucion 000013 de 11-02-2021.pdf** |  | ||||||
|  |  | ||||||
| # enlaces |  | ||||||
|  |  | ||||||
| * https://www.dian.gov.co/impuestos/Paginas/Sistema-de-Factura-Electronica/documento-soporte-de-pago-de-nomina-electronica.aspx |  | ||||||
| * https://bitbucket.org/presik/electronic_payroll.git |  | ||||||
| * https://bitbucket.org/presik/trytonpsk-staff_payroll_co.git |  | ||||||
										
											Binary file not shown.
										
									
								
							| @@ -1,117 +0,0 @@ | |||||||
| # este archivo es un ejemplo para le generacion |  | ||||||
| # una factura de venta nacional usando el comando **facho**. |  | ||||||
| # |  | ||||||
| # ejemplo: facho generate-invoice generate-invoice-from-cli.py |  | ||||||
| # |  | ||||||
| # importar libreria de modelos |  | ||||||
| from facho.fe import form |  | ||||||
| from facho.fe import form_xml |  | ||||||
|  |  | ||||||
| # importar libreria extensiones xml para cumplir decreto |  | ||||||
| from facho.fe import fe |  | ||||||
|  |  | ||||||
| # importar otras necesarias |  | ||||||
| from datetime import datetime, date |  | ||||||
|  |  | ||||||
| # Datos del fomulario del SET de pruebas |  | ||||||
| INVOICE_AUTHORIZATION = '181360000001' #Número suministrado por la Dian en el momento de la creación del SET de Pruebas   |  | ||||||
| ID_SOFTWARE = '57bcb6d1-c591-5a90-b80a-cb030ec91440' #Id suministrado por la Dian en el momento de la creación del SET de Pruebas   |  | ||||||
| PIN = '19642' #Número creado por la empresa para poder crear el SET de pruebas |  | ||||||
| CLAVE_TECNICA = 'fc9eac422eba16e21ffd8c5f94b3f30a6e38162d' ##Id suministrado por la Dian en el momento de la creación del SET de Pruebas   |  | ||||||
|  |  | ||||||
|  |  | ||||||
| # callback que retonar las extensiones XML necesarias |  | ||||||
| # para que el documento final XML cumpla el decreto. |  | ||||||
| # |  | ||||||
| # muchos de los valores usados son obtenidos |  | ||||||
| # del servicio web de la DIAN. |  | ||||||
| def extensions(inv): |  | ||||||
|     security_code = fe.DianXMLExtensionSoftwareSecurityCode(ID_SOFTWARE, PIN, inv.invoice_ident) |  | ||||||
|     authorization_provider = fe.DianXMLExtensionAuthorizationProvider() |  | ||||||
|     cufe = fe.DianXMLExtensionCUFE(inv, CLAVE_TECNICA, fe.AMBIENTE_PRUEBAS) |  | ||||||
|     software_provider = fe.DianXMLExtensionSoftwareProvider('nit_empresa', 'dígito_verificación', ID_SOFTWARE) |  | ||||||
|     inv_authorization = fe.DianXMLExtensionInvoiceAuthorization(INVOICE_AUTHORIZATION, |  | ||||||
|                                                                 datetime(2019, 1, 19),#Datos toamdos de  |  | ||||||
|                                                                 datetime(2030, 1, 19),#la configuración  |  | ||||||
|                                                                 'SETP', 990000000, 995000000)#del SET de pruebas |  | ||||||
|     return [security_code, authorization_provider, cufe, software_provider, inv_authorization] |  | ||||||
|  |  | ||||||
| def invoice(): |  | ||||||
|     # factura de venta nacional |  | ||||||
|     inv = form.Invoice('01') |  | ||||||
|     # asignar periodo de facturacion |  | ||||||
|     inv.set_period(datetime.now(), datetime.now()) |  | ||||||
|     # asignar fecha de emision de la factura |  | ||||||
|     inv.set_issue(datetime.now()) |  | ||||||
|     # asignar prefijo y numero del documento |  | ||||||
|     inv.set_ident('SETP990000008') |  | ||||||
|     # asignar tipo de operacion ver DIAN:6.1.5 |  | ||||||
|     inv.set_operation_type('10') |  | ||||||
|     inv.set_supplier(form.Party( |  | ||||||
|         legal_name = 'Nombre registrado de la empresa', |  | ||||||
|         name = 'Nombre comercial o él mismo nombre registrado', |  | ||||||
|         ident = form.PartyIdentification('nit_empresa', 'digito_verificación', '31'), |  | ||||||
|         # obligaciones del contribuyente ver DIAN:FAK26 |  | ||||||
|         responsability_code = form.Responsability(['O-07', 'O-14', 'O-48']), |  | ||||||
|         # ver DIAN:FAJ28 |  | ||||||
|         responsability_regime_code = '48', |  | ||||||
|         # tipo de organizacion juridica ver DIAN:6.2.3 |  | ||||||
|         organization_code = '1', |  | ||||||
|         email = "correoempresa@correoempresa.correo", |  | ||||||
|         address = form.Address( |  | ||||||
|             '', '', form.City('05001', 'Medellín'), |  | ||||||
|             form.Country('CO', 'Colombia'), |  | ||||||
|             form.CountrySubentity('05', 'Antioquia')), |  | ||||||
|     )) |  | ||||||
|     #Tercero a quien se le factura |  | ||||||
|     inv.set_customer(form.Party( |  | ||||||
|         legal_name = 'consumidor final', |  | ||||||
|         name = 'consumidor final', |  | ||||||
|         ident = form.PartyIdentification('222222222222', '', '13'), |  | ||||||
|         responsability_code = form.Responsability(['R-99-PN']), |  | ||||||
|         responsability_regime_code = '49', |  | ||||||
|         organization_code = '2', |  | ||||||
|         email = "consumidor_final0final.final", |  | ||||||
|         address = form.Address( |  | ||||||
|             '', '', form.City('05001', 'Medellín'), |  | ||||||
|             form.Country('CO', 'Colombia'), |  | ||||||
|             form.CountrySubentity('05', 'Antioquia')), |  | ||||||
| 		#tax_scheme = form.TaxScheme('01', 'IVA') |  | ||||||
|     )) |  | ||||||
|     # asignar metodo de pago     |  | ||||||
|     inv.set_payment_mean(form.PaymentMean( |  | ||||||
|         # metodo de pago ver DIAN:3.4.1 |  | ||||||
|         id = '1', |  | ||||||
|         # codigo correspondiente al medio de pago ver DIAN:3.4.2 |  | ||||||
|         code = '20', |  | ||||||
|         # fecha de vencimiento de la factura         |  | ||||||
|         due_at = datetime.now(), |  | ||||||
|         # identificador numerico |  | ||||||
|         payment_id = '2' |  | ||||||
|     )) |  | ||||||
|     # adicionar una linea al documento |  | ||||||
|     inv.add_invoice_line(form.InvoiceLine( |  | ||||||
|         quantity = form.Quantity(int(20.5), '94'), |  | ||||||
|         # item general de codigo 999 |  | ||||||
|         description = 'productO3', |  | ||||||
|         item = form.StandardItem('test', 9999), |  | ||||||
|         price = form.Price( |  | ||||||
|             # precio base del item (sin iva) |  | ||||||
|             amount = form.Amount(200.00), |  | ||||||
|             # ver DIAN:6.3.5.1 |  | ||||||
|             type_code = '01', |  | ||||||
|             type = 'x' |  | ||||||
|         ), |  | ||||||
|         tax = form.TaxTotal( |  | ||||||
|             subtotals = [ |  | ||||||
|                 form.TaxSubTotal( |  | ||||||
|                     percent = 19.00, |  | ||||||
|                     scheme=form.TaxScheme('01') |  | ||||||
|                 ) |  | ||||||
|             ] |  | ||||||
|         ) |  | ||||||
|     )) |  | ||||||
|     return inv |  | ||||||
|  |  | ||||||
| def document_xml(): |  | ||||||
|     return form_xml.DIANInvoiceXML |  | ||||||
							
								
								
									
										74
									
								
								examples/generate-invoice-invoice.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								examples/generate-invoice-invoice.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | |||||||
|  | import facho.fe.form as form | ||||||
|  | from facho.fe import fe | ||||||
|  | from datetime import datetime | ||||||
|  |  | ||||||
|  | def extensions(inv): | ||||||
|  |     nit = form.PartyIdentification('nit', '5', '31') | ||||||
|  |     security_code = fe.DianXMLExtensionSoftwareSecurityCode('id software', 'pin', inv.invoice_ident) | ||||||
|  |     authorization_provider = fe.DianXMLExtensionAuthorizationProvider() | ||||||
|  |     cufe = fe.DianXMLExtensionCUFE(inv, fe.DianXMLExtensionCUFE.AMBIENTE_PRUEBAS, | ||||||
|  |                                    'clave tecnica') | ||||||
|  |     software_provider = fe.DianXMLExtensionSoftwareProvider(nit, nit.dv, 'id software') | ||||||
|  |     inv_authorization = fe.DianXMLExtensionInvoiceAuthorization('invoice autorization', | ||||||
|  |                                                                 datetime(2019, 1, 19), | ||||||
|  |                                                                 datetime(2030, 1, 19), | ||||||
|  |                                                                 'SETP', 990000001, 995000000) | ||||||
|  |     return [security_code, authorization_provider, cufe, software_provider, inv_authorization] | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def invoice(): | ||||||
|  |     inv = form.Invoice() | ||||||
|  |     inv.set_period(datetime.now(), datetime.now()) | ||||||
|  |     inv.set_issue(datetime.now()) | ||||||
|  |     inv.set_ident('SETP990003033') | ||||||
|  |     inv.set_operation_type('10') | ||||||
|  |     inv.set_supplier(form.Party( | ||||||
|  |         legal_name = 'FACHO SOS', | ||||||
|  |         name = 'FACHO SOS', | ||||||
|  |         ident = form.PartyIdentification('900579212', '5', '31'), | ||||||
|  |         responsability_code = form.Responsability(['O-07', 'O-09', 'O-14', 'O-48']), | ||||||
|  |         responsability_regime_code = '48', | ||||||
|  |         organization_code = '1', | ||||||
|  |         email = "sdds@sd.com", | ||||||
|  |         address = form.Address( | ||||||
|  |             '', '', form.City('05001', 'Medellín'), | ||||||
|  |             form.Country('CO', 'Colombia'), | ||||||
|  |             form.CountrySubentity('05', 'Antioquia')) | ||||||
|  |     )) | ||||||
|  |     inv.set_customer(form.Party( | ||||||
|  |         legal_name = 'facho-customer', | ||||||
|  |         name = 'facho-customer', | ||||||
|  |         ident = form.PartyIdentification('999999999', '', '13'), | ||||||
|  |         responsability_code = form.Responsability(['R-99-PN']), | ||||||
|  |         responsability_regime_code = '49', | ||||||
|  |         organization_code = '2', | ||||||
|  |         email = "sdds@sd.com", | ||||||
|  |         address = form.Address( | ||||||
|  |             '', '', form.City('05001', 'Medellín'), | ||||||
|  |             form.Country('CO', 'Colombia'), | ||||||
|  |             form.CountrySubentity('05', 'Antioquia')) | ||||||
|  |     )) | ||||||
|  |     inv.set_payment_mean(form.PaymentMean( | ||||||
|  |         id = '1', | ||||||
|  |         code = '10', | ||||||
|  |         due_at = datetime.now(), | ||||||
|  |         payment_id = '1' | ||||||
|  |     )) | ||||||
|  |     inv.add_invoice_line(form.InvoiceLine( | ||||||
|  |         quantity = form.Quantity(1, '94'), | ||||||
|  |         description = 'producto facho', | ||||||
|  |         item = form.StandardItem('test', 9999), | ||||||
|  |         price = form.Price( | ||||||
|  |             amount = form.Amount(100.00), | ||||||
|  |             type_code = '01', | ||||||
|  |             type = 'x' | ||||||
|  |         ), | ||||||
|  |         tax = form.TaxTotal( | ||||||
|  |             subtotals = [ | ||||||
|  |                 form.TaxSubTotal( | ||||||
|  |                     percent = 19.00, | ||||||
|  |                 ) | ||||||
|  |             ] | ||||||
|  |         ) | ||||||
|  |     )) | ||||||
|  |     return inv | ||||||
| @@ -1,93 +0,0 @@ | |||||||
|  |  | ||||||
| from facho import fe |  | ||||||
|  |  | ||||||
| def extensions(nomina): |  | ||||||
|     return [] |  | ||||||
|  |  | ||||||
| def nomina(): |  | ||||||
|     nomina = fe.nomina.DIANNominaIndividual() |  | ||||||
|  |  | ||||||
|     nomina.asignar_metadata(fe.nomina.Metadata( |  | ||||||
|         secuencia=fe.nomina.NumeroSecuencia( |  | ||||||
|             numero = 'N00001', |  | ||||||
|             consecutivo=232 |  | ||||||
|         ), |  | ||||||
|         lugar_generacion=fe.nomina.Lugar( |  | ||||||
|             pais = fe.nomina.Pais( |  | ||||||
|                 code = 'CO' |  | ||||||
|             ), |  | ||||||
|             departamento = fe.nomina.Departamento( |  | ||||||
|                 code = '05' |  | ||||||
|             ), |  | ||||||
|             municipio = fe.nomina.Municipio( |  | ||||||
|                 code = '05001' |  | ||||||
|             ), |  | ||||||
|         ), |  | ||||||
|         proveedor=fe.nomina.Proveedor( |  | ||||||
|             nit='999999', |  | ||||||
|             dv=2, |  | ||||||
|             software_id='xx', |  | ||||||
|             software_sc='yy' |  | ||||||
|         ) |  | ||||||
|     )) |  | ||||||
|  |  | ||||||
|     nomina.asignar_informacion_general(fe.nomina.InformacionGeneral( |  | ||||||
|         fecha_generacion = '2020-01-16', |  | ||||||
|         hora_generacion = '1053:10-05:00', |  | ||||||
|         tipo_ambiente = fe.nomina.InformacionGeneral.AMBIENTE_PRODUCCION, |  | ||||||
|         software_pin = '693', |  | ||||||
|         periodo_nomina = fe.nomina.PeriodoNomina(code='1'), |  | ||||||
|         tipo_moneda = fe.nomina.TipoMoneda(code='COP') |  | ||||||
|     )) |  | ||||||
|  |  | ||||||
|     nomina.asignar_empleador(fe.nomina.Empleador( |  | ||||||
|         nit = '700085371', |  | ||||||
|         dv = '1', |  | ||||||
|         pais = fe.nomina.Pais( |  | ||||||
|             code = 'CO' |  | ||||||
|         ), |  | ||||||
|         departamento = fe.nomina.Departamento( |  | ||||||
|             code = '05' |  | ||||||
|         ), |  | ||||||
|         municipio = fe.nomina.Municipio( |  | ||||||
|             code = '05001' |  | ||||||
|         ), |  | ||||||
|         direccion = 'calle etrivial' |  | ||||||
|     )) |  | ||||||
|  |  | ||||||
|     nomina.asignar_trabajador(fe.nomina.Trabajador( |  | ||||||
|         tipo_contrato = fe.nomina.TipoContrato( |  | ||||||
|             code = '1' |  | ||||||
|         ), |  | ||||||
|         alto_riesgo = False, |  | ||||||
|         tipo_documento = fe.nomina.TipoDocumento( |  | ||||||
|             code = '11' |  | ||||||
|         ), |  | ||||||
|         primer_apellido = 'gnu', |  | ||||||
|         segundo_apellido = 'emacs', |  | ||||||
|         primer_nombre = 'facho', |  | ||||||
|         lugar_trabajo = fe.nomina.LugarTrabajo( |  | ||||||
|             pais = fe.nomina.Pais(code='CO'), |  | ||||||
|             departamento = fe.nomina.Departamento(code='05'), |  | ||||||
|             municipio = fe.nomina.Municipio(code='05001'), |  | ||||||
|             direccion = 'calle facho' |  | ||||||
|         ), |  | ||||||
|         numero_documento = '800199436', |  | ||||||
|         tipo = fe.nomina.TipoTrabajador( |  | ||||||
|             code = '01' |  | ||||||
|         ), |  | ||||||
|         salario_integral = True, |  | ||||||
|         sueldo = fe.nomina.Amount(1_500_000) |  | ||||||
|     )) |  | ||||||
|  |  | ||||||
|     nomina.adicionar_devengado(fe.nomina.DevengadoBasico( |  | ||||||
|         dias_trabajados = 60, |  | ||||||
|         sueldo_trabajado = fe.nomina.Amount(3_500_000) |  | ||||||
|     )) |  | ||||||
|  |  | ||||||
|     nomina.adicionar_deduccion(fe.nomina.DeduccionSalud( |  | ||||||
|         porcentaje = fe.nomina.Amount(19), |  | ||||||
|         deduccion = fe.nomina.Amount(1_000_000) |  | ||||||
|     )) |  | ||||||
|  |  | ||||||
|     return nomina |  | ||||||
| @@ -1,114 +0,0 @@ | |||||||
| # importar libreria de modelos |  | ||||||
| import facho.fe.form as form |  | ||||||
| import facho.fe.form_xml |  | ||||||
|  |  | ||||||
| PRIVATE_KEY_PATH='ruta a mi llave privada' |  | ||||||
| PRIVATE_PASSPHRASE='clave de la llave privada' |  | ||||||
|  |  | ||||||
| # consultar las extensiones necesarias |  | ||||||
| def extensions(inv): |  | ||||||
|     security_code = fe.DianXMLExtensionSoftwareSecurityCode('id software', 'pin', inv.invoice_ident) |  | ||||||
|     authorization_provider = fe.DianXMLExtensionAuthorizationProvider() |  | ||||||
|     cufe = fe.DianXMLExtensionCUFE(inv, fe.DianXMLExtensionCUFE.AMBIENTE_PRUEBAS, |  | ||||||
|                                    'clave tecnica') |  | ||||||
|     nit = form.PartyIdentification('nit', '5', '31') |  | ||||||
|     software_provider = fe.DianXMLExtensionSoftwareProvider(nit, nit.dv, 'id software') |  | ||||||
|     inv_authorization = fe.DianXMLExtensionInvoiceAuthorization('invoice autorization', |  | ||||||
|                                                                 datetime(2019, 1, 19), |  | ||||||
|                                                                 datetime(2030, 1, 19), |  | ||||||
|                                                                 'SETP', 990000001, 995000000) |  | ||||||
|     return [security_code, authorization_provider, cufe, software_provider, inv_authorization] |  | ||||||
|  |  | ||||||
| # generar documento desde modelo a ruta indicada |  | ||||||
| def generate_document(invoice, filepath): |  | ||||||
|     xml = form_xml.DIANInvoiceXML(invoice) |  | ||||||
|     for extension in extensions(invoice): |  | ||||||
|         xml.add_extension(extension) |  | ||||||
|     form_xml.utils.DIANWriteSigned(xml, filepath, PRIVATE_KEY_PATH, PRIVATE_PASSPHRASE, True) |  | ||||||
|  |  | ||||||
| # Modelars las facturas |  | ||||||
| # ... |  | ||||||
|  |  | ||||||
| # factura de venta nacional |  | ||||||
| inv = form.NationalSalesInvoice() |  | ||||||
| # asignar periodo de facturacion |  | ||||||
| inv.set_period(datetime.now(), datetime.now()) |  | ||||||
| # asignar fecha de emision de la factura |  | ||||||
| inv.set_issue(datetime.now()) |  | ||||||
| # asignar prefijo y numero del documento |  | ||||||
| inv.set_ident('SETP990003033') |  | ||||||
| # asignar tipo de operacion ver DIAN:6.1.5 |  | ||||||
| inv.set_operation_type('10') |  | ||||||
| # asignar proveedor |  | ||||||
| inv.set_supplier(form.Party( |  | ||||||
|     legal_name = 'FACHO SOS', |  | ||||||
|     name = 'FACHO SOS', |  | ||||||
|     ident = form.PartyIdentification('900579212', '5', '31'), |  | ||||||
|     # obligaciones del contribuyente ver DIAN:FAK26 |  | ||||||
|     responsability_code = form.Responsability(['O-07', 'O-09', 'O-14', 'O-48']), |  | ||||||
|     # ver DIAN:FAJ28 |  | ||||||
|     responsability_regime_code = '48', |  | ||||||
|     # tipo de organizacion juridica ver DIAN:6.2.3 |  | ||||||
|     organization_code = '1', |  | ||||||
|     email = "sdds@sd.com", |  | ||||||
|     address = form.Address( |  | ||||||
|         name = '', |  | ||||||
|         street = '', |  | ||||||
|         city = form.City('05001', 'Medellín'), |  | ||||||
|         country = form.Country('CO', 'Colombia'), |  | ||||||
|         countrysubentity = form.CountrySubentity('05', 'Antioquia')) |  | ||||||
| )) |  | ||||||
| inv.set_customer(form.Party( |  | ||||||
|     legal_name = 'facho-customer', |  | ||||||
|     name = 'facho-customer', |  | ||||||
|     ident = form.PartyIdentification('999999999', '', '13'), |  | ||||||
|     responsability_code = form.Responsability(['R-99-PN']), |  | ||||||
|     responsability_regime_code = '49', |  | ||||||
|     organization_code = '2', |  | ||||||
|     email = "sdds@sd.com", |  | ||||||
|     address = form.Address( |  | ||||||
|         name = '', |  | ||||||
|         street = '', |  | ||||||
|         city = form.City('05001', 'Medellín'), |  | ||||||
|         country = form.Country('CO', 'Colombia'), |  | ||||||
|         countrysubentity = form.CountrySubentity('05', 'Antioquia')) |  | ||||||
| )) |  | ||||||
| # asignar metodo de pago |  | ||||||
| inv.set_payment_mean(form.PaymentMean( |  | ||||||
|     # metodo de pago ver DIAN:3.4.1 |  | ||||||
|     id = '1', |  | ||||||
|     # codigo correspondiente al medio de pago ver DIAN:3.4.2 |  | ||||||
|     code = '10', |  | ||||||
|     # fecha de vencimiento de la factura |  | ||||||
|     due_at = datetime.now(), |  | ||||||
|      |  | ||||||
|     # identificador numerico |  | ||||||
|     payment_id = '1' |  | ||||||
| )) |  | ||||||
| # adicionar una linea al documento |  | ||||||
| inv.add_invoice_line(form.InvoiceLine( |  | ||||||
|     quantity = form.Quantity(1, '94'), |  | ||||||
|     description = 'producto facho', |  | ||||||
|     # item general de codigo 999 |  | ||||||
|     item = form.StandardItem('test', 9999), |  | ||||||
|     price = form.Price( |  | ||||||
|         # precio base del tiem |  | ||||||
|         amount = form.Amount(100.00), |  | ||||||
|         # ver DIAN:6.3.5.1 |  | ||||||
|         type_code = '01', |  | ||||||
|         type = 'x' |  | ||||||
|     ), |  | ||||||
|     tax = form.TaxTotal( |  | ||||||
|         subtotals = [ |  | ||||||
|             form.TaxSubTotal( |  | ||||||
|                 percent = 19.00, |  | ||||||
|             ) |  | ||||||
|         ] |  | ||||||
|     ) |  | ||||||
| )) |  | ||||||
|  |  | ||||||
| # refrescar valores de la factura |  | ||||||
| inv.calculate() |  | ||||||
|  |  | ||||||
| # generar el documento xml en la ruta indicada |  | ||||||
| generate_document(inv, 'ruta a donde guardar el .xml') |  | ||||||
| @@ -1,674 +0,0 @@ | |||||||
|                     GNU GENERAL PUBLIC LICENSE |  | ||||||
|                        Version 3, 29 June 2007 |  | ||||||
|  |  | ||||||
|  Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> |  | ||||||
|  Everyone is permitted to copy and distribute verbatim copies |  | ||||||
|  of this license document, but changing it is not allowed. |  | ||||||
|  |  | ||||||
|                             Preamble |  | ||||||
|  |  | ||||||
|   The GNU General Public License is a free, copyleft license for |  | ||||||
| software and other kinds of works. |  | ||||||
|  |  | ||||||
|   The licenses for most software and other practical works are designed |  | ||||||
| to take away your freedom to share and change the works.  By contrast, |  | ||||||
| the GNU General Public License is intended to guarantee your freedom to |  | ||||||
| share and change all versions of a program--to make sure it remains free |  | ||||||
| software for all its users.  We, the Free Software Foundation, use the |  | ||||||
| GNU General Public License for most of our software; it applies also to |  | ||||||
| any other work released this way by its authors.  You can apply it to |  | ||||||
| your programs, too. |  | ||||||
|  |  | ||||||
|   When we speak of free software, we are referring to freedom, not |  | ||||||
| price.  Our General Public Licenses are designed to make sure that you |  | ||||||
| have the freedom to distribute copies of free software (and charge for |  | ||||||
| them if you wish), that you receive source code or can get it if you |  | ||||||
| want it, that you can change the software or use pieces of it in new |  | ||||||
| free programs, and that you know you can do these things. |  | ||||||
|  |  | ||||||
|   To protect your rights, we need to prevent others from denying you |  | ||||||
| these rights or asking you to surrender the rights.  Therefore, you have |  | ||||||
| certain responsibilities if you distribute copies of the software, or if |  | ||||||
| you modify it: responsibilities to respect the freedom of others. |  | ||||||
|  |  | ||||||
|   For example, if you distribute copies of such a program, whether |  | ||||||
| gratis or for a fee, you must pass on to the recipients the same |  | ||||||
| freedoms that you received.  You must make sure that they, too, receive |  | ||||||
| or can get the source code.  And you must show them these terms so they |  | ||||||
| know their rights. |  | ||||||
|  |  | ||||||
|   Developers that use the GNU GPL protect your rights with two steps: |  | ||||||
| (1) assert copyright on the software, and (2) offer you this License |  | ||||||
| giving you legal permission to copy, distribute and/or modify it. |  | ||||||
|  |  | ||||||
|   For the developers' and authors' protection, the GPL clearly explains |  | ||||||
| that there is no warranty for this free software.  For both users' and |  | ||||||
| authors' sake, the GPL requires that modified versions be marked as |  | ||||||
| changed, so that their problems will not be attributed erroneously to |  | ||||||
| authors of previous versions. |  | ||||||
|  |  | ||||||
|   Some devices are designed to deny users access to install or run |  | ||||||
| modified versions of the software inside them, although the manufacturer |  | ||||||
| can do so.  This is fundamentally incompatible with the aim of |  | ||||||
| protecting users' freedom to change the software.  The systematic |  | ||||||
| pattern of such abuse occurs in the area of products for individuals to |  | ||||||
| use, which is precisely where it is most unacceptable.  Therefore, we |  | ||||||
| have designed this version of the GPL to prohibit the practice for those |  | ||||||
| products.  If such problems arise substantially in other domains, we |  | ||||||
| stand ready to extend this provision to those domains in future versions |  | ||||||
| of the GPL, as needed to protect the freedom of users. |  | ||||||
|  |  | ||||||
|   Finally, every program is threatened constantly by software patents. |  | ||||||
| States should not allow patents to restrict development and use of |  | ||||||
| software on general-purpose computers, but in those that do, we wish to |  | ||||||
| avoid the special danger that patents applied to a free program could |  | ||||||
| make it effectively proprietary.  To prevent this, the GPL assures that |  | ||||||
| patents cannot be used to render the program non-free. |  | ||||||
|  |  | ||||||
|   The precise terms and conditions for copying, distribution and |  | ||||||
| modification follow. |  | ||||||
|  |  | ||||||
|                        TERMS AND CONDITIONS |  | ||||||
|  |  | ||||||
|   0. Definitions. |  | ||||||
|  |  | ||||||
|   "This License" refers to version 3 of the GNU General Public License. |  | ||||||
|  |  | ||||||
|   "Copyright" also means copyright-like laws that apply to other kinds of |  | ||||||
| works, such as semiconductor masks. |  | ||||||
|  |  | ||||||
|   "The Program" refers to any copyrightable work licensed under this |  | ||||||
| License.  Each licensee is addressed as "you".  "Licensees" and |  | ||||||
| "recipients" may be individuals or organizations. |  | ||||||
|  |  | ||||||
|   To "modify" a work means to copy from or adapt all or part of the work |  | ||||||
| in a fashion requiring copyright permission, other than the making of an |  | ||||||
| exact copy.  The resulting work is called a "modified version" of the |  | ||||||
| earlier work or a work "based on" the earlier work. |  | ||||||
|  |  | ||||||
|   A "covered work" means either the unmodified Program or a work based |  | ||||||
| on the Program. |  | ||||||
|  |  | ||||||
|   To "propagate" a work means to do anything with it that, without |  | ||||||
| permission, would make you directly or secondarily liable for |  | ||||||
| infringement under applicable copyright law, except executing it on a |  | ||||||
| computer or modifying a private copy.  Propagation includes copying, |  | ||||||
| distribution (with or without modification), making available to the |  | ||||||
| public, and in some countries other activities as well. |  | ||||||
|  |  | ||||||
|   To "convey" a work means any kind of propagation that enables other |  | ||||||
| parties to make or receive copies.  Mere interaction with a user through |  | ||||||
| a computer network, with no transfer of a copy, is not conveying. |  | ||||||
|  |  | ||||||
|   An interactive user interface displays "Appropriate Legal Notices" |  | ||||||
| to the extent that it includes a convenient and prominently visible |  | ||||||
| feature that (1) displays an appropriate copyright notice, and (2) |  | ||||||
| tells the user that there is no warranty for the work (except to the |  | ||||||
| extent that warranties are provided), that licensees may convey the |  | ||||||
| work under this License, and how to view a copy of this License.  If |  | ||||||
| the interface presents a list of user commands or options, such as a |  | ||||||
| menu, a prominent item in the list meets this criterion. |  | ||||||
|  |  | ||||||
|   1. Source Code. |  | ||||||
|  |  | ||||||
|   The "source code" for a work means the preferred form of the work |  | ||||||
| for making modifications to it.  "Object code" means any non-source |  | ||||||
| form of a work. |  | ||||||
|  |  | ||||||
|   A "Standard Interface" means an interface that either is an official |  | ||||||
| standard defined by a recognized standards body, or, in the case of |  | ||||||
| interfaces specified for a particular programming language, one that |  | ||||||
| is widely used among developers working in that language. |  | ||||||
|  |  | ||||||
|   The "System Libraries" of an executable work include anything, other |  | ||||||
| than the work as a whole, that (a) is included in the normal form of |  | ||||||
| packaging a Major Component, but which is not part of that Major |  | ||||||
| Component, and (b) serves only to enable use of the work with that |  | ||||||
| Major Component, or to implement a Standard Interface for which an |  | ||||||
| implementation is available to the public in source code form.  A |  | ||||||
| "Major Component", in this context, means a major essential component |  | ||||||
| (kernel, window system, and so on) of the specific operating system |  | ||||||
| (if any) on which the executable work runs, or a compiler used to |  | ||||||
| produce the work, or an object code interpreter used to run it. |  | ||||||
|  |  | ||||||
|   The "Corresponding Source" for a work in object code form means all |  | ||||||
| the source code needed to generate, install, and (for an executable |  | ||||||
| work) run the object code and to modify the work, including scripts to |  | ||||||
| control those activities.  However, it does not include the work's |  | ||||||
| System Libraries, or general-purpose tools or generally available free |  | ||||||
| programs which are used unmodified in performing those activities but |  | ||||||
| which are not part of the work.  For example, Corresponding Source |  | ||||||
| includes interface definition files associated with source files for |  | ||||||
| the work, and the source code for shared libraries and dynamically |  | ||||||
| linked subprograms that the work is specifically designed to require, |  | ||||||
| such as by intimate data communication or control flow between those |  | ||||||
| subprograms and other parts of the work. |  | ||||||
|  |  | ||||||
|   The Corresponding Source need not include anything that users |  | ||||||
| can regenerate automatically from other parts of the Corresponding |  | ||||||
| Source. |  | ||||||
|  |  | ||||||
|   The Corresponding Source for a work in source code form is that |  | ||||||
| same work. |  | ||||||
|  |  | ||||||
|   2. Basic Permissions. |  | ||||||
|  |  | ||||||
|   All rights granted under this License are granted for the term of |  | ||||||
| copyright on the Program, and are irrevocable provided the stated |  | ||||||
| conditions are met.  This License explicitly affirms your unlimited |  | ||||||
| permission to run the unmodified Program.  The output from running a |  | ||||||
| covered work is covered by this License only if the output, given its |  | ||||||
| content, constitutes a covered work.  This License acknowledges your |  | ||||||
| rights of fair use or other equivalent, as provided by copyright law. |  | ||||||
|  |  | ||||||
|   You may make, run and propagate covered works that you do not |  | ||||||
| convey, without conditions so long as your license otherwise remains |  | ||||||
| in force.  You may convey covered works to others for the sole purpose |  | ||||||
| of having them make modifications exclusively for you, or provide you |  | ||||||
| with facilities for running those works, provided that you comply with |  | ||||||
| the terms of this License in conveying all material for which you do |  | ||||||
| not control copyright.  Those thus making or running the covered works |  | ||||||
| for you must do so exclusively on your behalf, under your direction |  | ||||||
| and control, on terms that prohibit them from making any copies of |  | ||||||
| your copyrighted material outside their relationship with you. |  | ||||||
|  |  | ||||||
|   Conveying under any other circumstances is permitted solely under |  | ||||||
| the conditions stated below.  Sublicensing is not allowed; section 10 |  | ||||||
| makes it unnecessary. |  | ||||||
|  |  | ||||||
|   3. Protecting Users' Legal Rights From Anti-Circumvention Law. |  | ||||||
|  |  | ||||||
|   No covered work shall be deemed part of an effective technological |  | ||||||
| measure under any applicable law fulfilling obligations under article |  | ||||||
| 11 of the WIPO copyright treaty adopted on 20 December 1996, or |  | ||||||
| similar laws prohibiting or restricting circumvention of such |  | ||||||
| measures. |  | ||||||
|  |  | ||||||
|   When you convey a covered work, you waive any legal power to forbid |  | ||||||
| circumvention of technological measures to the extent such circumvention |  | ||||||
| is effected by exercising rights under this License with respect to |  | ||||||
| the covered work, and you disclaim any intention to limit operation or |  | ||||||
| modification of the work as a means of enforcing, against the work's |  | ||||||
| users, your or third parties' legal rights to forbid circumvention of |  | ||||||
| technological measures. |  | ||||||
|  |  | ||||||
|   4. Conveying Verbatim Copies. |  | ||||||
|  |  | ||||||
|   You may convey verbatim copies of the Program's source code as you |  | ||||||
| receive it, in any medium, provided that you conspicuously and |  | ||||||
| appropriately publish on each copy an appropriate copyright notice; |  | ||||||
| keep intact all notices stating that this License and any |  | ||||||
| non-permissive terms added in accord with section 7 apply to the code; |  | ||||||
| keep intact all notices of the absence of any warranty; and give all |  | ||||||
| recipients a copy of this License along with the Program. |  | ||||||
|  |  | ||||||
|   You may charge any price or no price for each copy that you convey, |  | ||||||
| and you may offer support or warranty protection for a fee. |  | ||||||
|  |  | ||||||
|   5. Conveying Modified Source Versions. |  | ||||||
|  |  | ||||||
|   You may convey a work based on the Program, or the modifications to |  | ||||||
| produce it from the Program, in the form of source code under the |  | ||||||
| terms of section 4, provided that you also meet all of these conditions: |  | ||||||
|  |  | ||||||
|     a) The work must carry prominent notices stating that you modified |  | ||||||
|     it, and giving a relevant date. |  | ||||||
|  |  | ||||||
|     b) The work must carry prominent notices stating that it is |  | ||||||
|     released under this License and any conditions added under section |  | ||||||
|     7.  This requirement modifies the requirement in section 4 to |  | ||||||
|     "keep intact all notices". |  | ||||||
|  |  | ||||||
|     c) You must license the entire work, as a whole, under this |  | ||||||
|     License to anyone who comes into possession of a copy.  This |  | ||||||
|     License will therefore apply, along with any applicable section 7 |  | ||||||
|     additional terms, to the whole of the work, and all its parts, |  | ||||||
|     regardless of how they are packaged.  This License gives no |  | ||||||
|     permission to license the work in any other way, but it does not |  | ||||||
|     invalidate such permission if you have separately received it. |  | ||||||
|  |  | ||||||
|     d) If the work has interactive user interfaces, each must display |  | ||||||
|     Appropriate Legal Notices; however, if the Program has interactive |  | ||||||
|     interfaces that do not display Appropriate Legal Notices, your |  | ||||||
|     work need not make them do so. |  | ||||||
|  |  | ||||||
|   A compilation of a covered work with other separate and independent |  | ||||||
| works, which are not by their nature extensions of the covered work, |  | ||||||
| and which are not combined with it such as to form a larger program, |  | ||||||
| in or on a volume of a storage or distribution medium, is called an |  | ||||||
| "aggregate" if the compilation and its resulting copyright are not |  | ||||||
| used to limit the access or legal rights of the compilation's users |  | ||||||
| beyond what the individual works permit.  Inclusion of a covered work |  | ||||||
| in an aggregate does not cause this License to apply to the other |  | ||||||
| parts of the aggregate. |  | ||||||
|  |  | ||||||
|   6. Conveying Non-Source Forms. |  | ||||||
|  |  | ||||||
|   You may convey a covered work in object code form under the terms |  | ||||||
| of sections 4 and 5, provided that you also convey the |  | ||||||
| machine-readable Corresponding Source under the terms of this License, |  | ||||||
| in one of these ways: |  | ||||||
|  |  | ||||||
|     a) Convey the object code in, or embodied in, a physical product |  | ||||||
|     (including a physical distribution medium), accompanied by the |  | ||||||
|     Corresponding Source fixed on a durable physical medium |  | ||||||
|     customarily used for software interchange. |  | ||||||
|  |  | ||||||
|     b) Convey the object code in, or embodied in, a physical product |  | ||||||
|     (including a physical distribution medium), accompanied by a |  | ||||||
|     written offer, valid for at least three years and valid for as |  | ||||||
|     long as you offer spare parts or customer support for that product |  | ||||||
|     model, to give anyone who possesses the object code either (1) a |  | ||||||
|     copy of the Corresponding Source for all the software in the |  | ||||||
|     product that is covered by this License, on a durable physical |  | ||||||
|     medium customarily used for software interchange, for a price no |  | ||||||
|     more than your reasonable cost of physically performing this |  | ||||||
|     conveying of source, or (2) access to copy the |  | ||||||
|     Corresponding Source from a network server at no charge. |  | ||||||
|  |  | ||||||
|     c) Convey individual copies of the object code with a copy of the |  | ||||||
|     written offer to provide the Corresponding Source.  This |  | ||||||
|     alternative is allowed only occasionally and noncommercially, and |  | ||||||
|     only if you received the object code with such an offer, in accord |  | ||||||
|     with subsection 6b. |  | ||||||
|  |  | ||||||
|     d) Convey the object code by offering access from a designated |  | ||||||
|     place (gratis or for a charge), and offer equivalent access to the |  | ||||||
|     Corresponding Source in the same way through the same place at no |  | ||||||
|     further charge.  You need not require recipients to copy the |  | ||||||
|     Corresponding Source along with the object code.  If the place to |  | ||||||
|     copy the object code is a network server, the Corresponding Source |  | ||||||
|     may be on a different server (operated by you or a third party) |  | ||||||
|     that supports equivalent copying facilities, provided you maintain |  | ||||||
|     clear directions next to the object code saying where to find the |  | ||||||
|     Corresponding Source.  Regardless of what server hosts the |  | ||||||
|     Corresponding Source, you remain obligated to ensure that it is |  | ||||||
|     available for as long as needed to satisfy these requirements. |  | ||||||
|  |  | ||||||
|     e) Convey the object code using peer-to-peer transmission, provided |  | ||||||
|     you inform other peers where the object code and Corresponding |  | ||||||
|     Source of the work are being offered to the general public at no |  | ||||||
|     charge under subsection 6d. |  | ||||||
|  |  | ||||||
|   A separable portion of the object code, whose source code is excluded |  | ||||||
| from the Corresponding Source as a System Library, need not be |  | ||||||
| included in conveying the object code work. |  | ||||||
|  |  | ||||||
|   A "User Product" is either (1) a "consumer product", which means any |  | ||||||
| tangible personal property which is normally used for personal, family, |  | ||||||
| or household purposes, or (2) anything designed or sold for incorporation |  | ||||||
| into a dwelling.  In determining whether a product is a consumer product, |  | ||||||
| doubtful cases shall be resolved in favor of coverage.  For a particular |  | ||||||
| product received by a particular user, "normally used" refers to a |  | ||||||
| typical or common use of that class of product, regardless of the status |  | ||||||
| of the particular user or of the way in which the particular user |  | ||||||
| actually uses, or expects or is expected to use, the product.  A product |  | ||||||
| is a consumer product regardless of whether the product has substantial |  | ||||||
| commercial, industrial or non-consumer uses, unless such uses represent |  | ||||||
| the only significant mode of use of the product. |  | ||||||
|  |  | ||||||
|   "Installation Information" for a User Product means any methods, |  | ||||||
| procedures, authorization keys, or other information required to install |  | ||||||
| and execute modified versions of a covered work in that User Product from |  | ||||||
| a modified version of its Corresponding Source.  The information must |  | ||||||
| suffice to ensure that the continued functioning of the modified object |  | ||||||
| code is in no case prevented or interfered with solely because |  | ||||||
| modification has been made. |  | ||||||
|  |  | ||||||
|   If you convey an object code work under this section in, or with, or |  | ||||||
| specifically for use in, a User Product, and the conveying occurs as |  | ||||||
| part of a transaction in which the right of possession and use of the |  | ||||||
| User Product is transferred to the recipient in perpetuity or for a |  | ||||||
| fixed term (regardless of how the transaction is characterized), the |  | ||||||
| Corresponding Source conveyed under this section must be accompanied |  | ||||||
| by the Installation Information.  But this requirement does not apply |  | ||||||
| if neither you nor any third party retains the ability to install |  | ||||||
| modified object code on the User Product (for example, the work has |  | ||||||
| been installed in ROM). |  | ||||||
|  |  | ||||||
|   The requirement to provide Installation Information does not include a |  | ||||||
| requirement to continue to provide support service, warranty, or updates |  | ||||||
| for a work that has been modified or installed by the recipient, or for |  | ||||||
| the User Product in which it has been modified or installed.  Access to a |  | ||||||
| network may be denied when the modification itself materially and |  | ||||||
| adversely affects the operation of the network or violates the rules and |  | ||||||
| protocols for communication across the network. |  | ||||||
|  |  | ||||||
|   Corresponding Source conveyed, and Installation Information provided, |  | ||||||
| in accord with this section must be in a format that is publicly |  | ||||||
| documented (and with an implementation available to the public in |  | ||||||
| source code form), and must require no special password or key for |  | ||||||
| unpacking, reading or copying. |  | ||||||
|  |  | ||||||
|   7. Additional Terms. |  | ||||||
|  |  | ||||||
|   "Additional permissions" are terms that supplement the terms of this |  | ||||||
| License by making exceptions from one or more of its conditions. |  | ||||||
| Additional permissions that are applicable to the entire Program shall |  | ||||||
| be treated as though they were included in this License, to the extent |  | ||||||
| that they are valid under applicable law.  If additional permissions |  | ||||||
| apply only to part of the Program, that part may be used separately |  | ||||||
| under those permissions, but the entire Program remains governed by |  | ||||||
| this License without regard to the additional permissions. |  | ||||||
|  |  | ||||||
|   When you convey a copy of a covered work, you may at your option |  | ||||||
| remove any additional permissions from that copy, or from any part of |  | ||||||
| it.  (Additional permissions may be written to require their own |  | ||||||
| removal in certain cases when you modify the work.)  You may place |  | ||||||
| additional permissions on material, added by you to a covered work, |  | ||||||
| for which you have or can give appropriate copyright permission. |  | ||||||
|  |  | ||||||
|   Notwithstanding any other provision of this License, for material you |  | ||||||
| add to a covered work, you may (if authorized by the copyright holders of |  | ||||||
| that material) supplement the terms of this License with terms: |  | ||||||
|  |  | ||||||
|     a) Disclaiming warranty or limiting liability differently from the |  | ||||||
|     terms of sections 15 and 16 of this License; or |  | ||||||
|  |  | ||||||
|     b) Requiring preservation of specified reasonable legal notices or |  | ||||||
|     author attributions in that material or in the Appropriate Legal |  | ||||||
|     Notices displayed by works containing it; or |  | ||||||
|  |  | ||||||
|     c) Prohibiting misrepresentation of the origin of that material, or |  | ||||||
|     requiring that modified versions of such material be marked in |  | ||||||
|     reasonable ways as different from the original version; or |  | ||||||
|  |  | ||||||
|     d) Limiting the use for publicity purposes of names of licensors or |  | ||||||
|     authors of the material; or |  | ||||||
|  |  | ||||||
|     e) Declining to grant rights under trademark law for use of some |  | ||||||
|     trade names, trademarks, or service marks; or |  | ||||||
|  |  | ||||||
|     f) Requiring indemnification of licensors and authors of that |  | ||||||
|     material by anyone who conveys the material (or modified versions of |  | ||||||
|     it) with contractual assumptions of liability to the recipient, for |  | ||||||
|     any liability that these contractual assumptions directly impose on |  | ||||||
|     those licensors and authors. |  | ||||||
|  |  | ||||||
|   All other non-permissive additional terms are considered "further |  | ||||||
| restrictions" within the meaning of section 10.  If the Program as you |  | ||||||
| received it, or any part of it, contains a notice stating that it is |  | ||||||
| governed by this License along with a term that is a further |  | ||||||
| restriction, you may remove that term.  If a license document contains |  | ||||||
| a further restriction but permits relicensing or conveying under this |  | ||||||
| License, you may add to a covered work material governed by the terms |  | ||||||
| of that license document, provided that the further restriction does |  | ||||||
| not survive such relicensing or conveying. |  | ||||||
|  |  | ||||||
|   If you add terms to a covered work in accord with this section, you |  | ||||||
| must place, in the relevant source files, a statement of the |  | ||||||
| additional terms that apply to those files, or a notice indicating |  | ||||||
| where to find the applicable terms. |  | ||||||
|  |  | ||||||
|   Additional terms, permissive or non-permissive, may be stated in the |  | ||||||
| form of a separately written license, or stated as exceptions; |  | ||||||
| the above requirements apply either way. |  | ||||||
|  |  | ||||||
|   8. Termination. |  | ||||||
|  |  | ||||||
|   You may not propagate or modify a covered work except as expressly |  | ||||||
| provided under this License.  Any attempt otherwise to propagate or |  | ||||||
| modify it is void, and will automatically terminate your rights under |  | ||||||
| this License (including any patent licenses granted under the third |  | ||||||
| paragraph of section 11). |  | ||||||
|  |  | ||||||
|   However, if you cease all violation of this License, then your |  | ||||||
| license from a particular copyright holder is reinstated (a) |  | ||||||
| provisionally, unless and until the copyright holder explicitly and |  | ||||||
| finally terminates your license, and (b) permanently, if the copyright |  | ||||||
| holder fails to notify you of the violation by some reasonable means |  | ||||||
| prior to 60 days after the cessation. |  | ||||||
|  |  | ||||||
|   Moreover, your license from a particular copyright holder is |  | ||||||
| reinstated permanently if the copyright holder notifies you of the |  | ||||||
| violation by some reasonable means, this is the first time you have |  | ||||||
| received notice of violation of this License (for any work) from that |  | ||||||
| copyright holder, and you cure the violation prior to 30 days after |  | ||||||
| your receipt of the notice. |  | ||||||
|  |  | ||||||
|   Termination of your rights under this section does not terminate the |  | ||||||
| licenses of parties who have received copies or rights from you under |  | ||||||
| this License.  If your rights have been terminated and not permanently |  | ||||||
| reinstated, you do not qualify to receive new licenses for the same |  | ||||||
| material under section 10. |  | ||||||
|  |  | ||||||
|   9. Acceptance Not Required for Having Copies. |  | ||||||
|  |  | ||||||
|   You are not required to accept this License in order to receive or |  | ||||||
| run a copy of the Program.  Ancillary propagation of a covered work |  | ||||||
| occurring solely as a consequence of using peer-to-peer transmission |  | ||||||
| to receive a copy likewise does not require acceptance.  However, |  | ||||||
| nothing other than this License grants you permission to propagate or |  | ||||||
| modify any covered work.  These actions infringe copyright if you do |  | ||||||
| not accept this License.  Therefore, by modifying or propagating a |  | ||||||
| covered work, you indicate your acceptance of this License to do so. |  | ||||||
|  |  | ||||||
|   10. Automatic Licensing of Downstream Recipients. |  | ||||||
|  |  | ||||||
|   Each time you convey a covered work, the recipient automatically |  | ||||||
| receives a license from the original licensors, to run, modify and |  | ||||||
| propagate that work, subject to this License.  You are not responsible |  | ||||||
| for enforcing compliance by third parties with this License. |  | ||||||
|  |  | ||||||
|   An "entity transaction" is a transaction transferring control of an |  | ||||||
| organization, or substantially all assets of one, or subdividing an |  | ||||||
| organization, or merging organizations.  If propagation of a covered |  | ||||||
| work results from an entity transaction, each party to that |  | ||||||
| transaction who receives a copy of the work also receives whatever |  | ||||||
| licenses to the work the party's predecessor in interest had or could |  | ||||||
| give under the previous paragraph, plus a right to possession of the |  | ||||||
| Corresponding Source of the work from the predecessor in interest, if |  | ||||||
| the predecessor has it or can get it with reasonable efforts. |  | ||||||
|  |  | ||||||
|   You may not impose any further restrictions on the exercise of the |  | ||||||
| rights granted or affirmed under this License.  For example, you may |  | ||||||
| not impose a license fee, royalty, or other charge for exercise of |  | ||||||
| rights granted under this License, and you may not initiate litigation |  | ||||||
| (including a cross-claim or counterclaim in a lawsuit) alleging that |  | ||||||
| any patent claim is infringed by making, using, selling, offering for |  | ||||||
| sale, or importing the Program or any portion of it. |  | ||||||
|  |  | ||||||
|   11. Patents. |  | ||||||
|  |  | ||||||
|   A "contributor" is a copyright holder who authorizes use under this |  | ||||||
| License of the Program or a work on which the Program is based.  The |  | ||||||
| work thus licensed is called the contributor's "contributor version". |  | ||||||
|  |  | ||||||
|   A contributor's "essential patent claims" are all patent claims |  | ||||||
| owned or controlled by the contributor, whether already acquired or |  | ||||||
| hereafter acquired, that would be infringed by some manner, permitted |  | ||||||
| by this License, of making, using, or selling its contributor version, |  | ||||||
| but do not include claims that would be infringed only as a |  | ||||||
| consequence of further modification of the contributor version.  For |  | ||||||
| purposes of this definition, "control" includes the right to grant |  | ||||||
| patent sublicenses in a manner consistent with the requirements of |  | ||||||
| this License. |  | ||||||
|  |  | ||||||
|   Each contributor grants you a non-exclusive, worldwide, royalty-free |  | ||||||
| patent license under the contributor's essential patent claims, to |  | ||||||
| make, use, sell, offer for sale, import and otherwise run, modify and |  | ||||||
| propagate the contents of its contributor version. |  | ||||||
|  |  | ||||||
|   In the following three paragraphs, a "patent license" is any express |  | ||||||
| agreement or commitment, however denominated, not to enforce a patent |  | ||||||
| (such as an express permission to practice a patent or covenant not to |  | ||||||
| sue for patent infringement).  To "grant" such a patent license to a |  | ||||||
| party means to make such an agreement or commitment not to enforce a |  | ||||||
| patent against the party. |  | ||||||
|  |  | ||||||
|   If you convey a covered work, knowingly relying on a patent license, |  | ||||||
| and the Corresponding Source of the work is not available for anyone |  | ||||||
| to copy, free of charge and under the terms of this License, through a |  | ||||||
| publicly available network server or other readily accessible means, |  | ||||||
| then you must either (1) cause the Corresponding Source to be so |  | ||||||
| available, or (2) arrange to deprive yourself of the benefit of the |  | ||||||
| patent license for this particular work, or (3) arrange, in a manner |  | ||||||
| consistent with the requirements of this License, to extend the patent |  | ||||||
| license to downstream recipients.  "Knowingly relying" means you have |  | ||||||
| actual knowledge that, but for the patent license, your conveying the |  | ||||||
| covered work in a country, or your recipient's use of the covered work |  | ||||||
| in a country, would infringe one or more identifiable patents in that |  | ||||||
| country that you have reason to believe are valid. |  | ||||||
|  |  | ||||||
|   If, pursuant to or in connection with a single transaction or |  | ||||||
| arrangement, you convey, or propagate by procuring conveyance of, a |  | ||||||
| covered work, and grant a patent license to some of the parties |  | ||||||
| receiving the covered work authorizing them to use, propagate, modify |  | ||||||
| or convey a specific copy of the covered work, then the patent license |  | ||||||
| you grant is automatically extended to all recipients of the covered |  | ||||||
| work and works based on it. |  | ||||||
|  |  | ||||||
|   A patent license is "discriminatory" if it does not include within |  | ||||||
| the scope of its coverage, prohibits the exercise of, or is |  | ||||||
| conditioned on the non-exercise of one or more of the rights that are |  | ||||||
| specifically granted under this License.  You may not convey a covered |  | ||||||
| work if you are a party to an arrangement with a third party that is |  | ||||||
| in the business of distributing software, under which you make payment |  | ||||||
| to the third party based on the extent of your activity of conveying |  | ||||||
| the work, and under which the third party grants, to any of the |  | ||||||
| parties who would receive the covered work from you, a discriminatory |  | ||||||
| patent license (a) in connection with copies of the covered work |  | ||||||
| conveyed by you (or copies made from those copies), or (b) primarily |  | ||||||
| for and in connection with specific products or compilations that |  | ||||||
| contain the covered work, unless you entered into that arrangement, |  | ||||||
| or that patent license was granted, prior to 28 March 2007. |  | ||||||
|  |  | ||||||
|   Nothing in this License shall be construed as excluding or limiting |  | ||||||
| any implied license or other defenses to infringement that may |  | ||||||
| otherwise be available to you under applicable patent law. |  | ||||||
|  |  | ||||||
|   12. No Surrender of Others' Freedom. |  | ||||||
|  |  | ||||||
|   If conditions are imposed on you (whether by court order, agreement or |  | ||||||
| otherwise) that contradict the conditions of this License, they do not |  | ||||||
| excuse you from the conditions of this License.  If you cannot convey a |  | ||||||
| covered work so as to satisfy simultaneously your obligations under this |  | ||||||
| License and any other pertinent obligations, then as a consequence you may |  | ||||||
| not convey it at all.  For example, if you agree to terms that obligate you |  | ||||||
| to collect a royalty for further conveying from those to whom you convey |  | ||||||
| the Program, the only way you could satisfy both those terms and this |  | ||||||
| License would be to refrain entirely from conveying the Program. |  | ||||||
|  |  | ||||||
|   13. Use with the GNU Affero General Public License. |  | ||||||
|  |  | ||||||
|   Notwithstanding any other provision of this License, you have |  | ||||||
| permission to link or combine any covered work with a work licensed |  | ||||||
| under version 3 of the GNU Affero General Public License into a single |  | ||||||
| combined work, and to convey the resulting work.  The terms of this |  | ||||||
| License will continue to apply to the part which is the covered work, |  | ||||||
| but the special requirements of the GNU Affero General Public License, |  | ||||||
| section 13, concerning interaction through a network will apply to the |  | ||||||
| combination as such. |  | ||||||
|  |  | ||||||
|   14. Revised Versions of this License. |  | ||||||
|  |  | ||||||
|   The Free Software Foundation may publish revised and/or new versions of |  | ||||||
| the GNU General Public License from time to time.  Such new versions will |  | ||||||
| be similar in spirit to the present version, but may differ in detail to |  | ||||||
| address new problems or concerns. |  | ||||||
|  |  | ||||||
|   Each version is given a distinguishing version number.  If the |  | ||||||
| Program specifies that a certain numbered version of the GNU General |  | ||||||
| Public License "or any later version" applies to it, you have the |  | ||||||
| option of following the terms and conditions either of that numbered |  | ||||||
| version or of any later version published by the Free Software |  | ||||||
| Foundation.  If the Program does not specify a version number of the |  | ||||||
| GNU General Public License, you may choose any version ever published |  | ||||||
| by the Free Software Foundation. |  | ||||||
|  |  | ||||||
|   If the Program specifies that a proxy can decide which future |  | ||||||
| versions of the GNU General Public License can be used, that proxy's |  | ||||||
| public statement of acceptance of a version permanently authorizes you |  | ||||||
| to choose that version for the Program. |  | ||||||
|  |  | ||||||
|   Later license versions may give you additional or different |  | ||||||
| permissions.  However, no additional obligations are imposed on any |  | ||||||
| author or copyright holder as a result of your choosing to follow a |  | ||||||
| later version. |  | ||||||
|  |  | ||||||
|   15. Disclaimer of Warranty. |  | ||||||
|  |  | ||||||
|   THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY |  | ||||||
| APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT |  | ||||||
| HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY |  | ||||||
| OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, |  | ||||||
| THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |  | ||||||
| PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM |  | ||||||
| IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF |  | ||||||
| ALL NECESSARY SERVICING, REPAIR OR CORRECTION. |  | ||||||
|  |  | ||||||
|   16. Limitation of Liability. |  | ||||||
|  |  | ||||||
|   IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING |  | ||||||
| WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS |  | ||||||
| THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY |  | ||||||
| GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE |  | ||||||
| USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF |  | ||||||
| DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD |  | ||||||
| PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), |  | ||||||
| EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF |  | ||||||
| SUCH DAMAGES. |  | ||||||
|  |  | ||||||
|   17. Interpretation of Sections 15 and 16. |  | ||||||
|  |  | ||||||
|   If the disclaimer of warranty and limitation of liability provided |  | ||||||
| above cannot be given local legal effect according to their terms, |  | ||||||
| reviewing courts shall apply local law that most closely approximates |  | ||||||
| an absolute waiver of all civil liability in connection with the |  | ||||||
| Program, unless a warranty or assumption of liability accompanies a |  | ||||||
| copy of the Program in return for a fee. |  | ||||||
|  |  | ||||||
|                      END OF TERMS AND CONDITIONS |  | ||||||
|  |  | ||||||
|             How to Apply These Terms to Your New Programs |  | ||||||
|  |  | ||||||
|   If you develop a new program, and you want it to be of the greatest |  | ||||||
| possible use to the public, the best way to achieve this is to make it |  | ||||||
| free software which everyone can redistribute and change under these terms. |  | ||||||
|  |  | ||||||
|   To do so, attach the following notices to the program.  It is safest |  | ||||||
| to attach them to the start of each source file to most effectively |  | ||||||
| state the exclusion of warranty; and each file should have at least |  | ||||||
| the "copyright" line and a pointer to where the full notice is found. |  | ||||||
|  |  | ||||||
|     <one line to give the program's name and a brief idea of what it does.> |  | ||||||
|     Copyright (C) <year>  <name of author> |  | ||||||
|  |  | ||||||
|     This program is free software: you can redistribute it and/or modify |  | ||||||
|     it under the terms of the GNU General Public License as published by |  | ||||||
|     the Free Software Foundation, either version 3 of the License, or |  | ||||||
|     (at your option) any later version. |  | ||||||
|  |  | ||||||
|     This program is distributed in the hope that it will be useful, |  | ||||||
|     but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
|     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
|     GNU General Public License for more details. |  | ||||||
|  |  | ||||||
|     You should have received a copy of the GNU General Public License |  | ||||||
|     along with this program.  If not, see <https://www.gnu.org/licenses/>. |  | ||||||
|  |  | ||||||
| Also add information on how to contact you by electronic and paper mail. |  | ||||||
|  |  | ||||||
|   If the program does terminal interaction, make it output a short |  | ||||||
| notice like this when it starts in an interactive mode: |  | ||||||
|  |  | ||||||
|     facho-signer  Copyright (C) 2021  Jovany Leandro G.C <bit4bit@riseup.net> |  | ||||||
|     This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. |  | ||||||
|     This is free software, and you are welcome to redistribute it |  | ||||||
|     under certain conditions; type `show c' for details. |  | ||||||
|  |  | ||||||
| The hypothetical commands `show w' and `show c' should show the appropriate |  | ||||||
| parts of the General Public License.  Of course, your program's commands |  | ||||||
| might be different; for a GUI interface, you would use an "about box". |  | ||||||
|  |  | ||||||
|   You should also get your employer (if you work as a programmer) or school, |  | ||||||
| if any, to sign a "copyright disclaimer" for the program, if necessary. |  | ||||||
| For more information on this, and how to apply and follow the GNU GPL, see |  | ||||||
| <https://www.gnu.org/licenses/>. |  | ||||||
|  |  | ||||||
|   The GNU General Public License does not permit incorporating your program |  | ||||||
| into proprietary programs.  If your program is a subroutine library, you |  | ||||||
| may consider it more useful to permit linking proprietary applications with |  | ||||||
| the library.  If this is what you want to do, use the GNU Lesser General |  | ||||||
| Public License instead of this License.  But first, please read |  | ||||||
| <https://www.gnu.org/licenses/why-not-lgpl.html>. |  | ||||||
| @@ -1 +0,0 @@ | |||||||
| SUBDIRS = src |  | ||||||
| @@ -1,3 +0,0 @@ | |||||||
| #!/bin/sh |  | ||||||
| libtoolize -c --force |  | ||||||
| autoreconf --install --force |  | ||||||
| @@ -1,56 +0,0 @@ | |||||||
| #                                               -*- Autoconf -*- |  | ||||||
| # Process this file with autoconf to produce a configure script. |  | ||||||
|  |  | ||||||
| AC_PREREQ([2.71]) |  | ||||||
| AC_INIT([facho-signer], [0.0.1], [bit4bit@riseup.net]) |  | ||||||
| AM_INIT_AUTOMAKE |  | ||||||
| AC_CONFIG_SRCDIR([src/facho_signer.c]) |  | ||||||
| AC_CONFIG_HEADERS([config.h]) |  | ||||||
| AC_CONFIG_MACRO_DIRS([m4]) |  | ||||||
|  |  | ||||||
| # Checks for programs. |  | ||||||
| AC_PROG_CC |  | ||||||
|  |  | ||||||
| # Checks for libraries. |  | ||||||
| PKG_CHECK_MODULES([OPENSSL], [openssl]) |  | ||||||
| PKG_CHECK_MODULES([XMLSEC1], [xmlsec1-openssl], [ |  | ||||||
|                              AC_DEFINE([XMLSEC_CRYPTO_OPENSSL], [1], [enable crypto openssl]) |  | ||||||
|                              ]) |  | ||||||
| PKG_CHECK_MODULES([LZMA], [liblzma]) |  | ||||||
|  |  | ||||||
| AC_ARG_ENABLE([xmlsec-crypto-dynamic-loading], |  | ||||||
|         AS_HELP_STRING([--enable-xmlsec-crypto-dynamic-loading], |  | ||||||
|         [enable crypto xmlsec dynamic loading]) |  | ||||||
|        ) |  | ||||||
|  |  | ||||||
| if test "x$enable_xmlsec_crypto_dynamic_loading" == xyes; then |  | ||||||
|   AC_DEFINE([XMLSEC_CRYPTO_DYNAMIC_LOADING], [1], [enable xmlsec crypto dynamic loading]) |  | ||||||
|   AC_CHECK_HEADER([ltdl.h], [ |  | ||||||
| 		AC_CHECK_LIB( |  | ||||||
| 			[ltdl], |  | ||||||
| 			[lt_dlopenext], |  | ||||||
| 			[LIBLTDL=-lltdl], |  | ||||||
| 			[LIBLTDL=] |  | ||||||
| 			) |  | ||||||
| 		], [ LIBLTDL= ]) |  | ||||||
|  |  | ||||||
| else |  | ||||||
|   AC_DEFINE([XMLSEC_NO_CRYPTO_DYNAMIC_LOADING], [1], [disable xmlsec crypto dynamic loading]) |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| # Checks for header files. |  | ||||||
| AC_CHECK_HEADERS([sys/time.h unistd.h]) |  | ||||||
|  |  | ||||||
| # Checks for typedefs, structures, and compiler characteristics. |  | ||||||
| AC_TYPE_SIZE_T |  | ||||||
|  |  | ||||||
| # Checks for library functions. |  | ||||||
| AC_FUNC_MALLOC |  | ||||||
| AC_CHECK_FUNCS([clock_gettime gethrtime gettimeofday memset strdup]) |  | ||||||
|  |  | ||||||
| # libtool |  | ||||||
|  |  | ||||||
| LT_INIT |  | ||||||
|  |  | ||||||
| AC_CONFIG_FILES([Makefile src/Makefile]) |  | ||||||
| AC_OUTPUT |  | ||||||
| @@ -1,12 +0,0 @@ | |||||||
| SOURCES = xades/xmlsec1/xmltree.c xades/xmlsec1/errors.c xades/templates.c xades/xades.c facho_signer.c |  | ||||||
|  |  | ||||||
| lib_LTLIBRARIES = libfachosigner.la |  | ||||||
| libfachosigner_la_SOURCES = $(LTDL_SOURCE_FILES) $(SOURCES) |  | ||||||
| libfachosigner_la_CFLAGS = $(OPENSSL_CFLAGS) $(XMLSEC1_CFLAGS) -DXMLSEC_NOT_CRYPTO_DYNAMIC_LOADING |  | ||||||
| libfachosigner_la_LDFLAGS = $(OPENSSL_LIBS) $(LIBLTDL) $(XMLSEC1_LIBS) |  | ||||||
|  |  | ||||||
| bin_PROGRAMS = facho_signer |  | ||||||
| facho_signer_SOURCES = main.c |  | ||||||
| facho_signer_CFLAGS = $(OPENSSL_CFLAGS) $(XMLSEC1_CFLAGS) -DXMLSEC_NOT_CRYPTO_DYNAMIC_LOADING |  | ||||||
| facho_signer_LDADD = libfachosigner.la |  | ||||||
|  |  | ||||||
| @@ -1,11 +0,0 @@ | |||||||
| # facho-signer |  | ||||||
|  |  | ||||||
|  |  | ||||||
| ## guia |  | ||||||
|  |  | ||||||
| - http://xmlsoft.org/html/libxml-tree.html |  | ||||||
| - http://xmlsoft.org/html/libxml-xpath.html |  | ||||||
| - http://xmlsoft.org/examples/xpath1.c |  | ||||||
| - http://xmlsoft.org/tutorial/ar01s05.html |  | ||||||
| - https://www.aleksey.com/xmlsec/api/xmlsec-reference.html |  | ||||||
| - https://zakird.com/2013/10/13/certificate-parsing-with-openssl |  | ||||||
| @@ -1,371 +0,0 @@ | |||||||
| /** |  | ||||||
|  * This file is part of facho.  The COPYRIGHT file at the top level of |  | ||||||
|  * this repository contains the full copyright notices and license terms. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| #include "config.h" |  | ||||||
| #include "xades/xades.h" |  | ||||||
|  |  | ||||||
| #include <xmlsec/xmlsec.h> |  | ||||||
| #include <xmlsec/xmltree.h> |  | ||||||
| #include <xmlsec/xmldsig.h> |  | ||||||
| #include <xmlsec/templates.h> |  | ||||||
| #include <xmlsec/crypto.h> |  | ||||||
|  |  | ||||||
| #include <stdio.h> |  | ||||||
| #include <stdlib.h> |  | ||||||
|  |  | ||||||
| #define xmlFachoPrintError(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__) |  | ||||||
| #define xmlFachoPrintInfo(fmt, ...) fprintf(stdout, fmt, ##__VA_ARGS__) |  | ||||||
|  |  | ||||||
| static const xmlChar ublExtensionDSigNs[] = "urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"; |  | ||||||
| static const xmlChar policyIdDescription[] = "Política de firma para facturas electrónicas de la República de Colombia."; |  | ||||||
| static const xmlChar policyIdIdentifier[] = "https://facturaelectronica.dian.gov.co/politicadefirma/v2/politicadefirmav2.pdf"; |  | ||||||
|    |  | ||||||
| // crea elemento /Invoice/ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent |  | ||||||
| static xmlNodePtr |  | ||||||
| xmlFachoTmplUBLExtensionAddExtensionContent(xmlDocPtr doc); |  | ||||||
|  |  | ||||||
| // FeC requiere que el digest value del policy identifier sea |  | ||||||
| // apartir del contenido de la url. |  | ||||||
| static int |  | ||||||
| xmlFachoPolicyIdentifierCtxFromFilename(const xmlChar *, xmlSecBufferPtr); |  | ||||||
|  |  | ||||||
|  |  | ||||||
| static int |  | ||||||
| xmlFachoTmplXadesCreate(xmlDocPtr doc, xmlNodePtr signNode) { |  | ||||||
|   xmlNodePtr qualifyingPropertiesNode = NULL; |  | ||||||
|   xmlNodePtr signedPropertiesNode = NULL; |  | ||||||
|   xmlNodePtr signedSignaturePropertiesNode = NULL; |  | ||||||
|   xmlNodePtr signingCertificateNode = NULL; |  | ||||||
|   xmlNodePtr signaturePolicyIdentifierNode = NULL; |  | ||||||
|   xmlNodePtr signaturePolicyIdNode = NULL; |  | ||||||
|   xmlNodePtr sigPolicyIdNode = NULL; |  | ||||||
|   xmlNodePtr sigPolicyHashNode = NULL; |  | ||||||
|   xmlNodePtr signerRoleNode = NULL; |  | ||||||
|   xmlNodePtr refNode = NULL; |  | ||||||
|   const xmlChar signedPropertiesId[] = "xmldsig-facho-signed-props"; |  | ||||||
|   const xmlChar signedPropertiesRef[] = "#xmldsig-facho-signed-props"; |  | ||||||
|    |  | ||||||
|   qualifyingPropertiesNode = xmlXadesTmplQualifyingPropertiesCreate(doc, signNode, BAD_CAST "xades-ref1"); |  | ||||||
|   if (  qualifyingPropertiesNode == NULL ) { |  | ||||||
|     xmlFachoPrintError("error: failed to add QualifyingProperties node.\n"); |  | ||||||
|     goto fail; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   signedPropertiesNode = xmlXadesTmplAddSignedProperties(qualifyingPropertiesNode, signedPropertiesId); |  | ||||||
|   if ( signedPropertiesNode == NULL ) { |  | ||||||
|     xmlFachoPrintError("error: xades failed to add signed properties node.\n"); |  | ||||||
|     goto fail; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   refNode = xmlSecTmplSignatureAddReference(signNode, |  | ||||||
|                                             xmlSecTransformSha256Id, |  | ||||||
|                                             BAD_CAST "xmldsig-facho-ref1", |  | ||||||
|                                             signedPropertiesRef, |  | ||||||
|                                             BAD_CAST "http://uri.etsi.org/01903#SignedProperties"); |  | ||||||
|   if ( refNode == NULL ) { |  | ||||||
|     xmlFachoPrintError("error: failed to add reference to signature template xades.\n"); |  | ||||||
|     goto fail; |  | ||||||
|   } |  | ||||||
|   if ( xmlSecTmplReferenceAddTransform(refNode, xmlSecTransformInclC14NId) == NULL ) { |  | ||||||
|     xmlFachoPrintError("error: failed to add enveloped transform to reference for xades\n"); |  | ||||||
|     goto fail; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   const time_t now = time(NULL); |  | ||||||
|   signedSignaturePropertiesNode = xmlXadesTmplAddSignedSignatureProperties(signedPropertiesNode, localtime(&now)); |  | ||||||
|   if ( signedSignaturePropertiesNode == NULL ) { |  | ||||||
|     xmlFachoPrintError("error: xades failed to add signed signature properties node.\n"); |  | ||||||
|     goto fail; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   signingCertificateNode = xmlXadesTmplAddSigningCertificate(signedSignaturePropertiesNode, xmlSecTransformSha256Id); |  | ||||||
|   if ( signingCertificateNode == NULL ) { |  | ||||||
|     xmlFachoPrintError("error: failed to add SigningCertificate node \n"); |  | ||||||
|     goto fail; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   signaturePolicyIdentifierNode = xmlXadesTmplAddSignaturePolicyIdentifier(signedSignaturePropertiesNode); |  | ||||||
|   if ( signaturePolicyIdentifierNode == NULL ) { |  | ||||||
|     xmlFachoPrintError("error: failed to add PolicyIdentifier node\n"); |  | ||||||
|     goto fail; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   signaturePolicyIdNode = xmlXadesTmplAddSignaturePolicyId(signaturePolicyIdentifierNode); |  | ||||||
|   if ( signaturePolicyIdNode == NULL ) { |  | ||||||
|     xmlFachoPrintError("error: failed to add SignaturePolicyId node.\n"); |  | ||||||
|     goto fail; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   sigPolicyIdNode = xmlXadesTmplAddSigPolicyId(signaturePolicyIdNode, policyIdIdentifier, policyIdDescription); |  | ||||||
|   if ( sigPolicyIdNode == NULL ) { |  | ||||||
|     xmlFachoPrintError("error: failed to add SigPolicyId node.\n"); |  | ||||||
|     goto fail; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   sigPolicyHashNode = xmlXadesTmplAddSigPolicyHash(signaturePolicyIdNode, xmlSecTransformSha256Id); |  | ||||||
|   if ( sigPolicyHashNode == NULL ) { |  | ||||||
|     xmlFachoPrintError("error: failed to add SigPolicyHash node.\n"); |  | ||||||
|     goto fail; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   signerRoleNode = xmlXadesTmplAddSignerRole(signedSignaturePropertiesNode, BAD_CAST "supplier"); |  | ||||||
|   if ( signerRoleNode == NULL ) { |  | ||||||
|     xmlFachoPrintError("error: failed to add SignerRole node.\n"); |  | ||||||
|     goto fail; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|    |  | ||||||
|   return(0); |  | ||||||
|  fail: |  | ||||||
|   xmlUnlinkNode(qualifyingPropertiesNode); |  | ||||||
|   xmlFreeNode(qualifyingPropertiesNode); |  | ||||||
|   return(-1); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| int |  | ||||||
| xmlFachoInit() { |  | ||||||
|   xmlInitParser(); |  | ||||||
|   LIBXML_TEST_VERSION; |  | ||||||
|    |  | ||||||
|   if ( xmlSecInit() < 0 ) { |  | ||||||
|     xmlFachoPrintError("xmlsec initialization failed.\n"); |  | ||||||
|     return(-1); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if ( xmlSecCheckVersion() != 1 ) { |  | ||||||
|     xmlFachoPrintError("loaded xmlsec library version is not compatible.\n"); |  | ||||||
|     return(-1); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
| #ifdef XMLSEC_CRYPTO_DYNAMIC_LOADING |  | ||||||
|     if(xmlSecCryptoDLLoadLibrary( NULL ) < 0) { |  | ||||||
|         fprintf(stderr, "Error: unable to load default xmlsec-crypto library. Make sure\n" |  | ||||||
|                         "that you have it installed and check shared libraries path\n" |  | ||||||
|                         "(LD_LIBRARY_PATH and/or LTDL_LIBRARY_PATH) environment variables.\n"); |  | ||||||
|         return(-1);      |  | ||||||
|     } |  | ||||||
| #endif /* XMLSEC_CRYPTO_DYNAMIC_LOADING */ |  | ||||||
|     |  | ||||||
|   if ( xmlSecCryptoAppInit(NULL) < 0 ) { |  | ||||||
|     xmlFachoPrintError("crypto initialization failed.\n"); |  | ||||||
|     return(-1); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if ( xmlSecCryptoInit() < 0 ) { |  | ||||||
|     xmlFachoPrintError("xmlsec-crypto initialization failed.\n"); |  | ||||||
|     return(-1); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   return(0); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| int |  | ||||||
| xmlFachoShutdown() { |  | ||||||
|  |  | ||||||
|   if ( xmlSecCryptoShutdown() < 0 ) { |  | ||||||
|     xmlFachoPrintError("xmlSecCryptoShutdown failed.\n"); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if ( xmlSecCryptoAppShutdown() < 0 ) { |  | ||||||
|     xmlFachoPrintError("xmlSecCryptoAppShutdown failed.\n"); |  | ||||||
|   } |  | ||||||
|    |  | ||||||
|   if ( xmlSecShutdown() < 0 ) { |  | ||||||
|     xmlFachoPrintError("xmlsec shutdown failed.\n"); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   xmlCleanupParser(); |  | ||||||
|   return(0); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| int |  | ||||||
| xmlFachoSignFile(FILE *out, const char *filename, const char *pkcs12name, const char *password) { |  | ||||||
|   xmlDocPtr doc = NULL; |  | ||||||
|   xmlNodePtr signNode = NULL; |  | ||||||
|   xmlNodePtr refNode = NULL; |  | ||||||
|   xmlNodePtr keyInfoNode = NULL; |  | ||||||
|   xmlNodePtr x509DataNode = NULL; |  | ||||||
|   xmlNodePtr node = NULL; |  | ||||||
|   xmlSecDSigCtxPtr dsigCtx = NULL; |  | ||||||
|   xmlXadesDSigCtxPtr xadesDsigCtx = NULL; |  | ||||||
|  |  | ||||||
|   int res = -1; |  | ||||||
|    |  | ||||||
|   if (filename == NULL) { |  | ||||||
|    return(-1); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   doc = xmlParseFile(filename); |  | ||||||
|   if ( (doc == NULL) || (xmlDocGetRootElement(doc) == NULL) ) { |  | ||||||
|     xmlFachoPrintError("error: unable to parse file %s\n", filename); |  | ||||||
|     goto done; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   signNode = xmlSecTmplSignatureCreate(doc, xmlSecTransformInclC14NId, |  | ||||||
|                                        xmlSecTransformRsaSha256Id, NULL); |  | ||||||
|   if ( signNode == NULL ) { |  | ||||||
|     xmlFachoPrintError("error: failed to create signature template.\n"); |  | ||||||
|     goto done; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   xmlAddChild(xmlDocGetRootElement(doc), signNode); |  | ||||||
|  |  | ||||||
|   refNode = xmlSecTmplSignatureAddReference(signNode, |  | ||||||
|                                             xmlSecTransformSha256Id, |  | ||||||
|                                             BAD_CAST "xmldsig-facho-ref0", // id |  | ||||||
|                                             BAD_CAST "", //uri |  | ||||||
|                                             NULL); //type |  | ||||||
|   if ( refNode == NULL ) { |  | ||||||
|     xmlFachoPrintError("error: failed to add reference to signature template.\n"); |  | ||||||
|     goto done; |  | ||||||
|   } |  | ||||||
|   if ( xmlSecTmplReferenceAddTransform(refNode, xmlSecTransformEnvelopedId) == NULL ) { |  | ||||||
|     xmlFachoPrintError("error: failed to add enveloped transform to reference\n"); |  | ||||||
|     goto done; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   refNode = xmlSecTmplSignatureAddReference(signNode, |  | ||||||
|                                             xmlSecTransformSha256Id, |  | ||||||
|                                             BAD_CAST "xmldsig-facho-ref2", |  | ||||||
|                                             BAD_CAST "#xmldsig-facho-KeyInfo", |  | ||||||
|                                             NULL); |  | ||||||
|   if ( refNode == NULL ) { |  | ||||||
|     xmlFachoPrintError("error: failed to add reference to signature template key-info.\n"); |  | ||||||
|     goto done; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   keyInfoNode = xmlSecTmplSignatureEnsureKeyInfo(signNode, BAD_CAST "xmldsig-facho-KeyInfo"); |  | ||||||
|   if ( keyInfoNode == NULL ) { |  | ||||||
|     xmlFachoPrintError("error: failed to add key info.\n"); |  | ||||||
|     goto done; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   x509DataNode = xmlSecTmplKeyInfoAddX509Data(keyInfoNode); |  | ||||||
|   if ( x509DataNode == NULL ) { |  | ||||||
|     xmlFachoPrintError("error: failde to add x509 DATA \n"); |  | ||||||
|     goto done; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if ( xmlSecTmplX509DataAddCertificate(x509DataNode) == NULL ) { |  | ||||||
|     xmlFachoPrintError("error: failde to add x509Certificate node\n"); |  | ||||||
|     goto done; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|   if ( xmlFachoTmplXadesCreate(doc, signNode) < 0 ){ |  | ||||||
|     xmlFachoPrintError("error: xmlFachoTmplXadesCreate failed.\n"); |  | ||||||
|     goto done; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   dsigCtx = xmlSecDSigCtxCreate(NULL); |  | ||||||
|   if ( dsigCtx == NULL ) { |  | ||||||
|     xmlFachoPrintError("error: dsig context creating failed\n"); |  | ||||||
|     return(-1); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   // cargamos el archivo pkcs12 con llave privado y certificados x509 |  | ||||||
|   dsigCtx->signKey = xmlSecCryptoAppKeyLoad(pkcs12name, |  | ||||||
|                                             xmlSecKeyDataFormatPkcs12, |  | ||||||
|                                             password, |  | ||||||
|                                             NULL, NULL); |  | ||||||
|   if ( dsigCtx->signKey == NULL ) { |  | ||||||
|     xmlFachoPrintError("error: failed to load pkcs12\n"); |  | ||||||
|     goto done; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   xmlXadesPolicyIdentifierCtx policyIdCtx; |  | ||||||
|  |  | ||||||
|   // por ahora el hash del identificador lo tomamos del pdf de la dian |  | ||||||
|   policyIdCtx.contentCallback = &xmlFachoPolicyIdentifierCtxFromFilename; |  | ||||||
|      |  | ||||||
|   xadesDsigCtx = xmlXadesDSigCtxCreate(dsigCtx, XADES_DIGEST_SHA256, &policyIdCtx); |  | ||||||
|   if ( xadesDsigCtx == NULL ) { |  | ||||||
|     xmlFachoPrintError("error: xades context creating failed.\n"); |  | ||||||
|     return(-1); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   // debe existir el elemento antes del firmado |  | ||||||
|   node = xmlFachoTmplUBLExtensionAddExtensionContent(doc); |  | ||||||
|   if ( node == NULL ) { |  | ||||||
|     xmlFachoPrintError("error: failed to add UBLExtensions/UBLExtension/ExtensionContent\n"); |  | ||||||
|     goto done; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|   // realizar firma de documento |  | ||||||
|   if ( xmlXadesDSigCtxSign(xadesDsigCtx, signNode) < 0 ) { |  | ||||||
|     xmlFachoPrintError("error: signature failed\n"); |  | ||||||
|     goto done; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|   xmlUnlinkNode(signNode); |  | ||||||
|   xmlSecAddChildNode(node, signNode); |  | ||||||
|  |  | ||||||
|   xmlDocDump(out, doc); |  | ||||||
|  |  | ||||||
|   res = 0; |  | ||||||
|  |  | ||||||
|  done: |  | ||||||
|   if ( xadesDsigCtx != NULL ) { |  | ||||||
|     xmlXadesDSigCtxDestroy(xadesDsigCtx); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if ( dsigCtx != NULL ) { |  | ||||||
|     xmlSecDSigCtxDestroy(dsigCtx); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if ( doc != NULL ) { |  | ||||||
|     xmlFreeDoc(doc); |  | ||||||
|   } |  | ||||||
|   return(res); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static xmlNodePtr |  | ||||||
| xmlFachoTmplUBLExtensionAddExtensionContent(xmlDocPtr doc) { |  | ||||||
|   xmlNodePtr node = NULL; |  | ||||||
|   xmlNodePtr parent = NULL; |  | ||||||
|   const xmlChar ublExtensionsName[] = "UBLExtensions"; |  | ||||||
|   const xmlChar ublExtensionName[] = "UBLExtension"; |  | ||||||
|   const xmlChar extensionContentName[] = "ExtensionContent"; |  | ||||||
|      |  | ||||||
|   parent = xmlSecFindNode(xmlDocGetRootElement(doc), ublExtensionsName, ublExtensionDSigNs); |  | ||||||
|   if ( parent == NULL ) { |  | ||||||
|     parent = xmlSecAddChild(xmlDocGetRootElement(doc), ublExtensionsName,  ublExtensionDSigNs); |  | ||||||
|     if ( parent == NULL ) { |  | ||||||
|       xmlFachoPrintError("error: failed to cleate UBLExtensions.\n"); |  | ||||||
|       return(NULL); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   // adicionamos nuevo elemento UBLExtension |  | ||||||
|   node = xmlSecAddChild(parent, ublExtensionName, ublExtensionDSigNs); |  | ||||||
|   if ( node == NULL ) { |  | ||||||
|     xmlFachoPrintError("error: failed to add UBLExtension\n"); |  | ||||||
|     xmlFreeNode(parent); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   // adicionamos nuevo elemento ExtensionContent |  | ||||||
|   node = xmlSecAddChild(node, extensionContentName, ublExtensionDSigNs); |  | ||||||
|   if ( node == NULL ) { |  | ||||||
|     xmlFachoPrintError("error: failed to add ExtensionContent"); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   return(node); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static int |  | ||||||
| xmlFachoPolicyIdentifierCtxFromFilename(const xmlChar *policyId, xmlSecBufferPtr buffer) { |  | ||||||
|   static unsigned char politicafirmav2[] = { |  | ||||||
|     /** |  | ||||||
|      * generado con https://github.com/Jamesits/bin2array |  | ||||||
|      */ |  | ||||||
| #include "politicafirmav2.c" |  | ||||||
|   }; |  | ||||||
|  |  | ||||||
|   return xmlSecBufferAppend(buffer, politicafirmav2, sizeof(politicafirmav2)); |  | ||||||
| } |  | ||||||
| @@ -1,20 +0,0 @@ | |||||||
| /** |  | ||||||
|  * This file is part of facho.  The COPYRIGHT file at the top level of |  | ||||||
|  * this repository contains the full copyright notices and license terms. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| #ifndef FACHO_SIGNER_H |  | ||||||
| #define FACHO_SIGNER_H |  | ||||||
|  |  | ||||||
| #include <stdio.h> |  | ||||||
|  |  | ||||||
| int |  | ||||||
| xmlFachoInit(); |  | ||||||
|  |  | ||||||
| int |  | ||||||
| xmlFachoShutdown(); |  | ||||||
|  |  | ||||||
| int |  | ||||||
| xmlFachoSignFile(FILE *out, const char *filename, const char *pkcs12name, const char *password); |  | ||||||
|  |  | ||||||
| #endif /* FACHO_SIGNER_H */ |  | ||||||
| @@ -1,47 +0,0 @@ | |||||||
| /** |  | ||||||
|  * This file is part of facho.  The COPYRIGHT file at the top level of |  | ||||||
|  * this repository contains the full copyright notices and license terms. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| #include "xades/xades.h" |  | ||||||
| #include "facho_signer.h" |  | ||||||
|  |  | ||||||
| #include <stdio.h> |  | ||||||
| #include <stdlib.h> |  | ||||||
|  |  | ||||||
|  |  | ||||||
| static char *basename = NULL; |  | ||||||
|  |  | ||||||
| void usage(FILE *out); |  | ||||||
|  |  | ||||||
| int main(int argc, char *argv[]) { |  | ||||||
|   int exitStatus = EXIT_SUCCESS; |  | ||||||
|   basename = argv[0]; |  | ||||||
|    |  | ||||||
|   if (argc != 4) { |  | ||||||
|     usage(stderr); |  | ||||||
|     return(EXIT_FAILURE); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if ( xmlFachoInit() < 0 ) { |  | ||||||
|     fprintf(stderr, "initialization failed.\n"); |  | ||||||
|     return(EXIT_FAILURE); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if ( xmlFachoSignFile( stdout, argv[1], argv[2], argv[3] ) != 0 ) { |  | ||||||
|     fprintf(stderr, "fail to sign file\n"); |  | ||||||
|     exitStatus = EXIT_FAILURE; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   xmlFachoShutdown();   |  | ||||||
|   return(exitStatus); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void |  | ||||||
| usage(FILE *out) { |  | ||||||
|   fprintf(out, "%s: <factura.xml> <pc12> <password>\n", basename); |  | ||||||
|   fprintf(out, "%s", "Firmado electronico para facturacion en Colombia.\n" |  | ||||||
|           "Segun el documento (Anexo Técnico de Factura Electrónica de Venta – Versión 1.7.-2020).\n" |  | ||||||
|           "A considerar:\n" \ |  | ||||||
|           " * adiciona un nuevo elemento //ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent\n"); |  | ||||||
| } |  | ||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -1,391 +0,0 @@ | |||||||
| /* |  | ||||||
|  * Copyright (c) 2012 David Siñuela Pastor, siu.4coders@gmail.com |  | ||||||
|  *  |  | ||||||
|  * Permission is hereby granted, free of charge, to any person obtaining |  | ||||||
|  * a copy of this software and associated documentation files (the |  | ||||||
|  * "Software"), to deal in the Software without restriction, including |  | ||||||
|  * without limitation the rights to use, copy, modify, merge, publish, |  | ||||||
|  * distribute, sublicense, and/or sell copies of the Software, and to |  | ||||||
|  * permit persons to whom the Software is furnished to do so, subject to |  | ||||||
|  * the following conditions: |  | ||||||
|  *  |  | ||||||
|  * The above copyright notice and this permission notice shall be |  | ||||||
|  * included in all copies or substantial portions of the Software. |  | ||||||
|  *  |  | ||||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |  | ||||||
|  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |  | ||||||
|  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |  | ||||||
|  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |  | ||||||
|  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |  | ||||||
|  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |  | ||||||
|  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |  | ||||||
|  */ |  | ||||||
| #ifndef MINUNIT_MINUNIT_H |  | ||||||
| #define MINUNIT_MINUNIT_H |  | ||||||
|  |  | ||||||
| #ifdef __cplusplus |  | ||||||
| 	extern "C" { |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #if defined(_WIN32) |  | ||||||
| #include <Windows.h> |  | ||||||
| #if defined(_MSC_VER) && _MSC_VER < 1900 |  | ||||||
|   #define snprintf _snprintf |  | ||||||
|   #define __func__ __FUNCTION__ |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__)) |  | ||||||
|  |  | ||||||
| /* Change POSIX C SOURCE version for pure c99 compilers */ |  | ||||||
| #if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200112L |  | ||||||
| #undef _POSIX_C_SOURCE |  | ||||||
| #define _POSIX_C_SOURCE 200112L |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #include <unistd.h>	/* POSIX flags */ |  | ||||||
| #include <time.h>	/* clock_gettime(), time() */ |  | ||||||
| #include <sys/time.h>	/* gethrtime(), gettimeofday() */ |  | ||||||
| #include <sys/resource.h> |  | ||||||
| #include <sys/times.h> |  | ||||||
| #include <string.h> |  | ||||||
|  |  | ||||||
| #if defined(__MACH__) && defined(__APPLE__) |  | ||||||
| #include <mach/mach.h> |  | ||||||
| #include <mach/mach_time.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #if __GNUC__ >= 5 && !defined(__STDC_VERSION__) |  | ||||||
| #define __func__ __extension__ __FUNCTION__ |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #else |  | ||||||
| #error "Unable to define timers for an unknown OS." |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #include <stdio.h> |  | ||||||
| #include <math.h> |  | ||||||
|  |  | ||||||
| /*  Maximum length of last message */ |  | ||||||
| #define MINUNIT_MESSAGE_LEN 1024 |  | ||||||
| /*  Accuracy with which floats are compared */ |  | ||||||
| #define MINUNIT_EPSILON 1E-12 |  | ||||||
|  |  | ||||||
| /*  Misc. counters */ |  | ||||||
| static int minunit_run = 0; |  | ||||||
| static int minunit_assert = 0; |  | ||||||
| static int minunit_fail = 0; |  | ||||||
| static int minunit_status = 0; |  | ||||||
|  |  | ||||||
| /*  Timers */ |  | ||||||
| static double minunit_real_timer = 0; |  | ||||||
| static double minunit_proc_timer = 0; |  | ||||||
|  |  | ||||||
| /*  Last message */ |  | ||||||
| static char minunit_last_message[MINUNIT_MESSAGE_LEN]; |  | ||||||
|  |  | ||||||
| /*  Test setup and teardown function pointers */ |  | ||||||
| static void (*minunit_setup)(void) = NULL; |  | ||||||
| static void (*minunit_teardown)(void) = NULL; |  | ||||||
|  |  | ||||||
| /*  Definitions */ |  | ||||||
| #define MU_TEST(method_name) static void method_name(void) |  | ||||||
| #define MU_TEST_SUITE(suite_name) static void suite_name(void) |  | ||||||
|  |  | ||||||
| #define MU__SAFE_BLOCK(block) do {\ |  | ||||||
| 	block\ |  | ||||||
| } while(0) |  | ||||||
|  |  | ||||||
| /*  Run test suite and unset setup and teardown functions */ |  | ||||||
| #define MU_RUN_SUITE(suite_name) MU__SAFE_BLOCK(\ |  | ||||||
| 	suite_name();\ |  | ||||||
| 	minunit_setup = NULL;\ |  | ||||||
| 	minunit_teardown = NULL;\ |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| /*  Configure setup and teardown functions */ |  | ||||||
| #define MU_SUITE_CONFIGURE(setup_fun, teardown_fun) MU__SAFE_BLOCK(\ |  | ||||||
| 	minunit_setup = setup_fun;\ |  | ||||||
| 	minunit_teardown = teardown_fun;\ |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| /*  Test runner */ |  | ||||||
| #define MU_RUN_TEST(test) MU__SAFE_BLOCK(\ |  | ||||||
| 	if (minunit_real_timer==0 && minunit_proc_timer==0) {\ |  | ||||||
| 		minunit_real_timer = mu_timer_real();\ |  | ||||||
| 		minunit_proc_timer = mu_timer_cpu();\ |  | ||||||
| 	}\ |  | ||||||
| 	if (minunit_setup) (*minunit_setup)();\ |  | ||||||
| 	minunit_status = 0;\ |  | ||||||
| 	test();\ |  | ||||||
| 	minunit_run++;\ |  | ||||||
| 	if (minunit_status) {\ |  | ||||||
| 		minunit_fail++;\ |  | ||||||
| 		printf("F");\ |  | ||||||
| 		printf("\n%s\n", minunit_last_message);\ |  | ||||||
| 	}\ |  | ||||||
| 	fflush(stdout);\ |  | ||||||
| 	if (minunit_teardown) (*minunit_teardown)();\ |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| /*  Report */ |  | ||||||
| #define MU_REPORT() MU__SAFE_BLOCK(\ |  | ||||||
| 	double minunit_end_real_timer;\ |  | ||||||
| 	double minunit_end_proc_timer;\ |  | ||||||
| 	printf("\n\n%d tests, %d assertions, %d failures\n", minunit_run, minunit_assert, minunit_fail);\ |  | ||||||
| 	minunit_end_real_timer = mu_timer_real();\ |  | ||||||
| 	minunit_end_proc_timer = mu_timer_cpu();\ |  | ||||||
| 	printf("\nFinished in %.8f seconds (real) %.8f seconds (proc)\n\n",\ |  | ||||||
| 		minunit_end_real_timer - minunit_real_timer,\ |  | ||||||
| 		minunit_end_proc_timer - minunit_proc_timer);\ |  | ||||||
| ) |  | ||||||
| #define MU_EXIT_CODE minunit_fail |  | ||||||
|  |  | ||||||
| /*  Assertions */ |  | ||||||
| #define mu_check(test) MU__SAFE_BLOCK(\ |  | ||||||
| 	minunit_assert++;\ |  | ||||||
| 	if (!(test)) {\ |  | ||||||
| 		snprintf(minunit_last_message, MINUNIT_MESSAGE_LEN, "%s failed:\n\t%s:%d: %s", __func__, __FILE__, __LINE__, #test);\ |  | ||||||
| 		minunit_status = 1;\ |  | ||||||
| 		return;\ |  | ||||||
| 	} else {\ |  | ||||||
| 		printf(".");\ |  | ||||||
| 	}\ |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| #define mu_fail(message) MU__SAFE_BLOCK(\ |  | ||||||
| 	minunit_assert++;\ |  | ||||||
| 	snprintf(minunit_last_message, MINUNIT_MESSAGE_LEN, "%s failed:\n\t%s:%d: %s", __func__, __FILE__, __LINE__, message);\ |  | ||||||
| 	minunit_status = 1;\ |  | ||||||
| 	return;\ |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| #define mu_assert(test, message) MU__SAFE_BLOCK(\ |  | ||||||
| 	minunit_assert++;\ |  | ||||||
| 	if (!(test)) {\ |  | ||||||
| 		snprintf(minunit_last_message, MINUNIT_MESSAGE_LEN, "%s failed:\n\t%s:%d: %s", __func__, __FILE__, __LINE__, message);\ |  | ||||||
| 		minunit_status = 1;\ |  | ||||||
| 		return;\ |  | ||||||
| 	} else {\ |  | ||||||
| 		printf(".");\ |  | ||||||
| 	}\ |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| #define mu_assert_int_eq(expected, result) MU__SAFE_BLOCK(\ |  | ||||||
| 	int minunit_tmp_e;\ |  | ||||||
| 	int minunit_tmp_r;\ |  | ||||||
| 	minunit_assert++;\ |  | ||||||
| 	minunit_tmp_e = (expected);\ |  | ||||||
| 	minunit_tmp_r = (result);\ |  | ||||||
| 	if (minunit_tmp_e != minunit_tmp_r) {\ |  | ||||||
| 		snprintf(minunit_last_message, MINUNIT_MESSAGE_LEN, "%s failed:\n\t%s:%d: %d expected but was %d", __func__, __FILE__, __LINE__, minunit_tmp_e, minunit_tmp_r);\ |  | ||||||
| 		minunit_status = 1;\ |  | ||||||
| 		return;\ |  | ||||||
| 	} else {\ |  | ||||||
| 		printf(".");\ |  | ||||||
| 	}\ |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| #define mu_assert_double_eq(expected, result) MU__SAFE_BLOCK(\ |  | ||||||
| 	double minunit_tmp_e;\ |  | ||||||
| 	double minunit_tmp_r;\ |  | ||||||
| 	minunit_assert++;\ |  | ||||||
| 	minunit_tmp_e = (expected);\ |  | ||||||
| 	minunit_tmp_r = (result);\ |  | ||||||
| 	if (fabs(minunit_tmp_e-minunit_tmp_r) > MINUNIT_EPSILON) {\ |  | ||||||
| 		int minunit_significant_figures = 1 - log10(MINUNIT_EPSILON);\ |  | ||||||
| 		snprintf(minunit_last_message, MINUNIT_MESSAGE_LEN, "%s failed:\n\t%s:%d: %.*g expected but was %.*g", __func__, __FILE__, __LINE__, minunit_significant_figures, minunit_tmp_e, minunit_significant_figures, minunit_tmp_r);\ |  | ||||||
| 		minunit_status = 1;\ |  | ||||||
| 		return;\ |  | ||||||
| 	} else {\ |  | ||||||
| 		printf(".");\ |  | ||||||
| 	}\ |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| #define mu_assert_string_eq(expected, result) MU__SAFE_BLOCK(\ |  | ||||||
| 	const char* minunit_tmp_e = expected;\ |  | ||||||
| 	const char* minunit_tmp_r = result;\ |  | ||||||
| 	minunit_assert++;\ |  | ||||||
| 	if (!minunit_tmp_e) {\ |  | ||||||
| 		minunit_tmp_e = "<null pointer>";\ |  | ||||||
| 	}\ |  | ||||||
| 	if (!minunit_tmp_r) {\ |  | ||||||
| 		minunit_tmp_r = "<null pointer>";\ |  | ||||||
| 	}\ |  | ||||||
| 	if(strcmp(minunit_tmp_e, minunit_tmp_r)) {\ |  | ||||||
| 		snprintf(minunit_last_message, MINUNIT_MESSAGE_LEN, "%s failed:\n\t%s:%d: '%s' expected but was '%s'", __func__, __FILE__, __LINE__, minunit_tmp_e, minunit_tmp_r);\ |  | ||||||
| 		minunit_status = 1;\ |  | ||||||
| 		return;\ |  | ||||||
| 	} else {\ |  | ||||||
| 		printf(".");\ |  | ||||||
| 	}\ |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| /* |  | ||||||
|  * The following two functions were written by David Robert Nadeau |  | ||||||
|  * from http://NadeauSoftware.com/ and distributed under the |  | ||||||
|  * Creative Commons Attribution 3.0 Unported License |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Returns the real time, in seconds, or -1.0 if an error occurred. |  | ||||||
|  * |  | ||||||
|  * Time is measured since an arbitrary and OS-dependent start time. |  | ||||||
|  * The returned real time is only useful for computing an elapsed time |  | ||||||
|  * between two calls to this function. |  | ||||||
|  */ |  | ||||||
| static double mu_timer_real(void) |  | ||||||
| { |  | ||||||
| #if defined(_WIN32) |  | ||||||
| 	/* Windows 2000 and later. ---------------------------------- */ |  | ||||||
| 	LARGE_INTEGER Time; |  | ||||||
| 	LARGE_INTEGER Frequency; |  | ||||||
| 	 |  | ||||||
| 	QueryPerformanceFrequency(&Frequency); |  | ||||||
| 	QueryPerformanceCounter(&Time); |  | ||||||
| 	 |  | ||||||
| 	Time.QuadPart *= 1000000; |  | ||||||
| 	Time.QuadPart /= Frequency.QuadPart; |  | ||||||
| 	 |  | ||||||
| 	return (double)Time.QuadPart / 1000000.0; |  | ||||||
|  |  | ||||||
| #elif (defined(__hpux) || defined(hpux)) || ((defined(__sun__) || defined(__sun) || defined(sun)) && (defined(__SVR4) || defined(__svr4__))) |  | ||||||
| 	/* HP-UX, Solaris. ------------------------------------------ */ |  | ||||||
| 	return (double)gethrtime( ) / 1000000000.0; |  | ||||||
|  |  | ||||||
| #elif defined(__MACH__) && defined(__APPLE__) |  | ||||||
| 	/* OSX. ----------------------------------------------------- */ |  | ||||||
| 	static double timeConvert = 0.0; |  | ||||||
| 	if ( timeConvert == 0.0 ) |  | ||||||
| 	{ |  | ||||||
| 		mach_timebase_info_data_t timeBase; |  | ||||||
| 		(void)mach_timebase_info( &timeBase ); |  | ||||||
| 		timeConvert = (double)timeBase.numer / |  | ||||||
| 			(double)timeBase.denom / |  | ||||||
| 			1000000000.0; |  | ||||||
| 	} |  | ||||||
| 	return (double)mach_absolute_time( ) * timeConvert; |  | ||||||
|  |  | ||||||
| #elif defined(_POSIX_VERSION) |  | ||||||
| 	/* POSIX. --------------------------------------------------- */ |  | ||||||
| 	struct timeval tm; |  | ||||||
| #if defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0) |  | ||||||
| 	{ |  | ||||||
| 		struct timespec ts; |  | ||||||
| #if defined(CLOCK_MONOTONIC_PRECISE) |  | ||||||
| 		/* BSD. --------------------------------------------- */ |  | ||||||
| 		const clockid_t id = CLOCK_MONOTONIC_PRECISE; |  | ||||||
| #elif defined(CLOCK_MONOTONIC_RAW) |  | ||||||
| 		/* Linux. ------------------------------------------- */ |  | ||||||
| 		const clockid_t id = CLOCK_MONOTONIC_RAW; |  | ||||||
| #elif defined(CLOCK_HIGHRES) |  | ||||||
| 		/* Solaris. ----------------------------------------- */ |  | ||||||
| 		const clockid_t id = CLOCK_HIGHRES; |  | ||||||
| #elif defined(CLOCK_MONOTONIC) |  | ||||||
| 		/* AIX, BSD, Linux, POSIX, Solaris. ----------------- */ |  | ||||||
| 		const clockid_t id = CLOCK_MONOTONIC; |  | ||||||
| #elif defined(CLOCK_REALTIME) |  | ||||||
| 		/* AIX, BSD, HP-UX, Linux, POSIX. ------------------- */ |  | ||||||
| 		const clockid_t id = CLOCK_REALTIME; |  | ||||||
| #else |  | ||||||
| 		const clockid_t id = (clockid_t)-1;	/* Unknown. */ |  | ||||||
| #endif /* CLOCK_* */ |  | ||||||
| 		if ( id != (clockid_t)-1 && clock_gettime( id, &ts ) != -1 ) |  | ||||||
| 			return (double)ts.tv_sec + |  | ||||||
| 				(double)ts.tv_nsec / 1000000000.0; |  | ||||||
| 		/* Fall thru. */ |  | ||||||
| 	} |  | ||||||
| #endif /* _POSIX_TIMERS */ |  | ||||||
|  |  | ||||||
| 	/* AIX, BSD, Cygwin, HP-UX, Linux, OSX, POSIX, Solaris. ----- */ |  | ||||||
| 	gettimeofday( &tm, NULL ); |  | ||||||
| 	return (double)tm.tv_sec + (double)tm.tv_usec / 1000000.0; |  | ||||||
| #else |  | ||||||
| 	return -1.0;		/* Failed. */ |  | ||||||
| #endif |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Returns the amount of CPU time used by the current process, |  | ||||||
|  * in seconds, or -1.0 if an error occurred. |  | ||||||
|  */ |  | ||||||
| static double mu_timer_cpu(void) |  | ||||||
| { |  | ||||||
| #if defined(_WIN32) |  | ||||||
| 	/* Windows -------------------------------------------------- */ |  | ||||||
| 	FILETIME createTime; |  | ||||||
| 	FILETIME exitTime; |  | ||||||
| 	FILETIME kernelTime; |  | ||||||
| 	FILETIME userTime; |  | ||||||
|  |  | ||||||
| 	/* This approach has a resolution of 1/64 second. Unfortunately, Windows' API does not offer better */ |  | ||||||
| 	if ( GetProcessTimes( GetCurrentProcess( ), |  | ||||||
| 		&createTime, &exitTime, &kernelTime, &userTime ) != 0 ) |  | ||||||
| 	{ |  | ||||||
| 		ULARGE_INTEGER userSystemTime; |  | ||||||
| 		memcpy(&userSystemTime, &userTime, sizeof(ULARGE_INTEGER)); |  | ||||||
| 		return (double)userSystemTime.QuadPart / 10000000.0; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__)) |  | ||||||
| 	/* AIX, BSD, Cygwin, HP-UX, Linux, OSX, and Solaris --------- */ |  | ||||||
|  |  | ||||||
| #if defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0) |  | ||||||
| 	/* Prefer high-res POSIX timers, when available. */ |  | ||||||
| 	{ |  | ||||||
| 		clockid_t id; |  | ||||||
| 		struct timespec ts; |  | ||||||
| #if _POSIX_CPUTIME > 0 |  | ||||||
| 		/* Clock ids vary by OS.  Query the id, if possible. */ |  | ||||||
| 		if ( clock_getcpuclockid( 0, &id ) == -1 ) |  | ||||||
| #endif |  | ||||||
| #if defined(CLOCK_PROCESS_CPUTIME_ID) |  | ||||||
| 			/* Use known clock id for AIX, Linux, or Solaris. */ |  | ||||||
| 			id = CLOCK_PROCESS_CPUTIME_ID; |  | ||||||
| #elif defined(CLOCK_VIRTUAL) |  | ||||||
| 			/* Use known clock id for BSD or HP-UX. */ |  | ||||||
| 			id = CLOCK_VIRTUAL; |  | ||||||
| #else |  | ||||||
| 			id = (clockid_t)-1; |  | ||||||
| #endif |  | ||||||
| 		if ( id != (clockid_t)-1 && clock_gettime( id, &ts ) != -1 ) |  | ||||||
| 			return (double)ts.tv_sec + |  | ||||||
| 				(double)ts.tv_nsec / 1000000000.0; |  | ||||||
| 	} |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #if defined(RUSAGE_SELF) |  | ||||||
| 	{ |  | ||||||
| 		struct rusage rusage; |  | ||||||
| 		if ( getrusage( RUSAGE_SELF, &rusage ) != -1 ) |  | ||||||
| 			return (double)rusage.ru_utime.tv_sec + |  | ||||||
| 				(double)rusage.ru_utime.tv_usec / 1000000.0; |  | ||||||
| 	} |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #if defined(_SC_CLK_TCK) |  | ||||||
| 	{ |  | ||||||
| 		const double ticks = (double)sysconf( _SC_CLK_TCK ); |  | ||||||
| 		struct tms tms; |  | ||||||
| 		if ( times( &tms ) != (clock_t)-1 ) |  | ||||||
| 			return (double)tms.tms_utime / ticks; |  | ||||||
| 	} |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #if defined(CLOCKS_PER_SEC) |  | ||||||
| 	{ |  | ||||||
| 		clock_t cl = clock( ); |  | ||||||
| 		if ( cl != (clock_t)-1 ) |  | ||||||
| 			return (double)cl / (double)CLOCKS_PER_SEC; |  | ||||||
| 	} |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| 	return -1;		/* Failed. */ |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #ifdef __cplusplus |  | ||||||
| } |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #endif /* MINUNIT_MINUNIT_H */ |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| #ifndef MINUNIT_EXT_H |  | ||||||
|  |  | ||||||
| #include <string.h> |  | ||||||
|  |  | ||||||
| #include "minunit.h" |  | ||||||
|  |  | ||||||
| // cuando escribe esto el compilar me arrojo que si no era |  | ||||||
| // mejor usar mu_assert_string_eq increble a  |  | ||||||
| //int mu_assert_string_equals(const char *a, const char *b) { |  | ||||||
| //  return mu_assert(strcmp(a, b) == 0, "string not equals"); |  | ||||||
| //} |  | ||||||
|  |  | ||||||
| #endif //MINUNIT_EXT_H |  | ||||||
| @@ -1,456 +0,0 @@ | |||||||
| /** |  | ||||||
|  * This file is part of facho.  The COPYRIGHT file at the top level of |  | ||||||
|  * this repository contains the full copyright notices and license terms. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| #include "xades.h" |  | ||||||
|  |  | ||||||
| #include <xmlsec/templates.h> |  | ||||||
|  |  | ||||||
| #include <time.h> |  | ||||||
| #include <string.h> |  | ||||||
|  |  | ||||||
| static const xmlChar xmlXadesNodeQualifyingProperties[] = "QualifyingProperties"; |  | ||||||
| static const xmlChar xmlXadesNodeSignedProperties[] = "SignedProperties"; |  | ||||||
|  |  | ||||||
| static const xmlChar xmlXadesNodeSignedSignatureProperties[] = "SignedSignatureProperties"; |  | ||||||
| static const xmlChar xmlXadesNodeSigningTime[] = "SigningTime"; |  | ||||||
| static const xmlChar xmlXadesNodeSigningCertificate[] = "SigningCertificate"; |  | ||||||
| static const xmlChar xmlXadesNodeCert[] = "Cert"; |  | ||||||
| static const xmlChar xmlXadesNodeCertDigest[] = "CertDigest"; |  | ||||||
| static const xmlChar xmlXadesNodeSignaturePolicyIdentifier[] = "SignaturePolicyIdentifier"; |  | ||||||
| static const xmlChar xmlXadesNodeSignaturePolicyId[] = "SignaturePolicyId"; |  | ||||||
| static const xmlChar xmlXadesNodeSigPolicyId[] = "SigPolicyId"; |  | ||||||
| static const xmlChar xmlXadesNodeIdentifier[] = "Identifier"; |  | ||||||
| static const xmlChar xmlXadesNodeDescription[] = "Description"; |  | ||||||
| static const xmlChar xmlXadesNodeSigPolicyHash[] = "SigPolicyHash"; |  | ||||||
|  |  | ||||||
| static const xmlChar xmlXadesNodeSignerRole[] = "SignerRole"; |  | ||||||
| static const xmlChar xmlXadesNodeClaimedRoles[] = "ClaimedRoles"; |  | ||||||
| static const xmlChar xmlXadesNodeClaimedRole[] = "ClaimedRole"; |  | ||||||
| static const xmlChar xmlXadesNodeIssuerSerial[] = "IssuerSerial"; |  | ||||||
| static const xmlChar xmlXadesNodeX509IssuerName[] = "X509IssuerName"; |  | ||||||
| static const xmlChar xmlXadesNodeX509IssuerNumber[] = "X509IssuerNumber"; |  | ||||||
|    |  | ||||||
| static const xmlChar xmlXadesDSigNs[] = "http://uri.etsi.org/01903/v1.3.2#"; |  | ||||||
|  |  | ||||||
| xmlNodePtr |  | ||||||
| xmlXadesAddChildRecursiveNs(xmlNodePtr startNode, const xmlChar* path, const xmlChar* nsPrefix) { |  | ||||||
|   char *curToken; |  | ||||||
|   char* cpath = strdup((char *)path); |  | ||||||
|   char* savePtr; |  | ||||||
|   xmlNodePtr curNode = NULL; |  | ||||||
|   xmlNodePtr parentNode = startNode; |  | ||||||
|  |  | ||||||
|  |  | ||||||
|   curToken = strtok_r(cpath, "/", &savePtr); |  | ||||||
|   while(curToken != NULL) { |  | ||||||
|     curNode = xmlSecFindChild(parentNode, BAD_CAST curToken, nsPrefix); |  | ||||||
|     if (curNode == NULL) { |  | ||||||
|       curNode = xmlSecAddChild(parentNode, BAD_CAST curToken, nsPrefix); |  | ||||||
|       if (curNode == NULL) { |  | ||||||
|         xmlXadesInternalError("xmlSecAddChild(%s)", curToken); |  | ||||||
|         return(NULL); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     parentNode = curNode; |  | ||||||
|  |  | ||||||
|     curToken = strtok_r(NULL, "/", &savePtr); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   free(cpath); |  | ||||||
|   return(curNode); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| xmlNodePtr |  | ||||||
| xmlXadesTmplQualifyingPropertiesCreate(xmlDocPtr doc, xmlNodePtr signatureNode, const xmlChar *id) { |  | ||||||
|   xmlNodePtr objectNode; |  | ||||||
|   xmlNodePtr qualifyingPropertiesNode; |  | ||||||
|  |  | ||||||
|   xmlNewGlobalNs(doc, xmlXadesDSigNs, BAD_CAST "xades"); |  | ||||||
|  |  | ||||||
|   objectNode = xmlSecTmplSignatureAddObject(signatureNode, NULL, NULL, NULL); |  | ||||||
|   if (objectNode == NULL) { |  | ||||||
|     xmlXadesInternalError("xmlSecTmplSignatureAddObject(signatureNode)", NULL); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   qualifyingPropertiesNode = xmlSecAddChild(objectNode, xmlXadesNodeQualifyingProperties, xmlXadesDSigNs); |  | ||||||
|   if (qualifyingPropertiesNode == NULL) { |  | ||||||
|     xmlXadesXmlError2("xmlNewDocNode", NULL, "node=%s", xmlXadesErrorsSafeString(xmlXadesNodeQualifyingProperties)); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if (id != NULL) { |  | ||||||
|     xmlSetProp(qualifyingPropertiesNode, BAD_CAST "Id", id); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   return(qualifyingPropertiesNode); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| xmlNodePtr |  | ||||||
| xmlXadesTmplQualifyingPropertiesCreateNsPref(xmlDocPtr doc, const xmlChar* id, const xmlChar* nsPrefix) { |  | ||||||
|   xmlNodePtr qualifyingPropertiesNode; |  | ||||||
|   xmlNsPtr ns; |  | ||||||
|  |  | ||||||
|   // crear nodo |  | ||||||
|   qualifyingPropertiesNode = xmlNewDocNode(doc, NULL, xmlXadesNodeQualifyingProperties, NULL); |  | ||||||
|   if (qualifyingPropertiesNode == NULL) { |  | ||||||
|     xmlXadesXmlError2("xmlNewDocNode", NULL, "node=%s", xmlXadesErrorsSafeString(xmlXadesNodeQualifyingProperties)); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   // crear namespace y asignar |  | ||||||
|   ns = xmlNewNs(qualifyingPropertiesNode, xmlXadesDSigNs, nsPrefix); |  | ||||||
|   if (ns == NULL) { |  | ||||||
|     xmlXadesXmlError2("xmlNewNs", NULL, |  | ||||||
|                    "ns=%s", xmlXadesErrorsSafeString(xmlXadesDSigNs)); |  | ||||||
|     xmlFreeNode(qualifyingPropertiesNode); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|   xmlSetNs(qualifyingPropertiesNode, ns); |  | ||||||
|  |  | ||||||
|   if (id != NULL) { |  | ||||||
|     xmlSetProp(qualifyingPropertiesNode, BAD_CAST "Id", id); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   |  | ||||||
|   return (qualifyingPropertiesNode); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| xmlNodePtr |  | ||||||
| xmlXadesTmplAddSignedProperties(xmlNodePtr qualifyingPropertiesNode, const xmlChar* id) { |  | ||||||
|   xmlNodePtr cur; |  | ||||||
|  |  | ||||||
|   xmlXadesAssert2(qualifyingPropertiesNode != NULL, NULL); |  | ||||||
|    |  | ||||||
|   cur = xmlSecAddChild(qualifyingPropertiesNode, xmlXadesNodeSignedProperties, xmlXadesDSigNs); |  | ||||||
|   if (cur == NULL) { |  | ||||||
|     xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeSignedProperties)", NULL); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if (id != NULL) { |  | ||||||
|     xmlSetProp(cur, BAD_CAST "Id", id); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   return(cur); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| xmlNodePtr |  | ||||||
| xmlXadesTmplAddSignedSignatureProperties(xmlNodePtr signedPropertiesNode, struct tm* signingTime) { |  | ||||||
|   xmlNodePtr cur; |  | ||||||
|   xmlNodePtr node; |  | ||||||
|  |  | ||||||
|   xmlXadesAssert2(signedPropertiesNode != NULL, NULL); |  | ||||||
|    |  | ||||||
|   // add SignedSignatureProperties |  | ||||||
|   node = xmlSecAddChild(signedPropertiesNode, xmlXadesNodeSignedSignatureProperties, xmlXadesDSigNs); |  | ||||||
|   if (node == NULL) { |  | ||||||
|     xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeSignedSignatureProperties)", NULL); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   // add SignigTime |  | ||||||
|   cur = xmlSecAddChild(node, xmlXadesNodeSigningTime, xmlXadesDSigNs); |  | ||||||
|   if (cur == NULL) { |  | ||||||
|     xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeSigningTime)", NULL); |  | ||||||
|     xmlFreeNode(node); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   { |  | ||||||
|     int ret; |  | ||||||
|     char strtime[200]; |  | ||||||
|  |  | ||||||
|     if (strftime(strtime, sizeof(strtime), "%Y-%m-%dT%T", signingTime) == 0) { |  | ||||||
|       xmlXadesInternalError("strftime", NULL); |  | ||||||
|       xmlFreeNode(cur); |  | ||||||
|       xmlFreeNode(node); |  | ||||||
|       return(NULL); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     ret = xmlSecNodeEncodeAndSetContent(cur, BAD_CAST strtime); |  | ||||||
|     if (ret < 0) { |  | ||||||
|       xmlXadesInternalError("xmlSecNodeEncodeAndSetContent", NULL); |  | ||||||
|       xmlFreeNode(cur); |  | ||||||
|       xmlFreeNode(node); |  | ||||||
|       return(NULL); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   return(node); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| xmlNodePtr |  | ||||||
| xmlXadesTmplAddSigningCertificate(xmlNodePtr signedSignaturePropertiesNode, xmlSecTransformId digestMethodId) { |  | ||||||
|   xmlNodePtr node; |  | ||||||
|  |  | ||||||
|   xmlXadesAssert2(signedSignaturePropertiesNode != NULL, NULL); |  | ||||||
|   if (xmlSecFindChild(signedSignaturePropertiesNode, xmlXadesNodeSigningCertificate, xmlXadesDSigNs) != NULL) { |  | ||||||
|     xmlXadesNodeAlreadyPresentError(signedSignaturePropertiesNode, xmlXadesNodeSigningCertificate, NULL); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   node = xmlSecAddChild(signedSignaturePropertiesNode, xmlXadesNodeSigningCertificate, xmlXadesDSigNs); |  | ||||||
|   if (node == NULL) { |  | ||||||
|     xmlXadesInternalError("xmlsecAddChild(xmlXadesNodeSigningCertificate)", NULL); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   return(node); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| xmlNodePtr |  | ||||||
| xmlXadesTmplAddCert(xmlNodePtr signingCertificateNode) { |  | ||||||
|   xmlNodePtr certNode; |  | ||||||
|  |  | ||||||
|   xmlXadesAssert2(signingCertificateNode != NULL, NULL); |  | ||||||
|  |  | ||||||
|   certNode = xmlSecAddChild(signingCertificateNode, xmlXadesNodeCert, xmlXadesDSigNs); |  | ||||||
|   if (certNode == NULL) { |  | ||||||
|     xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeCert)", NULL); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   return(certNode); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| xmlNodePtr |  | ||||||
| xmlXadesTmplAddCertDigest(xmlNodePtr certNode, const xmlChar *digestMethod, const xmlChar *digestValue) { |  | ||||||
|   xmlNodePtr node; |  | ||||||
|  |  | ||||||
|   xmlXadesAssert2(certNode != NULL, NULL); |  | ||||||
|  |  | ||||||
|   node = xmlSecAddChild(certNode, xmlXadesNodeCertDigest, xmlXadesDSigNs); |  | ||||||
|   if ( node == NULL ) { |  | ||||||
|     xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeCertDigest)", NULL); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if ( xmlXadesTmplAddDigest(node, digestMethod, digestValue) == NULL) { |  | ||||||
|     xmlXadesInternalError("xmlXadesTmplAddDigest(node, digestMethodId)", NULL); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   return(certNode); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| xmlNodePtr |  | ||||||
| xmlXadesTmplAddSignaturePolicyIdentifier(xmlNodePtr signedSignaturePropertiesNode) { |  | ||||||
|   xmlNodePtr cur; |  | ||||||
|  |  | ||||||
|   xmlXadesAssert2(signedSignaturePropertiesNode != NULL, NULL); |  | ||||||
|  |  | ||||||
|   cur = xmlSecAddChild(signedSignaturePropertiesNode, xmlXadesNodeSignaturePolicyIdentifier, xmlXadesDSigNs); |  | ||||||
|   if (cur == NULL) { |  | ||||||
|     xmlXadesInternalError("xmlsecAddChild(xmlXadesNodeSignaturePolicyIdentifier)", NULL); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   return(cur); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| xmlNodePtr |  | ||||||
| xmlXadesTmplAddSignaturePolicyId(xmlNodePtr signaturePolicyIdentifierNode) { |  | ||||||
|   xmlNodePtr cur; |  | ||||||
|  |  | ||||||
|   xmlXadesAssert2(signaturePolicyIdentifierNode != NULL, NULL); |  | ||||||
|  |  | ||||||
|   cur = xmlSecAddChild(signaturePolicyIdentifierNode, xmlXadesNodeSignaturePolicyId, xmlXadesDSigNs); |  | ||||||
|   if (cur == NULL) { |  | ||||||
|     xmlXadesInternalError("xmlsecAddChild(cur)", NULL); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   return(cur); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| xmlNodePtr |  | ||||||
| xmlXadesTmplAddSigPolicyId(xmlNodePtr signaturePolicyId, const xmlChar* identifier, const xmlChar *description) { |  | ||||||
|   xmlNodePtr sigPolicyIdNode; |  | ||||||
|   xmlNodePtr node; |  | ||||||
|   int ret; |  | ||||||
|    |  | ||||||
|   sigPolicyIdNode = xmlSecAddChild(signaturePolicyId, xmlXadesNodeSigPolicyId, xmlXadesDSigNs); |  | ||||||
|   if (sigPolicyIdNode == NULL) { |  | ||||||
|     xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeSigPolicyId)", NULL); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   node = xmlSecAddChild(sigPolicyIdNode, xmlXadesNodeIdentifier, xmlXadesDSigNs); |  | ||||||
|   if (node == NULL) { |  | ||||||
|     xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeIdentifier)", NULL); |  | ||||||
|     xmlFreeNode(sigPolicyIdNode); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   ret = xmlSecNodeEncodeAndSetContent(node, identifier); |  | ||||||
|   if (ret < 0) { |  | ||||||
|     xmlXadesInternalError("xmlSecNodeEncodeAndSetContent", NULL); |  | ||||||
|     xmlFreeNode(sigPolicyIdNode); |  | ||||||
|     xmlFreeNode(node); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   node = xmlSecAddChild(sigPolicyIdNode, xmlXadesNodeDescription, xmlXadesDSigNs); |  | ||||||
|   if (node == NULL) { |  | ||||||
|     xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeDescription)", NULL); |  | ||||||
|     xmlFreeNode(sigPolicyIdNode); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   ret = xmlSecNodeEncodeAndSetContent(node, description); |  | ||||||
|   if (ret < 0) { |  | ||||||
|     xmlXadesInternalError("xmlSecNodeEncodeAndSetContent", NULL); |  | ||||||
|     xmlFreeNode(sigPolicyIdNode); |  | ||||||
|     xmlFreeNode(node); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   return(sigPolicyIdNode); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| xmlNodePtr |  | ||||||
| xmlXadesTmplAddSigPolicyHash(xmlNodePtr parentNode, xmlSecTransformId digestMethodId) { |  | ||||||
|   xmlNodePtr node; |  | ||||||
|   xmlXadesAssert2(parentNode != NULL, NULL); |  | ||||||
|  |  | ||||||
|   //add policyHash |  | ||||||
|   node = xmlSecAddChild(parentNode, xmlXadesNodeSigPolicyHash, xmlXadesDSigNs); |  | ||||||
|   if (node == NULL) { |  | ||||||
|     xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeSigPolicyHash)", NULL); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if ( xmlXadesTmplAddDigest(node, digestMethodId->href, NULL) == NULL) { |  | ||||||
|     xmlXadesInternalError("xmlXadesTmplAddDigest(node, digestMethodId)", NULL); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   return node; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // MACHETE(bit4bit) como usar SecTransform para almacenar el digest |  | ||||||
| xmlNodePtr |  | ||||||
| xmlXadesTmplAddDigest(xmlNodePtr parentNode, const xmlChar *digestMethod, const xmlChar *digestValue) { |  | ||||||
|   xmlNodePtr node; |  | ||||||
|    |  | ||||||
|   xmlXadesAssert2(parentNode != NULL, NULL); |  | ||||||
|  |  | ||||||
|   if ( digestMethod != NULL ) { |  | ||||||
|     node = xmlSecAddChild(parentNode, xmlSecNodeDigestMethod, xmlSecDSigNs); |  | ||||||
|     if (node == NULL) { |  | ||||||
|       xmlXadesInternalError("xmlSecAddChild(xmlSecNodeDigestMethod)", NULL); |  | ||||||
|       return(NULL); |  | ||||||
|     } |  | ||||||
|     if (xmlSetProp(node, xmlSecAttrAlgorithm, digestMethod) == NULL) { |  | ||||||
|       xmlXadesXmlError2("xmlSetProp", NULL, |  | ||||||
|                         "name=%s", xmlXadesErrorsSafeString(xmlSecAttrAlgorithm)); |  | ||||||
|       xmlUnlinkNode(node); |  | ||||||
|       xmlFreeNode(node); |  | ||||||
|       return(NULL); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if ( digestValue != NULL ) { |  | ||||||
|     node = xmlSecAddChild(parentNode, xmlSecNodeDigestValue, xmlSecDSigNs); |  | ||||||
|     if (node == NULL) { |  | ||||||
|       xmlXadesInternalError("xmlSecAddChild(xmlSecNodeDigestValue)", NULL); |  | ||||||
|       return(NULL); |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     if (xmlSecNodeEncodeAndSetContent(node, digestValue) < 0) { |  | ||||||
|       xmlXadesInternalError("xmlSecNodeEncodeAndSetContent", NULL); |  | ||||||
|       return(NULL); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|    |  | ||||||
|   return parentNode; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| xmlNodePtr |  | ||||||
| xmlXadesTmplAddSignerRole(xmlNodePtr signedSignaturePropertiesNode, const xmlChar* role) { |  | ||||||
|   xmlNodePtr signerRoleNode; |  | ||||||
|   xmlNodePtr claimedRolesNode; |  | ||||||
|   xmlNodePtr claimedRoleNode; |  | ||||||
|   int ret; |  | ||||||
|  |  | ||||||
|   signerRoleNode = xmlSecAddChild(signedSignaturePropertiesNode, xmlXadesNodeSignerRole, xmlXadesDSigNs); |  | ||||||
|   if (signerRoleNode == NULL) { |  | ||||||
|     xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeSignerRole)", NULL); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   claimedRolesNode = xmlSecAddChild(signerRoleNode, xmlXadesNodeClaimedRoles, xmlXadesDSigNs); |  | ||||||
|   if (claimedRolesNode == NULL) { |  | ||||||
|     xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeClaimedRoles)", NULL); |  | ||||||
|     xmlUnlinkNode(signerRoleNode); |  | ||||||
|     xmlFreeNode(signerRoleNode); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   claimedRoleNode = xmlSecAddChild(claimedRolesNode, xmlXadesNodeClaimedRole, xmlXadesDSigNs); |  | ||||||
|   if (claimedRoleNode == NULL) { |  | ||||||
|     xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeClaimedRole)", NULL); |  | ||||||
|     xmlUnlinkNode(signerRoleNode); |  | ||||||
|     xmlFreeNode(signerRoleNode); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   ret = xmlSecNodeEncodeAndSetContent(claimedRoleNode, role); |  | ||||||
|   if (ret < 0) { |  | ||||||
|     xmlXadesInternalError("xmlSecNodeEncodeAndSetContent", NULL); |  | ||||||
|     xmlUnlinkNode(signerRoleNode); |  | ||||||
|     xmlFreeNode(signerRoleNode); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   return(signerRoleNode); |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| xmlNodePtr |  | ||||||
| xmlXadesTmplAddIssuerSerial(xmlNodePtr certNode, const xmlChar *issuerName, const xmlChar *issuerNumber) { |  | ||||||
|   xmlNodePtr issuerSerialNode; |  | ||||||
|   xmlNodePtr node; |  | ||||||
|  |  | ||||||
|   xmlXadesAssert2(certNode != NULL, NULL); |  | ||||||
|  |  | ||||||
|   issuerSerialNode = xmlSecAddChild(certNode, xmlXadesNodeIssuerSerial, xmlXadesDSigNs); |  | ||||||
|   if ( issuerSerialNode == NULL ) { |  | ||||||
|     xmlXadesInternalError("xmlSecAddChild(certNode, xmlXadesIssuerSerial)", NULL); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   node = xmlSecAddChild(issuerSerialNode, xmlXadesNodeX509IssuerName, xmlSecDSigNs); |  | ||||||
|   if ( node == NULL ) { |  | ||||||
|     xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeX509IssuerName)", NULL); |  | ||||||
|     xmlFreeNode(issuerSerialNode); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if (xmlSecNodeEncodeAndSetContent(node, issuerName) < 0) { |  | ||||||
|     xmlXadesInternalError("xmlSecNodeEncodeAndSetContent", NULL); |  | ||||||
|     xmlUnlinkNode(issuerSerialNode); |  | ||||||
|     xmlFreeNode(issuerSerialNode); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   node = xmlSecAddChild(issuerSerialNode, xmlXadesNodeX509IssuerNumber, xmlSecDSigNs); |  | ||||||
|   if ( node == NULL ) { |  | ||||||
|     xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeX509IssuerNumber)", NULL); |  | ||||||
|     xmlFreeNode(issuerSerialNode); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if (xmlSecNodeEncodeAndSetContent(node, issuerNumber) < 0) { |  | ||||||
|     xmlXadesInternalError("xmlSecNodeEncodeAndSetContent", NULL); |  | ||||||
|     xmlUnlinkNode(issuerSerialNode); |  | ||||||
|     xmlFreeNode(issuerSerialNode); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   return(issuerSerialNode); |  | ||||||
| } |  | ||||||
| @@ -1,301 +0,0 @@ | |||||||
| /** |  | ||||||
|  * This file is part of facho.  The COPYRIGHT file at the top level of |  | ||||||
|  * this repository contains the full copyright notices and license terms. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| #include "config.h" |  | ||||||
|  |  | ||||||
| #include "xades.h" |  | ||||||
|  |  | ||||||
| #include <libxml/xpath.h> |  | ||||||
| #include <libxml/xpathInternals.h> |  | ||||||
| #include <openssl/x509.h> |  | ||||||
| #include <openssl/x509v3.h> |  | ||||||
| #include <openssl/bio.h> |  | ||||||
| #include <openssl/asn1.h> |  | ||||||
| #include <openssl/bn.h> |  | ||||||
|  |  | ||||||
| #include <xmlsec/buffer.h> |  | ||||||
| #include <xmlsec/app.h> |  | ||||||
| #include <xmlsec/transforms.h> |  | ||||||
| #include <xmlsec/keysdata.h> |  | ||||||
|  |  | ||||||
| #ifdef XMLSEC_NO_CRYPTO_DYNAMIC_LOADING |  | ||||||
| #include <xmlsec/openssl/x509.h> |  | ||||||
| #include <xmlsec/openssl/crypto.h> |  | ||||||
| #include <xmlsec/openssl/symbols.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #include <string.h> |  | ||||||
| #include <ctype.h> |  | ||||||
|  |  | ||||||
|  |  | ||||||
| static xmlChar * |  | ||||||
| xmlXadesSha256DigestValueInBase64(const unsigned char *message, size_t message_len); |  | ||||||
|  |  | ||||||
| static xmlNodePtr |  | ||||||
| xmlXadesXPathFirstElement(xmlDocPtr doc, const xmlChar *xpath); |  | ||||||
|  |  | ||||||
| xmlXadesDSigCtxPtr |  | ||||||
| xmlXadesDSigCtxCreate(xmlSecDSigCtxPtr dsigCtx, XADES_DIGEST_METHOD digestMethod, xmlXadesPolicyIdentifierCtxPtr policyCtx) { |  | ||||||
|   xmlXadesDSigCtxPtr ctx = NULL; |  | ||||||
|  |  | ||||||
|   ctx = malloc(sizeof(xmlXadesDSigCtx)); |  | ||||||
|   if ( ctx == NULL ) { |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   ctx->dsigCtx = dsigCtx; |  | ||||||
|   ctx->digestMethod = digestMethod; |  | ||||||
|   ctx->policyCtx = policyCtx; |  | ||||||
|   return ctx; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| int |  | ||||||
| xmlXadesDSigCtxSign(xmlXadesDSigCtxPtr ctx, xmlNodePtr signNode) { |  | ||||||
|   xmlNodePtr signingCertificateNode = NULL; |  | ||||||
|   xmlSecKeyDataPtr keyDataX509; |  | ||||||
|   xmlSecSize certsSize; |  | ||||||
|  |  | ||||||
|   signingCertificateNode = xmlXadesXPathFirstElement(signNode->doc, BAD_CAST "//ds:Object/xades:QualifyingProperties//xades:SigningCertificate[1]"); |  | ||||||
|   if ( signingCertificateNode == NULL ) { |  | ||||||
|     return(-1); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   keyDataX509 = xmlSecKeyEnsureData(ctx->dsigCtx->signKey, xmlSecKeyDataX509Id); |  | ||||||
|   if ( keyDataX509 == NULL ) { |  | ||||||
|     xmlXadesInternalError("failed to get X509.\n", NULL); |  | ||||||
|     return(-1); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   certsSize = xmlSecOpenSSLKeyDataX509GetCertsSize(keyDataX509); |  | ||||||
|   for (xmlSecSize i = 0; i < certsSize; i++) { |  | ||||||
|     // calculamos el digest del certificado |  | ||||||
|     unsigned char md[EVP_MAX_MD_SIZE]; |  | ||||||
|     unsigned int md_n; |  | ||||||
|     // TODO(bit4bit) podemos obtener el digest de openssl por medio de la transformacion? o se puede usar la transformacion para generar el digest? |  | ||||||
|     xmlChar *digestMethod = NULL; |  | ||||||
|     EVP_MD *digest = NULL; |  | ||||||
|  |  | ||||||
|     switch(ctx->digestMethod) { |  | ||||||
|     case XADES_DIGEST_SHA256: |  | ||||||
|       digestMethod = (xmlChar *)xmlSecTransformSha256Id->href; |  | ||||||
|       digest = (EVP_MD *) EVP_sha256(); |  | ||||||
|       break; |  | ||||||
|     default: |  | ||||||
|       xmlXadesInternalError("xmlXadesDSigCtxSign not known how to handle digest method.\n", NULL); |  | ||||||
|       return(-1); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     X509 *cert = xmlSecOpenSSLKeyDataX509GetCert(keyDataX509, i); |  | ||||||
|     if ( cert == NULL ) { |  | ||||||
|       xmlXadesInternalError("openssl: failed to get X509 cert.\n", NULL); |  | ||||||
|       return(-1); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     X509_digest(cert, digest, md, &md_n); |  | ||||||
|     xmlChar *digestValue = xmlSecBase64Encode(md, md_n, 0); |  | ||||||
|  |  | ||||||
|     xmlNodePtr certNode = xmlXadesTmplAddCert(signingCertificateNode); |  | ||||||
|     if ( certNode == NULL ) { |  | ||||||
|       xmlXadesInternalError("xmlXadesTmplAddCert(signingCertificateNode)\n", NULL); |  | ||||||
|       return(-1); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // adicionamos digest  |  | ||||||
|     xmlXadesTmplAddCertDigest(certNode, |  | ||||||
|                               digestMethod, |  | ||||||
|                               digestValue); |  | ||||||
|  |  | ||||||
|     char *issuerName = X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0); |  | ||||||
|  |  | ||||||
|     /* TODO(bit4bit) formatear? |  | ||||||
|     char *issuerNamePtr = issuerName; |  | ||||||
|      |  | ||||||
|     for(issuerNamePtr = strchr(issuerNamePtr, '/'); issuerNamePtr != NULL; issuerNamePtr = strchr(issuerNamePtr, '/')) { |  | ||||||
|       if (issuerNamePtr == issuerName) { |  | ||||||
|         issuerName += 1; |  | ||||||
|       } else { |  | ||||||
|         *issuerNamePtr = ','; |  | ||||||
|       } |  | ||||||
|       }*/ |  | ||||||
|  |  | ||||||
|     ASN1_INTEGER *serial = X509_get_serialNumber(cert); |  | ||||||
|     BIGNUM *bn = ASN1_INTEGER_to_BN(serial, NULL); |  | ||||||
|     if ( bn == NULL ) { |  | ||||||
|       xmlXadesInternalError("unable to convert ASN1_INTEGER_to_BN to BN\n", NULL); |  | ||||||
|       return(-1); |  | ||||||
|     } |  | ||||||
|     char *issuerNumber = BN_bn2dec(bn); |  | ||||||
|     if ( issuerNumber == NULL ) { |  | ||||||
|       xmlXadesInternalError("unable to convert BN to decimal string\n", NULL); |  | ||||||
|       return(-1); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if (xmlXadesTmplAddIssuerSerial(certNode, BAD_CAST issuerName, BAD_CAST issuerNumber) == NULL) { |  | ||||||
|       xmlXadesInternalError("xmlXadesTmplAddIssuerSerial", NULL); |  | ||||||
|       return(-1); |  | ||||||
|     } |  | ||||||
|     BN_free(bn); |  | ||||||
|     OPENSSL_free(issuerNumber); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   // digest de policy identifier |  | ||||||
|   xmlNodePtr sigPolicyId = xmlXadesXPathFirstElement(signNode->doc, BAD_CAST "//xades:SigPolicyId/xades:Identifier[1]"); |  | ||||||
|   if ( sigPolicyId == NULL ) { |  | ||||||
|     xmlXadesInternalError("xmlXadesXPathFirstElement(xades:SigPolicyId/xades:Identifier\n", NULL); |  | ||||||
|     return(-1); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if ( ctx->policyCtx == NULL ) { |  | ||||||
|     xmlXadesInternalError("not found policy context.\n", NULL); |  | ||||||
|     return(-1); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if ( ctx->policyCtx != NULL ) { |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     if ( ctx->policyCtx->contentCallback == NULL ) { |  | ||||||
|       xmlXadesInternalError("not found policy content callback.\n", NULL); |  | ||||||
|       return(-1); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     xmlSecTransformCtxPtr transformCtx = xmlSecTransformCtxCreate(); |  | ||||||
|     if (transformCtx == NULL ) { |  | ||||||
|       xmlXadesInternalError("xmlSecTransformCtxCreate().\n", NULL); |  | ||||||
|       return(-1); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // elemento del digest |  | ||||||
|     xmlNodePtr sigPolicyHashDigestMethod = xmlXadesXPathFirstElement(signNode->doc, BAD_CAST "//xades:SigPolicyHash/ds:DigestMethod[1]"); |  | ||||||
|     if ( sigPolicyHashDigestMethod == NULL ) { |  | ||||||
|       xmlXadesInternalError("xmlXadesXPathFirstElement(xades:SigPolicyHash/xades:DigestMethod\n", NULL); |  | ||||||
|       return(-1); |  | ||||||
|     } |  | ||||||
|     xmlSecTransformPtr transformPolicyDigestMethod = xmlSecTransformNodeRead(sigPolicyHashDigestMethod, |  | ||||||
|                                                                              xmlSecTransformUsageDigestMethod, |  | ||||||
|                                                                              transformCtx); |  | ||||||
|     if ( transformPolicyDigestMethod == NULL ) { |  | ||||||
|       xmlXadesInternalError("xmlSecTransformNodeRead\n", NULL); |  | ||||||
|       xmlFreeNode(sigPolicyHashDigestMethod); |  | ||||||
|       return(-1); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if ( xmlSecTransformCheckId(transformPolicyDigestMethod, xmlSecTransformSha256Id) == 0 ) { |  | ||||||
|       xmlXadesInternalError("sigPolicyHash only support sha256 digest method .\n", NULL); |  | ||||||
|       xmlFreeNode(sigPolicyHashDigestMethod); |  | ||||||
|       return(-1); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // TODO(bit4bit) podemos usar xmlSecTransform para calcular el digest? |  | ||||||
|     xmlNodePtr sigPolicyHashNode = xmlXadesXPathFirstElement(signNode->doc, BAD_CAST "//xades:SigPolicyHash[1]"); |  | ||||||
|     if ( sigPolicyHashNode == NULL ) { |  | ||||||
|       xmlXadesInternalError("failed to find sigPolicyHash node.\n", NULL); |  | ||||||
|       xmlFreeNode(sigPolicyHashDigestMethod); |  | ||||||
|       return(-1); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // obtenemos contenido de la policy |  | ||||||
|     xmlChar *identifier = xmlNodeListGetString(signNode->doc, sigPolicyId->xmlChildrenNode, 1); |  | ||||||
|     xmlSecBufferPtr policyContent = xmlSecBufferCreate(1024); |  | ||||||
|     ; |  | ||||||
|     if ( (ctx->policyCtx->contentCallback)(identifier, policyContent) < 0 ) { |  | ||||||
|       xmlXadesInternalError("policyContext callback fails.\n", NULL); |  | ||||||
|       xmlFree(identifier); |  | ||||||
|       return(-1); |  | ||||||
|     } |  | ||||||
|     xmlFree(identifier); |  | ||||||
|  |  | ||||||
|     xmlChar *policyHashValue = xmlXadesSha256DigestValueInBase64(xmlSecBufferGetData(policyContent), |  | ||||||
|                                                                  xmlSecBufferGetSize(policyContent)); |  | ||||||
|  |  | ||||||
|     xmlSecBufferDestroy(policyContent); |  | ||||||
|     xmlXadesTmplAddDigest(sigPolicyHashNode, NULL, policyHashValue); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   return xmlSecDSigCtxSign(ctx->dsigCtx, signNode); |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| int |  | ||||||
| xmlXadesDSigCtxDestroy(xmlXadesDSigCtxPtr ctx) { |  | ||||||
|   if ( ctx == NULL ) { |  | ||||||
|     return(-1); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   free(ctx); |  | ||||||
|   return(0); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| xmlNodePtr |  | ||||||
| xmlXadesXPathFirstElement(xmlDocPtr doc, const xmlChar *xpath) { |  | ||||||
|   xmlXPathContextPtr xpathCtx; |  | ||||||
|   xmlXPathObjectPtr xpathResult; |  | ||||||
|   xmlNodePtr node; |  | ||||||
|  |  | ||||||
|   // obtener QualifyingProteries |  | ||||||
|  |  | ||||||
|   xpathCtx = xmlXPathNewContext(doc); |  | ||||||
|   /* register namespaces */ |  | ||||||
|   // TOMADO DE: xmlsec1/src/xpath.c |  | ||||||
|   for(xmlNsPtr ns = xmlDocGetRootElement(doc)->nsDef; ns != NULL; ns = ns->next) { |  | ||||||
|     /* check that we have no other namespace with same prefix already */ |  | ||||||
|     if((ns->prefix != NULL) && (xmlXPathNsLookup(xpathCtx, ns->prefix) == NULL)){ |  | ||||||
|       int ret = xmlXPathRegisterNs(xpathCtx, ns->prefix, ns->href); |  | ||||||
|       if(ret != 0) { |  | ||||||
|         xmlXadesXmlError2("xmlXPathRegisterNs", NULL, |  | ||||||
|                           "prefix=%s", xmlSecErrorsSafeString(ns->prefix)); |  | ||||||
|         return(NULL); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|   xpathResult = xmlXPathEvalExpression(xpath, xpathCtx); |  | ||||||
|   if ( xmlXPathNodeSetIsEmpty( xpathResult->nodesetval ) ) { |  | ||||||
|     xmlXadesInternalError("can't find %s \n", xpath); |  | ||||||
|     xmlXPathFreeObject(xpathResult); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   // obtener puntero a nodo |  | ||||||
|   node = xpathResult->nodesetval->nodeTab[0]; |  | ||||||
|   if ( node->type != XML_ELEMENT_NODE ) { |  | ||||||
|     xmlXadesInternalError("expected element\n", NULL); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   return(node); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static xmlChar * |  | ||||||
| xmlXadesSha256DigestValueInBase64(const unsigned char *message, size_t message_len) |  | ||||||
| { |  | ||||||
|   unsigned char digest[2048]; |  | ||||||
|   unsigned int digest_len; |  | ||||||
|   EVP_MD_CTX *mdctx; |  | ||||||
|  |  | ||||||
|   if((mdctx = EVP_MD_CTX_new()) == NULL) { |  | ||||||
|     xmlXadesInternalError("EVP_MD_CTX_new().\n", NULL); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if(1 != EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL)) { |  | ||||||
|     xmlXadesInternalError("EVP_DigestInit_ex().\n", NULL); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if(1 != EVP_DigestUpdate(mdctx, message, message_len)) { |  | ||||||
|     xmlXadesInternalError("EVP_DigestUpdate().\n", NULL); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if(1 != EVP_DigestFinal_ex(mdctx, digest, &digest_len)) { |  | ||||||
|     xmlXadesInternalError("EVP_DigestFinal_ex().\n", NULL); |  | ||||||
|     return(NULL); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   EVP_MD_CTX_free(mdctx); |  | ||||||
|   return(xmlSecBase64Encode(digest, digest_len, 0)); |  | ||||||
| } |  | ||||||
| @@ -1,108 +0,0 @@ | |||||||
| /** |  | ||||||
|  * This file is part of facho.  The COPYRIGHT file at the top level of |  | ||||||
|  * this repository contains the full copyright notices and license terms. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| #ifndef XADES_H |  | ||||||
| #define XADES_H |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| #include <libxml/tree.h> |  | ||||||
|  |  | ||||||
| #define XMLSEC_NO_XSLT 1 |  | ||||||
|  |  | ||||||
| #include <xmlsec/xmltree.h> |  | ||||||
| #include <xmlsec/transforms.h> |  | ||||||
| #include <xmlsec/xmldsig.h> |  | ||||||
| #include <xmlsec/base64.h> |  | ||||||
|  |  | ||||||
| #include "xmlsec1/errors_helpers.h" |  | ||||||
|  |  | ||||||
| #define xmlXadesAssert2(p, ret) \ |  | ||||||
|   xmlSecAssert2(p, ret) |  | ||||||
|  |  | ||||||
| #define xmlXadesNodeNotFoundError(errorFunction, startNode, targetNodeName, errorObject) \ |  | ||||||
|   xmlSecNodeNotFoundError(errorFunction, startNode, targetNodeName, errorObject) |  | ||||||
|  |  | ||||||
| #define xmlXadesXmlError2(errorFunction, errorObject, msg, param) \ |  | ||||||
|   xmlSecXmlError2(errorFunction, errorObject, msg, param) |  | ||||||
|  |  | ||||||
| #define xmlXadesErrorsSafeString(msg) \ |  | ||||||
|   xmlSecErrorsSafeString(msg) |  | ||||||
|  |  | ||||||
| #define xmlXadesInternalError(errorFunction, errorObject) \ |  | ||||||
|   xmlSecInternalError(errorFunction, errorObject) |  | ||||||
|  |  | ||||||
| #define xmlXadesNodeAlreadyPresentError(parent, nodeName, errObject) \ |  | ||||||
|   xmlSecNodeAlreadyPresentError(parent, nodeName, errObject) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| typedef int xmlXadesSize; |  | ||||||
| typedef enum _XADES_DIGEST_METHOD{ |  | ||||||
|   XADES_DIGEST_SHA256 |  | ||||||
| } XADES_DIGEST_METHOD; |  | ||||||
|  |  | ||||||
| typedef int(*xmlXadesPolicyIdentifierContentCallback)(const xmlChar *policyId, xmlSecBuffer *); |  | ||||||
|  |  | ||||||
| typedef struct _xmlXadesPolicyIdentifierCtx  xmlXadesPolicyIdentifierCtx, *xmlXadesPolicyIdentifierCtxPtr; |  | ||||||
| struct _xmlXadesPolicyIdentifierCtx { |  | ||||||
|   xmlXadesPolicyIdentifierContentCallback contentCallback; |  | ||||||
| }; |  | ||||||
|    |  | ||||||
| typedef struct _xmlXadesDSigCtx xmlXadesDSigCtx, *xmlXadesDSigCtxPtr; |  | ||||||
| struct _xmlXadesDSigCtx { |  | ||||||
|   xmlSecDSigCtxPtr dsigCtx; |  | ||||||
|   XADES_DIGEST_METHOD digestMethod; |  | ||||||
|   xmlXadesPolicyIdentifierCtxPtr policyCtx; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| xmlXadesDSigCtxPtr |  | ||||||
| xmlXadesDSigCtxCreate(xmlSecDSigCtxPtr dsigCtx, XADES_DIGEST_METHOD digestMethod,  xmlXadesPolicyIdentifierCtxPtr policyCtx); |  | ||||||
|  |  | ||||||
| int |  | ||||||
| xmlXadesDSigCtxSign(xmlXadesDSigCtxPtr ctx, xmlNodePtr signNode); |  | ||||||
|  |  | ||||||
| int |  | ||||||
| xmlXadesDSigCtxDestroy(xmlXadesDSigCtxPtr ctx); |  | ||||||
|  |  | ||||||
| xmlNodePtr |  | ||||||
| xmlXadesTmplQualifyingPropertiesCreate(xmlDocPtr doc, xmlNodePtr signatureNode, const xmlChar *id); |  | ||||||
|  |  | ||||||
| xmlNodePtr |  | ||||||
| xmlXadesTmplAddSignedProperties(xmlNodePtr qualifyingPropertiesNode, const xmlChar* id); |  | ||||||
|  |  | ||||||
| xmlNodePtr |  | ||||||
| xmlXadesTmplAddSigningCertificate(xmlNodePtr parentNode, xmlSecTransformId digestMethodId); |  | ||||||
|  |  | ||||||
| xmlNodePtr |  | ||||||
| xmlXadesTmplAddCert(xmlNodePtr signingCertificateNode); |  | ||||||
|  |  | ||||||
| xmlNodePtr |  | ||||||
| xmlXadesTmplAddCertDigest(xmlNodePtr signingCertificateNode, const xmlChar *digestMethod, const xmlChar *digestValue); |  | ||||||
|  |  | ||||||
| xmlNodePtr |  | ||||||
| xmlXadesTmplAddSignedSignatureProperties(xmlNodePtr parentNode, struct tm* signingTime); |  | ||||||
|  |  | ||||||
| xmlNodePtr |  | ||||||
| xmlXadesTmplAddSignaturePolicyIdentifier(xmlNodePtr signedSignaturePropertiesNode); |  | ||||||
|  |  | ||||||
| xmlNodePtr |  | ||||||
| xmlXadesTmplAddSignaturePolicyId(xmlNodePtr signaturePolicyIdentifierNode); |  | ||||||
|  |  | ||||||
| xmlNodePtr |  | ||||||
| xmlXadesTmplAddSigPolicyId(xmlNodePtr signaturePolicyId, const xmlChar* identifier, const xmlChar *description); |  | ||||||
|  |  | ||||||
| xmlNodePtr |  | ||||||
| xmlXadesTmplAddSigPolicyHash(xmlNodePtr parentNode, xmlSecTransformId digestMethodId); |  | ||||||
|  |  | ||||||
| xmlNodePtr |  | ||||||
| xmlXadesTmplAddSignerRole(xmlNodePtr signedSignaturePropertiesNode, const xmlChar* role); |  | ||||||
|  |  | ||||||
| xmlNodePtr |  | ||||||
| xmlXadesTmplAddDigest(xmlNodePtr parentNode, const xmlChar *digestMethod, const xmlChar *digestValue); |  | ||||||
|  |  | ||||||
| xmlNodePtr |  | ||||||
| xmlXadesTmplAddIssuerSerial(xmlNodePtr certNode, const xmlChar *issuerName, const xmlChar *issuerNumber); |  | ||||||
|  |  | ||||||
| #endif //XADES_H |  | ||||||
| @@ -1,94 +0,0 @@ | |||||||
| /** |  | ||||||
|  * This file is part of facho.  The COPYRIGHT file at the top level of |  | ||||||
|  * this repository contains the full copyright notices and license terms. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| #include <time.h> |  | ||||||
|  |  | ||||||
| #include <libxml/tree.h> |  | ||||||
| #include "minunit.h" |  | ||||||
|  |  | ||||||
| #include "xades.h" |  | ||||||
|  |  | ||||||
|  |  | ||||||
| MU_TEST(test_xml_add_node_recursive) { |  | ||||||
|   xmlDocPtr doc; |  | ||||||
|   xmlNodePtr root; |  | ||||||
|   xmlNodePtr child; |  | ||||||
|   xmlChar* xmlbuff; |  | ||||||
|   int xmlbuffsize; |  | ||||||
|    |  | ||||||
|   doc = xmlNewDoc(BAD_CAST "1.0"); |  | ||||||
|   root = xmlNewNode(NULL, BAD_CAST "root"); |  | ||||||
|   xmlDocSetRootElement(doc, root); |  | ||||||
|  |  | ||||||
|   child = xmlXadesAddChildRecursiveNs(root, BAD_CAST "A/B/C", NULL); |  | ||||||
|   mu_check(child != NULL); |  | ||||||
|  |  | ||||||
|   xmlDocDumpMemory(doc, &xmlbuff, &xmlbuffsize); |  | ||||||
|   mu_assert_string_eq("<?xml version=\"1.0\"?>\n" |  | ||||||
|                       "<root>\n" |  | ||||||
|                       "<A>\n" |  | ||||||
|                       "<B>\n" |  | ||||||
|                       "<C/>\n" |  | ||||||
|                       "</B>\n" |  | ||||||
|                       "</A>\n" |  | ||||||
|                       "</root>\n" |  | ||||||
|                       , (char *)xmlbuff); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| MU_TEST(test_qualifying_properties_layout) { |  | ||||||
|   xmlDocPtr doc; |  | ||||||
|   xmlNodePtr root; |  | ||||||
|   xmlNodePtr node; |  | ||||||
|   xmlChar* xmlbuff; |  | ||||||
|   int buffersize; |  | ||||||
|   struct tm tm; |  | ||||||
|  |  | ||||||
|   memset(&tm, 0, sizeof(tm)); |  | ||||||
|   tm.tm_year = 2021 - 1900; |  | ||||||
|   tm.tm_mon = 11; |  | ||||||
|   tm.tm_mday = 6; |  | ||||||
|   tm.tm_hour = 12; |  | ||||||
|   tm.tm_min = 0; |  | ||||||
|   tm.tm_sec = 50; |  | ||||||
|  |  | ||||||
|  |  | ||||||
|   doc = xmlNewDoc(BAD_CAST "1.0"); |  | ||||||
|   root = xmlNewNode(NULL, BAD_CAST "root"); |  | ||||||
|   xmlDocSetRootElement(doc, root); |  | ||||||
|    |  | ||||||
|   node = xmlXadesTmplQualifyingPropertiesCreateNsPref(doc, BAD_CAST "123", NULL); |  | ||||||
|   xmlXadesTmplAddSignedSignatureProperties(node, &tm); |  | ||||||
|   mu_check(node != NULL); |  | ||||||
|    |  | ||||||
|   xmlSecAddChildNode(root, node); |  | ||||||
|   xmlDocDumpMemory(doc, &xmlbuff, &buffersize); |  | ||||||
|  |  | ||||||
|   // bit4bit: no se como pasar el namespace al root |  | ||||||
|   mu_assert_string_eq("<?xml version=\"1.0\"?>\n" |  | ||||||
|                       "<root>\n" |  | ||||||
|                       "<QualifyingProperties xmlns=\"http://uri.etsi.org/01903/v1.3.2#\" id=\"123\">\n" |  | ||||||
|                       "<SignedProperties>\n" |  | ||||||
|                       "<SignedSignatureProperties>\n" |  | ||||||
|                       "<SigningTime>2021-12-06T12:00:50</SigningTime>\n" |  | ||||||
|                       "</SignedSignatureProperties>\n" |  | ||||||
|                       "</SignedProperties>\n" |  | ||||||
|                       "</QualifyingProperties>\n" |  | ||||||
|                       "</root>\n" |  | ||||||
|                       , (char *)xmlbuff); |  | ||||||
|    |  | ||||||
|   xmlFree(xmlbuff); |  | ||||||
|   xmlFreeDoc(doc); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| MU_TEST_SUITE(test_suite) { |  | ||||||
|   MU_RUN_TEST(test_xml_add_node_recursive); |  | ||||||
|   MU_RUN_TEST(test_qualifying_properties_layout); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| int main() { |  | ||||||
|   MU_RUN_SUITE(test_suite); |  | ||||||
|   MU_REPORT(); |  | ||||||
|   return MU_EXIT_CODE; |  | ||||||
| } |  | ||||||
| @@ -1,260 +0,0 @@ | |||||||
| /* |  | ||||||
|  * XML Security Library (http://www.aleksey.com/xmlsec). |  | ||||||
|  * |  | ||||||
|  * |  | ||||||
|  * This is free software; see Copyright file in the source |  | ||||||
|  * distribution for preciese wording. |  | ||||||
|  * |  | ||||||
|  * Copyright (C) 2002-2016 Aleksey Sanin <aleksey@aleksey.com>. All Rights Reserved. |  | ||||||
|  */ |  | ||||||
| /** |  | ||||||
|  * SECTION:errors |  | ||||||
|  * @Short_description: Error reporting and logging functions. |  | ||||||
|  * @Stability: Stable |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| #define XMLSEC_PRIVATE 1 |  | ||||||
| #define XMLSEC_NO_XSLT 1 |  | ||||||
|  |  | ||||||
| #include <stdlib.h> |  | ||||||
| #include <stdio.h> |  | ||||||
| #include <stdarg.h> |  | ||||||
| #include <time.h> |  | ||||||
| #include <string.h> |  | ||||||
|  |  | ||||||
| #include <libxml/tree.h> |  | ||||||
|  |  | ||||||
| #include <xmlsec/xmlsec.h> |  | ||||||
| #include <xmlsec/xmltree.h> |  | ||||||
| #include <xmlsec/private.h> |  | ||||||
| #include <xmlsec/errors.h> |  | ||||||
|  |  | ||||||
| /* Must be bigger than fatal_error */ |  | ||||||
| #define XMLSEC_ERRORS_BUFFER_SIZE       1024 |  | ||||||
|  |  | ||||||
| /* Must fit into xmlChar[XMLSEC_ERRORS_BUFFER_SIZE] */ |  | ||||||
| static const xmlChar fatal_error[] = "Can not format error message"; |  | ||||||
|  |  | ||||||
| typedef struct _xmlSecErrorDescription                  xmlSecErrorDescription, *xmlSecErrorDescriptionPtr; |  | ||||||
| struct _xmlSecErrorDescription { |  | ||||||
|     int                 errorCode; |  | ||||||
|     const char*         errorMsg; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| static xmlSecErrorDescription xmlSecErrorsTable[XMLSEC_ERRORS_MAX_NUMBER + 1] = { |  | ||||||
|   { XMLSEC_ERRORS_R_XMLSEC_FAILED,              "xmlsec library function failed" }, |  | ||||||
|   { XMLSEC_ERRORS_R_MALLOC_FAILED,              "malloc function failed" }, |  | ||||||
|   { XMLSEC_ERRORS_R_STRDUP_FAILED,              "strdup function failed" }, |  | ||||||
|   { XMLSEC_ERRORS_R_CRYPTO_FAILED,              "crypto library function failed" }, |  | ||||||
|   { XMLSEC_ERRORS_R_XML_FAILED,                 "libxml2 library function failed" }, |  | ||||||
|   { XMLSEC_ERRORS_R_XSLT_FAILED,                "libxslt library function failed" }, |  | ||||||
|   { XMLSEC_ERRORS_R_IO_FAILED,                  "io function failed" }, |  | ||||||
|   { XMLSEC_ERRORS_R_DISABLED,                   "feature is disabled" }, |  | ||||||
|   { XMLSEC_ERRORS_R_NOT_IMPLEMENTED,            "feature is not implemented" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_CONFIG,             "invalid configuration" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_SIZE,               "invalid size" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_DATA,               "invalid data" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_RESULT,             "invalid result" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_TYPE,               "invalid type" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_OPERATION,          "invalid operation" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_STATUS,             "invalid status" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_FORMAT,             "invalid format" }, |  | ||||||
|   { XMLSEC_ERRORS_R_DATA_NOT_MATCH,             "data do not match" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_VERSION,            "invalid version" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_NODE,               "invalid node" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,       "invalid node content" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_NODE_ATTRIBUTE,     "invalid node attribute" }, |  | ||||||
|   { XMLSEC_ERRORS_R_MISSING_NODE_ATTRIBUTE,     "missing node attribute" }, |  | ||||||
|   { XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,       "node already present" }, |  | ||||||
|   { XMLSEC_ERRORS_R_UNEXPECTED_NODE,            "unexpected node" }, |  | ||||||
|   { XMLSEC_ERRORS_R_NODE_NOT_FOUND,             "node node found" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_TRANSFORM,          "invalid transform" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_TRANSFORM_KEY,      "invalid transform key" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_URI_TYPE,           "invalid URI type" }, |  | ||||||
|   { XMLSEC_ERRORS_R_TRANSFORM_SAME_DOCUMENT_REQUIRED,   "same document is required for transform" }, |  | ||||||
|   { XMLSEC_ERRORS_R_TRANSFORM_DISABLED,         "transform is disabled" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_KEY_DATA,           "invalid key data" }, |  | ||||||
|   { XMLSEC_ERRORS_R_KEY_DATA_NOT_FOUND,         "key data is not found" }, |  | ||||||
|   { XMLSEC_ERRORS_R_KEY_DATA_ALREADY_EXIST,     "key data already exist" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE,      "invalid key data size" }, |  | ||||||
|   { XMLSEC_ERRORS_R_KEY_NOT_FOUND,              "key is not found" }, |  | ||||||
|   { XMLSEC_ERRORS_R_KEYDATA_DISABLED,           "key data is disabled" }, |  | ||||||
|   { XMLSEC_ERRORS_R_MAX_RETRIEVALS_LEVEL,       "maximum key retrieval level" }, |  | ||||||
|   { XMLSEC_ERRORS_R_MAX_RETRIEVAL_TYPE_MISMATCH,"key retrieval type mismatch" }, |  | ||||||
|   { XMLSEC_ERRORS_R_MAX_ENCKEY_LEVEL,           "maximum encrypted key level" }, |  | ||||||
|   { XMLSEC_ERRORS_R_CERT_VERIFY_FAILED,         "certificate verification failed" }, |  | ||||||
|   { XMLSEC_ERRORS_R_CERT_NOT_FOUND,             "certificate is not found" }, |  | ||||||
|   { XMLSEC_ERRORS_R_CERT_REVOKED,               "certificate is revoked" }, |  | ||||||
|   { XMLSEC_ERRORS_R_CERT_ISSUER_FAILED,         "certificate issuer check failed" }, |  | ||||||
|   { XMLSEC_ERRORS_R_CERT_NOT_YET_VALID,         "certificate is not yet valid" }, |  | ||||||
|   { XMLSEC_ERRORS_R_CERT_HAS_EXPIRED,           "certificate has expired" }, |  | ||||||
|   { XMLSEC_ERRORS_R_DSIG_NO_REFERENCES,         "Reference nodes are not found" }, |  | ||||||
|   { XMLSEC_ERRORS_R_DSIG_INVALID_REFERENCE,     "Reference verification failed" }, |  | ||||||
|   { XMLSEC_ERRORS_R_ASSERTION,                  "assertion" }, |  | ||||||
|   { 0,                                          NULL} |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| static xmlSecErrorsCallback xmlSecErrorsClbk = xmlSecErrorsDefaultCallback; |  | ||||||
| static int  xmlSecPrintErrorMessages = 1;       /* whether the error messages will be printed immediately */ |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecErrorsInit: |  | ||||||
|  * |  | ||||||
|  * Initializes the errors reporting. It is called from #xmlSecInit function. |  | ||||||
|  * and applications must not call this function directly. |  | ||||||
|  */ |  | ||||||
| void |  | ||||||
| xmlSecErrorsInit(void) { |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecErrorsShutdown: |  | ||||||
|  * |  | ||||||
|  * Cleanups the errors reporting. It is called from #xmlSecShutdown function. |  | ||||||
|  * and applications must not call this function directly. |  | ||||||
|  */ |  | ||||||
| void |  | ||||||
| xmlSecErrorsShutdown(void) { |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecErrorsSetCallback: |  | ||||||
|  * @callback:           the new errors callback function. |  | ||||||
|  * |  | ||||||
|  * Sets the errors callback function to @callback that will be called |  | ||||||
|  * every time an error occurs. |  | ||||||
|  */ |  | ||||||
| void |  | ||||||
| xmlSecErrorsSetCallback(xmlSecErrorsCallback callback) { |  | ||||||
|     xmlSecErrorsClbk = callback; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecErrorsDefaultCallback: |  | ||||||
|  * @file:               the error location file name (__FILE__ macro). |  | ||||||
|  * @line:               the error location line number (__LINE__ macro). |  | ||||||
|  * @func:               the error location function name (__FUNCTION__ macro). |  | ||||||
|  * @errorObject:        the error specific error object |  | ||||||
|  * @errorSubject:       the error specific error subject. |  | ||||||
|  * @reason:             the error code. |  | ||||||
|  * @msg:                the additional error message. |  | ||||||
|  * |  | ||||||
|  * The default error reporting callback that utilizes LibXML |  | ||||||
|  * error reporting #xmlGenericError function. |  | ||||||
|  */ |  | ||||||
| void |  | ||||||
| xmlSecErrorsDefaultCallback(const char* file, int line, const char* func, |  | ||||||
|                             const char* errorObject, const char* errorSubject, |  | ||||||
|                             int reason, const char* msg) { |  | ||||||
|     if(xmlSecPrintErrorMessages) { |  | ||||||
|         const char* error_msg = NULL; |  | ||||||
|         xmlSecSize i; |  | ||||||
|  |  | ||||||
|         for(i = 0; (i < XMLSEC_ERRORS_MAX_NUMBER) && (xmlSecErrorsGetMsg(i) != NULL); ++i) { |  | ||||||
|             if(xmlSecErrorsGetCode(i) == reason) { |  | ||||||
|                 error_msg = xmlSecErrorsGetMsg(i); |  | ||||||
|                 break; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         xmlGenericError(xmlGenericErrorContext, |  | ||||||
|             "func=%s:file=%s:line=%d:obj=%s:subj=%s:error=%d:%s:%s\n", |  | ||||||
|             (func != NULL) ? func : "unknown", |  | ||||||
|             (file != NULL) ? file : "unknown", |  | ||||||
|             line, |  | ||||||
|             (errorObject != NULL) ? errorObject : "unknown", |  | ||||||
|             (errorSubject != NULL) ? errorSubject : "unknown", |  | ||||||
|             reason, |  | ||||||
|             (error_msg != NULL) ? error_msg : "", |  | ||||||
|             (msg != NULL) ? msg : ""); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecErrorsDefaultCallbackEnableOutput: |  | ||||||
|  * @enabled:            the flag. |  | ||||||
|  * |  | ||||||
|  * Enables or disables calling LibXML2 callback from the default |  | ||||||
|  * errors callback. |  | ||||||
|  */ |  | ||||||
| void |  | ||||||
| xmlSecErrorsDefaultCallbackEnableOutput(int enabled) { |  | ||||||
|     xmlSecPrintErrorMessages = enabled; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecErrorsGetCode: |  | ||||||
|  * @pos:                the error position. |  | ||||||
|  * |  | ||||||
|  * Gets the known error code at position @pos. |  | ||||||
|  * |  | ||||||
|  * Returns: the known error code or 0 if @pos is greater than |  | ||||||
|  * total number of known error codes. |  | ||||||
|  */ |  | ||||||
| int |  | ||||||
| xmlSecErrorsGetCode(xmlSecSize pos) { |  | ||||||
|     /* could not use asserts here! */ |  | ||||||
|     if(pos < sizeof(xmlSecErrorsTable) / sizeof(xmlSecErrorsTable[0])) { |  | ||||||
|         return(xmlSecErrorsTable[pos].errorCode); |  | ||||||
|     } |  | ||||||
|     return(0); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecErrorsGetMsg: |  | ||||||
|  * @pos:                the error position. |  | ||||||
|  * |  | ||||||
|  * Gets the known error message at position @pos. |  | ||||||
|  * |  | ||||||
|  * Returns: the known error message or NULL if @pos is greater than |  | ||||||
|  * total number of known error codes. |  | ||||||
|  */ |  | ||||||
| const char* |  | ||||||
| xmlSecErrorsGetMsg(xmlSecSize pos) { |  | ||||||
|     /* could not use asserts here! */ |  | ||||||
|     if(pos < sizeof(xmlSecErrorsTable) / sizeof(xmlSecErrorsTable[0])) { |  | ||||||
|         return(xmlSecErrorsTable[pos].errorMsg); |  | ||||||
|     } |  | ||||||
|     return(NULL); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecError: |  | ||||||
|  * @file:               the error location filename (__FILE__). |  | ||||||
|  * @line:               the error location line number (__LINE__). |  | ||||||
|  * @func:               the error location function (__FUNCTION__). |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * @errorSubject:       the error specific error subject (e.g. failed function name). |  | ||||||
|  * @reason:             the error code. |  | ||||||
|  * @msg:                the error message in printf format. |  | ||||||
|  * @...:                the parameters for the @msg. |  | ||||||
|  * |  | ||||||
|  * Reports an error to the default (#xmlSecErrorsDefaultCallback) or |  | ||||||
|  * application specific callback installed using #xmlSecErrorsSetCallback |  | ||||||
|  * function. |  | ||||||
|  */ |  | ||||||
| void |  | ||||||
| xmlSecError(const char* file, int line, const char* func, |  | ||||||
|             const char* errorObject, const char* errorSubject, |  | ||||||
|             int reason, const char* msg, ...) { |  | ||||||
|     if(xmlSecErrorsClbk != NULL) { |  | ||||||
|         xmlChar error_msg[XMLSEC_ERRORS_BUFFER_SIZE]; |  | ||||||
|         int ret; |  | ||||||
|  |  | ||||||
|         if(msg != NULL) { |  | ||||||
|             va_list va; |  | ||||||
|  |  | ||||||
|             va_start(va, msg); |  | ||||||
|             ret = xmlStrVPrintf(error_msg, sizeof(error_msg), msg, va); |  | ||||||
|             if(ret < 0) { |  | ||||||
|                 /* Can't really report an error from an error callback */ |  | ||||||
|                 memcpy(error_msg, fatal_error, sizeof(fatal_error)); |  | ||||||
|             } |  | ||||||
|             error_msg[sizeof(error_msg) - 1] = '\0'; /* just in case */ |  | ||||||
|             va_end(va); |  | ||||||
|         } else { |  | ||||||
|             error_msg[0] = '\0'; |  | ||||||
|         } |  | ||||||
|         xmlSecErrorsClbk(file, line, func, errorObject, errorSubject, reason, (char*)error_msg); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,869 +0,0 @@ | |||||||
| /* |  | ||||||
|  * XML Security Library (http://www.aleksey.com/xmlsec). |  | ||||||
|  * |  | ||||||
|  * Internal header only used during the compilation, |  | ||||||
|  * |  | ||||||
|  * This is free software; see Copyright file in the source |  | ||||||
|  * distribution for preciese wording. |  | ||||||
|  * |  | ||||||
|  * Copyright (C) 2002-2016 Aleksey Sanin <aleksey@aleksey.com>. All Rights Reserved. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| #ifndef __XMLSEC_ERROR_HELPERS_H__ |  | ||||||
| #define __XMLSEC_ERROR_HELPERS_H__ |  | ||||||
|  |  | ||||||
| #include <errno.h> |  | ||||||
| #include <xmlsec/errors.h> |  | ||||||
|  |  | ||||||
| #ifdef __cplusplus |  | ||||||
| extern "C" { |  | ||||||
| #endif /* __cplusplus */ |  | ||||||
|  |  | ||||||
| /********************************************************************** |  | ||||||
|  * |  | ||||||
|  * Error handling macros. |  | ||||||
|  * |  | ||||||
|  **********************************************************************/ |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInternalError: |  | ||||||
|  * @errorFunction:      the failed function name. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting internal XMLSec errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInternalError(errorFunction, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     (errorFunction),                        \ |  | ||||||
|                     XMLSEC_ERRORS_R_XMLSEC_FAILED,          \ |  | ||||||
|                     XMLSEC_ERRORS_NO_MESSAGE                \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInternalError2: |  | ||||||
|  * @errorFunction:      the failed function name. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * @msg:                the extra message. |  | ||||||
|  * @param:              the extra message param. |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting internal XMLSec errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInternalError2(errorFunction, errorObject, msg, param) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     (errorFunction),                        \ |  | ||||||
|                     XMLSEC_ERRORS_R_XMLSEC_FAILED,          \ |  | ||||||
|                     (msg), (param)                          \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInternalError3: |  | ||||||
|  * @errorFunction:      the failed function name. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * @msg:                the extra message. |  | ||||||
|  * @param1:             the extra message param1. |  | ||||||
|  * @param2:             the extra message param2. |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting internal XMLSec errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInternalError3(errorFunction, errorObject, msg, param1, param2) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     (errorFunction),                        \ |  | ||||||
|                     XMLSEC_ERRORS_R_XMLSEC_FAILED,          \ |  | ||||||
|                     (msg), (param1), (param2)               \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInternalError4: |  | ||||||
|  * @errorFunction:      the failed function name. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * @msg:                the extra message. |  | ||||||
|  * @param1:             the extra message param1. |  | ||||||
|  * @param2:             the extra message param2. |  | ||||||
|  * @param3:             the extra message param3. |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting internal XMLSec errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInternalError4(errorFunction, errorObject, msg, param1, param2, param3) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     (errorFunction),                        \ |  | ||||||
|                     XMLSEC_ERRORS_R_XMLSEC_FAILED,          \ |  | ||||||
|                     (msg), (param1), (param2), (param3)     \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecMallocError: |  | ||||||
|  * @allocSize:          the failed allocation size. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting xmlMalloc() errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecMallocError(allocSize, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     "xmlMalloc",                            \ |  | ||||||
|                     XMLSEC_ERRORS_R_MALLOC_FAILED,          \ |  | ||||||
|                     "size=%lu", (unsigned long)(allocSize)  \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecStrdupError: |  | ||||||
|  * @str:                the failed string. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting xmlStrdup() errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecStrdupError(str, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     "xmlStrdup",                            \ |  | ||||||
|                     XMLSEC_ERRORS_R_STRDUP_FAILED,          \ |  | ||||||
|                     "size=%lu", (unsigned long)xmlStrlen(str) \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecXmlError: |  | ||||||
|  * @errorFunction:      the failed function. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting generic XML errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecXmlError(errorFunction, errorObject) \ |  | ||||||
|     {                                                 \ |  | ||||||
|         xmlErrorPtr error = xmlGetLastError();        \ |  | ||||||
|         int code = (error != NULL) ? error->code : 0; \ |  | ||||||
|         const char* message = (error != NULL) ? error->message : NULL; \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,               \ |  | ||||||
|                    (const char*)(errorObject),        \ |  | ||||||
|                    (errorFunction),                   \ |  | ||||||
|                    XMLSEC_ERRORS_R_XML_FAILED,        \ |  | ||||||
|                    "xml error: %lu: %s",              \ |  | ||||||
|                    (unsigned long)code,               \ |  | ||||||
|                    xmlSecErrorsSafeString(message)    \ |  | ||||||
|         );                                            \ |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecXmlError2: |  | ||||||
|  * @errorFunction:      the failed function. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * @msg:                the extra message. |  | ||||||
|  * @param:              the extra message param. |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting generic XML errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecXmlError2(errorFunction, errorObject, msg, param) \ |  | ||||||
|     {                                                 \ |  | ||||||
|         xmlErrorPtr error = xmlGetLastError();        \ |  | ||||||
|         int code = (error != NULL) ? error->code : 0; \ |  | ||||||
|         const char* message = (error != NULL) ? error->message : NULL; \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,               \ |  | ||||||
|                    (const char*)(errorObject),        \ |  | ||||||
|                    (errorFunction),                   \ |  | ||||||
|                    XMLSEC_ERRORS_R_XML_FAILED,        \ |  | ||||||
|                    msg "; xml error: %lu: %s",        \ |  | ||||||
|                    (param),                           \ |  | ||||||
|                    (unsigned long)code,               \ |  | ||||||
|                    xmlSecErrorsSafeString(message)    \ |  | ||||||
|         );                                            \ |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecXmlParserError: |  | ||||||
|  * @errorFunction:      the failed function. |  | ||||||
|  * @ctxt:               the parser context. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting XML parser errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecXmlParserError(errorFunction, ctxt, errorObject) \ |  | ||||||
|     {                                                 \ |  | ||||||
|         xmlErrorPtr error = xmlCtxtGetLastError(ctxt);\ |  | ||||||
|         int code = (error != NULL) ? error->code : 0; \ |  | ||||||
|         const char* message = (error != NULL) ? error->message : NULL; \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,               \ |  | ||||||
|                    (const char*)(errorObject),        \ |  | ||||||
|                    (errorFunction),                   \ |  | ||||||
|                    XMLSEC_ERRORS_R_XML_FAILED,        \ |  | ||||||
|                    "xml error: %lu: %s",              \ |  | ||||||
|                    (unsigned long)code,               \ |  | ||||||
|                    xmlSecErrorsSafeString(message)    \ |  | ||||||
|         );                                            \ |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecXmlParserError2: |  | ||||||
|  * @errorFunction:      the failed function. |  | ||||||
|  * @ctxt:               the parser context. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * @msg:                the extra message. |  | ||||||
|  * @param:              the extra message param. |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting XML parser errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecXmlParserError2(errorFunction, ctxt, errorObject, msg, param) \ |  | ||||||
|     {                                                 \ |  | ||||||
|         xmlErrorPtr error = xmlCtxtGetLastError(ctxt);\ |  | ||||||
|         int code = (error != NULL) ? error->code : 0; \ |  | ||||||
|         const char* message = (error != NULL) ? error->message : NULL; \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,               \ |  | ||||||
|                    (const char*)(errorObject),        \ |  | ||||||
|                    (errorFunction),                   \ |  | ||||||
|                    XMLSEC_ERRORS_R_XML_FAILED,        \ |  | ||||||
|                    msg "; xml error: %lu: %s",        \ |  | ||||||
|                    (param),                           \ |  | ||||||
|                    (unsigned long)code,               \ |  | ||||||
|                    xmlSecErrorsSafeString(message)    \ |  | ||||||
|         );                                            \ |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecXsltError: |  | ||||||
|  * @errorFunction:      the failed function. |  | ||||||
|  * @ctxt:               the parser context. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting XSLT errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecXsltError(errorFunction, ctxt, errorObject) \ |  | ||||||
|     {                                                 \ |  | ||||||
|         xmlErrorPtr error = xmlGetLastError();        \ |  | ||||||
|         int code = (error != NULL) ? error->code : 0; \ |  | ||||||
|         const char* message = (error != NULL) ? error->message : NULL; \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,               \ |  | ||||||
|                    (const char*)(errorObject),        \ |  | ||||||
|                    (errorFunction),                   \ |  | ||||||
|                    XMLSEC_ERRORS_R_XSLT_FAILED,       \ |  | ||||||
|                    "xslt error: %lu: %s",             \ |  | ||||||
|                    (unsigned long)code,               \ |  | ||||||
|                    xmlSecErrorsSafeString(message)    \ |  | ||||||
|         );                                            \ |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecIOError: |  | ||||||
|  * @errorFunction:      the failed function. |  | ||||||
|  * @name:               the filename, function name, uri, etc. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting IO errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecIOError(errorFunction, name, errorObject) \ |  | ||||||
|     {                                                 \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,               \ |  | ||||||
|                    (const char*)(errorObject),        \ |  | ||||||
|                    (errorFunction),                   \ |  | ||||||
|                    XMLSEC_ERRORS_R_IO_FAILED,         \ |  | ||||||
|                    "name=\"%s\"; errno=%d",           \ |  | ||||||
|                    xmlSecErrorsSafeString(name),      \ |  | ||||||
|                    errno                              \ |  | ||||||
|         );                                            \ |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecNotImplementedError: |  | ||||||
|  * @details:           the additional details. |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting "not implemented" errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecNotImplementedError(details) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     XMLSEC_ERRORS_R_NOT_IMPLEMENTED,        \ |  | ||||||
|                     "details=%s",                           \ |  | ||||||
|                     xmlSecErrorsSafeString(details)         \ |  | ||||||
|         ) |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidSizeError: |  | ||||||
|  * @name:               the name of the variable, parameter, etc. |  | ||||||
|  * @actual:             the actual value. |  | ||||||
|  * @expected:           the expected value. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting "invalid size" errors when |  | ||||||
|  * we expect exact match. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidSizeError(name, actual, expected, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     XMLSEC_ERRORS_R_INVALID_SIZE,           \ |  | ||||||
|                     "invalid size for '%s': actual=%lu is not equal to expected=%lu", \ |  | ||||||
|                     xmlSecErrorsSafeString(name),           \ |  | ||||||
|                     (unsigned long)(actual),                \ |  | ||||||
|                     (unsigned long)(expected)               \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidSizeLessThanError: |  | ||||||
|  * @name:               the name of the variable, parameter, etc. |  | ||||||
|  * @actual:             the actual value. |  | ||||||
|  * @expected:           the expected value. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting "invalid size" errors when |  | ||||||
|  * we expect at least the expected size. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidSizeLessThanError(name, actual, expected, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     XMLSEC_ERRORS_R_INVALID_SIZE,           \ |  | ||||||
|                     "invalid size for '%s': actual=%lu is less than expected=%lu", \ |  | ||||||
|                     xmlSecErrorsSafeString(name),           \ |  | ||||||
|                     (unsigned long)(actual),                \ |  | ||||||
|                     (unsigned long)(expected)               \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidSizeMoreThanError: |  | ||||||
|  * @name:               the name of the variable, parameter, etc. |  | ||||||
|  * @actual:             the actual value. |  | ||||||
|  * @expected:           the expected value. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting "invalid size" errors when |  | ||||||
|  * we expect at most the expected size. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidSizeMoreThanError(name, actual, expected, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     XMLSEC_ERRORS_R_NOT_IMPLEMENTED,        \ |  | ||||||
|                     "invalid size for '%s': actual=%lu is more than expected=%lu", \ |  | ||||||
|                     xmlSecErrorsSafeString(name),           \ |  | ||||||
|                     (unsigned long)(actual),                \ |  | ||||||
|                     (unsigned long)(expected)               \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidSizeNotMultipleOfError: |  | ||||||
|  * @name:               the name of the variable, parameter, etc. |  | ||||||
|  * @actual:             the actual value. |  | ||||||
|  * @divider:            the expected divider. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting "invalid size" errors when |  | ||||||
|  * we expect the size to be a multiple of the divider. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidSizeNotMultipleOfError(name, actual, divider, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     XMLSEC_ERRORS_R_NOT_IMPLEMENTED,        \ |  | ||||||
|                     "invalid size for '%s': actual=%lu is not a multiple of %lu", \ |  | ||||||
|                     xmlSecErrorsSafeString(name),           \ |  | ||||||
|                     (unsigned long)(actual),                \ |  | ||||||
|                     (unsigned long)(divider)               \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidSizeOtherError: |  | ||||||
|  * @msg:                the message about the error. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting "invalid size" errors when |  | ||||||
|  * we expect exact match. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidSizeOtherError(msg, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     XMLSEC_ERRORS_R_INVALID_SIZE,           \ |  | ||||||
|                     "invalid size: %s",                     \ |  | ||||||
|                     xmlSecErrorsSafeString(msg)             \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidDataError: |  | ||||||
|  * @msg:                the msg with explanation. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting "invalid data" errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidDataError(msg, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     XMLSEC_ERRORS_R_INVALID_DATA,           \ |  | ||||||
|                     "%s",                                   \ |  | ||||||
|                     xmlSecErrorsSafeString(msg)             \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidStringDataError: |  | ||||||
|  * @name:               the name of the variable, parameter, etc. |  | ||||||
|  * @actual:             the actual value as a string. |  | ||||||
|  * @expected:           the expected value(s) as a string. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting "invalid data" errors for string. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidStringDataError(name, actual, expected, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     XMLSEC_ERRORS_R_INVALID_DATA,           \ |  | ||||||
|                     "invalid data for '%s': actual='%s' and expected %s", \ |  | ||||||
|                     xmlSecErrorsSafeString(name),           \ |  | ||||||
|                     xmlSecErrorsSafeString(actual),         \ |  | ||||||
|                     (expected)                              \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidIntegerDataError: |  | ||||||
|  * @name:               the name of the variable, parameter, etc. |  | ||||||
|  * @actual:             the actual value as an integer. |  | ||||||
|  * @expected:           the expected value(s) as a string. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting "invalid data" errors for integers. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidIntegerDataError(name, actual, expected, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     XMLSEC_ERRORS_R_INVALID_DATA,           \ |  | ||||||
|                     "invalid data for '%s': actual=%ld and expected %s", \ |  | ||||||
|                     xmlSecErrorsSafeString(name),           \ |  | ||||||
|                     (unsigned long)(actual),                \ |  | ||||||
|                     (expected)                              \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidIntegerDataError2: |  | ||||||
|  * @name1:              the name of the first variable, parameter, etc. |  | ||||||
|  * @actual1:            the actual first value as an integer. |  | ||||||
|  * @name2:              the name of the second variable, parameter, etc. |  | ||||||
|  * @actual2:            the actual second value as an integer. |  | ||||||
|  * @expected:           the expected value(s) as a string. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting "invalid data" errors for integers. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidIntegerDataError2(name1, actual1, name2, actual2, expected, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     XMLSEC_ERRORS_R_INVALID_DATA,           \ |  | ||||||
|                     "invalid data: actual value '%s'=%ld, actual value '%s'=%ld and expected %s", \ |  | ||||||
|                     xmlSecErrorsSafeString(name1),          \ |  | ||||||
|                     (unsigned long)(actual1),               \ |  | ||||||
|                     xmlSecErrorsSafeString(name2),          \ |  | ||||||
|                     (unsigned long)(actual2),               \ |  | ||||||
|                     (expected)                              \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidTypeError: |  | ||||||
|  * @msg:                the msg with explanation. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting "invalid type" errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidTypeError(msg, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     XMLSEC_ERRORS_R_INVALID_TYPE,           \ |  | ||||||
|                     "%s",                                   \ |  | ||||||
|                     xmlSecErrorsSafeString(msg)             \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidStringTypeError: |  | ||||||
|  * @name:               the name of the variable, parameter, etc. |  | ||||||
|  * @actual:             the actual value as a string. |  | ||||||
|  * @expected:           the expected value(s) as a string. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting "invalid type" errors for string. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidStringTypeError(name, actual, expected, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     XMLSEC_ERRORS_R_INVALID_TYPE,           \ |  | ||||||
|                     "invalid type for '%s': actual='%s' and expected %s", \ |  | ||||||
|                     xmlSecErrorsSafeString(name),           \ |  | ||||||
|                     xmlSecErrorsSafeString(actual),         \ |  | ||||||
|                     (expected)                              \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidIntegerTypeError: |  | ||||||
|  * @name:               the name of the variable, parameter, etc. |  | ||||||
|  * @actual:             the actual value as an integer. |  | ||||||
|  * @expected:           the expected value(s) as a string. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting "invalid type" errors for integers. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidIntegerTypeError(name, actual, expected, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     XMLSEC_ERRORS_R_INVALID_TYPE,           \ |  | ||||||
|                     "invalid type for '%s': actual=%ld and expected %s", \ |  | ||||||
|                     xmlSecErrorsSafeString(name),           \ |  | ||||||
|                     (unsigned long)(actual),                \ |  | ||||||
|                     (expected)                              \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidIntegerTypeError2: |  | ||||||
|  * @name1:              the name of the first variable, parameter, etc. |  | ||||||
|  * @actual1:            the actual first value as an integer. |  | ||||||
|  * @name2:              the name of the second variable, parameter, etc. |  | ||||||
|  * @actual2:            the actual second value as an integer. |  | ||||||
|  * @expected:           the expected value(s) as a string. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting "invalid type" errors for integers. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidIntegerTypeError2(name1, actual1, name2, actual2, expected, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     XMLSEC_ERRORS_R_INVALID_TYPE,           \ |  | ||||||
|                     "invalid type: actual value '%s'=%ld, actual value '%s'=%ld and expected %s", \ |  | ||||||
|                     xmlSecErrorsSafeString(name1),          \ |  | ||||||
|                     (unsigned long)(actual1),               \ |  | ||||||
|                     xmlSecErrorsSafeString(name2),          \ |  | ||||||
|                     (unsigned long)(actual2),               \ |  | ||||||
|                     (expected)                              \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidNodeError: |  | ||||||
|  * @actualNode:         the actual node. |  | ||||||
|  * @expectedNodeName:   the expected node name. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting an invalid node errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidNodeError(actualNode, expectedNodeName, errorObject) \ |  | ||||||
|     {                                                 \ |  | ||||||
|         const char* actualNodeName = xmlSecNodeGetName(actualNode); \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,               \ |  | ||||||
|                    (const char*)(errorObject),        \ |  | ||||||
|                    NULL,                              \ |  | ||||||
|                    XMLSEC_ERRORS_R_INVALID_NODE,      \ |  | ||||||
|                    "actual=%s; expected=%s",          \ |  | ||||||
|                    xmlSecErrorsSafeString(actualNodeName),  \ |  | ||||||
|                    xmlSecErrorsSafeString(expectedNodeName) \ |  | ||||||
|         );                                            \ |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidNodeContentError: |  | ||||||
|  * @node:               the node. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * @reason:             the reason why node content is invalid. |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting an invalid node content errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidNodeContentError(node, errorObject, reason) \ |  | ||||||
|     {                                                 \ |  | ||||||
|         const char* nName = xmlSecNodeGetName(node);  \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,               \ |  | ||||||
|                    (const char*)(errorObject),        \ |  | ||||||
|                    NULL,                              \ |  | ||||||
|                    XMLSEC_ERRORS_R_INVALID_NODE_CONTENT, \ |  | ||||||
|                    "node=%s; reason=%s",              \ |  | ||||||
|                    xmlSecErrorsSafeString(nName),     \ |  | ||||||
|                    xmlSecErrorsSafeString(reason)     \ |  | ||||||
|         );                                            \ |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidNodeAttributeError: |  | ||||||
|  * @node:               the node. |  | ||||||
|  * @attrName:           the attribute name. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * @reason:             the reason why node content is invalid. |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting an invalid node attribute errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidNodeAttributeError(node, attrName, errorObject, reason) \ |  | ||||||
|     {                                                 \ |  | ||||||
|         const char* nName = xmlSecNodeGetName(node);  \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,               \ |  | ||||||
|                    (const char*)(errorObject),        \ |  | ||||||
|                    NULL,                              \ |  | ||||||
|                    XMLSEC_ERRORS_R_INVALID_NODE_ATTRIBUTE, \ |  | ||||||
|                    "node=%s; attribute=%s; reason=%s",\ |  | ||||||
|                    xmlSecErrorsSafeString(nName),     \ |  | ||||||
|                    xmlSecErrorsSafeString(attrName),  \ |  | ||||||
|                    xmlSecErrorsSafeString(reason)     \ |  | ||||||
|         );                                            \ |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecNodeAlreadyPresentError: |  | ||||||
|  * @parent:             the parent node. |  | ||||||
|  * @nodeName:           the node name. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting node already present errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecNodeAlreadyPresentError(parent, nodeName, errorObject) \ |  | ||||||
|     {                                                 \ |  | ||||||
|         const char* pName = xmlSecNodeGetName(parent);\ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,               \ |  | ||||||
|                    (const char*)(errorObject),        \ |  | ||||||
|                    NULL,                              \ |  | ||||||
|                    XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT, \ |  | ||||||
|                    "parent=%s; node=%s",              \ |  | ||||||
|                    xmlSecErrorsSafeString(pName),     \ |  | ||||||
|                    xmlSecErrorsSafeString(nodeName)   \ |  | ||||||
|         );                                            \ |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecUnexpectedNodeError: |  | ||||||
|  * @node:               the node. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting an invalid node errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecUnexpectedNodeError(node, errorObject) \ |  | ||||||
|     {                                                 \ |  | ||||||
|         const char* nName = xmlSecNodeGetName(node);  \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,               \ |  | ||||||
|                    (const char*)(errorObject),        \ |  | ||||||
|                    NULL,                              \ |  | ||||||
|                    XMLSEC_ERRORS_R_UNEXPECTED_NODE,   \ |  | ||||||
|                    "node=%s",                         \ |  | ||||||
|                    xmlSecErrorsSafeString(nName)      \ |  | ||||||
|         );                                            \ |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecNodeNotFoundError: |  | ||||||
|  * @errorFunction:      the failed function. |  | ||||||
|  * @startNode:          the search start node. |  | ||||||
|  * @targetNodeName:     the expected child node name. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting node not found errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecNodeNotFoundError(errorFunction, startNode, targetNodeName, errorObject) \ |  | ||||||
|     {                                                 \ |  | ||||||
|         const char* startNodeName = xmlSecNodeGetName(startNode); \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,               \ |  | ||||||
|                    (const char*)(errorObject),        \ |  | ||||||
|                    (errorFunction),                   \ |  | ||||||
|                    XMLSEC_ERRORS_R_NODE_NOT_FOUND,    \ |  | ||||||
|                    "startNode=%s; target=%s",         \ |  | ||||||
|                    xmlSecErrorsSafeString(startNodeName), \ |  | ||||||
|                    xmlSecErrorsSafeString(targetNodeName) \ |  | ||||||
|         );                                            \ |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidTransfromError: |  | ||||||
|  * @transform:          the transform. |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting an invalid transform errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidTransfromError(transform) \ |  | ||||||
|     {                                                 \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,               \ |  | ||||||
|                    (const char*)xmlSecTransformGetName(transform), \ |  | ||||||
|                    NULL,                              \ |  | ||||||
|                    XMLSEC_ERRORS_R_INVALID_TRANSFORM, \ |  | ||||||
|                    XMLSEC_ERRORS_NO_MESSAGE           \ |  | ||||||
|         );                                            \ |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidTransfromError2: |  | ||||||
|  * @transform:          the transform. |  | ||||||
|  * @msg:                the extra message. |  | ||||||
|  * @param:              the extra message param. |  | ||||||
|  * |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting an invalid transform errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidTransfromError2(transform, msg, param) \ |  | ||||||
|     {                                                 \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,               \ |  | ||||||
|                    (const char*)xmlSecTransformGetName(transform), \ |  | ||||||
|                    NULL,                              \ |  | ||||||
|                    XMLSEC_ERRORS_R_INVALID_TRANSFORM, \ |  | ||||||
|                    (msg), (param)                     \ |  | ||||||
|         );                                            \ |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidTransfromStatusError: |  | ||||||
|  * @transform:          the transform. |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting an invalid transform status errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidTransfromStatusError(transform) \ |  | ||||||
|     {                                                 \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,               \ |  | ||||||
|                    (const char*)xmlSecTransformGetName(transform), \ |  | ||||||
|                    NULL,                              \ |  | ||||||
|                    XMLSEC_ERRORS_R_INVALID_STATUS,    \ |  | ||||||
|                    "transformStatus=%d",              \ |  | ||||||
|                    (int)((transform)->status)         \ |  | ||||||
|         );                                            \ |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidTransfromStatusError2: |  | ||||||
|  * @transform:          the transform. |  | ||||||
|  * @msg:                the extra message. |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting an invalid transform status errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidTransfromStatusError2(transform, msg) \ |  | ||||||
|     {                                                 \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,               \ |  | ||||||
|                    (const char*)xmlSecTransformGetName(transform), \ |  | ||||||
|                    NULL,                              \ |  | ||||||
|                    XMLSEC_ERRORS_R_INVALID_STATUS,    \ |  | ||||||
|                    "transformStatus=%ld, msg=%s",     \ |  | ||||||
|                    (long int)((transform)->status),   \ |  | ||||||
|                    msg                                \ |  | ||||||
|         );                                            \ |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidKeyDataSizeError: |  | ||||||
|  * @name:               the name of the variable, parameter, etc. |  | ||||||
|  * @actual:             the actual value. |  | ||||||
|  * @expected:           the expected value(s). |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting "invalid keydata size" errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidKeyDataSizeError(actual, expected, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE,  \ |  | ||||||
|                     "invalid key data size: actual=%ld and expected=%ld", \ |  | ||||||
|                     (unsigned long)(actual),                \ |  | ||||||
|                     (unsigned long)(expected)               \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidZeroKeyDataSizeError: |  | ||||||
|  * @name:               the name of the variable, parameter, etc. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting "invalid keydata size" errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidZeroKeyDataSizeError(errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE,  \ |  | ||||||
|                     "invalid zero key data size"            \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecOtherError: |  | ||||||
|  * @code:               the error code. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * @details:            the error message. |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting other XMLSec errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecOtherError(code, errorObject, details) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     (code),                                 \ |  | ||||||
|                     "details=%s",                           \ |  | ||||||
|                     xmlSecErrorsSafeString(details)         \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecOtherError2: |  | ||||||
|  * @code:               the error code. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * @msg:                the extra message. |  | ||||||
|  * @param:              the extra message param. |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting other XMLSec errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecOtherError2(code, errorObject, msg, param) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     (code),                                 \ |  | ||||||
|                     (msg), (param)                          \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecOtherError3: |  | ||||||
|  * @code:               the error code. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * @msg:                the extra message. |  | ||||||
|  * @param1:             the extra message param. |  | ||||||
|  * @param2:             the extra message param. |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting other XMLSec errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecOtherError3(code, errorObject, msg, param1, param2) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     (code),                                 \ |  | ||||||
|                     (msg), (param1), (param2)               \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecOtherError4: |  | ||||||
|  * @code:               the error code. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * @msg:                the extra message. |  | ||||||
|  * @param1:             the extra message param. |  | ||||||
|  * @param2:             the extra message param. |  | ||||||
|  * @param3:             the extra message param. |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting other XMLSec errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecOtherError4(code, errorObject, msg, param1, param2, param3) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     (code),                                 \ |  | ||||||
|                     (msg), (param1), (param2), (param3)     \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecOtherError5: |  | ||||||
|  * @code:               the error code. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * @msg:                the extra message. |  | ||||||
|  * @param1:             the extra message param. |  | ||||||
|  * @param2:             the extra message param. |  | ||||||
|  * @param3:             the extra message param. |  | ||||||
|  * @param4:             the extra message param. |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting other XMLSec errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecOtherError5(code, errorObject, msg, param1, param2, param3, param4) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     (code),                                 \ |  | ||||||
|                     (msg), (param1), (param2), (param3), (param4) \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| #ifdef __cplusplus |  | ||||||
| } |  | ||||||
| #endif /* __cplusplus */ |  | ||||||
|  |  | ||||||
| #endif /* __XMLSEC_ERROR_HELPERS_H__ */ |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,259 +0,0 @@ | |||||||
| /* |  | ||||||
|  * XML Security Library (http://www.aleksey.com/xmlsec). |  | ||||||
|  * |  | ||||||
|  * |  | ||||||
|  * This is free software; see Copyright file in the source |  | ||||||
|  * distribution for preciese wording. |  | ||||||
|  * |  | ||||||
|  * Copyright (C) 2002-2016 Aleksey Sanin <aleksey@aleksey.com>. All Rights Reserved. |  | ||||||
|  */ |  | ||||||
| /** |  | ||||||
|  * SECTION:errors |  | ||||||
|  * @Short_description: Error reporting and logging functions. |  | ||||||
|  * @Stability: Stable |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| #define XMLSEC_PRIVATE 1 |  | ||||||
|  |  | ||||||
| #include <stdlib.h> |  | ||||||
| #include <stdio.h> |  | ||||||
| #include <stdarg.h> |  | ||||||
| #include <time.h> |  | ||||||
| #include <string.h> |  | ||||||
|  |  | ||||||
| #include <libxml/tree.h> |  | ||||||
|  |  | ||||||
| #include <xmlsec/xmlsec.h> |  | ||||||
| #include <xmlsec/xmltree.h> |  | ||||||
| #include <xmlsec/private.h> |  | ||||||
| #include <xmlsec/errors.h> |  | ||||||
|  |  | ||||||
| /* Must be bigger than fatal_error */ |  | ||||||
| #define XMLSEC_ERRORS_BUFFER_SIZE       1024 |  | ||||||
|  |  | ||||||
| /* Must fit into xmlChar[XMLSEC_ERRORS_BUFFER_SIZE] */ |  | ||||||
| static const xmlChar fatal_error[] = "Can not format error message"; |  | ||||||
|  |  | ||||||
| typedef struct _xmlSecErrorDescription                  xmlSecErrorDescription, *xmlSecErrorDescriptionPtr; |  | ||||||
| struct _xmlSecErrorDescription { |  | ||||||
|     int                 errorCode; |  | ||||||
|     const char*         errorMsg; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| static xmlSecErrorDescription xmlSecErrorsTable[XMLSEC_ERRORS_MAX_NUMBER + 1] = { |  | ||||||
|   { XMLSEC_ERRORS_R_XMLSEC_FAILED,              "xmlsec library function failed" }, |  | ||||||
|   { XMLSEC_ERRORS_R_MALLOC_FAILED,              "malloc function failed" }, |  | ||||||
|   { XMLSEC_ERRORS_R_STRDUP_FAILED,              "strdup function failed" }, |  | ||||||
|   { XMLSEC_ERRORS_R_CRYPTO_FAILED,              "crypto library function failed" }, |  | ||||||
|   { XMLSEC_ERRORS_R_XML_FAILED,                 "libxml2 library function failed" }, |  | ||||||
|   { XMLSEC_ERRORS_R_XSLT_FAILED,                "libxslt library function failed" }, |  | ||||||
|   { XMLSEC_ERRORS_R_IO_FAILED,                  "io function failed" }, |  | ||||||
|   { XMLSEC_ERRORS_R_DISABLED,                   "feature is disabled" }, |  | ||||||
|   { XMLSEC_ERRORS_R_NOT_IMPLEMENTED,            "feature is not implemented" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_CONFIG,             "invalid configuration" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_SIZE,               "invalid size" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_DATA,               "invalid data" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_RESULT,             "invalid result" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_TYPE,               "invalid type" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_OPERATION,          "invalid operation" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_STATUS,             "invalid status" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_FORMAT,             "invalid format" }, |  | ||||||
|   { XMLSEC_ERRORS_R_DATA_NOT_MATCH,             "data do not match" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_VERSION,            "invalid version" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_NODE,               "invalid node" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,       "invalid node content" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_NODE_ATTRIBUTE,     "invalid node attribute" }, |  | ||||||
|   { XMLSEC_ERRORS_R_MISSING_NODE_ATTRIBUTE,     "missing node attribute" }, |  | ||||||
|   { XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,       "node already present" }, |  | ||||||
|   { XMLSEC_ERRORS_R_UNEXPECTED_NODE,            "unexpected node" }, |  | ||||||
|   { XMLSEC_ERRORS_R_NODE_NOT_FOUND,             "node node found" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_TRANSFORM,          "invalid transform" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_TRANSFORM_KEY,      "invalid transform key" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_URI_TYPE,           "invalid URI type" }, |  | ||||||
|   { XMLSEC_ERRORS_R_TRANSFORM_SAME_DOCUMENT_REQUIRED,   "same document is required for transform" }, |  | ||||||
|   { XMLSEC_ERRORS_R_TRANSFORM_DISABLED,         "transform is disabled" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_KEY_DATA,           "invalid key data" }, |  | ||||||
|   { XMLSEC_ERRORS_R_KEY_DATA_NOT_FOUND,         "key data is not found" }, |  | ||||||
|   { XMLSEC_ERRORS_R_KEY_DATA_ALREADY_EXIST,     "key data already exist" }, |  | ||||||
|   { XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE,      "invalid key data size" }, |  | ||||||
|   { XMLSEC_ERRORS_R_KEY_NOT_FOUND,              "key is not found" }, |  | ||||||
|   { XMLSEC_ERRORS_R_KEYDATA_DISABLED,           "key data is disabled" }, |  | ||||||
|   { XMLSEC_ERRORS_R_MAX_RETRIEVALS_LEVEL,       "maximum key retrieval level" }, |  | ||||||
|   { XMLSEC_ERRORS_R_MAX_RETRIEVAL_TYPE_MISMATCH,"key retrieval type mismatch" }, |  | ||||||
|   { XMLSEC_ERRORS_R_MAX_ENCKEY_LEVEL,           "maximum encrypted key level" }, |  | ||||||
|   { XMLSEC_ERRORS_R_CERT_VERIFY_FAILED,         "certificate verification failed" }, |  | ||||||
|   { XMLSEC_ERRORS_R_CERT_NOT_FOUND,             "certificate is not found" }, |  | ||||||
|   { XMLSEC_ERRORS_R_CERT_REVOKED,               "certificate is revoked" }, |  | ||||||
|   { XMLSEC_ERRORS_R_CERT_ISSUER_FAILED,         "certificate issuer check failed" }, |  | ||||||
|   { XMLSEC_ERRORS_R_CERT_NOT_YET_VALID,         "certificate is not yet valid" }, |  | ||||||
|   { XMLSEC_ERRORS_R_CERT_HAS_EXPIRED,           "certificate has expired" }, |  | ||||||
|   { XMLSEC_ERRORS_R_DSIG_NO_REFERENCES,         "Reference nodes are not found" }, |  | ||||||
|   { XMLSEC_ERRORS_R_DSIG_INVALID_REFERENCE,     "Reference verification failed" }, |  | ||||||
|   { XMLSEC_ERRORS_R_ASSERTION,                  "assertion" }, |  | ||||||
|   { 0,                                          NULL} |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| static xmlSecErrorsCallback xmlSecErrorsClbk = xmlSecErrorsDefaultCallback; |  | ||||||
| static int  xmlSecPrintErrorMessages = 1;       /* whether the error messages will be printed immediately */ |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecErrorsInit: |  | ||||||
|  * |  | ||||||
|  * Initializes the errors reporting. It is called from #xmlSecInit function. |  | ||||||
|  * and applications must not call this function directly. |  | ||||||
|  */ |  | ||||||
| void |  | ||||||
| xmlSecErrorsInit(void) { |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecErrorsShutdown: |  | ||||||
|  * |  | ||||||
|  * Cleanups the errors reporting. It is called from #xmlSecShutdown function. |  | ||||||
|  * and applications must not call this function directly. |  | ||||||
|  */ |  | ||||||
| void |  | ||||||
| xmlSecErrorsShutdown(void) { |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecErrorsSetCallback: |  | ||||||
|  * @callback:           the new errors callback function. |  | ||||||
|  * |  | ||||||
|  * Sets the errors callback function to @callback that will be called |  | ||||||
|  * every time an error occurs. |  | ||||||
|  */ |  | ||||||
| void |  | ||||||
| xmlSecErrorsSetCallback(xmlSecErrorsCallback callback) { |  | ||||||
|     xmlSecErrorsClbk = callback; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecErrorsDefaultCallback: |  | ||||||
|  * @file:               the error location file name (__FILE__ macro). |  | ||||||
|  * @line:               the error location line number (__LINE__ macro). |  | ||||||
|  * @func:               the error location function name (__FUNCTION__ macro). |  | ||||||
|  * @errorObject:        the error specific error object |  | ||||||
|  * @errorSubject:       the error specific error subject. |  | ||||||
|  * @reason:             the error code. |  | ||||||
|  * @msg:                the additional error message. |  | ||||||
|  * |  | ||||||
|  * The default error reporting callback that utilizes LibXML |  | ||||||
|  * error reporting #xmlGenericError function. |  | ||||||
|  */ |  | ||||||
| void |  | ||||||
| xmlSecErrorsDefaultCallback(const char* file, int line, const char* func, |  | ||||||
|                             const char* errorObject, const char* errorSubject, |  | ||||||
|                             int reason, const char* msg) { |  | ||||||
|     if(xmlSecPrintErrorMessages) { |  | ||||||
|         const char* error_msg = NULL; |  | ||||||
|         xmlSecSize i; |  | ||||||
|  |  | ||||||
|         for(i = 0; (i < XMLSEC_ERRORS_MAX_NUMBER) && (xmlSecErrorsGetMsg(i) != NULL); ++i) { |  | ||||||
|             if(xmlSecErrorsGetCode(i) == reason) { |  | ||||||
|                 error_msg = xmlSecErrorsGetMsg(i); |  | ||||||
|                 break; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         xmlGenericError(xmlGenericErrorContext, |  | ||||||
|             "func=%s:file=%s:line=%d:obj=%s:subj=%s:error=%d:%s:%s\n", |  | ||||||
|             (func != NULL) ? func : "unknown", |  | ||||||
|             (file != NULL) ? file : "unknown", |  | ||||||
|             line, |  | ||||||
|             (errorObject != NULL) ? errorObject : "unknown", |  | ||||||
|             (errorSubject != NULL) ? errorSubject : "unknown", |  | ||||||
|             reason, |  | ||||||
|             (error_msg != NULL) ? error_msg : "", |  | ||||||
|             (msg != NULL) ? msg : ""); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecErrorsDefaultCallbackEnableOutput: |  | ||||||
|  * @enabled:            the flag. |  | ||||||
|  * |  | ||||||
|  * Enables or disables calling LibXML2 callback from the default |  | ||||||
|  * errors callback. |  | ||||||
|  */ |  | ||||||
| void |  | ||||||
| xmlSecErrorsDefaultCallbackEnableOutput(int enabled) { |  | ||||||
|     xmlSecPrintErrorMessages = enabled; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecErrorsGetCode: |  | ||||||
|  * @pos:                the error position. |  | ||||||
|  * |  | ||||||
|  * Gets the known error code at position @pos. |  | ||||||
|  * |  | ||||||
|  * Returns: the known error code or 0 if @pos is greater than |  | ||||||
|  * total number of known error codes. |  | ||||||
|  */ |  | ||||||
| int |  | ||||||
| xmlSecErrorsGetCode(xmlSecSize pos) { |  | ||||||
|     /* could not use asserts here! */ |  | ||||||
|     if(pos < sizeof(xmlSecErrorsTable) / sizeof(xmlSecErrorsTable[0])) { |  | ||||||
|         return(xmlSecErrorsTable[pos].errorCode); |  | ||||||
|     } |  | ||||||
|     return(0); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecErrorsGetMsg: |  | ||||||
|  * @pos:                the error position. |  | ||||||
|  * |  | ||||||
|  * Gets the known error message at position @pos. |  | ||||||
|  * |  | ||||||
|  * Returns: the known error message or NULL if @pos is greater than |  | ||||||
|  * total number of known error codes. |  | ||||||
|  */ |  | ||||||
| const char* |  | ||||||
| xmlSecErrorsGetMsg(xmlSecSize pos) { |  | ||||||
|     /* could not use asserts here! */ |  | ||||||
|     if(pos < sizeof(xmlSecErrorsTable) / sizeof(xmlSecErrorsTable[0])) { |  | ||||||
|         return(xmlSecErrorsTable[pos].errorMsg); |  | ||||||
|     } |  | ||||||
|     return(NULL); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecError: |  | ||||||
|  * @file:               the error location filename (__FILE__). |  | ||||||
|  * @line:               the error location line number (__LINE__). |  | ||||||
|  * @func:               the error location function (__FUNCTION__). |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * @errorSubject:       the error specific error subject (e.g. failed function name). |  | ||||||
|  * @reason:             the error code. |  | ||||||
|  * @msg:                the error message in printf format. |  | ||||||
|  * @...:                the parameters for the @msg. |  | ||||||
|  * |  | ||||||
|  * Reports an error to the default (#xmlSecErrorsDefaultCallback) or |  | ||||||
|  * application specific callback installed using #xmlSecErrorsSetCallback |  | ||||||
|  * function. |  | ||||||
|  */ |  | ||||||
| void |  | ||||||
| xmlSecError(const char* file, int line, const char* func, |  | ||||||
|             const char* errorObject, const char* errorSubject, |  | ||||||
|             int reason, const char* msg, ...) { |  | ||||||
|     if(xmlSecErrorsClbk != NULL) { |  | ||||||
|         xmlChar error_msg[XMLSEC_ERRORS_BUFFER_SIZE]; |  | ||||||
|         int ret; |  | ||||||
|  |  | ||||||
|         if(msg != NULL) { |  | ||||||
|             va_list va; |  | ||||||
|  |  | ||||||
|             va_start(va, msg); |  | ||||||
|             ret = xmlStrVPrintf(error_msg, sizeof(error_msg), msg, va); |  | ||||||
|             if(ret < 0) { |  | ||||||
|                 /* Can't really report an error from an error callback */ |  | ||||||
|                 memcpy(error_msg, fatal_error, sizeof(fatal_error)); |  | ||||||
|             } |  | ||||||
|             error_msg[sizeof(error_msg) - 1] = '\0'; /* just in case */ |  | ||||||
|             va_end(va); |  | ||||||
|         } else { |  | ||||||
|             error_msg[0] = '\0'; |  | ||||||
|         } |  | ||||||
|         xmlSecErrorsClbk(file, line, func, errorObject, errorSubject, reason, (char*)error_msg); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,869 +0,0 @@ | |||||||
| /* |  | ||||||
|  * XML Security Library (http://www.aleksey.com/xmlsec). |  | ||||||
|  * |  | ||||||
|  * Internal header only used during the compilation, |  | ||||||
|  * |  | ||||||
|  * This is free software; see Copyright file in the source |  | ||||||
|  * distribution for preciese wording. |  | ||||||
|  * |  | ||||||
|  * Copyright (C) 2002-2016 Aleksey Sanin <aleksey@aleksey.com>. All Rights Reserved. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| #ifndef __XMLSEC_ERROR_HELPERS_H__ |  | ||||||
| #define __XMLSEC_ERROR_HELPERS_H__ |  | ||||||
|  |  | ||||||
| #include <errno.h> |  | ||||||
| #include <xmlsec/errors.h> |  | ||||||
|  |  | ||||||
| #ifdef __cplusplus |  | ||||||
| extern "C" { |  | ||||||
| #endif /* __cplusplus */ |  | ||||||
|  |  | ||||||
| /********************************************************************** |  | ||||||
|  * |  | ||||||
|  * Error handling macros. |  | ||||||
|  * |  | ||||||
|  **********************************************************************/ |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInternalError: |  | ||||||
|  * @errorFunction:      the failed function name. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting internal XMLSec errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInternalError(errorFunction, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     (errorFunction),                        \ |  | ||||||
|                     XMLSEC_ERRORS_R_XMLSEC_FAILED,          \ |  | ||||||
|                     XMLSEC_ERRORS_NO_MESSAGE                \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInternalError2: |  | ||||||
|  * @errorFunction:      the failed function name. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * @msg:                the extra message. |  | ||||||
|  * @param:              the extra message param. |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting internal XMLSec errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInternalError2(errorFunction, errorObject, msg, param) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     (errorFunction),                        \ |  | ||||||
|                     XMLSEC_ERRORS_R_XMLSEC_FAILED,          \ |  | ||||||
|                     (msg), (param)                          \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInternalError3: |  | ||||||
|  * @errorFunction:      the failed function name. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * @msg:                the extra message. |  | ||||||
|  * @param1:             the extra message param1. |  | ||||||
|  * @param2:             the extra message param2. |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting internal XMLSec errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInternalError3(errorFunction, errorObject, msg, param1, param2) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     (errorFunction),                        \ |  | ||||||
|                     XMLSEC_ERRORS_R_XMLSEC_FAILED,          \ |  | ||||||
|                     (msg), (param1), (param2)               \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInternalError4: |  | ||||||
|  * @errorFunction:      the failed function name. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * @msg:                the extra message. |  | ||||||
|  * @param1:             the extra message param1. |  | ||||||
|  * @param2:             the extra message param2. |  | ||||||
|  * @param3:             the extra message param3. |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting internal XMLSec errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInternalError4(errorFunction, errorObject, msg, param1, param2, param3) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     (errorFunction),                        \ |  | ||||||
|                     XMLSEC_ERRORS_R_XMLSEC_FAILED,          \ |  | ||||||
|                     (msg), (param1), (param2), (param3)     \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecMallocError: |  | ||||||
|  * @allocSize:          the failed allocation size. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting xmlMalloc() errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecMallocError(allocSize, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     "xmlMalloc",                            \ |  | ||||||
|                     XMLSEC_ERRORS_R_MALLOC_FAILED,          \ |  | ||||||
|                     "size=%lu", (unsigned long)(allocSize)  \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecStrdupError: |  | ||||||
|  * @str:                the failed string. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting xmlStrdup() errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecStrdupError(str, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     "xmlStrdup",                            \ |  | ||||||
|                     XMLSEC_ERRORS_R_STRDUP_FAILED,          \ |  | ||||||
|                     "size=%lu", (unsigned long)xmlStrlen(str) \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecXmlError: |  | ||||||
|  * @errorFunction:      the failed function. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting generic XML errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecXmlError(errorFunction, errorObject) \ |  | ||||||
|     {                                                 \ |  | ||||||
|         xmlErrorPtr error = xmlGetLastError();        \ |  | ||||||
|         int code = (error != NULL) ? error->code : 0; \ |  | ||||||
|         const char* message = (error != NULL) ? error->message : NULL; \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,               \ |  | ||||||
|                    (const char*)(errorObject),        \ |  | ||||||
|                    (errorFunction),                   \ |  | ||||||
|                    XMLSEC_ERRORS_R_XML_FAILED,        \ |  | ||||||
|                    "xml error: %lu: %s",              \ |  | ||||||
|                    (unsigned long)code,               \ |  | ||||||
|                    xmlSecErrorsSafeString(message)    \ |  | ||||||
|         );                                            \ |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecXmlError2: |  | ||||||
|  * @errorFunction:      the failed function. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * @msg:                the extra message. |  | ||||||
|  * @param:              the extra message param. |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting generic XML errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecXmlError2(errorFunction, errorObject, msg, param) \ |  | ||||||
|     {                                                 \ |  | ||||||
|         xmlErrorPtr error = xmlGetLastError();        \ |  | ||||||
|         int code = (error != NULL) ? error->code : 0; \ |  | ||||||
|         const char* message = (error != NULL) ? error->message : NULL; \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,               \ |  | ||||||
|                    (const char*)(errorObject),        \ |  | ||||||
|                    (errorFunction),                   \ |  | ||||||
|                    XMLSEC_ERRORS_R_XML_FAILED,        \ |  | ||||||
|                    msg "; xml error: %lu: %s",        \ |  | ||||||
|                    (param),                           \ |  | ||||||
|                    (unsigned long)code,               \ |  | ||||||
|                    xmlSecErrorsSafeString(message)    \ |  | ||||||
|         );                                            \ |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecXmlParserError: |  | ||||||
|  * @errorFunction:      the failed function. |  | ||||||
|  * @ctxt:               the parser context. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting XML parser errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecXmlParserError(errorFunction, ctxt, errorObject) \ |  | ||||||
|     {                                                 \ |  | ||||||
|         xmlErrorPtr error = xmlCtxtGetLastError(ctxt);\ |  | ||||||
|         int code = (error != NULL) ? error->code : 0; \ |  | ||||||
|         const char* message = (error != NULL) ? error->message : NULL; \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,               \ |  | ||||||
|                    (const char*)(errorObject),        \ |  | ||||||
|                    (errorFunction),                   \ |  | ||||||
|                    XMLSEC_ERRORS_R_XML_FAILED,        \ |  | ||||||
|                    "xml error: %lu: %s",              \ |  | ||||||
|                    (unsigned long)code,               \ |  | ||||||
|                    xmlSecErrorsSafeString(message)    \ |  | ||||||
|         );                                            \ |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecXmlParserError2: |  | ||||||
|  * @errorFunction:      the failed function. |  | ||||||
|  * @ctxt:               the parser context. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * @msg:                the extra message. |  | ||||||
|  * @param:              the extra message param. |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting XML parser errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecXmlParserError2(errorFunction, ctxt, errorObject, msg, param) \ |  | ||||||
|     {                                                 \ |  | ||||||
|         xmlErrorPtr error = xmlCtxtGetLastError(ctxt);\ |  | ||||||
|         int code = (error != NULL) ? error->code : 0; \ |  | ||||||
|         const char* message = (error != NULL) ? error->message : NULL; \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,               \ |  | ||||||
|                    (const char*)(errorObject),        \ |  | ||||||
|                    (errorFunction),                   \ |  | ||||||
|                    XMLSEC_ERRORS_R_XML_FAILED,        \ |  | ||||||
|                    msg "; xml error: %lu: %s",        \ |  | ||||||
|                    (param),                           \ |  | ||||||
|                    (unsigned long)code,               \ |  | ||||||
|                    xmlSecErrorsSafeString(message)    \ |  | ||||||
|         );                                            \ |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecXsltError: |  | ||||||
|  * @errorFunction:      the failed function. |  | ||||||
|  * @ctxt:               the parser context. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting XSLT errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecXsltError(errorFunction, ctxt, errorObject) \ |  | ||||||
|     {                                                 \ |  | ||||||
|         xmlErrorPtr error = xmlGetLastError();        \ |  | ||||||
|         int code = (error != NULL) ? error->code : 0; \ |  | ||||||
|         const char* message = (error != NULL) ? error->message : NULL; \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,               \ |  | ||||||
|                    (const char*)(errorObject),        \ |  | ||||||
|                    (errorFunction),                   \ |  | ||||||
|                    XMLSEC_ERRORS_R_XSLT_FAILED,       \ |  | ||||||
|                    "xslt error: %lu: %s",             \ |  | ||||||
|                    (unsigned long)code,               \ |  | ||||||
|                    xmlSecErrorsSafeString(message)    \ |  | ||||||
|         );                                            \ |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecIOError: |  | ||||||
|  * @errorFunction:      the failed function. |  | ||||||
|  * @name:               the filename, function name, uri, etc. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting IO errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecIOError(errorFunction, name, errorObject) \ |  | ||||||
|     {                                                 \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,               \ |  | ||||||
|                    (const char*)(errorObject),        \ |  | ||||||
|                    (errorFunction),                   \ |  | ||||||
|                    XMLSEC_ERRORS_R_IO_FAILED,         \ |  | ||||||
|                    "name=\"%s\"; errno=%d",           \ |  | ||||||
|                    xmlSecErrorsSafeString(name),      \ |  | ||||||
|                    errno                              \ |  | ||||||
|         );                                            \ |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecNotImplementedError: |  | ||||||
|  * @details:           the additional details. |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting "not implemented" errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecNotImplementedError(details) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     XMLSEC_ERRORS_R_NOT_IMPLEMENTED,        \ |  | ||||||
|                     "details=%s",                           \ |  | ||||||
|                     xmlSecErrorsSafeString(details)         \ |  | ||||||
|         ) |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidSizeError: |  | ||||||
|  * @name:               the name of the variable, parameter, etc. |  | ||||||
|  * @actual:             the actual value. |  | ||||||
|  * @expected:           the expected value. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting "invalid size" errors when |  | ||||||
|  * we expect exact match. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidSizeError(name, actual, expected, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     XMLSEC_ERRORS_R_INVALID_SIZE,           \ |  | ||||||
|                     "invalid size for '%s': actual=%lu is not equal to expected=%lu", \ |  | ||||||
|                     xmlSecErrorsSafeString(name),           \ |  | ||||||
|                     (unsigned long)(actual),                \ |  | ||||||
|                     (unsigned long)(expected)               \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidSizeLessThanError: |  | ||||||
|  * @name:               the name of the variable, parameter, etc. |  | ||||||
|  * @actual:             the actual value. |  | ||||||
|  * @expected:           the expected value. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting "invalid size" errors when |  | ||||||
|  * we expect at least the expected size. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidSizeLessThanError(name, actual, expected, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     XMLSEC_ERRORS_R_INVALID_SIZE,           \ |  | ||||||
|                     "invalid size for '%s': actual=%lu is less than expected=%lu", \ |  | ||||||
|                     xmlSecErrorsSafeString(name),           \ |  | ||||||
|                     (unsigned long)(actual),                \ |  | ||||||
|                     (unsigned long)(expected)               \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidSizeMoreThanError: |  | ||||||
|  * @name:               the name of the variable, parameter, etc. |  | ||||||
|  * @actual:             the actual value. |  | ||||||
|  * @expected:           the expected value. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting "invalid size" errors when |  | ||||||
|  * we expect at most the expected size. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidSizeMoreThanError(name, actual, expected, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     XMLSEC_ERRORS_R_NOT_IMPLEMENTED,        \ |  | ||||||
|                     "invalid size for '%s': actual=%lu is more than expected=%lu", \ |  | ||||||
|                     xmlSecErrorsSafeString(name),           \ |  | ||||||
|                     (unsigned long)(actual),                \ |  | ||||||
|                     (unsigned long)(expected)               \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidSizeNotMultipleOfError: |  | ||||||
|  * @name:               the name of the variable, parameter, etc. |  | ||||||
|  * @actual:             the actual value. |  | ||||||
|  * @divider:            the expected divider. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting "invalid size" errors when |  | ||||||
|  * we expect the size to be a multiple of the divider. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidSizeNotMultipleOfError(name, actual, divider, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     XMLSEC_ERRORS_R_NOT_IMPLEMENTED,        \ |  | ||||||
|                     "invalid size for '%s': actual=%lu is not a multiple of %lu", \ |  | ||||||
|                     xmlSecErrorsSafeString(name),           \ |  | ||||||
|                     (unsigned long)(actual),                \ |  | ||||||
|                     (unsigned long)(divider)               \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidSizeOtherError: |  | ||||||
|  * @msg:                the message about the error. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting "invalid size" errors when |  | ||||||
|  * we expect exact match. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidSizeOtherError(msg, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     XMLSEC_ERRORS_R_INVALID_SIZE,           \ |  | ||||||
|                     "invalid size: %s",                     \ |  | ||||||
|                     xmlSecErrorsSafeString(msg)             \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidDataError: |  | ||||||
|  * @msg:                the msg with explanation. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting "invalid data" errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidDataError(msg, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     XMLSEC_ERRORS_R_INVALID_DATA,           \ |  | ||||||
|                     "%s",                                   \ |  | ||||||
|                     xmlSecErrorsSafeString(msg)             \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidStringDataError: |  | ||||||
|  * @name:               the name of the variable, parameter, etc. |  | ||||||
|  * @actual:             the actual value as a string. |  | ||||||
|  * @expected:           the expected value(s) as a string. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting "invalid data" errors for string. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidStringDataError(name, actual, expected, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     XMLSEC_ERRORS_R_INVALID_DATA,           \ |  | ||||||
|                     "invalid data for '%s': actual='%s' and expected %s", \ |  | ||||||
|                     xmlSecErrorsSafeString(name),           \ |  | ||||||
|                     xmlSecErrorsSafeString(actual),         \ |  | ||||||
|                     (expected)                              \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidIntegerDataError: |  | ||||||
|  * @name:               the name of the variable, parameter, etc. |  | ||||||
|  * @actual:             the actual value as an integer. |  | ||||||
|  * @expected:           the expected value(s) as a string. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting "invalid data" errors for integers. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidIntegerDataError(name, actual, expected, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     XMLSEC_ERRORS_R_INVALID_DATA,           \ |  | ||||||
|                     "invalid data for '%s': actual=%ld and expected %s", \ |  | ||||||
|                     xmlSecErrorsSafeString(name),           \ |  | ||||||
|                     (unsigned long)(actual),                \ |  | ||||||
|                     (expected)                              \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidIntegerDataError2: |  | ||||||
|  * @name1:              the name of the first variable, parameter, etc. |  | ||||||
|  * @actual1:            the actual first value as an integer. |  | ||||||
|  * @name2:              the name of the second variable, parameter, etc. |  | ||||||
|  * @actual2:            the actual second value as an integer. |  | ||||||
|  * @expected:           the expected value(s) as a string. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting "invalid data" errors for integers. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidIntegerDataError2(name1, actual1, name2, actual2, expected, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     XMLSEC_ERRORS_R_INVALID_DATA,           \ |  | ||||||
|                     "invalid data: actual value '%s'=%ld, actual value '%s'=%ld and expected %s", \ |  | ||||||
|                     xmlSecErrorsSafeString(name1),          \ |  | ||||||
|                     (unsigned long)(actual1),               \ |  | ||||||
|                     xmlSecErrorsSafeString(name2),          \ |  | ||||||
|                     (unsigned long)(actual2),               \ |  | ||||||
|                     (expected)                              \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidTypeError: |  | ||||||
|  * @msg:                the msg with explanation. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting "invalid type" errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidTypeError(msg, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     XMLSEC_ERRORS_R_INVALID_TYPE,           \ |  | ||||||
|                     "%s",                                   \ |  | ||||||
|                     xmlSecErrorsSafeString(msg)             \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidStringTypeError: |  | ||||||
|  * @name:               the name of the variable, parameter, etc. |  | ||||||
|  * @actual:             the actual value as a string. |  | ||||||
|  * @expected:           the expected value(s) as a string. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting "invalid type" errors for string. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidStringTypeError(name, actual, expected, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     XMLSEC_ERRORS_R_INVALID_TYPE,           \ |  | ||||||
|                     "invalid type for '%s': actual='%s' and expected %s", \ |  | ||||||
|                     xmlSecErrorsSafeString(name),           \ |  | ||||||
|                     xmlSecErrorsSafeString(actual),         \ |  | ||||||
|                     (expected)                              \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidIntegerTypeError: |  | ||||||
|  * @name:               the name of the variable, parameter, etc. |  | ||||||
|  * @actual:             the actual value as an integer. |  | ||||||
|  * @expected:           the expected value(s) as a string. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting "invalid type" errors for integers. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidIntegerTypeError(name, actual, expected, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     XMLSEC_ERRORS_R_INVALID_TYPE,           \ |  | ||||||
|                     "invalid type for '%s': actual=%ld and expected %s", \ |  | ||||||
|                     xmlSecErrorsSafeString(name),           \ |  | ||||||
|                     (unsigned long)(actual),                \ |  | ||||||
|                     (expected)                              \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidIntegerTypeError2: |  | ||||||
|  * @name1:              the name of the first variable, parameter, etc. |  | ||||||
|  * @actual1:            the actual first value as an integer. |  | ||||||
|  * @name2:              the name of the second variable, parameter, etc. |  | ||||||
|  * @actual2:            the actual second value as an integer. |  | ||||||
|  * @expected:           the expected value(s) as a string. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting "invalid type" errors for integers. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidIntegerTypeError2(name1, actual1, name2, actual2, expected, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     XMLSEC_ERRORS_R_INVALID_TYPE,           \ |  | ||||||
|                     "invalid type: actual value '%s'=%ld, actual value '%s'=%ld and expected %s", \ |  | ||||||
|                     xmlSecErrorsSafeString(name1),          \ |  | ||||||
|                     (unsigned long)(actual1),               \ |  | ||||||
|                     xmlSecErrorsSafeString(name2),          \ |  | ||||||
|                     (unsigned long)(actual2),               \ |  | ||||||
|                     (expected)                              \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidNodeError: |  | ||||||
|  * @actualNode:         the actual node. |  | ||||||
|  * @expectedNodeName:   the expected node name. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting an invalid node errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidNodeError(actualNode, expectedNodeName, errorObject) \ |  | ||||||
|     {                                                 \ |  | ||||||
|         const char* actualNodeName = xmlSecNodeGetName(actualNode); \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,               \ |  | ||||||
|                    (const char*)(errorObject),        \ |  | ||||||
|                    NULL,                              \ |  | ||||||
|                    XMLSEC_ERRORS_R_INVALID_NODE,      \ |  | ||||||
|                    "actual=%s; expected=%s",          \ |  | ||||||
|                    xmlSecErrorsSafeString(actualNodeName),  \ |  | ||||||
|                    xmlSecErrorsSafeString(expectedNodeName) \ |  | ||||||
|         );                                            \ |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidNodeContentError: |  | ||||||
|  * @node:               the node. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * @reason:             the reason why node content is invalid. |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting an invalid node content errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidNodeContentError(node, errorObject, reason) \ |  | ||||||
|     {                                                 \ |  | ||||||
|         const char* nName = xmlSecNodeGetName(node);  \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,               \ |  | ||||||
|                    (const char*)(errorObject),        \ |  | ||||||
|                    NULL,                              \ |  | ||||||
|                    XMLSEC_ERRORS_R_INVALID_NODE_CONTENT, \ |  | ||||||
|                    "node=%s; reason=%s",              \ |  | ||||||
|                    xmlSecErrorsSafeString(nName),     \ |  | ||||||
|                    xmlSecErrorsSafeString(reason)     \ |  | ||||||
|         );                                            \ |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidNodeAttributeError: |  | ||||||
|  * @node:               the node. |  | ||||||
|  * @attrName:           the attribute name. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * @reason:             the reason why node content is invalid. |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting an invalid node attribute errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidNodeAttributeError(node, attrName, errorObject, reason) \ |  | ||||||
|     {                                                 \ |  | ||||||
|         const char* nName = xmlSecNodeGetName(node);  \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,               \ |  | ||||||
|                    (const char*)(errorObject),        \ |  | ||||||
|                    NULL,                              \ |  | ||||||
|                    XMLSEC_ERRORS_R_INVALID_NODE_ATTRIBUTE, \ |  | ||||||
|                    "node=%s; attribute=%s; reason=%s",\ |  | ||||||
|                    xmlSecErrorsSafeString(nName),     \ |  | ||||||
|                    xmlSecErrorsSafeString(attrName),  \ |  | ||||||
|                    xmlSecErrorsSafeString(reason)     \ |  | ||||||
|         );                                            \ |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecNodeAlreadyPresentError: |  | ||||||
|  * @parent:             the parent node. |  | ||||||
|  * @nodeName:           the node name. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting node already present errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecNodeAlreadyPresentError(parent, nodeName, errorObject) \ |  | ||||||
|     {                                                 \ |  | ||||||
|         const char* pName = xmlSecNodeGetName(parent);\ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,               \ |  | ||||||
|                    (const char*)(errorObject),        \ |  | ||||||
|                    NULL,                              \ |  | ||||||
|                    XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT, \ |  | ||||||
|                    "parent=%s; node=%s",              \ |  | ||||||
|                    xmlSecErrorsSafeString(pName),     \ |  | ||||||
|                    xmlSecErrorsSafeString(nodeName)   \ |  | ||||||
|         );                                            \ |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecUnexpectedNodeError: |  | ||||||
|  * @node:               the node. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting an invalid node errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecUnexpectedNodeError(node, errorObject) \ |  | ||||||
|     {                                                 \ |  | ||||||
|         const char* nName = xmlSecNodeGetName(node);  \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,               \ |  | ||||||
|                    (const char*)(errorObject),        \ |  | ||||||
|                    NULL,                              \ |  | ||||||
|                    XMLSEC_ERRORS_R_UNEXPECTED_NODE,   \ |  | ||||||
|                    "node=%s",                         \ |  | ||||||
|                    xmlSecErrorsSafeString(nName)      \ |  | ||||||
|         );                                            \ |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecNodeNotFoundError: |  | ||||||
|  * @errorFunction:      the failed function. |  | ||||||
|  * @startNode:          the search start node. |  | ||||||
|  * @targetNodeName:     the expected child node name. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting node not found errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecNodeNotFoundError(errorFunction, startNode, targetNodeName, errorObject) \ |  | ||||||
|     {                                                 \ |  | ||||||
|         const char* startNodeName = xmlSecNodeGetName(startNode); \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,               \ |  | ||||||
|                    (const char*)(errorObject),        \ |  | ||||||
|                    (errorFunction),                   \ |  | ||||||
|                    XMLSEC_ERRORS_R_NODE_NOT_FOUND,    \ |  | ||||||
|                    "startNode=%s; target=%s",         \ |  | ||||||
|                    xmlSecErrorsSafeString(startNodeName), \ |  | ||||||
|                    xmlSecErrorsSafeString(targetNodeName) \ |  | ||||||
|         );                                            \ |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidTransfromError: |  | ||||||
|  * @transform:          the transform. |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting an invalid transform errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidTransfromError(transform) \ |  | ||||||
|     {                                                 \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,               \ |  | ||||||
|                    (const char*)xmlSecTransformGetName(transform), \ |  | ||||||
|                    NULL,                              \ |  | ||||||
|                    XMLSEC_ERRORS_R_INVALID_TRANSFORM, \ |  | ||||||
|                    XMLSEC_ERRORS_NO_MESSAGE           \ |  | ||||||
|         );                                            \ |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidTransfromError2: |  | ||||||
|  * @transform:          the transform. |  | ||||||
|  * @msg:                the extra message. |  | ||||||
|  * @param:              the extra message param. |  | ||||||
|  * |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting an invalid transform errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidTransfromError2(transform, msg, param) \ |  | ||||||
|     {                                                 \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,               \ |  | ||||||
|                    (const char*)xmlSecTransformGetName(transform), \ |  | ||||||
|                    NULL,                              \ |  | ||||||
|                    XMLSEC_ERRORS_R_INVALID_TRANSFORM, \ |  | ||||||
|                    (msg), (param)                     \ |  | ||||||
|         );                                            \ |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidTransfromStatusError: |  | ||||||
|  * @transform:          the transform. |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting an invalid transform status errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidTransfromStatusError(transform) \ |  | ||||||
|     {                                                 \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,               \ |  | ||||||
|                    (const char*)xmlSecTransformGetName(transform), \ |  | ||||||
|                    NULL,                              \ |  | ||||||
|                    XMLSEC_ERRORS_R_INVALID_STATUS,    \ |  | ||||||
|                    "transformStatus=%d",              \ |  | ||||||
|                    (int)((transform)->status)         \ |  | ||||||
|         );                                            \ |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidTransfromStatusError2: |  | ||||||
|  * @transform:          the transform. |  | ||||||
|  * @msg:                the extra message. |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting an invalid transform status errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidTransfromStatusError2(transform, msg) \ |  | ||||||
|     {                                                 \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,               \ |  | ||||||
|                    (const char*)xmlSecTransformGetName(transform), \ |  | ||||||
|                    NULL,                              \ |  | ||||||
|                    XMLSEC_ERRORS_R_INVALID_STATUS,    \ |  | ||||||
|                    "transformStatus=%ld, msg=%s",     \ |  | ||||||
|                    (long int)((transform)->status),   \ |  | ||||||
|                    msg                                \ |  | ||||||
|         );                                            \ |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidKeyDataSizeError: |  | ||||||
|  * @name:               the name of the variable, parameter, etc. |  | ||||||
|  * @actual:             the actual value. |  | ||||||
|  * @expected:           the expected value(s). |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting "invalid keydata size" errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidKeyDataSizeError(actual, expected, errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE,  \ |  | ||||||
|                     "invalid key data size: actual=%ld and expected=%ld", \ |  | ||||||
|                     (unsigned long)(actual),                \ |  | ||||||
|                     (unsigned long)(expected)               \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecInvalidZeroKeyDataSizeError: |  | ||||||
|  * @name:               the name of the variable, parameter, etc. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting "invalid keydata size" errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecInvalidZeroKeyDataSizeError(errorObject) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE,  \ |  | ||||||
|                     "invalid zero key data size"            \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecOtherError: |  | ||||||
|  * @code:               the error code. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * @details:            the error message. |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting other XMLSec errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecOtherError(code, errorObject, details) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     (code),                                 \ |  | ||||||
|                     "details=%s",                           \ |  | ||||||
|                     xmlSecErrorsSafeString(details)         \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecOtherError2: |  | ||||||
|  * @code:               the error code. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * @msg:                the extra message. |  | ||||||
|  * @param:              the extra message param. |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting other XMLSec errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecOtherError2(code, errorObject, msg, param) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     (code),                                 \ |  | ||||||
|                     (msg), (param)                          \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecOtherError3: |  | ||||||
|  * @code:               the error code. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * @msg:                the extra message. |  | ||||||
|  * @param1:             the extra message param. |  | ||||||
|  * @param2:             the extra message param. |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting other XMLSec errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecOtherError3(code, errorObject, msg, param1, param2) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     (code),                                 \ |  | ||||||
|                     (msg), (param1), (param2)               \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecOtherError4: |  | ||||||
|  * @code:               the error code. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * @msg:                the extra message. |  | ||||||
|  * @param1:             the extra message param. |  | ||||||
|  * @param2:             the extra message param. |  | ||||||
|  * @param3:             the extra message param. |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting other XMLSec errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecOtherError4(code, errorObject, msg, param1, param2, param3) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     (code),                                 \ |  | ||||||
|                     (msg), (param1), (param2), (param3)     \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * xmlSecOtherError5: |  | ||||||
|  * @code:               the error code. |  | ||||||
|  * @errorObject:        the error specific error object (e.g. transform, key data, etc). |  | ||||||
|  * @msg:                the extra message. |  | ||||||
|  * @param1:             the extra message param. |  | ||||||
|  * @param2:             the extra message param. |  | ||||||
|  * @param3:             the extra message param. |  | ||||||
|  * @param4:             the extra message param. |  | ||||||
|  * |  | ||||||
|  * Macro. The XMLSec library macro for reporting other XMLSec errors. |  | ||||||
|  */ |  | ||||||
| #define xmlSecOtherError5(code, errorObject, msg, param1, param2, param3, param4) \ |  | ||||||
|         xmlSecError(XMLSEC_ERRORS_HERE,                     \ |  | ||||||
|                     (const char*)(errorObject),             \ |  | ||||||
|                     NULL,                                   \ |  | ||||||
|                     (code),                                 \ |  | ||||||
|                     (msg), (param1), (param2), (param3), (param4) \ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| #ifdef __cplusplus |  | ||||||
| } |  | ||||||
| #endif /* __cplusplus */ |  | ||||||
|  |  | ||||||
| #endif /* __XMLSEC_ERROR_HELPERS_H__ */ |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,200 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> |  | ||||||
| <Invoice xmlns="http://www.dian.gov.co/contratos/facturaelectronica/v1" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns:cdt="urn:DocumentInformation:names:specification:ubl:colombia:schema:xsd:DocumentInformationAggregateComponents-1" xmlns:clm54217="urn:un:unece:uncefact:codelist:specification:54217:2001" xmlns:clmIANAMIMEMediaType="urn:un:unece:uncefact:codelist:specification:IANAMIMEMediaType:2003" xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" xmlns:qdt="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2" xmlns:sts="http://www.dian.gov.co/contratos/facturaelectronica/v1/Structures" xmlns:udt="urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xades="http://uri.etsi.org/01903/v1.3.2#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:sig="http://www.w3.org/2000/09/xmldsig#"> |  | ||||||
|   <ext:UBLExtensions> |  | ||||||
|     <ext:UBLExtension> |  | ||||||
|       <ext:ExtensionContent> |  | ||||||
|         <sts:DianExtensions> |  | ||||||
|           <sts:SoftwareSecurityCode schemeAgencyName="CO, DIAN (Dirección de Impuestos y Aduanas Nacionales)" schemeAgencyID="195">2bd9a18f23cf1188d36888d218e9b0c31df77aa00bc036eaeaa1619184054237eee56d2d8db4ecab0173f65f8dab7753</sts:SoftwareSecurityCode> |  | ||||||
|           <sts:AuthorizationProvider> |  | ||||||
|             <sts:AuthorizationProviderID schemeID="4" schemeName="31" schemeAgencyName="CO, DIAN (Dirección de Impuestos y Aduanas Nacionales)" schemeAgencyID="195">800197268</sts:AuthorizationProviderID> |  | ||||||
|           </sts:AuthorizationProvider> |  | ||||||
|           <sts:SoftwareProvider> |  | ||||||
|             <sts:ProviderID schemeAgencyName="CO, DIAN (Dirección de Impuestos y Aduanas Nacionales)" schemeAgencyID="195" schemeID="5" schemaName="31">900579212</sts:ProviderID> |  | ||||||
|             <sts:SoftwareID schemeAgencyName="CO, DIAN (Dirección de Impuestos y Aduanas Nacionales)" schemeAgencyID="195">01ab9caa-6838-461e-82fb-da44da36a084</sts:SoftwareID> |  | ||||||
|           </sts:SoftwareProvider> |  | ||||||
|           <sts:InvoiceSource> |  | ||||||
|             <cbc:IdentificationCode>CO</cbc:IdentificationCode> |  | ||||||
|           </sts:InvoiceSource> |  | ||||||
|           <sts:InvoiceControl> |  | ||||||
|             <sts:InvoiceAuthorization>fc8eac422eba16e22ffd8c6f94b3f40a6e38162c</sts:InvoiceAuthorization> |  | ||||||
|             <sts:AuthorizationPeriod> |  | ||||||
|               <cbc:StartDate>2019-01-19</cbc:StartDate> |  | ||||||
|               <cbc:EndDate>2030-01-19</cbc:EndDate> |  | ||||||
|             </sts:AuthorizationPeriod> |  | ||||||
|             <sts:AuthorizedInvoices> |  | ||||||
|               <sts:Prefix>SETP</sts:Prefix> |  | ||||||
|               <sts:From>990000000</sts:From> |  | ||||||
|               <sts:To>995000000</sts:To> |  | ||||||
|             </sts:AuthorizedInvoices> |  | ||||||
|           </sts:InvoiceControl> |  | ||||||
|         </sts:DianExtensions> |  | ||||||
|       </ext:ExtensionContent> |  | ||||||
|     </ext:UBLExtension> |  | ||||||
|   </ext:UBLExtensions> |  | ||||||
|   <cbc:UBLVersionID>UBL 2.1</cbc:UBLVersionID> |  | ||||||
|   <cbc:CustomizationID>10</cbc:CustomizationID> |  | ||||||
|   <cbc:ProfileID>DIAN 2.1</cbc:ProfileID> |  | ||||||
|   <cbc:ProfileExecutionID>2</cbc:ProfileExecutionID> |  | ||||||
|   <cbc:ID>SETP990000001</cbc:ID> |  | ||||||
|   <cbc:UUID schemeID="2" schemeName="CUFE-SHA384">50578625ce1fb2f6bb2bc57b22180d2763c8a868c4e62da72e0e43001f9c7f3459c81e2bf9324830175b1225af37e435</cbc:UUID> |  | ||||||
|   <cbc:DocumentCurrencyCode>COP</cbc:DocumentCurrencyCode> |  | ||||||
|   <cbc:IssueDate>2020-09-05</cbc:IssueDate> |  | ||||||
|   <cbc:IssueTime>22:38:53-05:00</cbc:IssueTime> |  | ||||||
|   <cbc:InvoiceTypeCode listAgencyID="195" listAgencyName="No matching global declaration available for the validation root" listURI="http://www.dian.gov.co">01</cbc:InvoiceTypeCode> |  | ||||||
|   <cbc:LineCountNumeric>1</cbc:LineCountNumeric> |  | ||||||
|   <cac:InvoicePeriod> |  | ||||||
|     <cbc:StartDate>2020-09-05</cbc:StartDate> |  | ||||||
|     <cbc:EndDate>2020-09-05</cbc:EndDate> |  | ||||||
|   </cac:InvoicePeriod> |  | ||||||
|   <cac:AccountingSupplierParty> |  | ||||||
|     <cbc:AdditionalAccountID>1</cbc:AdditionalAccountID> |  | ||||||
|     <cac:Party> |  | ||||||
|       <cac:PartyName> |  | ||||||
|         <cbc:Name>NEUROTEC TECNOLOGIA S.A.S</cbc:Name> |  | ||||||
|       </cac:PartyName> |  | ||||||
|       <cac:PhysicalLocation> |  | ||||||
|         <cac:Address> |  | ||||||
|           <cac:AddressLine> |  | ||||||
|             <cbc:Line/> |  | ||||||
|           </cac:AddressLine> |  | ||||||
|         </cac:Address> |  | ||||||
|       </cac:PhysicalLocation> |  | ||||||
|       <cac:PartyLegalEntity> |  | ||||||
|         <cbc:CompanyID schemeAgencyName="CO, DIAN (Dirección de Impuestos y Aduanas Nacionales)" schemeAgencyID="195" schemeID="5" schemeName="31">900579212</cbc:CompanyID> |  | ||||||
|         <cbc:RegistrationName>NEUROTEC TECNOLOGIA S.A.S</cbc:RegistrationName> |  | ||||||
|         <cac:RegistrationAddress> |  | ||||||
|           <cbc:CityName/> |  | ||||||
|           <cac:AddressLine> |  | ||||||
|             <cbc:Line/> |  | ||||||
|           </cac:AddressLine> |  | ||||||
|           <cac:Country> |  | ||||||
|             <cbc:IdentificationCode>CO</cbc:IdentificationCode> |  | ||||||
|             <cbc:Name>COLOMBIA</cbc:Name> |  | ||||||
|           </cac:Country> |  | ||||||
|         </cac:RegistrationAddress> |  | ||||||
|       </cac:PartyLegalEntity> |  | ||||||
|       <cac:PartyTaxScheme> |  | ||||||
|         <cbc:RegistrationName>NEUROTEC TECNOLOGIA S.A.S</cbc:RegistrationName> |  | ||||||
|         <cbc:CompanyID schemeAgencyName="CO, DIAN (Dirección de Impuestos y Aduanas Nacionales)" schemeAgencyID="195" schemeID="5" schemeName="31">900579212</cbc:CompanyID> |  | ||||||
|         <cbc:TaxLevelCode listName="48">O-07;O-09;O-14;O-48</cbc:TaxLevelCode> |  | ||||||
|         <cac:TaxScheme/> |  | ||||||
|       </cac:PartyTaxScheme> |  | ||||||
|       <cac:Contact> |  | ||||||
|         <cbc:ElectronicMail>sdds@sd.com</cbc:ElectronicMail> |  | ||||||
|       </cac:Contact> |  | ||||||
|     </cac:Party> |  | ||||||
|   </cac:AccountingSupplierParty> |  | ||||||
|   <cac:AccountingCustomerParty> |  | ||||||
|     <cbc:AdditionalAccountID>2</cbc:AdditionalAccountID> |  | ||||||
|     <cac:Party> |  | ||||||
|       <cac:PartyName> |  | ||||||
|         <cbc:Name>facho-customer</cbc:Name> |  | ||||||
|       </cac:PartyName> |  | ||||||
|       <cac:PhysicalLocation> |  | ||||||
|         <cac:Address> |  | ||||||
|           <cac:AddressLine> |  | ||||||
|             <cbc:Line/> |  | ||||||
|           </cac:AddressLine> |  | ||||||
|         </cac:Address> |  | ||||||
|       </cac:PhysicalLocation> |  | ||||||
|       <cac:PartyTaxScheme> |  | ||||||
|         <cbc:CompanyID schemeAgencyName="CO, DIAN (Dirección de Impuestos y Aduanas Nacionales)" schemeAgencyID="195" schemeID="" schemeName="13">43851425</cbc:CompanyID> |  | ||||||
|         <cbc:RegistrationName>facho-customer</cbc:RegistrationName> |  | ||||||
|         <cbc:TaxLevelCode>ZZ</cbc:TaxLevelCode> |  | ||||||
|         <cac:TaxScheme/> |  | ||||||
|       </cac:PartyTaxScheme> |  | ||||||
|       <cac:PartyLegalEntity> |  | ||||||
|         <cbc:RegistrationName>facho-customer</cbc:RegistrationName> |  | ||||||
|         <cac:RegistrationAddress> |  | ||||||
|           <cbc:CityName/> |  | ||||||
|           <cac:AddressLine> |  | ||||||
|             <cbc:Line/> |  | ||||||
|           </cac:AddressLine> |  | ||||||
|           <cac:Country> |  | ||||||
|             <cbc:IdentificationCode>CO</cbc:IdentificationCode> |  | ||||||
|             <cbc:Name>COLOMBIA</cbc:Name> |  | ||||||
|           </cac:Country> |  | ||||||
|         </cac:RegistrationAddress> |  | ||||||
|       </cac:PartyLegalEntity> |  | ||||||
|     </cac:Party> |  | ||||||
|   </cac:AccountingCustomerParty> |  | ||||||
|   <cac:LegalMonetaryTotal> |  | ||||||
|     <cbc:LineExtensionAmount currencyID="COP">100.00</cbc:LineExtensionAmount> |  | ||||||
|     <cbc:TaxExclusiveAmount currencyID="COP">100.00</cbc:TaxExclusiveAmount> |  | ||||||
|     <cbc:TaxInclusiveAmount currencyID="COP">119.00</cbc:TaxInclusiveAmount> |  | ||||||
|     <cbc:ChargeTotalAmount currencyID="COP">19.00</cbc:ChargeTotalAmount> |  | ||||||
|     <cbc:PayableAmount currencyID="COP">119.00</cbc:PayableAmount> |  | ||||||
|   </cac:LegalMonetaryTotal> |  | ||||||
|   <cac:TaxTotal/> |  | ||||||
|   <cac:TaxTotal> |  | ||||||
|     <cac:TaxSubtotal> |  | ||||||
|       <cac:TaxCategory> |  | ||||||
|         <cac:TaxScheme> |  | ||||||
|           <cbc:ID>01</cbc:ID> |  | ||||||
|         </cac:TaxScheme> |  | ||||||
|       </cac:TaxCategory> |  | ||||||
|     </cac:TaxSubtotal> |  | ||||||
|     <cbc:TaxAmount>19.00</cbc:TaxAmount> |  | ||||||
|   </cac:TaxTotal> |  | ||||||
|   <cac:TaxTotal> |  | ||||||
|     <cac:TaxSubtotal> |  | ||||||
|       <cac:TaxCategory> |  | ||||||
|         <cac:TaxScheme> |  | ||||||
|           <cbc:ID>04</cbc:ID> |  | ||||||
|         </cac:TaxScheme> |  | ||||||
|       </cac:TaxCategory> |  | ||||||
|     </cac:TaxSubtotal> |  | ||||||
|     <cbc:TaxAmount>0.00</cbc:TaxAmount> |  | ||||||
|   </cac:TaxTotal> |  | ||||||
|   <cac:TaxTotal> |  | ||||||
|     <cac:TaxSubtotal> |  | ||||||
|       <cac:TaxCategory> |  | ||||||
|         <cac:TaxScheme> |  | ||||||
|           <cbc:ID>03</cbc:ID> |  | ||||||
|         </cac:TaxScheme> |  | ||||||
|       </cac:TaxCategory> |  | ||||||
|     </cac:TaxSubtotal> |  | ||||||
|     <cbc:TaxAmount>0.00</cbc:TaxAmount> |  | ||||||
|   </cac:TaxTotal> |  | ||||||
|   <cac:InvoiceLine> |  | ||||||
|     <cbc:ID>1</cbc:ID> |  | ||||||
|     <cbc:InvoicedQuantity unitCode="NAR">1</cbc:InvoicedQuantity> |  | ||||||
|     <cbc:LineExtensionAmount currencyID="COP">100.0</cbc:LineExtensionAmount> |  | ||||||
|     <cac:TaxTotal> |  | ||||||
|       <cbc:TaxAmount currencyID="COP">19.0</cbc:TaxAmount> |  | ||||||
|       <cac:TaxSubtotal> |  | ||||||
|         <cbc:TaxableAmount currencyID="COP">100.0</cbc:TaxableAmount> |  | ||||||
|         <cbc:TaxAmount currencyID="COP">19.0</cbc:TaxAmount> |  | ||||||
|         <cac:TaxCategory> |  | ||||||
|           <cbc:Percent>19.0</cbc:Percent> |  | ||||||
|           <cac:TaxScheme> |  | ||||||
|             <cbc:ID>01</cbc:ID> |  | ||||||
|             <cbc:Name>IVA</cbc:Name> |  | ||||||
|           </cac:TaxScheme> |  | ||||||
|         </cac:TaxCategory> |  | ||||||
|       </cac:TaxSubtotal> |  | ||||||
|     </cac:TaxTotal> |  | ||||||
|     <cac:PricingReference> |  | ||||||
|       <cac:AlternativeConditionPrice> |  | ||||||
|         <cbc:PriceAmount currencyID="COP">100.0</cbc:PriceAmount> |  | ||||||
|         <cbc:PriceTypeCode>01</cbc:PriceTypeCode> |  | ||||||
|         <cbc:PriceType>x</cbc:PriceType> |  | ||||||
|       </cac:AlternativeConditionPrice> |  | ||||||
|     </cac:PricingReference> |  | ||||||
|     <cac:Item> |  | ||||||
|       <cbc:Description>test</cbc:Description> |  | ||||||
|       <cac:StandardItemIdentification> |  | ||||||
|         <cbc:ID>9999</cbc:ID> |  | ||||||
|       </cac:StandardItemIdentification> |  | ||||||
|     </cac:Item> |  | ||||||
|     <cac:Price> |  | ||||||
|       <cbc:PriceAmount currencyID="COP">100.0</cbc:PriceAmount> |  | ||||||
|     </cac:Price> |  | ||||||
|   </cac:InvoiceLine> |  | ||||||
|   <cac:PaymentMeans> |  | ||||||
|     <cbc:ID>1</cbc:ID> |  | ||||||
|     <cbc:PaymentMeansCode>10</cbc:PaymentMeansCode> |  | ||||||
|     <cbc:PaymentDueDate>2020-09-05</cbc:PaymentDueDate> |  | ||||||
|     <cbc:PaymentID>1</cbc:PaymentID> |  | ||||||
|   </cac:PaymentMeans> |  | ||||||
| </Invoice> |  | ||||||
| @@ -1,7 +0,0 @@ | |||||||
| #!/bin/sh |  | ||||||
|  |  | ||||||
| set -ex |  | ||||||
|  |  | ||||||
| sh build_openssl.sh |  | ||||||
| sh build_libxml2.sh |  | ||||||
| sh build_xmlsec.sh |  | ||||||
| @@ -1,21 +0,0 @@ | |||||||
| #!/bin/sh |  | ||||||
|  |  | ||||||
| LIBXML2_VERSION=2.9.12 |  | ||||||
|  |  | ||||||
| tar xf libxml2-${LIBXML2_VERSION}.tar.gz |  | ||||||
|  |  | ||||||
| mv libxml2-${LIBXML2_VERSION} libxml2 |  | ||||||
|  |  | ||||||
| pushd libxml2 |  | ||||||
|  |  | ||||||
| wasiconfigure  ./configure --enable-static --without-http --without-ftp --without-modules --without-python --without-zlib --without-lzma --without-threads --host=x86_64 |  | ||||||
|  |  | ||||||
| wasimake make clean |  | ||||||
| wasimake make -j4 |  | ||||||
|  |  | ||||||
| popd |  | ||||||
|  |  | ||||||
| mkdir -p vendor/libxml2/lib |  | ||||||
| mkdir -p vendor/libxml2/include |  | ||||||
| cp -r libxml2/include/libxml2 vendor/libxml2/include |  | ||||||
| cp -r libxml2/.libs/libxml2.a vendor/libxml2/lib |  | ||||||
| @@ -1,41 +0,0 @@ | |||||||
| #!/bin/sh |  | ||||||
| # TOMADO DE: https://github.com/voltbuilder/openssl-wasm |  | ||||||
|  |  | ||||||
| OPENSSL_VERSION=1.1.1l |  | ||||||
|  |  | ||||||
| # get the source |  | ||||||
| tar xf openssl-${OPENSSL_VERSION}.tar.gz |  | ||||||
|  |  | ||||||
| patch -p0 < openssl-${OPENSSL_VERSION}.patch |  | ||||||
|  |  | ||||||
| cd openssl-${OPENSSL_VERSION} |  | ||||||
| make clean |  | ||||||
|  |  | ||||||
| set -e |  | ||||||
|  |  | ||||||
| # why ./Configure instead of ./config? We want to force using the generic gcc profile which is more conservative than linux-x32 |  | ||||||
| # -no-sock - we don't have sockets in WASI |  | ||||||
| # new -no-ui-console - sdk 12 has no termios??? |  | ||||||
| # check in 12 -DHAVE_FORK=0 - no fork() in WASI |  | ||||||
| # new -D_WASI_EMULATED_MMAN - works with the library below to enable WASI mman emulation |  | ||||||
| # new -D_WASI_EMULATED_SIGNAL - with sdk 12 |  | ||||||
| # new -DOPENSSL_NO_SECURE_MEMORY - wasi doesn't have secure mem (madvise, mlock, etc...) |  | ||||||
| # new -DNO_SYSLOG - get rid of need for patch above |  | ||||||
| # --with-rand-seed=getrandom (needed to force using getentropy because WASI has no /dev/random or getrandom) |  | ||||||
| wasiconfigure ./Configure gcc -no-sock -no-ui-console -DHAVE_FORK=0 -D_WASI_EMULATED_MMAN -D_WASI_EMULATED_SIGNAL -DOPENSSL_NO_SECURE_MEMORY -DNO_SYSLOG --with-rand-seed=getrandom |  | ||||||
|  |  | ||||||
| # enables stuff from mman.h (see define above) also add -lwasi-emulated-signal |  | ||||||
| #sed -i -e "s/CNF_EX_LIBS=/CNF_EX_LIBS=-lwasi-emulated-mman -lwasi-emulated-signal /g" Makefile |  | ||||||
|  |  | ||||||
| # build! |  | ||||||
| wasimake make -j4 build_generated libssl.a libcrypto.a |  | ||||||
|  |  | ||||||
| rm -rf ../vendor/openssl/include |  | ||||||
| mkdir -p ../vendor/openssl/include |  | ||||||
| cp -R include/openssl ../vendor/openssl/include |  | ||||||
|  |  | ||||||
| mkdir -p ../vendor/openssl/lib/ |  | ||||||
| cp libssl.a ../vendor/openssl/lib/ |  | ||||||
| cp libcrypto.a ../vendor/openssl/lib/ |  | ||||||
|  |  | ||||||
| exit 0 |  | ||||||
| @@ -1,14 +0,0 @@ | |||||||
| #!/bin/sh |  | ||||||
|  |  | ||||||
| XMLSEC1_VERSION=1.2.33 |  | ||||||
|  |  | ||||||
| tar xf xmlsec1-${XMLSEC1_VERSION}.tar.gz |  | ||||||
|  |  | ||||||
| cd xmlsec1-${XMLSEC1_VERSION} |  | ||||||
|  |  | ||||||
| cp -r ../libxml2 . |  | ||||||
| cp -r ../vendor . |  | ||||||
|  |  | ||||||
| wasiconfigure ./configure --with-libxml-src=`pwd`/libxml2 --with-openssl=`pwd`/vendor/openssl  --enable-static-linking  --disable-folders-search --disable-apps --disable-apps-crypto-dl --disable-crypto-dl |  | ||||||
|  |  | ||||||
| wasimake make -j4 |  | ||||||
| @@ -1,6 +0,0 @@ | |||||||
| # ejemplo |  | ||||||
|  |  | ||||||
| ~~~ |  | ||||||
| $ bash build.sh |  | ||||||
| $ wasirun ./a.out sign1-tmpl.xml example.key |  | ||||||
| ~~~ |  | ||||||
| @@ -1,12 +0,0 @@ | |||||||
| cp ../vendor/openssl/lib/*.a . |  | ||||||
| cp ../xmlsec1-1.2.33/src/.libs/*.a . |  | ||||||
| cp ../xmlsec1-1.2.33/src/openssl/.libs/*.a . |  | ||||||
| cp ../libxml2/.libs/libxml2.a . |  | ||||||
|  |  | ||||||
| mkdir -p include |  | ||||||
|  |  | ||||||
| cp -r ../libxml2/include/libxml include/ |  | ||||||
| cp -r ../xmlsec1-1.2.33/include/xmlsec include/ |  | ||||||
| cp -r ../vendor/openssl/include/* include/ |  | ||||||
|  |  | ||||||
| wasicc -Iinclude libxml2.a libcrypto.a libssl.a libxmlsec1.a libxmlsec1-openssl.a sign.c  |  | ||||||
| @@ -1,216 +0,0 @@ | |||||||
| /**  |  | ||||||
|  * XML Security Library example: Signing a template file. |  | ||||||
|  *  |  | ||||||
|  * Signs a template file using a key from PEM file |  | ||||||
|  *  |  | ||||||
|  * Usage:  |  | ||||||
|  *      ./sign1 <xml-tmpl> <pem-key>  |  | ||||||
|  * |  | ||||||
|  * Example: |  | ||||||
|  *      ./sign1 sign1-tmpl.xml rsakey.pem > sign1-res.xml |  | ||||||
|  * |  | ||||||
|  * The result signature could be validated using verify1 example: |  | ||||||
|  *      ./verify1 sign1-res.xml rsapub.pem |  | ||||||
|  * |  | ||||||
|  * This is free software; see Copyright file in the source |  | ||||||
|  * distribution for preciese wording. |  | ||||||
|  *  |  | ||||||
|  * Copyright (C) 2002-2016 Aleksey Sanin <aleksey@aleksey.com>. All Rights Reserved. |  | ||||||
|  */ |  | ||||||
| #include <stdlib.h> |  | ||||||
| #include <string.h> |  | ||||||
| #include <assert.h> |  | ||||||
|  |  | ||||||
| #include <libxml/tree.h> |  | ||||||
| #include <libxml/xmlmemory.h> |  | ||||||
| #include <libxml/parser.h> |  | ||||||
|  |  | ||||||
| #define XMLSEC_NO_XSLT |  | ||||||
| #define XMLSEC_CRYPTO_OPENSSL |  | ||||||
|  |  | ||||||
| #ifndef XMLSEC_NO_XSLT |  | ||||||
| #include <libxslt/xslt.h> |  | ||||||
| #include <libxslt/security.h> |  | ||||||
| #endif /* XMLSEC_NO_XSLT */ |  | ||||||
|  |  | ||||||
| #include <xmlsec/xmlsec.h> |  | ||||||
| #include <xmlsec/xmltree.h> |  | ||||||
| #include <xmlsec/xmldsig.h> |  | ||||||
| #include <xmlsec/crypto.h> |  | ||||||
|  |  | ||||||
| int sign_file(const char* tmpl_file, const char* key_file); |  | ||||||
|  |  | ||||||
| int  |  | ||||||
| main(int argc, char **argv) { |  | ||||||
| #ifndef XMLSEC_NO_XSLT |  | ||||||
|     xsltSecurityPrefsPtr xsltSecPrefs = NULL; |  | ||||||
| #endif /* XMLSEC_NO_XSLT */ |  | ||||||
| 	setenv("RANDFILE", "/dev/random", 1); |  | ||||||
|     assert(argv); |  | ||||||
|  |  | ||||||
|     if(argc != 3) { |  | ||||||
|         fprintf(stderr, "Error: wrong number of arguments.\n"); |  | ||||||
|         fprintf(stderr, "Usage: %s <tmpl-file> <key-file>\n", argv[0]); |  | ||||||
|         return(1); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     printf("template %s key %s\n", argv[1], argv[2]); |  | ||||||
|     /* Init libxml and libxslt libraries */ |  | ||||||
|     xmlInitParser(); |  | ||||||
|     LIBXML_TEST_VERSION |  | ||||||
|     xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS; |  | ||||||
|     xmlSubstituteEntitiesDefault(1); |  | ||||||
| #ifndef XMLSEC_NO_XSLT |  | ||||||
|     xmlIndentTreeOutput = 1;  |  | ||||||
| #endif /* XMLSEC_NO_XSLT */ |  | ||||||
|  |  | ||||||
|     /* Init libxslt */ |  | ||||||
| #ifndef XMLSEC_NO_XSLT |  | ||||||
|     /* disable everything */ |  | ||||||
|     xsltSecPrefs = xsltNewSecurityPrefs();  |  | ||||||
|     xsltSetSecurityPrefs(xsltSecPrefs,  XSLT_SECPREF_READ_FILE,        xsltSecurityForbid); |  | ||||||
|     xsltSetSecurityPrefs(xsltSecPrefs,  XSLT_SECPREF_WRITE_FILE,       xsltSecurityForbid); |  | ||||||
|     xsltSetSecurityPrefs(xsltSecPrefs,  XSLT_SECPREF_CREATE_DIRECTORY, xsltSecurityForbid); |  | ||||||
|     xsltSetSecurityPrefs(xsltSecPrefs,  XSLT_SECPREF_READ_NETWORK,     xsltSecurityForbid); |  | ||||||
|     xsltSetSecurityPrefs(xsltSecPrefs,  XSLT_SECPREF_WRITE_NETWORK,    xsltSecurityForbid); |  | ||||||
|     xsltSetDefaultSecurityPrefs(xsltSecPrefs);  |  | ||||||
| #endif /* XMLSEC_NO_XSLT */                 |  | ||||||
|  |  | ||||||
|     /* Init xmlsec library */ |  | ||||||
|     if(xmlSecInit() < 0) { |  | ||||||
|         fprintf(stderr, "Error: xmlsec initialization failed.\n"); |  | ||||||
|         return(-1); |  | ||||||
|     } |  | ||||||
| 	puts("done xmlSecInit"); |  | ||||||
|  |  | ||||||
|     /* Check loaded library version */ |  | ||||||
|     if(xmlSecCheckVersion() != 1) { |  | ||||||
|         fprintf(stderr, "Error: loaded xmlsec library version is not compatible.\n"); |  | ||||||
|         return(-1); |  | ||||||
|     } |  | ||||||
| 	puts("done xmlSecCheckVersion"); |  | ||||||
|     /* Load default crypto engine if we are supporting dynamic |  | ||||||
|      * loading for xmlsec-crypto libraries. Use the crypto library |  | ||||||
|      * name ("openssl", "nss", etc.) to load corresponding  |  | ||||||
|      * xmlsec-crypto library. |  | ||||||
|      */ |  | ||||||
| #ifdef XMLSEC_CRYPTO_DYNAMIC_LOADING |  | ||||||
|     if(xmlSecCryptoDLLoadLibrary(NULL) < 0) { |  | ||||||
|         fprintf(stderr, "Error: unable to load default xmlsec-crypto library. Make sure\n" |  | ||||||
|                         "that you have it installed and check shared libraries path\n" |  | ||||||
|                         "(LD_LIBRARY_PATH and/or LTDL_LIBRARY_PATH) environment variables.\n"); |  | ||||||
|         return(-1);      |  | ||||||
|     } |  | ||||||
| #endif /* XMLSEC_CRYPTO_DYNAMIC_LOADING */ |  | ||||||
|  |  | ||||||
|     /* Init crypto library */ |  | ||||||
|     if(xmlSecCryptoAppInit(NULL) < 0) { |  | ||||||
|         fprintf(stderr, "Error: crypto initialization failed.\n"); |  | ||||||
|         return(-1); |  | ||||||
|     } |  | ||||||
| puts("done xmlSecCryptoAppInit"); |  | ||||||
|     /* Init xmlsec-crypto library */ |  | ||||||
|     if(xmlSecCryptoInit() < 0) { |  | ||||||
|         fprintf(stderr, "Error: xmlsec-crypto initialization failed.\n"); |  | ||||||
|         return(-1); |  | ||||||
|     } |  | ||||||
| puts("done xmlSecCryptoInit"); |  | ||||||
|     if(sign_file(argv[1], argv[2]) < 0) { |  | ||||||
|         return(-1); |  | ||||||
|     }     |  | ||||||
|      |  | ||||||
|     /* Shutdown xmlsec-crypto library */ |  | ||||||
|     xmlSecCryptoShutdown(); |  | ||||||
|      |  | ||||||
|     /* Shutdown crypto library */ |  | ||||||
|     xmlSecCryptoAppShutdown(); |  | ||||||
|      |  | ||||||
|     /* Shutdown xmlsec library */ |  | ||||||
|     xmlSecShutdown(); |  | ||||||
|  |  | ||||||
|     /* Shutdown libxslt/libxml */ |  | ||||||
| #ifndef XMLSEC_NO_XSLT |  | ||||||
|     xsltFreeSecurityPrefs(xsltSecPrefs); |  | ||||||
|     xsltCleanupGlobals(); |  | ||||||
| #endif /* XMLSEC_NO_XSLT */ |  | ||||||
|     xmlCleanupParser(); |  | ||||||
|      |  | ||||||
|     return(0); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /**  |  | ||||||
|  * sign_file: |  | ||||||
|  * @tmpl_file:          the signature template file name. |  | ||||||
|  * @key_file:           the PEM private key file name. |  | ||||||
|  * |  | ||||||
|  * Signs the #tmpl_file using private key from #key_file. |  | ||||||
|  * |  | ||||||
|  * Returns 0 on success or a negative value if an error occurs. |  | ||||||
|  */ |  | ||||||
| int  |  | ||||||
| sign_file(const char* tmpl_file, const char* key_file) { |  | ||||||
|     xmlDocPtr doc = NULL; |  | ||||||
|     xmlNodePtr node = NULL; |  | ||||||
|     xmlSecDSigCtxPtr dsigCtx = NULL; |  | ||||||
|     int res = -1; |  | ||||||
|      |  | ||||||
|     assert(tmpl_file); |  | ||||||
|     assert(key_file); |  | ||||||
|  |  | ||||||
|     /* load template */ |  | ||||||
|     doc = xmlParseFile(tmpl_file); |  | ||||||
|     if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)){ |  | ||||||
|         fprintf(stderr, "Error: unable to parse file \"%s\"\n", tmpl_file); |  | ||||||
|         goto done;       |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     /* find start node */ |  | ||||||
|     node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs); |  | ||||||
|     if(node == NULL) { |  | ||||||
|         fprintf(stderr, "Error: start node not found in \"%s\"\n", tmpl_file); |  | ||||||
|         goto done;       |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /* create signature context, we don't need keys manager in this example */ |  | ||||||
|     dsigCtx = xmlSecDSigCtxCreate(NULL); |  | ||||||
|     if(dsigCtx == NULL) { |  | ||||||
|         fprintf(stderr,"Error: failed to create signature context\n"); |  | ||||||
|         goto done; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /* load private key, assuming that there is not password */ |  | ||||||
|     dsigCtx->signKey = xmlSecCryptoAppKeyLoad(key_file, xmlSecKeyDataFormatPem, NULL, NULL, NULL); |  | ||||||
|     if(dsigCtx->signKey == NULL) { |  | ||||||
|         fprintf(stderr,"Error: failed to load private pem key from \"%s\"\n", key_file); |  | ||||||
|         goto done; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /* set key name to the file name, this is just an example! */ |  | ||||||
|     if(xmlSecKeySetName(dsigCtx->signKey, key_file) < 0) { |  | ||||||
|         fprintf(stderr,"Error: failed to set key name for key from \"%s\"\n", key_file); |  | ||||||
|         goto done; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /* sign the template */ |  | ||||||
|     if(xmlSecDSigCtxSign(dsigCtx, node) < 0) { |  | ||||||
|         fprintf(stderr,"Error: signature failed\n"); |  | ||||||
|         goto done; |  | ||||||
|     } |  | ||||||
|          |  | ||||||
|     /* print signed document to stdout */ |  | ||||||
|     xmlDocDump(stdout, doc); |  | ||||||
|      |  | ||||||
|     /* success */ |  | ||||||
|     res = 0; |  | ||||||
|  |  | ||||||
| done:     |  | ||||||
|     /* cleanup */ |  | ||||||
|     if(dsigCtx != NULL) { |  | ||||||
|         xmlSecDSigCtxDestroy(dsigCtx); |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     if(doc != NULL) { |  | ||||||
|         xmlFreeDoc(doc);  |  | ||||||
|     } |  | ||||||
|     return(res); |  | ||||||
| } |  | ||||||
| @@ -1,27 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> |  | ||||||
| <!--  |  | ||||||
| XML Security Library example: Simple signature template file for sign1 example.  |  | ||||||
| --> |  | ||||||
| <Envelope xmlns="urn:envelope"> |  | ||||||
|   <Data> |  | ||||||
| 	Hello, World! |  | ||||||
|   </Data> |  | ||||||
|   <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> |  | ||||||
|     <SignedInfo> |  | ||||||
|       <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" /> |  | ||||||
|       <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" /> |  | ||||||
|       <Reference URI=""> |  | ||||||
|         <Transforms> |  | ||||||
|           <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /> |  | ||||||
|         </Transforms> |  | ||||||
|         <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /> |  | ||||||
|         <DigestValue></DigestValue> |  | ||||||
|       </Reference> |  | ||||||
|     </SignedInfo> |  | ||||||
|     <SignatureValue/> |  | ||||||
|     <KeyInfo> |  | ||||||
| 	<KeyName/> |  | ||||||
|     </KeyInfo> |  | ||||||
|   </Signature> |  | ||||||
| </Envelope> |  | ||||||
|  |  | ||||||
| @@ -1,199 +0,0 @@ | |||||||
| diff '--color=auto' -ruN openssl-1.1.1l/crypto/rand/rand_unix.c patch-1.1.1l/crypto/rand/rand_unix.c |  | ||||||
| --- openssl-1.1.1l/crypto/rand/rand_unix.c	2021-08-24 09:38:47.000000000 -0400 |  | ||||||
| +++ patch-1.1.1l/crypto/rand/rand_unix.c	2021-09-12 02:26:35.765347423 -0400 |  | ||||||
| @@ -372,36 +372,36 @@ |  | ||||||
|       * Note: Sometimes getentropy() can be provided but not implemented |  | ||||||
|       * internally. So we need to check errno for ENOSYS |  | ||||||
|       */ |  | ||||||
| -#  if defined(__GNUC__) && __GNUC__>=2 && defined(__ELF__) && !defined(__hpux) |  | ||||||
| -    extern int getentropy(void *buffer, size_t length) __attribute__((weak)); |  | ||||||
| +/* #  if defined(__GNUC__) && __GNUC__>=2 && defined(__ELF__) && !defined(__hpux) */ |  | ||||||
| +/*     extern int getentropy(void *buffer, size_t length) __attribute__((weak)); */ |  | ||||||
|   |  | ||||||
| -    if (getentropy != NULL) { |  | ||||||
| +/*     if (getentropy != NULL) { */ |  | ||||||
|          if (getentropy(buf, buflen) == 0) |  | ||||||
|              return (ssize_t)buflen; |  | ||||||
|          if (errno != ENOSYS) |  | ||||||
|              return -1; |  | ||||||
| -    } |  | ||||||
| -#  elif defined(__APPLE__) |  | ||||||
| -    if (CCRandomGenerateBytes(buf, buflen) == kCCSuccess) |  | ||||||
| -	    return (ssize_t)buflen; |  | ||||||
| - |  | ||||||
| -    return -1; |  | ||||||
| -#  else |  | ||||||
| -    union { |  | ||||||
| -        void *p; |  | ||||||
| -        int (*f)(void *buffer, size_t length); |  | ||||||
| -    } p_getentropy; |  | ||||||
| - |  | ||||||
| -    /* |  | ||||||
| -     * We could cache the result of the lookup, but we normally don't |  | ||||||
| -     * call this function often. |  | ||||||
| -     */ |  | ||||||
| -    ERR_set_mark(); |  | ||||||
| -    p_getentropy.p = DSO_global_lookup("getentropy"); |  | ||||||
| -    ERR_pop_to_mark(); |  | ||||||
| -    if (p_getentropy.p != NULL) |  | ||||||
| -        return p_getentropy.f(buf, buflen) == 0 ? (ssize_t)buflen : -1; |  | ||||||
| -#  endif |  | ||||||
| +/*     } */ |  | ||||||
| +/* #  elif defined(__APPLE__) */ |  | ||||||
| +/*     if (CCRandomGenerateBytes(buf, buflen) == kCCSuccess) */ |  | ||||||
| +/* 	    return (ssize_t)buflen; */ |  | ||||||
| + |  | ||||||
| +/*     return -1; */ |  | ||||||
| +/* #  else */ |  | ||||||
| +/*     union { */ |  | ||||||
| +/*         void *p; */ |  | ||||||
| +/*         int (*f)(void *buffer, size_t length); */ |  | ||||||
| +/*     } p_getentropy; */ |  | ||||||
| + |  | ||||||
| +/*     /\* */ |  | ||||||
| +/*      * We could cache the result of the lookup, but we normally don't */ |  | ||||||
| +/*      * call this function often. */ |  | ||||||
| +/*      *\/ */ |  | ||||||
| +/*     ERR_set_mark(); */ |  | ||||||
| +/*     p_getentropy.p = DSO_global_lookup("getentropy"); */ |  | ||||||
| +/*     ERR_pop_to_mark(); */ |  | ||||||
| +/*     if (p_getentropy.p != NULL) */ |  | ||||||
| +/*         return p_getentropy.f(buf, buflen) == 0 ? (ssize_t)buflen : -1; */ |  | ||||||
| +/* #  endif */ |  | ||||||
|   |  | ||||||
|      /* Linux supports this since version 3.17 */ |  | ||||||
|  #  if defined(__linux) && defined(__NR_getrandom) |  | ||||||
| @@ -635,12 +635,12 @@ |  | ||||||
|   */ |  | ||||||
|  size_t rand_pool_acquire_entropy(RAND_POOL *pool) |  | ||||||
|  { |  | ||||||
| -#  if defined(OPENSSL_RAND_SEED_NONE) |  | ||||||
| -    return rand_pool_entropy_available(pool); |  | ||||||
| -#  else |  | ||||||
| +/* #  if defined(OPENSSL_RAND_SEED_NONE) */ |  | ||||||
| +/*     return rand_pool_entropy_available(pool); */ |  | ||||||
| +/* #  else */ |  | ||||||
|      size_t entropy_available; |  | ||||||
|   |  | ||||||
| -#   if defined(OPENSSL_RAND_SEED_GETRANDOM) |  | ||||||
| +/* #   if defined(OPENSSL_RAND_SEED_GETRANDOM) */ |  | ||||||
|      { |  | ||||||
|          size_t bytes_needed; |  | ||||||
|          unsigned char *buffer; |  | ||||||
| @@ -664,7 +664,7 @@ |  | ||||||
|      entropy_available = rand_pool_entropy_available(pool); |  | ||||||
|      if (entropy_available > 0) |  | ||||||
|          return entropy_available; |  | ||||||
| -#   endif |  | ||||||
| +/* #   endif */ |  | ||||||
|   |  | ||||||
|  #   if defined(OPENSSL_RAND_SEED_LIBRANDOM) |  | ||||||
|      { |  | ||||||
| @@ -752,7 +752,7 @@ |  | ||||||
|  #   endif |  | ||||||
|   |  | ||||||
|      return rand_pool_entropy_available(pool); |  | ||||||
| -#  endif |  | ||||||
| +/* #  endif */ |  | ||||||
|  } |  | ||||||
|  # endif |  | ||||||
|  #endif |  | ||||||
| diff '--color=auto' -ruN openssl-1.1.1l/test/drbgtest.c patch-1.1.1l/test/drbgtest.c |  | ||||||
| --- openssl-1.1.1l/test/drbgtest.c	2021-08-24 09:38:47.000000000 -0400 |  | ||||||
| +++ patch-1.1.1l/test/drbgtest.c	2021-09-12 02:07:38.062332301 -0400 |  | ||||||
| @@ -22,8 +22,21 @@ |  | ||||||
|  # include <windows.h> |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
| +#ifndef HAVE_FORK |  | ||||||
| +# if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_VXWORKS) |  | ||||||
| +#  define HAVE_FORK 0 |  | ||||||
| +# else |  | ||||||
| +#  define HAVE_FORK 1 |  | ||||||
| +# endif |  | ||||||
| +#endif |  | ||||||
| + |  | ||||||
| +#if HAVE_FORK |  | ||||||
| +# undef NO_FORK |  | ||||||
| +#else |  | ||||||
| +# define NO_FORK |  | ||||||
| +#endif |  | ||||||
|   |  | ||||||
| -#if defined(OPENSSL_SYS_UNIX) |  | ||||||
| +#if defined(OPENSSL_SYS_UNIX) && !defined(NO_FORK) |  | ||||||
|  # include <sys/types.h> |  | ||||||
|  # include <sys/wait.h> |  | ||||||
|  # include <unistd.h> |  | ||||||
| @@ -676,7 +689,7 @@ |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|   |  | ||||||
| -#if defined(OPENSSL_SYS_UNIX) |  | ||||||
| +#if defined(OPENSSL_SYS_UNIX) && !defined(NO_FORK) |  | ||||||
|  /* |  | ||||||
|   * Test whether master, public and private DRBG are reseeded after |  | ||||||
|   * forking the process. |  | ||||||
| @@ -795,7 +808,7 @@ |  | ||||||
|          goto error; |  | ||||||
|      reset_drbg_hook_ctx(); |  | ||||||
|   |  | ||||||
| -#if defined(OPENSSL_SYS_UNIX) |  | ||||||
| +#if defined(OPENSSL_SYS_UNIX) && !defined(NO_FORK) |  | ||||||
|      if (!TEST_true(test_drbg_reseed_after_fork(master, public, private))) |  | ||||||
|          goto error; |  | ||||||
|  #endif |  | ||||||
| diff '--color=auto' -ruN openssl-1.1.1l/test/run_tests.pl patch-1.1.1l/test/run_tests.pl |  | ||||||
| --- openssl-1.1.1l/test/run_tests.pl	2021-08-24 09:38:47.000000000 -0400 |  | ||||||
| +++ patch-1.1.1l/test/run_tests.pl	2021-09-12 02:03:57.603451471 -0400 |  | ||||||
| @@ -28,7 +28,7 @@ |  | ||||||
|  my $recipesdir = catdir($srctop, "test", "recipes"); |  | ||||||
|  my $libdir = rel2abs(catdir($srctop, "util", "perl")); |  | ||||||
|   |  | ||||||
| -$ENV{OPENSSL_CONF} = catdir($srctop, "apps", "openssl.cnf"); |  | ||||||
| +$ENV{OPENSSL_CONF} = rel2abs(catdir($srctop, "apps", "openssl.cnf")); |  | ||||||
|   |  | ||||||
|  my %tapargs = |  | ||||||
|      ( verbosity => $ENV{VERBOSE} || $ENV{V} || $ENV{HARNESS_VERBOSE} ? 1 : 0, |  | ||||||
| diff '--color=auto' -ruN openssl-1.1.1l/util/perl/OpenSSL/Test.pm patch-1.1.1l/util/perl/OpenSSL/Test.pm |  | ||||||
| --- openssl-1.1.1l/util/perl/OpenSSL/Test.pm	2021-08-24 09:38:47.000000000 -0400 |  | ||||||
| +++ patch-1.1.1l/util/perl/OpenSSL/Test.pm	2021-09-12 02:01:14.155136681 -0400 |  | ||||||
| @@ -65,7 +65,7 @@ |  | ||||||
|                               rel2abs/; |  | ||||||
|  use File::Path 2.00 qw/rmtree mkpath/; |  | ||||||
|  use File::Basename; |  | ||||||
| -use Cwd qw/getcwd abs_path/; |  | ||||||
| +use Cwd qw/abs_path/; |  | ||||||
|   |  | ||||||
|  my $level = 0; |  | ||||||
|   |  | ||||||
| @@ -904,26 +904,26 @@ |  | ||||||
|      BAIL_OUT("Must run setup() first") if (! $test_name); |  | ||||||
|   |  | ||||||
|      my $f = pop; |  | ||||||
| -    return abs2rel(catfile($directories{SRCTOP},@_,$f),getcwd); |  | ||||||
| +    return catfile($directories{SRCTOP},@_,$f); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  sub __srctop_dir { |  | ||||||
|      BAIL_OUT("Must run setup() first") if (! $test_name); |  | ||||||
|   |  | ||||||
| -    return abs2rel(catdir($directories{SRCTOP},@_), getcwd); |  | ||||||
| +    return catdir($directories{SRCTOP},@_); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  sub __bldtop_file { |  | ||||||
|      BAIL_OUT("Must run setup() first") if (! $test_name); |  | ||||||
|   |  | ||||||
|      my $f = pop; |  | ||||||
| -    return abs2rel(catfile($directories{BLDTOP},@_,$f), getcwd); |  | ||||||
| +    return catfile($directories{BLDTOP},@_,$f); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  sub __bldtop_dir { |  | ||||||
|      BAIL_OUT("Must run setup() first") if (! $test_name); |  | ||||||
|   |  | ||||||
| -    return abs2rel(catdir($directories{BLDTOP},@_), getcwd); |  | ||||||
| +    return catdir($directories{BLDTOP},@_); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  # __exeext is a function that returns the platform dependent file extension |  | ||||||
							
								
								
									
										104
									
								
								facho/cli.py
									
									
									
									
									
								
							
							
						
						
									
										104
									
								
								facho/cli.py
									
									
									
									
									
								
							| @@ -200,18 +200,6 @@ def validate_invoice(invoice_path): | |||||||
|     XSD.validate(content, XSD.UBLInvoice) |     XSD.validate(content, XSD.UBLInvoice) | ||||||
|  |  | ||||||
|  |  | ||||||
| @click.command() |  | ||||||
| @click.argument('nomina_path') |  | ||||||
| def validate_nominaindividual(nomina_path): |  | ||||||
|     from facho.fe.data.dian import XSD |  | ||||||
|     content = open(nomina_path, 'r').read() |  | ||||||
|     content = content.replace( |  | ||||||
|         'xmlns="http://www.dian.gov.co/contratos/facturaelectronica/v1"', |  | ||||||
|         'xmlns="dian:gov:co:facturaelectronica:NominaIndividual"', |  | ||||||
|     ) |  | ||||||
|     XSD.validate(content, XSD.NominaIndividual) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| @click.command() | @click.command() | ||||||
| @click.option('--private-key', type=click.Path(exists=True)) | @click.option('--private-key', type=click.Path(exists=True)) | ||||||
| @click.option('--passphrase') | @click.option('--passphrase') | ||||||
| @@ -227,7 +215,7 @@ def sign_xml(private_key, passphrase, xmlfile, ssl=True, use_cache_policy=False, | |||||||
|     if use_cache_policy: |     if use_cache_policy: | ||||||
|         warnings.warn("xades using cache policy") |         warnings.warn("xades using cache policy") | ||||||
|  |  | ||||||
|     signer = fe.DianXMLExtensionSigner(private_key, passphrase=passphrase, localpolicy=use_cache_policy) |     signer = fe.DianXMLExtensionSigner(private_key, passphrase=passphrase, mockpolicy=use_cache_policy) | ||||||
|     document = open(xmlfile, 'r').read().encode('utf-8') |     document = open(xmlfile, 'r').read().encode('utf-8') | ||||||
|     with open(output, 'w') as f: |     with open(output, 'w') as f: | ||||||
|         f.write(signer.sign_xml_string(document)) |         f.write(signer.sign_xml_string(document)) | ||||||
| @@ -259,14 +247,14 @@ def generate_invoice(private_key, passphrase, scriptname, generate=False, ssl=Tr | |||||||
|     spec.loader.exec_module(module) |     spec.loader.exec_module(module) | ||||||
|  |  | ||||||
|     import facho.fe.form as form |     import facho.fe.form as form | ||||||
|     from facho.fe.form_xml import DIANInvoiceXML, DIANWriteSigned, DIANWrite, DIANSupportDocumentXML |     from facho.fe.form_xml import DIANInvoiceXML, DIANWriteSigned,DIANWrite | ||||||
|     from facho import fe |     from facho import fe | ||||||
|  |  | ||||||
|     try: |     try: | ||||||
|         invoice_xml = module.document_xml() |         invoice_xml = module.document_xml() | ||||||
|     except AttributeError: |     except AttributeError: | ||||||
|         #invoice_xml = DIANInvoiceXML |         invoice_xml = DIANInvoiceXML | ||||||
|         invoice_xml = DIANSupportDocumentXML  |  | ||||||
|     print("Using document xml:", invoice_xml) |     print("Using document xml:", invoice_xml) | ||||||
|     invoice = module.invoice() |     invoice = module.invoice() | ||||||
|     invoice.calculate() |     invoice.calculate() | ||||||
| @@ -283,65 +271,6 @@ def generate_invoice(private_key, passphrase, scriptname, generate=False, ssl=Tr | |||||||
|         else: |         else: | ||||||
|             DIANWrite(xml, output) |             DIANWrite(xml, output) | ||||||
|  |  | ||||||
| @click.command() |  | ||||||
| @click.option('--private-key', type=click.Path(exists=True)) |  | ||||||
| @click.option('--passphrase') |  | ||||||
| @click.option('--ssl/--no-ssl', default=False) |  | ||||||
| @click.option('--sign/--no-sign', default=False) |  | ||||||
| @click.option('--use-cache-policy/--no-use-cache-policy', default=False) |  | ||||||
| @click.argument('scriptname', type=click.Path(exists=True), required=True) |  | ||||||
| @click.argument('output', required=True) |  | ||||||
| def generate_nomina(private_key, passphrase, scriptname, ssl=True, sign=False, use_cache_policy=False, output=None): |  | ||||||
|     """ |  | ||||||
|     imprime xml en pantalla. |  | ||||||
|     SCRIPTNAME espera |  | ||||||
|      def nomina() -> fe.nomina.NominaIndividual |  | ||||||
|      def extensions(fe.nomina.NominaIndividual): -> List[facho.FachoXMLExtension] |  | ||||||
|     """ |  | ||||||
|  |  | ||||||
|     if not ssl: |  | ||||||
|         disable_ssl() |  | ||||||
|  |  | ||||||
|     import importlib.util |  | ||||||
|  |  | ||||||
|     spec = importlib.util.spec_from_file_location('nomina', scriptname) |  | ||||||
|     module = importlib.util.module_from_spec(spec) |  | ||||||
|     spec.loader.exec_module(module) |  | ||||||
|  |  | ||||||
|     from facho.fe.form_xml import DIANWriteSigned, DIANWrite |  | ||||||
|     import facho.fe |  | ||||||
|  |  | ||||||
|     nomina = module.nomina() |  | ||||||
|  |  | ||||||
|     xml = nomina.toFachoXML() |  | ||||||
|  |  | ||||||
|     extensions = module.extensions(nomina) |  | ||||||
|     for extension in extensions: |  | ||||||
|         xml.add_extension(extension) |  | ||||||
|  |  | ||||||
|     if sign: |  | ||||||
|         DIANWriteSigned(xml, output, private_key, passphrase, use_cache_policy, dian_signer=facho.fe.nomina.DianXMLExtensionSigner) |  | ||||||
|     else: |  | ||||||
|         DIANWrite(xml, output) |  | ||||||
|  |  | ||||||
| @click.command() |  | ||||||
| @click.option('--private-key', required=True) |  | ||||||
| @click.option('--public-key', required=True) |  | ||||||
| @click.option('--habilitacion/--produccion', default=False) |  | ||||||
| @click.option('--password') |  | ||||||
| @click.argument('filename', required=True) |  | ||||||
| @click.argument('zipfile', type=click.Path(exists=True)) |  | ||||||
| def soap_send_nomina_sync(private_key, public_key, habilitacion, password, filename, zipfile): |  | ||||||
|     from facho.fe.client import dian |  | ||||||
|  |  | ||||||
|     client = dian.DianSignatureClient(private_key, public_key, password=password) |  | ||||||
|     req = dian.SendNominaSync |  | ||||||
|     if habilitacion: |  | ||||||
|         req = dian.Habilitacion.SendNominaSync |  | ||||||
|     resp = client.request(req( |  | ||||||
|         open(zipfile, 'rb').read() |  | ||||||
|     )) |  | ||||||
|     print(resp) |  | ||||||
|  |  | ||||||
| @click.command() | @click.command() | ||||||
| @click.option('--private-key', type=click.Path(exists=True)) | @click.option('--private-key', type=click.Path(exists=True)) | ||||||
| @@ -358,7 +287,7 @@ def sign_verify_xml(private_key, passphrase, xmlfile, ssl=True, use_cache_policy | |||||||
|         warnings.warn("xades using cache policy") |         warnings.warn("xades using cache policy") | ||||||
|  |  | ||||||
|     print("THIS ONLY WORKS FOR DOCUMENTS GENERATE WITH FACHO") |     print("THIS ONLY WORKS FOR DOCUMENTS GENERATE WITH FACHO") | ||||||
|     signer = fe.DianXMLExtensionSignerVerifier(private_key, passphrase=passphrase, localpolicy=use_cache_policy) |     signer = fe.DianXMLExtensionSignerVerifier(private_key, passphrase=passphrase, mockpolicy=use_cache_policy) | ||||||
|     document = open(xmlfile, 'r').read().encode('utf-8') |     document = open(xmlfile, 'r').read().encode('utf-8') | ||||||
|  |  | ||||||
|     if signer.verify_string(document): |     if signer.verify_string(document): | ||||||
| @@ -366,25 +295,6 @@ def sign_verify_xml(private_key, passphrase, xmlfile, ssl=True, use_cache_policy | |||||||
|     else: |     else: | ||||||
|         print("-INVALID") |         print("-INVALID") | ||||||
|  |  | ||||||
| @click.command() |  | ||||||
| @click.option('--software-id') |  | ||||||
| @click.option('--software-pin') |  | ||||||
| @click.option('--nit') |  | ||||||
| @click.option('--dv') |  | ||||||
| @click.option('--output-zippath') |  | ||||||
| def generate_nomina_habilitacion(software_id, software_pin, nit, dv, output_zippath): |  | ||||||
|     from facho import fe |  | ||||||
|  |  | ||||||
|     generador = fe.nomina.habilitacion.Habilitacion( |  | ||||||
|         fe.nomina.habilitacion.Habilitacion.Metadata( |  | ||||||
|             software_id=software_id, |  | ||||||
|             software_pin=software_pin, |  | ||||||
|             nit=nit, |  | ||||||
|             dv=dv |  | ||||||
|         ) |  | ||||||
|     ) |  | ||||||
|     generador.generar(output_zippath) |  | ||||||
|  |  | ||||||
| @click.group() | @click.group() | ||||||
| def main(): | def main(): | ||||||
|     pass |     pass | ||||||
| @@ -400,7 +310,3 @@ main.add_command(generate_invoice) | |||||||
| main.add_command(validate_invoice) | main.add_command(validate_invoice) | ||||||
| main.add_command(sign_xml) | main.add_command(sign_xml) | ||||||
| main.add_command(sign_verify_xml) | main.add_command(sign_verify_xml) | ||||||
| main.add_command(generate_nomina) |  | ||||||
| main.add_command(soap_send_nomina_sync) |  | ||||||
| main.add_command(validate_nominaindividual) |  | ||||||
| main.add_command(generate_nomina_habilitacion) |  | ||||||
|   | |||||||
							
								
								
									
										305
									
								
								facho/facho.py
									
									
									
									
									
								
							
							
						
						
									
										305
									
								
								facho/facho.py
									
									
									
									
									
								
							| @@ -1,15 +1,9 @@ | |||||||
| # This file is part of facho.  The COPYRIGHT file at the top level of | # This file is part of facho.  The COPYRIGHT file at the top level of | ||||||
| # this repository contains the full copyright notices and license terms. | # this repository contains the full copyright notices and license terms. | ||||||
|  |  | ||||||
| from lxml import etree | from lxml import etree | ||||||
| from lxml.etree import Element, tostring | from lxml.etree import Element, SubElement, tostring | ||||||
| import re | import re | ||||||
| from collections import defaultdict |  | ||||||
| from copy import deepcopy |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class FachoValueInvalid(Exception): |  | ||||||
|     def __init__(self, xpath): |  | ||||||
|         super().__init__('FachoValueInvalid invalid xpath %s' % (xpath)) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class FachoXMLExtension: | class FachoXMLExtension: | ||||||
| @@ -31,10 +25,7 @@ class LXMLBuilder: | |||||||
|  |  | ||||||
|     def __init__(self, nsmap): |     def __init__(self, nsmap): | ||||||
|         self.nsmap = nsmap |         self.nsmap = nsmap | ||||||
|         self._re_node_expr = \ |         self._re_node_expr = re.compile(r'^(?P<path>((?P<ns>\w+):)?(?P<tag>[a-zA-Z0-9_-]+))(?P<attrs>\[.+\])?') | ||||||
|             re.compile( |  | ||||||
|                 r'^(?P<path>((?P<ns>\w+):)?(?P<tag>[a-zA-Z0-9_-]+))' |  | ||||||
|                 r'(?P<attrs>\[.+\])?') |  | ||||||
|         self._re_attrs = re.compile(r'(\w+)\s*=\s*\"?(\w+)\"?') |         self._re_attrs = re.compile(r'(\w+)\s*=\s*\"?(\w+)\"?') | ||||||
|  |  | ||||||
|     def match_expression(self, node_expr): |     def match_expression(self, node_expr): | ||||||
| @@ -91,64 +82,29 @@ class LXMLBuilder: | |||||||
|     def append(self, elem, child): |     def append(self, elem, child): | ||||||
|         elem.append(child) |         elem.append(child) | ||||||
|  |  | ||||||
|     def append_next(self, elem, slibing): |  | ||||||
|         elem.addnext(slibing) |  | ||||||
|  |  | ||||||
|     def remove(self, elem): |     def remove(self, elem): | ||||||
|         elem.getparent().remove(elem) |         elem.getparent().remove(elem) | ||||||
|  |  | ||||||
|     def set_text(self, elem, text): |     def set_text(self, elem, text): | ||||||
|         elem.text = text |         elem.text = text | ||||||
|  |  | ||||||
|     def xpath(self, elem, xpath, multiple=False): |     def xpath(self, elem, xpath): | ||||||
|         elems = elem.xpath(xpath, namespaces=self.nsmap) |         elems = elem.xpath(xpath, namespaces=self.nsmap) | ||||||
|         if elems: |         if elems: | ||||||
|             if multiple: |             return elems[0] | ||||||
|                 return elems |  | ||||||
|             else: |  | ||||||
|                 return elems[0] |  | ||||||
|  |  | ||||||
|         return None |         return None | ||||||
|  |  | ||||||
|     def get_text(self, elem): |     def get_text(self, elem): | ||||||
|         return elem.text |         return elem.text | ||||||
|  |  | ||||||
|     def get_attribute(self, elem, key): |  | ||||||
|         return elem.attrib[key] |  | ||||||
|  |  | ||||||
|     def is_attribute(self, elem, key, value): |  | ||||||
|         return elem.get(key, False) == value |  | ||||||
|  |  | ||||||
|     def set_attribute(self,  elem, key, value): |     def set_attribute(self,  elem, key, value): | ||||||
|         elem.attrib[key] = value |         elem.attrib[key] = value | ||||||
|  |  | ||||||
|     @classmethod |     @classmethod | ||||||
|     def remove_attributes(cls, elem, keys, exclude=[]): |     def tostring(self, elem, **attrs): | ||||||
|         for key in keys: |  | ||||||
|             if key in exclude: |  | ||||||
|                 continue |  | ||||||
|  |  | ||||||
|             try: |  | ||||||
|                 del elem.attrib[key] |  | ||||||
|             except KeyError: |  | ||||||
|                 pass |  | ||||||
|  |  | ||||||
|     @classmethod |  | ||||||
|     def tostring(self, oelem, **attrs): |  | ||||||
|         elem = deepcopy(oelem) |  | ||||||
|  |  | ||||||
|         attrs['pretty_print'] = attrs.pop('pretty_print', False) |         attrs['pretty_print'] = attrs.pop('pretty_print', False) | ||||||
|         attrs['encoding'] = attrs.pop('encoding', 'UTF-8') |         attrs['encoding'] = attrs.pop('encoding', 'UTF-8') | ||||||
|  |  | ||||||
|         for el in elem.getiterator(): |  | ||||||
|             keys = filter(lambda key: key.startswith('facho_'), el.keys()) |  | ||||||
|             self.remove_attributes(el, keys, exclude=['facho_optional']) |  | ||||||
|  |  | ||||||
|             is_optional = el.get('facho_optional', 'False') == 'True' |  | ||||||
|             if is_optional and el.getchildren() == [] and el.keys() == [ |  | ||||||
|                     'facho_optional']: |  | ||||||
|                 el.getparent().remove(el) |  | ||||||
|  |  | ||||||
|         return tostring(elem, **attrs).decode('utf-8') |         return tostring(elem, **attrs).decode('utf-8') | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -156,8 +112,7 @@ class FachoXML: | |||||||
|     """ |     """ | ||||||
|     Decora XML con funciones de consulta XPATH de un solo elemento |     Decora XML con funciones de consulta XPATH de un solo elemento | ||||||
|     """ |     """ | ||||||
|     def __init__(self, root, builder=None, nsmap=None, fragment_prefix='', |     def __init__(self, root, builder=None, nsmap=None, fragment_prefix=''): | ||||||
|                  fragment_root_element=None): |  | ||||||
|         if builder is None: |         if builder is None: | ||||||
|             self.builder = LXMLBuilder(nsmap) |             self.builder = LXMLBuilder(nsmap) | ||||||
|         else: |         else: | ||||||
| @@ -170,33 +125,20 @@ class FachoXML: | |||||||
|         else: |         else: | ||||||
|             self.root = root |             self.root = root | ||||||
|  |  | ||||||
|         self.fragment_root_element = fragment_root_element |  | ||||||
|         self.fragment_prefix = fragment_prefix |         self.fragment_prefix = fragment_prefix | ||||||
|         self.xpath_for = {} |         self.xpath_for = {} | ||||||
|         self.extensions = [] |         self.extensions = [] | ||||||
|         self._validators = defaultdict(lambda: lambda v, attrs: True) |  | ||||||
|  |  | ||||||
|     @classmethod |  | ||||||
|     def from_string(cls, document: str, namespaces: dict() = []) -> 'FachoXML': |  | ||||||
|         xml = LXMLBuilder.from_string(document) |  | ||||||
|         return FachoXML(xml, nsmap=namespaces) |  | ||||||
|  |  | ||||||
|     def root_namespace(self): |  | ||||||
|         return etree.QName(self.root).namespace |  | ||||||
|  |  | ||||||
|     def root_localname(self): |  | ||||||
|         return etree.QName(self.root).localname |  | ||||||
|  |  | ||||||
|     def append_element(self, elem, new_elem): |     def append_element(self, elem, new_elem): | ||||||
|         # elem = self.find_or_create_element(xpath, append=append) |         #elem = self.find_or_create_element(xpath, append=append) | ||||||
|         # self.builder.append(elem, new_elem) |         #self.builder.append(elem, new_elem) | ||||||
|         self.builder.append(elem, new_elem) |         self.builder.append(elem, new_elem) | ||||||
|  |  | ||||||
|     def add_extension(self, extension): |     def add_extension(self, extension): | ||||||
|         extension.build(self) |         extension.build(self) | ||||||
|  |  | ||||||
|     def fragment( |  | ||||||
|             self, xpath, append=False, append_not_exists=False): |     def fragment(self, xpath, append=False, append_not_exists=False): | ||||||
|         nodes = xpath.split('/') |         nodes = xpath.split('/') | ||||||
|         nodes.pop() |         nodes.pop() | ||||||
|         root_prefix = '/'.join(nodes) |         root_prefix = '/'.join(nodes) | ||||||
| @@ -206,9 +148,7 @@ class FachoXML: | |||||||
|  |  | ||||||
|         if parent is None: |         if parent is None: | ||||||
|             parent = self.find_or_create_element(xpath, append=append) |             parent = self.find_or_create_element(xpath, append=append) | ||||||
|         return FachoXML( |         return FachoXML(parent, nsmap=self.nsmap, fragment_prefix=root_prefix) | ||||||
|             parent, nsmap=self.nsmap, fragment_prefix=root_prefix, |  | ||||||
|             fragment_root_element=self.root) |  | ||||||
|  |  | ||||||
|     def register_alias_xpath(self, alias, xpath): |     def register_alias_xpath(self, alias, xpath): | ||||||
|         self.xpath_for[alias] = xpath |         self.xpath_for[alias] = xpath | ||||||
| @@ -224,12 +164,8 @@ class FachoXML: | |||||||
|     def _path_xpath_for(self, xpath): |     def _path_xpath_for(self, xpath): | ||||||
|         return self._normalize_xpath(self._translate_xpath_for(xpath)) |         return self._normalize_xpath(self._translate_xpath_for(xpath)) | ||||||
|  |  | ||||||
|     def placeholder_for(self, xpath, append=False, optional=False): |     def placeholder_for(self, xpath, append=False): | ||||||
|         elem = self.find_or_create_element(xpath, append) |         return self.find_or_create_element(xpath, append) | ||||||
|         if optional: |  | ||||||
|             elem.set('facho_optional', 'True') |  | ||||||
|         elem.set('facho_placeholder', 'True') |  | ||||||
|         return elem |  | ||||||
|  |  | ||||||
|     def replacement_for(self, xpath, new_xpath, content, **attrs): |     def replacement_for(self, xpath, new_xpath, content, **attrs): | ||||||
|         elem = self.get_element(xpath) |         elem = self.get_element(xpath) | ||||||
| @@ -244,8 +180,7 @@ class FachoXML: | |||||||
|         """ |         """ | ||||||
|         xpath = self._path_xpath_for(xpath) |         xpath = self._path_xpath_for(xpath) | ||||||
|         node_paths = xpath.split('/') |         node_paths = xpath.split('/') | ||||||
|         # remove empty / |         node_paths.pop(0) #remove empty / | ||||||
|         node_paths.pop(0) |  | ||||||
|         root_tag = node_paths.pop(0) |         root_tag = node_paths.pop(0) | ||||||
|  |  | ||||||
|         root_node = self.builder.build_from_expression(root_tag) |         root_node = self.builder.build_from_expression(root_tag) | ||||||
| @@ -253,21 +188,18 @@ class FachoXML: | |||||||
|             # restaurar ya que no es la raiz y asignar actual como raiz |             # restaurar ya que no es la raiz y asignar actual como raiz | ||||||
|             node_paths.insert(0, root_tag) |             node_paths.insert(0, root_tag) | ||||||
|             root_node = self.root |             root_node = self.root | ||||||
|  |              | ||||||
|         if not self.builder.same_tag(root_node.tag, self.root.tag): |         if not self.builder.same_tag(root_node.tag, self.root.tag): | ||||||
|             raise ValueError('xpath %s must be absolute to /%s' % ( |              | ||||||
|                 xpath, self.root.tag)) |             raise ValueError('xpath %s must be absolute to /%s' % (xpath, self.root.tag)) | ||||||
|  |  | ||||||
|         # crea jerarquia segun xpath indicado |         # crea jerarquia segun xpath indicado | ||||||
|         parent = None |         parent = None | ||||||
|         current_elem = self.root |         current_elem = self.root | ||||||
|         node_tag = node_paths.pop(-1) |  | ||||||
|  |  | ||||||
|         for node_path in node_paths: |         for node_path in node_paths: | ||||||
|             node_expr = self.builder.match_expression(node_path) |             node_expr = self.builder.match_expression(node_path) | ||||||
|             node = self.builder.build_from_expression(node_path) |             node = self.builder.build_from_expression(node_path) | ||||||
|             child = self.builder.find_relative( |             child = self.builder.find_relative(current_elem, node_expr['path'], self.nsmap) | ||||||
|                 current_elem, node_expr['path'], self.nsmap) |  | ||||||
|  |  | ||||||
|             parent = current_elem |             parent = current_elem | ||||||
|             if child is not None: |             if child is not None: | ||||||
| @@ -276,61 +208,15 @@ class FachoXML: | |||||||
|                 self.builder.append(current_elem, node) |                 self.builder.append(current_elem, node) | ||||||
|                 current_elem = node |                 current_elem = node | ||||||
|  |  | ||||||
|         node_expr = self.builder.match_expression(node_tag) |         # se fuerza la adicion como un nuevo elemento | ||||||
|         node = self.builder.build_from_expression(node_tag) |         if append: | ||||||
|         child = self.builder.find_relative( |             node = self.builder.build_from_expression(node_paths[-1]) | ||||||
|             current_elem, node_expr['path'], self.nsmap) |  | ||||||
|         parent = current_elem |  | ||||||
|         if child is not None: |  | ||||||
|             current_elem = child |  | ||||||
|  |  | ||||||
|         if parent == current_elem: |  | ||||||
|             self.builder.append(parent, node) |             self.builder.append(parent, node) | ||||||
|             return node |             return node | ||||||
|  |  | ||||||
|         # se fuerza la adicion como un nuevo elemento |  | ||||||
|         if append: |  | ||||||
|             last_slibing = None |  | ||||||
|             for child in parent.getchildren(): |  | ||||||
|                 if child.tag == node_tag: |  | ||||||
|                     last_slibing = child |  | ||||||
|  |  | ||||||
|             # si no ahi primos se adiciona como hijo |  | ||||||
|             if last_slibing is None: |  | ||||||
|                 self.builder.append(parent, node) |  | ||||||
|                 return node |  | ||||||
|  |  | ||||||
|             if self.builder.is_attribute( |  | ||||||
|                     last_slibing, 'facho_placeholder', 'True'): |  | ||||||
|                 self._remove_facho_attributes(last_slibing) |  | ||||||
|                 return last_slibing |  | ||||||
|             self.builder.append_next(last_slibing, node) |  | ||||||
|             return node |  | ||||||
|  |  | ||||||
|         if child is None: |  | ||||||
|             self.builder.append(current_elem, node) |  | ||||||
|             return node |  | ||||||
|  |  | ||||||
|         self._remove_facho_attributes(current_elem) |  | ||||||
|         return current_elem |         return current_elem | ||||||
|  |  | ||||||
|     def set_element_validator( |     def set_element(self, xpath, content, **attrs): | ||||||
|             self, xpath, validator=False): |  | ||||||
|         """ |  | ||||||
|         validador al asignar contenido a xpath indicado |  | ||||||
|  |  | ||||||
|         @param xpath ruta tipo XPath |  | ||||||
|         @param validator callback(content, attributes) |  | ||||||
|         """ |  | ||||||
|  |  | ||||||
|         key = self._path_xpath_for(xpath) |  | ||||||
|         if not validator: |  | ||||||
|             self._validators[key] = lambda v, attrs: True |  | ||||||
|         else: |  | ||||||
|             self._validators[key] = validator |  | ||||||
|  |  | ||||||
|     def set_element( |  | ||||||
|             self, xpath, content, **attrs): |  | ||||||
|         """ |         """ | ||||||
|         asigna contenido ubicado por ruta tipo XPATH. |         asigna contenido ubicado por ruta tipo XPATH. | ||||||
|         @param xpath ruta tipo XPATH |         @param xpath ruta tipo XPATH | ||||||
| @@ -341,18 +227,10 @@ class FachoXML: | |||||||
|         format_ = attrs.pop('format_', '%s') |         format_ = attrs.pop('format_', '%s') | ||||||
|         append_ = attrs.pop('append_', False) |         append_ = attrs.pop('append_', False) | ||||||
|         elem = self.find_or_create_element(xpath, append=append_) |         elem = self.find_or_create_element(xpath, append=append_) | ||||||
|  |  | ||||||
|         validator = self._validators[xpath] |  | ||||||
|  |  | ||||||
|         if not validator(content, attrs): |  | ||||||
|             raise FachoValueInvalid(xpath) |  | ||||||
|  |  | ||||||
|         if content: |         if content: | ||||||
|             self.builder.set_text(elem, format_ % content) |             self.builder.set_text(elem, format_ % content) | ||||||
|         for k, v in attrs.items(): |         for k, v in attrs.items(): | ||||||
|             if v is not None or str(v) != 'None': |             self.builder.set_attribute(elem, k, v) | ||||||
|                 self.builder.set_attribute(elem, k, str(v)) |  | ||||||
|  |  | ||||||
|         return elem |         return elem | ||||||
|  |  | ||||||
|     def set_attributes(self, xpath, **attrs): |     def set_attributes(self, xpath, **attrs): | ||||||
| @@ -363,143 +241,22 @@ class FachoXML: | |||||||
|         """ |         """ | ||||||
|         xpath = self._path_xpath_for(xpath) |         xpath = self._path_xpath_for(xpath) | ||||||
|         elem = self.get_element(xpath) |         elem = self.get_element(xpath) | ||||||
|  |  | ||||||
|         if elem is None: |  | ||||||
|             raise ValueError("xpath %s not found" % (xpath)) |  | ||||||
|  |  | ||||||
|         for k, v in attrs.items(): |         for k, v in attrs.items(): | ||||||
|             if v is not None or str(v) != 'None': |             self.builder.set_attribute(elem, k, v) | ||||||
|                 self.builder.set_attribute(elem, k, str(v)) |  | ||||||
|         return self |         return self | ||||||
|  |  | ||||||
|     def get_element_attribute( |     def get_element(self, xpath): | ||||||
|             self, xpath, attribute, multiple=False): |  | ||||||
|         elem = self.get_element(xpath, multiple=multiple) |  | ||||||
|  |  | ||||||
|         if elem is None: |  | ||||||
|             raise ValueError("xpath %s not found" % (xpath)) |  | ||||||
|  |  | ||||||
|         if multiple: |  | ||||||
|             vals = [] |  | ||||||
|             for e in elem: |  | ||||||
|                 vals.append(self.builder.get_attribute(e, attribute)) |  | ||||||
|             return vals |  | ||||||
|         else: |  | ||||||
|             return self.builder.get_attribute(elem, attribute) |  | ||||||
|  |  | ||||||
|     def get_element(self, xpath, multiple=False): |  | ||||||
|         xpath = self.fragment_prefix + self._path_xpath_for(xpath) |         xpath = self.fragment_prefix + self._path_xpath_for(xpath) | ||||||
|         return self.builder.xpath(self.root, xpath, multiple=multiple) |         return self.builder.xpath(self.root, xpath) | ||||||
|  |  | ||||||
|     def get_element_text(self, xpath, format_=str, multiple=False): |     def get_element_text(self, xpath, format_=str): | ||||||
|         xpath = self.fragment_prefix + self._path_xpath_for(xpath) |         xpath = self.fragment_prefix + self._path_xpath_for(xpath) | ||||||
|         # MACHETE(bit4bit) al usar ./ queda ../ |         elem = self.builder.xpath(self.root, xpath) | ||||||
|         xpath = re.sub(r'^\.\.+', '.', xpath) |         text = self.builder.get_text(elem) | ||||||
|  |         return format_(text) | ||||||
|         elem = self.builder.xpath(self.root, xpath, multiple=multiple) |  | ||||||
|         if multiple: |  | ||||||
|             vals = [] |  | ||||||
|             for e in elem: |  | ||||||
|                 text = self.builder.get_text(e) |  | ||||||
|                 if text is not None: |  | ||||||
|                     vals.append(format_(text)) |  | ||||||
|             return vals |  | ||||||
|         else: |  | ||||||
|             text = self.builder.get_text(elem) |  | ||||||
|             if text is None: |  | ||||||
|                 return None |  | ||||||
|             return format_(text) |  | ||||||
|  |  | ||||||
|     def get_element_text_or_attribute( |  | ||||||
|             self, xpath, default=None, multiple=False, raise_on_fail=False): |  | ||||||
|         parts = xpath.split('/') |  | ||||||
|         is_attribute = parts[-1].startswith('@') |  | ||||||
|         if is_attribute: |  | ||||||
|             attribute_name = parts.pop(-1).lstrip('@') |  | ||||||
|             element_path = "/".join(parts) |  | ||||||
|             try: |  | ||||||
|                 val = self.get_element_attribute( |  | ||||||
|                     element_path, attribute_name, multiple=multiple) |  | ||||||
|                 if val is None: |  | ||||||
|                     return default |  | ||||||
|                 return val |  | ||||||
|             except KeyError as e: |  | ||||||
|                 if raise_on_fail: |  | ||||||
|                     raise e |  | ||||||
|                 return default |  | ||||||
|             except ValueError as e: |  | ||||||
|                 if raise_on_fail: |  | ||||||
|                     raise e |  | ||||||
|                 return default |  | ||||||
|         else: |  | ||||||
|             try: |  | ||||||
|                 val = self.get_element_text(xpath, multiple=multiple) |  | ||||||
|                 if val is None: |  | ||||||
|                     return default |  | ||||||
|                 return val |  | ||||||
|             except ValueError as e: |  | ||||||
|                 if raise_on_fail: |  | ||||||
|                     raise e |  | ||||||
|                 return default |  | ||||||
|  |  | ||||||
|     def get_elements_text_or_attributes(self, xpaths, raise_on_fail=True): |  | ||||||
|         """ |  | ||||||
|         returna el contenido o attributos de un conjunto de XPATHS |  | ||||||
|         si algun XPATH es una tupla se retorna el primer elemento del mismo. |  | ||||||
|         """ |  | ||||||
|         vals = [] |  | ||||||
|         for xpath in xpaths: |  | ||||||
|             if isinstance(xpath, tuple): |  | ||||||
|                 val = xpath[0] |  | ||||||
|             else: |  | ||||||
|                 val = self.get_element_text_or_attribute( |  | ||||||
|                     xpath, raise_on_fail=raise_on_fail) |  | ||||||
|             vals.append(val) |  | ||||||
|         return vals |  | ||||||
|  |  | ||||||
|     def exist_element(self, xpath): |  | ||||||
|         elem = self.get_element(xpath) |  | ||||||
|  |  | ||||||
|         # no se encontro elemento |  | ||||||
|         if elem is None: |  | ||||||
|             return False |  | ||||||
|  |  | ||||||
|         # el placeholder no ha sido populado |  | ||||||
|         if elem.get('facho_placeholder') == 'True': |  | ||||||
|             return False |  | ||||||
|  |  | ||||||
|         # el valor opcional no ha sido populado |  | ||||||
|         if elem.get('facho_optional') == 'True': |  | ||||||
|             return False |  | ||||||
|  |  | ||||||
|         return True |  | ||||||
|  |  | ||||||
|     def _remove_facho_attributes(self, elem): |  | ||||||
|         self.builder.remove_attributes( |  | ||||||
|             elem, ['facho_optional', 'facho_placeholder']) |  | ||||||
|  |  | ||||||
|     def tostring(self, **kw): |     def tostring(self, **kw): | ||||||
|         return self.builder.tostring(self.root, **kw) |         return self.builder.tostring(self.root, **kw) | ||||||
|  |  | ||||||
|     def xpath_from_root(self, xpath): |  | ||||||
|         nsmap = {} |  | ||||||
|         ns = '' |  | ||||||
|  |  | ||||||
|         root = self.root |  | ||||||
|         if self.fragment_root_element is not None: |  | ||||||
|             root = self.fragment_root_element |  | ||||||
|  |  | ||||||
|         if isinstance(self.nsmap, dict): |  | ||||||
|             nsmap = dict(map(reversed, self.nsmap.items())) |  | ||||||
|             ns = nsmap[etree.QName(root).namespace] + ':' |  | ||||||
|  |  | ||||||
|         if self.fragment_root_element is not None: |  | ||||||
|             new_xpath = '/' + ns + etree.QName(root).localname + '/' + \ |  | ||||||
|                 etree.QName(self.root).localname + '/' + xpath.lstrip('/') |  | ||||||
|         else: |  | ||||||
|             new_xpath = '/' + ns + etree.QName(root).localname + '/' + \ |  | ||||||
|                 xpath.lstrip('/') |  | ||||||
|         return new_xpath |  | ||||||
|  |  | ||||||
|     def __str__(self): |     def __str__(self): | ||||||
|         return self.tostring() |         return self.tostring() | ||||||
|   | |||||||
| @@ -5,7 +5,6 @@ from .fe import DianXMLExtensionSigner | |||||||
| from .fe import DianXMLExtensionSoftwareSecurityCode | from .fe import DianXMLExtensionSoftwareSecurityCode | ||||||
| from .fe import DianXMLExtensionCUFE | from .fe import DianXMLExtensionCUFE | ||||||
| from .fe import DianXMLExtensionCUDE | from .fe import DianXMLExtensionCUDE | ||||||
| from .fe import DianXMLExtensionCUDS |  | ||||||
| from .fe import DianXMLExtensionInvoiceAuthorization | from .fe import DianXMLExtensionInvoiceAuthorization | ||||||
| from .fe import DianXMLExtensionSoftwareProvider | from .fe import DianXMLExtensionSoftwareProvider | ||||||
| from .fe import DianXMLExtensionAuthorizationProvider | from .fe import DianXMLExtensionAuthorizationProvider | ||||||
| @@ -13,4 +12,3 @@ from .fe import DianZIP | |||||||
| from .fe import AMBIENTE_PRUEBAS | from .fe import AMBIENTE_PRUEBAS | ||||||
| from .fe import AMBIENTE_PRODUCCION | from .fe import AMBIENTE_PRODUCCION | ||||||
| from . import form_xml | from . import form_xml | ||||||
| from . import nomina |  | ||||||
|   | |||||||
| @@ -27,7 +27,7 @@ class SOAPService: | |||||||
|     def get_service(self): |     def get_service(self): | ||||||
|         raise NotImplementedError() |         raise NotImplementedError() | ||||||
|  |  | ||||||
|     def build_response(self, as_dict): |     def builder_response(self, as_dict): | ||||||
|         raise NotImplementedError() |         raise NotImplementedError() | ||||||
|  |  | ||||||
|     def todict(self): |     def todict(self): | ||||||
| @@ -138,16 +138,10 @@ class GetStatusResponse: | |||||||
|  |  | ||||||
|     @classmethod |     @classmethod | ||||||
|     def fromdict(cls, data): |     def fromdict(cls, data): | ||||||
|         if data['ErrorMessage']: |  | ||||||
|             error_message = data['ErrorMessage']['string'] |  | ||||||
|         else: |  | ||||||
|             error_message = None |  | ||||||
|              |  | ||||||
|         return cls(data['IsValid'], |         return cls(data['IsValid'], | ||||||
|                    data['StatusDescription'], |                    data['StatusDescription'], | ||||||
|                    data['StatusCode'], |                    data['StatusCode'], | ||||||
|                    error_message) |                    data['ErrorMessage']['string']) | ||||||
|                     |  | ||||||
|  |  | ||||||
| @dataclass | @dataclass | ||||||
| class GetStatus(SOAPService): | class GetStatus(SOAPService): | ||||||
| @@ -175,20 +169,7 @@ class GetStatusZip(SOAPService): | |||||||
|     def build_response(self, as_dict): |     def build_response(self, as_dict): | ||||||
|         return GetStatusResponse.fromdict(as_dict[0]) |         return GetStatusResponse.fromdict(as_dict[0]) | ||||||
|  |  | ||||||
| @dataclass |  | ||||||
| class SendNominaSync(SOAPService): |  | ||||||
|     contentFile: bytes |  | ||||||
|  |  | ||||||
|     def get_wsdl(self): |  | ||||||
|         return 'https://vpfe.dian.gov.co/WcfDianCustomerServices.svc?wsdl' |  | ||||||
|  |  | ||||||
|     def get_service(self): |  | ||||||
|         return 'SendNominaSync' |  | ||||||
|  |  | ||||||
|     def build_response(self, as_dict): |  | ||||||
|         return as_dict |  | ||||||
|  |  | ||||||
|      |  | ||||||
| class Habilitacion: | class Habilitacion: | ||||||
|     WSDL = 'https://vpfe-hab.dian.gov.co/WcfDianCustomerServices.svc?wsdl' |     WSDL = 'https://vpfe-hab.dian.gov.co/WcfDianCustomerServices.svc?wsdl' | ||||||
|  |  | ||||||
| @@ -216,9 +197,6 @@ class Habilitacion: | |||||||
|         def get_wsdl(self): |         def get_wsdl(self): | ||||||
|             return Habilitacion.WSDL |             return Habilitacion.WSDL | ||||||
|  |  | ||||||
|     class SendNominaSync(SendNominaSync): |  | ||||||
|         def get_wsdl(self): |  | ||||||
|             return Habilitacion.WSDL |  | ||||||
|  |  | ||||||
| class DianGateway: | class DianGateway: | ||||||
|  |  | ||||||
|   | |||||||
| @@ -234,10 +234,9 @@ def _append_timestamp(security, expires_dt=None): | |||||||
|     if expires_dt is None: |     if expires_dt is None: | ||||||
|         expires_dt = timedelta(seconds=6000) |         expires_dt = timedelta(seconds=6000) | ||||||
|  |  | ||||||
|     timestamp = datetime.now() |  | ||||||
|     etimestamp = utils.WSU.Timestamp({'{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Id': utils.get_unique_id()}) |     etimestamp = utils.WSU.Timestamp({'{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Id': utils.get_unique_id()}) | ||||||
|     etimestamp.append(utils.WSU.Created(get_timestamp(timestamp=timestamp))) |     etimestamp.append(utils.WSU.Created(get_timestamp())) | ||||||
|     etimestamp.append(utils.WSU.Expires(get_timestamp(timestamp=timestamp, delta=expires_dt))) |     etimestamp.append(utils.WSU.Expires(get_timestamp(delta=expires_dt))) | ||||||
|     security.insert(0, etimestamp) |     security.insert(0, etimestamp) | ||||||
|     if etree.LXML_VERSION[:2] >= (3, 5): |     if etree.LXML_VERSION[:2] >= (3, 5): | ||||||
|         etree.cleanup_namespaces(security, |         etree.cleanup_namespaces(security, | ||||||
|   | |||||||
| @@ -9,8 +9,5 @@ def path_for_xsd(dirname, xsdname): | |||||||
|  |  | ||||||
| UBLInvoice= xmlschema.XMLSchema(path_for_xsd('maindoc', 'UBL-Invoice-2.1.xsd')) | UBLInvoice= xmlschema.XMLSchema(path_for_xsd('maindoc', 'UBL-Invoice-2.1.xsd')) | ||||||
|  |  | ||||||
| NominaIndividual = xmlschema.XMLSchema(path_for_xsd('nomina', 'NominaIndividualElectronicaXSDV1.0.6.xsd')) |  | ||||||
| NominaIndividualDeAjuste = xmlschema.XMLSchema(path_for_xsd('nomina', 'NominaIndividualDeAjusteElectronicaXSDV1.0.6.xsd')) |  | ||||||
|  |  | ||||||
| def validate(xml, schema): | def validate(xml, schema): | ||||||
|     schema.validate(xml) |     schema.validate(xml) | ||||||
|   | |||||||
| @@ -1,36 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> |  | ||||||
| <!-- |  | ||||||
|      creado por facho, la dian tiene oficial? |  | ||||||
|      poblar usando anexo tecnico 5.3.1 |  | ||||||
| --> |  | ||||||
| <gc:CodeList xmlns:gc="http://docs.oasis-open.org/codelist/ns/genericode/1.0/"> |  | ||||||
| 	<Identification> |  | ||||||
| 		<ShortName>Idioma</ShortName> |  | ||||||
| 		<LongName xml:lang="es">Idioma</LongName> |  | ||||||
| 		<Version>1</Version> |  | ||||||
| 	</Identification> |  | ||||||
| 	<ColumnSet> |  | ||||||
| 		<Column Id="iso-639-1" Use="required"> |  | ||||||
| 			<ShortName>ISO 639 1</ShortName> |  | ||||||
| 			<Data Type="normalizedString"/> |  | ||||||
| 		</Column> |  | ||||||
| 		<Column Id="name" Use="required"> |  | ||||||
| 			<ShortName>Nombre</ShortName> |  | ||||||
| 			<Data Type="normalizedString"/> |  | ||||||
| 		</Column> |  | ||||||
| 		<Key Id="codeKey"> |  | ||||||
| 			<ShortName>CodeKey</ShortName> |  | ||||||
| 			<ColumnRef Ref="code"/> |  | ||||||
| 		</Key> |  | ||||||
| 	</ColumnSet> |  | ||||||
| 	<SimpleCodeList> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="iso-639-1"> |  | ||||||
| 				<SimpleValue>es</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Español, castellano</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
|         </SimpleCodeList> |  | ||||||
| </gc:CodeList> |  | ||||||
| @@ -1,76 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> |  | ||||||
| <!-- |  | ||||||
|      creado por facho, la dian tiene oficial? |  | ||||||
|      poblar usando anexo tecnico 5.5.1 |  | ||||||
| --> |  | ||||||
| <gc:CodeList xmlns:gc="http://docs.oasis-open.org/codelist/ns/genericode/1.0/"> |  | ||||||
| 	<Identification> |  | ||||||
| 		<ShortName>PeriodoNomina</ShortName> |  | ||||||
| 		<LongName xml:lang="es">Periodos Nomina</LongName> |  | ||||||
| 		<Version>1</Version> |  | ||||||
| 	</Identification> |  | ||||||
| 	<ColumnSet> |  | ||||||
| 		<Column Id="code" Use="required"> |  | ||||||
| 			<ShortName>Code</ShortName> |  | ||||||
| 			<Data Type="normalizedString"/> |  | ||||||
| 		</Column> |  | ||||||
| 		<Column Id="name" Use="required"> |  | ||||||
| 			<ShortName>Nombre</ShortName> |  | ||||||
| 			<Data Type="normalizedString"/> |  | ||||||
| 		</Column> |  | ||||||
| 		<Key Id="codeKey"> |  | ||||||
| 			<ShortName>CodeKey</ShortName> |  | ||||||
| 			<ColumnRef Ref="code"/> |  | ||||||
| 		</Key> |  | ||||||
| 	</ColumnSet> |  | ||||||
| 	<SimpleCodeList> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>1</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Semanal</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>2</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Decenal</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>3</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Catorcenal</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>4</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Quincenal</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>5</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Mensual</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>6</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Otro</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
|         </SimpleCodeList> |  | ||||||
| </gc:CodeList> |  | ||||||
| @@ -1,44 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> |  | ||||||
| <!-- |  | ||||||
|      creado por facho, la dian tiene oficial? |  | ||||||
|      poblar usando anexo tecnico 5.5.4 |  | ||||||
| --> |  | ||||||
| <gc:CodeList xmlns:gc="http://docs.oasis-open.org/codelist/ns/genericode/1.0/"> |  | ||||||
| 	<Identification> |  | ||||||
| 		<ShortName>SubTipoTrabajador</ShortName> |  | ||||||
| 		<LongName xml:lang="es">Sub tipos de trabajador</LongName> |  | ||||||
| 		<Version>1</Version> |  | ||||||
| 	</Identification> |  | ||||||
| 	<ColumnSet> |  | ||||||
| 		<Column Id="code" Use="required"> |  | ||||||
| 			<ShortName>Code</ShortName> |  | ||||||
| 			<Data Type="normalizedString"/> |  | ||||||
| 		</Column> |  | ||||||
| 		<Column Id="name" Use="required"> |  | ||||||
| 			<ShortName>Nombre</ShortName> |  | ||||||
| 			<Data Type="normalizedString"/> |  | ||||||
| 		</Column> |  | ||||||
| 		<Key Id="codeKey"> |  | ||||||
| 			<ShortName>CodeKey</ShortName> |  | ||||||
| 			<ColumnRef Ref="code"/> |  | ||||||
| 		</Key> |  | ||||||
| 	</ColumnSet> |  | ||||||
| 	<SimpleCodeList> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>00</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>No Aplica</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>01</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Dependiente pensionado por vejez activo</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
|         </SimpleCodeList> |  | ||||||
| </gc:CodeList> |  | ||||||
| @@ -1,61 +1,50 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> | <?xml version="1.0" encoding="UTF-8"?> | ||||||
| <!-- DIAN Genericode listas de validacion :: Ultima modificación 18-02-2019 - evb--> | <!-- DIAN Genericode listas de validacion :: Ultima modificación 18-02-2019 - evb--> | ||||||
| <gc:CodeList xmlns:gc="http://docs.oasis-open.org/codelist/ns/genericode/1.0/"> | <gc:CodeList xmlns:gc="http://docs.oasis-open.org/codelist/ns/genericode/1.0/"> | ||||||
|    <Identification> |    <Identification> | ||||||
|       <ShortName>TarifaImpuestos</ShortName> |       <ShortName>TarifaImpuestos</ShortName> | ||||||
|       <LongName xml:lang="es">Tarifas por Impuesto</LongName> |       <LongName xml:lang="es">Tarifas por Impuesto</LongName> | ||||||
|       <Version>1</Version> |       <Version>1</Version> | ||||||
|       <CanonicalUri>urn:dian:names:especificacion:ubl:listacodigos:gc:TarifaImpuestos</CanonicalUri> |       <CanonicalUri>urn:dian:names:especificacion:ubl:listacodigos:gc:TarifaImpuestos</CanonicalUri> | ||||||
|       <CanonicalVersionUri>urn:dian:names:especificacion:ubl:listacodigos:gc:TarifaImpuestos-2.1</CanonicalVersionUri> |       <CanonicalVersionUri>urn:dian:names:especificacion:ubl:listacodigos:gc:TarifaImpuestos-2.1</CanonicalVersionUri> | ||||||
|       <LocationUri>http://dian.gov.co/ubl/os-ubl-2.0/cl/gc/default/TarifaImpuestos-2.1.gc</LocationUri> |       <LocationUri>http://dian.gov.co/ubl/os-ubl-2.0/cl/gc/default/TarifaImpuestos-2.1.gc</LocationUri> | ||||||
|       <Agency> |       <Agency> | ||||||
|          <LongName xml:lang="es">DIAN (Dirección de Impuestos y Aduanas Nacionales)</LongName> |          <LongName xml:lang="es">DIAN (Dirección de Impuestos y Aduanas Nacionales)</LongName> | ||||||
|          <Identifier>195</Identifier> |          <Identifier>195</Identifier> | ||||||
|       </Agency> |       </Agency> | ||||||
|    </Identification> |    </Identification> | ||||||
|    <ColumnSet> |    <ColumnSet> | ||||||
|       <Column Id="code" Use="required"> |       <Column Id="code" Use="required"> | ||||||
|          <ShortName>Code</ShortName> |          <ShortName>Code</ShortName> | ||||||
|          <LongName xml:lang="es">Codigo Comun</LongName> |          <LongName xml:lang="es">Codigo Comun</LongName> | ||||||
|          <Data Type="normalizedString"/> |          <Data Type="normalizedString"/> | ||||||
|       </Column> |       </Column> | ||||||
|       <Column Id="name" Use="required"> |       <Column Id="name" Use="required"> | ||||||
|          <ShortName>Name</ShortName> |          <ShortName>Name</ShortName> | ||||||
|          <LongName xml:lang="es">Nombre</LongName> |          <LongName xml:lang="es">Nombre</LongName> | ||||||
|          <Data Type="string"/> |          <Data Type="string"/> | ||||||
|       </Column> |       </Column> | ||||||
|       <Column Id="description" Use="required"> |       <Column Id="description" Use="required"> | ||||||
|          <ShortName>Description</ShortName> |          <ShortName>Description</ShortName> | ||||||
|          <LongName xml:lang="es">Descripcion</LongName> |          <LongName xml:lang="es">Descripcion</LongName> | ||||||
|          <Data Type="string"/> |          <Data Type="string"/> | ||||||
|       </Column> |       </Column> | ||||||
|       <Key Id="codeKey"> |       <Key Id="codeKey"> | ||||||
|          <ShortName>CodeKey</ShortName> |          <ShortName>CodeKey</ShortName> | ||||||
|          <ColumnRef Ref="code"/> |          <ColumnRef Ref="code"/> | ||||||
|       </Key> |       </Key> | ||||||
|    </ColumnSet> |    </ColumnSet> | ||||||
|    <SimpleCodeList> |    <SimpleCodeList> | ||||||
|       <Row> |       <Row> | ||||||
|          <Value ColumnRef="code"> |          <Value ColumnRef="code"> | ||||||
|             <SimpleValue>15.00</SimpleValue> |             <SimpleValue>15.00</SimpleValue> | ||||||
|          </Value> |          </Value> | ||||||
|          <Value ColumnRef="name"> |          <Value ColumnRef="name"> | ||||||
|             <SimpleValue>ReteIVA</SimpleValue> |             <SimpleValue>ReteIVA</SimpleValue> | ||||||
|          </Value> |          </Value> | ||||||
|          <Value ColumnRef="description"> |          <Value ColumnRef="description"> | ||||||
|             <SimpleValue>ReteIVA</SimpleValue> |             <SimpleValue>ReteIVA</SimpleValue> | ||||||
|          </Value> |          </Value> | ||||||
|       </Row> |       </Row> | ||||||
|       <Row> |    </SimpleCodeList> | ||||||
|          <Value ColumnRef="code"> | </gc:CodeList> | ||||||
|             <SimpleValue>100.00</SimpleValue> |  | ||||||
|          </Value> |  | ||||||
|          <Value ColumnRef="name"> |  | ||||||
|             <SimpleValue>ReteIVA</SimpleValue> |  | ||||||
|          </Value> |  | ||||||
|          <Value ColumnRef="description"> |  | ||||||
|             <SimpleValue>ReteIVA</SimpleValue> |  | ||||||
|          </Value> |  | ||||||
|       </Row> |  | ||||||
|    </SimpleCodeList> |  | ||||||
| </gc:CodeList> |  | ||||||
|   | |||||||
| @@ -1,68 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> |  | ||||||
| <!-- |  | ||||||
|      creado por facho, la dian tiene oficial? |  | ||||||
|      poblar usando anexo tecnico 5.5.2 |  | ||||||
| --> |  | ||||||
| <gc:CodeList xmlns:gc="http://docs.oasis-open.org/codelist/ns/genericode/1.0/"> |  | ||||||
| 	<Identification> |  | ||||||
| 		<ShortName>TipoContrato</ShortName> |  | ||||||
| 		<LongName xml:lang="es">Tipos de contratos</LongName> |  | ||||||
| 		<Version>1</Version> |  | ||||||
| 	</Identification> |  | ||||||
| 	<ColumnSet> |  | ||||||
| 		<Column Id="code" Use="required"> |  | ||||||
| 			<ShortName>Code</ShortName> |  | ||||||
| 			<Data Type="normalizedString"/> |  | ||||||
| 		</Column> |  | ||||||
| 		<Column Id="name" Use="required"> |  | ||||||
| 			<ShortName>Nombre</ShortName> |  | ||||||
| 			<Data Type="normalizedString"/> |  | ||||||
| 		</Column> |  | ||||||
| 		<Key Id="codeKey"> |  | ||||||
| 			<ShortName>CodeKey</ShortName> |  | ||||||
| 			<ColumnRef Ref="code"/> |  | ||||||
| 		</Key> |  | ||||||
| 	</ColumnSet> |  | ||||||
| 	<SimpleCodeList> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>1</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Termino Fijo</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>2</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Término Indefinido</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>3</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Obra o Labor</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>4</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Aprendizaje</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>5</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Pŕacticas o Pasantías</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
|         </SimpleCodeList> |  | ||||||
| </gc:CodeList> |  | ||||||
| @@ -1,122 +1,74 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> | <?xml version="1.0" encoding="UTF-8"?> | ||||||
| <!-- DIAN Genericode listas de valores: Ultima modificación 03-04-2022 - wcbr--> | <!-- DIAN Genericode listas de valores:: Ultima modificación 18-02-2019 - evb--> | ||||||
| <gc:CodeList xmlns:gc="http://docs.oasis-open.org/codelist/ns/genericode/1.0/"> | <gc:CodeList xmlns:gc="http://docs.oasis-open.org/codelist/ns/genericode/1.0/"> | ||||||
| 	<Identification> | 	<Identification> | ||||||
| 		<ShortName>TipoDocumento</ShortName> | 		<ShortName>TipoDocumento</ShortName> | ||||||
| 		<LongName xml:lang="es">Tipo de Documento</LongName> | 		<LongName xml:lang="es">Tipo de Documento</LongName> | ||||||
| 		<Version>1</Version> | 		<Version>1</Version> | ||||||
| 		<CanonicalUri>urn:dian:names:especificacion:ubl:listacodigos:gc:TipoDocumento</CanonicalUri> | 		<CanonicalUri>urn:dian:names:especificacion:ubl:listacodigos:gc:TipoDocumento</CanonicalUri> | ||||||
| 		<CanonicalVersionUri>urn:dian:names:especificacion:ubl:listacodigos:gc:TipoDocumento-2.1</CanonicalVersionUri> | 		<CanonicalVersionUri>urn:dian:names:especificacion:ubl:listacodigos:gc:TipoDocumento-2.1</CanonicalVersionUri> | ||||||
| 		<LocationUri>http://dian.gov.co/ubl/os-ubl-2.0/cl/gc/default/TipoDocumento-2.1.gc</LocationUri> | 		<LocationUri>http://dian.gov.co/ubl/os-ubl-2.0/cl/gc/default/TipoDocumento-2.1.gc</LocationUri> | ||||||
| 		<Agency> | 		<Agency> | ||||||
| 			<LongName xml:lang="es">DIAN (Dirección de Impuestos y Aduanas Nacionales)</LongName> | 			<LongName xml:lang="es">DIAN (Dirección de Impuestos y Aduanas Nacionales)</LongName> | ||||||
| 			<Identifier>195</Identifier> | 			<Identifier>195</Identifier> | ||||||
| 		</Agency> | 		</Agency> | ||||||
| 	</Identification> | 	</Identification> | ||||||
| 	<ColumnSet> | 	<ColumnSet> | ||||||
| 		<Column Id="code" Use="required"> | 		<Column Id="code" Use="required"> | ||||||
| 			<ShortName>Code</ShortName> | 			<ShortName>Code</ShortName> | ||||||
| 			<LongName xml:lang="es">Codigo Comun</LongName> | 			<LongName xml:lang="es">Codigo Comun</LongName> | ||||||
| 			<Data Type="normalizedString"/> | 			<Data Type="normalizedString"/> | ||||||
| 		</Column> | 		</Column> | ||||||
| 		<Column Id="name" Use="required"> | 		<Column Id="name" Use="required"> | ||||||
| 			<ShortName>Name</ShortName> | 			<ShortName>Name</ShortName> | ||||||
| 			<LongName xml:lang="es">Nombre</LongName> | 			<LongName xml:lang="es">Nombre</LongName> | ||||||
| 			<Data Type="string"/> | 			<Data Type="string"/> | ||||||
| 		</Column> | 		</Column> | ||||||
| 		<Key Id="codeKey"> | 		<Key Id="codeKey"> | ||||||
| 			<ShortName>CodeKey</ShortName> | 			<ShortName>CodeKey</ShortName> | ||||||
| 			<ColumnRef Ref="code"/> | 			<ColumnRef Ref="code"/> | ||||||
| 		</Key> | 		</Key> | ||||||
| 	</ColumnSet> | 	</ColumnSet> | ||||||
| 	<SimpleCodeList> | 	<SimpleCodeList> | ||||||
| 		<Row> | 		<Row> | ||||||
| 			<Value ColumnRef="code"> | 			<Value ColumnRef="code"> | ||||||
| 				<SimpleValue>01</SimpleValue> | 				<SimpleValue>01</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 			<Value ColumnRef="name"> | 			<Value ColumnRef="name"> | ||||||
| 				<SimpleValue>Factura electrónica de Venta</SimpleValue> | 				<SimpleValue>Factura de Venta Nacional</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 			<Value ColumnRef="description"> | 		</Row> | ||||||
| 				<SimpleValue>Tipos de factura</SimpleValue> | 		<Row> | ||||||
| 			</Value> | 			<Value ColumnRef="code"> | ||||||
| 		</Row> | 				<SimpleValue>02</SimpleValue> | ||||||
| 		<Row> | 			</Value> | ||||||
| 			<Value ColumnRef="code"> | 			<Value ColumnRef="name"> | ||||||
| 				<SimpleValue>02</SimpleValue> | 				<SimpleValue>Factura de Exportación </SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 			<Value ColumnRef="name"> | 		</Row> | ||||||
| 				<SimpleValue>Factura electrónica de venta con propósito de exportación</SimpleValue> | 		<Row> | ||||||
| 			</Value> | 			<Value ColumnRef="code"> | ||||||
| 			<Value ColumnRef="description"> | 				<SimpleValue>03</SimpleValue> | ||||||
| 				<SimpleValue>Tipos de factura</SimpleValue> | 			</Value> | ||||||
| 			</Value> | 			<Value ColumnRef="name"> | ||||||
| 		</Row> | 				<SimpleValue>Factura de Contingencia</SimpleValue> | ||||||
| 		<Row> | 			</Value> | ||||||
| 			<Value ColumnRef="code"> | 		</Row> | ||||||
| 				<SimpleValue>03</SimpleValue> | 		<Row> | ||||||
| 			</Value> | 			<Value ColumnRef="code"> | ||||||
| 			<Value ColumnRef="name"> | 				<SimpleValue>91</SimpleValue> | ||||||
| 				<SimpleValue>Factura de talonario o papel con numeración de contingencia.</SimpleValue> | 			</Value> | ||||||
| 			</Value> | 			<Value ColumnRef="name"> | ||||||
| 			<Value ColumnRef="description"> | 				<SimpleValue>Nota Crédito</SimpleValue> | ||||||
| 				<SimpleValue>Tipos de factura</SimpleValue> | 			</Value> | ||||||
| 			</Value> | 		</Row> | ||||||
| 		</Row> | 		<Row> | ||||||
| 		<Row> | 			<Value ColumnRef="code"> | ||||||
| 			<Value ColumnRef="code"> | 				<SimpleValue>92</SimpleValue> | ||||||
| 				<SimpleValue>04</SimpleValue> | 			</Value> | ||||||
| 			</Value> | 			<Value ColumnRef="name"> | ||||||
| 			<Value ColumnRef="name"> | 				<SimpleValue>Nota Débito</SimpleValue> | ||||||
| 				<SimpleValue>Factura electrónica de Venta  por Contingencia DIAN</SimpleValue> | 			</Value> | ||||||
| 			</Value> | 		</Row> | ||||||
| 			<Value ColumnRef="description"> | 	</SimpleCodeList> | ||||||
| 				<SimpleValue>Tipos de factura</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>91</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Nota Crédito</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="description"> |  | ||||||
| 				<SimpleValue>Exclusivo en referencias a documentos (elementos DocumentReference)</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>92</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Nota Débito</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="description"> |  | ||||||
| 				<SimpleValue>Exclusivo en referencias a documentos (elementos DocumentReference)</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>05</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Documento soporte en adquisiciones efectuadas a sujetos no obligados a expedir factura o documento equivalente</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="description"> |  | ||||||
| 				<SimpleValue>Tipo de documento</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>95</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Nota de ajuste al documento soporte en adquisiciones efectuadas a sujetos no obligados a expedir factura o documento equivalente</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="description"> |  | ||||||
| 				<SimpleValue>Exclusivo en referencias a documentos (elementos DocumentReference)</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
| 	</SimpleCodeList>	 |  | ||||||
| </gc:CodeList> | </gc:CodeList> | ||||||
|   | |||||||
| @@ -1,171 +1,162 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> | <?xml version="1.0" encoding="UTF-8"?> | ||||||
| <!-- DIAN Genericode listas de valores:: Ultima modificación 18-02-2019 - evb--> | <!-- DIAN Genericode listas de valores:: Ultima modificación 18-02-2019 - evb--> | ||||||
| <gc:CodeList xmlns:gc="http://docs.oasis-open.org/codelist/ns/genericode/1.0/"> | <gc:CodeList xmlns:gc="http://docs.oasis-open.org/codelist/ns/genericode/1.0/"> | ||||||
| 	<Identification> | 	<Identification> | ||||||
| 		<ShortName>TipoImpuesto</ShortName> | 		<ShortName>TipoImpuesto</ShortName> | ||||||
| 		<LongName xml:lang="es">Tipo de Tributos</LongName> | 		<LongName xml:lang="es">Tipo de Tributos</LongName> | ||||||
| 		<Version>1</Version> | 		<Version>1</Version> | ||||||
| 		<CanonicalUri>urn:dian:names:especificacion:ubl:listacodigos:gc:TipoImpuesto</CanonicalUri> | 		<CanonicalUri>urn:dian:names:especificacion:ubl:listacodigos:gc:TipoImpuesto</CanonicalUri> | ||||||
| 		<CanonicalVersionUri>urn:dian:names:especificacion:ubl:listacodigos:gc:TipoImpuesto-2.1</CanonicalVersionUri> | 		<CanonicalVersionUri>urn:dian:names:especificacion:ubl:listacodigos:gc:TipoImpuesto-2.1</CanonicalVersionUri> | ||||||
| 		<LocationUri>http://dian.gov.co/ubl/os-ubl-2.0/cl/gc/default/TipoImpuesto-2.1.gc</LocationUri> | 		<LocationUri>http://dian.gov.co/ubl/os-ubl-2.0/cl/gc/default/TipoImpuesto-2.1.gc</LocationUri> | ||||||
| 		<Agency> | 		<Agency> | ||||||
| 			<LongName xml:lang="es">DIAN (Dirección de Impuestos y Aduanas Nacionales)</LongName> | 			<LongName xml:lang="es">DIAN (Dirección de Impuestos y Aduanas Nacionales)</LongName> | ||||||
| 			<Identifier>195</Identifier> | 			<Identifier>195</Identifier> | ||||||
| 		</Agency> | 		</Agency> | ||||||
| 	</Identification> | 	</Identification> | ||||||
| 	<ColumnSet> | 	<ColumnSet> | ||||||
| 		<Column Id="code" Use="required"> | 		<Column Id="code" Use="required"> | ||||||
| 			<ShortName>Code</ShortName> | 			<ShortName>Code</ShortName> | ||||||
| 			<LongName xml:lang="es">Codigo Comun</LongName> | 			<LongName xml:lang="es">Codigo Comun</LongName> | ||||||
| 			<Data Type="normalizedString"/> | 			<Data Type="normalizedString"/> | ||||||
| 		</Column> | 		</Column> | ||||||
| 		<Column Id="name" Use="required"> | 		<Column Id="name" Use="required"> | ||||||
| 			<ShortName>Name</ShortName> | 			<ShortName>Name</ShortName> | ||||||
| 			<LongName xml:lang="es">Nombre</LongName> | 			<LongName xml:lang="es">Nombre</LongName> | ||||||
| 			<Data Type="string"/> | 			<Data Type="string"/> | ||||||
| 		</Column> | 		</Column> | ||||||
| 		<Key Id="codeKey"> | 		<Key Id="codeKey"> | ||||||
| 			<ShortName>CodeKey</ShortName> | 			<ShortName>CodeKey</ShortName> | ||||||
| 			<ColumnRef Ref="code"/> | 			<ColumnRef Ref="code"/> | ||||||
| 		</Key> | 		</Key> | ||||||
| 	</ColumnSet> | 	</ColumnSet> | ||||||
| 	<SimpleCodeList> | 	<SimpleCodeList> | ||||||
| 		<Row> | 		<Row> | ||||||
| 			<Value ColumnRef="code"> | 			<Value ColumnRef="code"> | ||||||
| 				<SimpleValue>01</SimpleValue> | 				<SimpleValue>01</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 			<Value ColumnRef="name"> | 			<Value ColumnRef="name"> | ||||||
| 				<SimpleValue>IVA</SimpleValue> | 				<SimpleValue>IVA</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 		</Row> | 		</Row> | ||||||
| 		<Row> | 		<Row> | ||||||
| 			<Value ColumnRef="code"> | 			<Value ColumnRef="code"> | ||||||
| 				<SimpleValue>02</SimpleValue> | 				<SimpleValue>02</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 			<Value ColumnRef="name"> | 			<Value ColumnRef="name"> | ||||||
| 				<SimpleValue>IC</SimpleValue> | 				<SimpleValue>IC</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 		</Row> | 		</Row> | ||||||
| 		<Row> | 		<Row> | ||||||
| 			<Value ColumnRef="code"> | 			<Value ColumnRef="code"> | ||||||
| 				<SimpleValue>03</SimpleValue> | 				<SimpleValue>03</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 			<Value ColumnRef="name"> | 			<Value ColumnRef="name"> | ||||||
| 				<SimpleValue>ICA</SimpleValue> | 				<SimpleValue>ICA</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 		</Row> | 		</Row> | ||||||
| 		<Row> | 		<Row> | ||||||
| 			<Value ColumnRef="code"> | 			<Value ColumnRef="code"> | ||||||
| 				<SimpleValue>04</SimpleValue> | 				<SimpleValue>04</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 			<Value ColumnRef="name"> | 			<Value ColumnRef="name"> | ||||||
| 				<SimpleValue>INC</SimpleValue> | 				<SimpleValue>INC</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 		</Row> | 		</Row> | ||||||
| 		<Row> | 		<Row> | ||||||
| 			<Value ColumnRef="code"> | 			<Value ColumnRef="code"> | ||||||
| 				<SimpleValue>05</SimpleValue> | 				<SimpleValue>05</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 			<Value ColumnRef="name"> | 			<Value ColumnRef="name"> | ||||||
| 				<SimpleValue>ReteIVA</SimpleValue> | 				<SimpleValue>ReteIVA</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 		</Row> | 		</Row> | ||||||
| 		<Row> | 		<Row> | ||||||
| 			<Value ColumnRef="code"> | 			<Value ColumnRef="code"> | ||||||
| 				<SimpleValue>06</SimpleValue> | 				<SimpleValue>06</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 			<Value ColumnRef="name"> | 			<Value ColumnRef="name"> | ||||||
| 				<SimpleValue>ReteRenta</SimpleValue> | 				<SimpleValue>ReteFuente</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 		</Row> | 		</Row> | ||||||
| 		<Row> | 		<Row> | ||||||
| 			<Value ColumnRef="code"> | 			<Value ColumnRef="code"> | ||||||
| 				<SimpleValue>07</SimpleValue> | 				<SimpleValue>07</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 			<Value ColumnRef="name"> | 			<Value ColumnRef="name"> | ||||||
| 				<SimpleValue>ReteICA</SimpleValue> | 				<SimpleValue>ReteICA</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 		</Row> | 		</Row> | ||||||
| 		<Row> | 		<Row> | ||||||
| 			<Value ColumnRef="code"> | 			<Value ColumnRef="code"> | ||||||
| 				<SimpleValue>08</SimpleValue> | 				<SimpleValue>08</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 			<Value ColumnRef="name"> | 			<Value ColumnRef="name"> | ||||||
| 				<SimpleValue>ReteCREE</SimpleValue> | 				<SimpleValue>ReteCREE</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 		</Row> | 		</Row> | ||||||
| 		<Row> | 		<Row> | ||||||
| 			<Value ColumnRef="code"> | 			<Value ColumnRef="code"> | ||||||
| 				<SimpleValue>20</SimpleValue> | 				<SimpleValue>20</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 			<Value ColumnRef="name"> | 			<Value ColumnRef="name"> | ||||||
| 				<SimpleValue>FtoHorticultura</SimpleValue> | 				<SimpleValue>FtoHorticultura</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 		</Row> | 		</Row> | ||||||
| 		<Row> | 		<Row> | ||||||
| 			<Value ColumnRef="code"> | 			<Value ColumnRef="code"> | ||||||
| 				<SimpleValue>21</SimpleValue> | 				<SimpleValue>21</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 			<Value ColumnRef="name"> | 			<Value ColumnRef="name"> | ||||||
| 				<SimpleValue>Timbre</SimpleValue> | 				<SimpleValue>Timbre</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 		</Row> | 		</Row> | ||||||
| 		<Row> | 		<Row> | ||||||
| 			<Value ColumnRef="code"> | 			<Value ColumnRef="code"> | ||||||
| 				<SimpleValue>22</SimpleValue> | 				<SimpleValue>22</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 			<Value ColumnRef="name"> | 			<Value ColumnRef="name"> | ||||||
| 				<SimpleValue>Bolsas</SimpleValue> | 				<SimpleValue>Bolsas</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 		</Row> | 		</Row> | ||||||
| 		<Row> | 		<Row> | ||||||
| 			<Value ColumnRef="code"> | 			<Value ColumnRef="code"> | ||||||
| 				<SimpleValue>23</SimpleValue> | 				<SimpleValue>23</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 			<Value ColumnRef="name"> | 			<Value ColumnRef="name"> | ||||||
| 				<SimpleValue>INCarbono</SimpleValue> | 				<SimpleValue>INCarbono</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 		</Row> | 		</Row> | ||||||
| 		<Row> | 		<Row> | ||||||
| 			<Value ColumnRef="code"> | 			<Value ColumnRef="code"> | ||||||
| 				<SimpleValue>24</SimpleValue> | 				<SimpleValue>24</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 			<Value ColumnRef="name"> | 			<Value ColumnRef="name"> | ||||||
| 				<SimpleValue>INCombustibles</SimpleValue> | 				<SimpleValue>INCombustibles</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 		</Row> | 		</Row> | ||||||
| 		<Row> | 		<Row> | ||||||
| 			<Value ColumnRef="code"> | 			<Value ColumnRef="code"> | ||||||
| 				<SimpleValue>25</SimpleValue> | 				<SimpleValue>25</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 			<Value ColumnRef="name"> | 			<Value ColumnRef="name"> | ||||||
| 				<SimpleValue>Sobretasa Combustibles</SimpleValue> | 				<SimpleValue>Sobretasa Combustibles</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 		</Row> | 		</Row> | ||||||
| 		<Row> | 		<Row> | ||||||
| 			<Value ColumnRef="code"> | 			<Value ColumnRef="code"> | ||||||
| 				<SimpleValue>26</SimpleValue> | 				<SimpleValue>26</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 			<Value ColumnRef="name"> | 			<Value ColumnRef="name"> | ||||||
| 				<SimpleValue>Sordicom</SimpleValue> | 				<SimpleValue>Sordicom</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 		</Row> | 		</Row> | ||||||
| 		<Row> | 		<Row> | ||||||
| 			<Value ColumnRef="code"> | 			<Value ColumnRef="code"> | ||||||
| 				<SimpleValue>30</SimpleValue> | 				<SimpleValue>ZZ</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 			<Value ColumnRef="name"> | 			<Value ColumnRef="name"> | ||||||
| 				<SimpleValue>Impuesto al Consumo de Datos</SimpleValue> | 				<SimpleValue>Nombre de la figura tributaria</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 		</Row> | 		</Row> | ||||||
|   | 	</SimpleCodeList> | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>ZZ</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Nombre de la figura tributaria</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
|       </SimpleCodeList> |  | ||||||
| </gc:CodeList> | </gc:CodeList> | ||||||
|   | |||||||
| @@ -1,47 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> |  | ||||||
| <gc:CodeList xmlns:gc="http://docs.oasis-open.org/codelist/ns/genericode/1.0/"> |  | ||||||
|    <Identification> |  | ||||||
|       <ShortName>TipoOperacion</ShortName> |  | ||||||
|       <LongName xml:lang="es">Tipo de operacion</LongName> |  | ||||||
|       <Version>1</Version> |  | ||||||
|       <CanonicalUri>urn:dian:names:especificacion:ubl:listacodigos:gc:TipoOperacion</CanonicalUri> |  | ||||||
|       <CanonicalVersionUri>urn:dian:names:especificacion:ubl:listacodigos:gc:TipoOperacion-2.1</CanonicalVersionUri> |  | ||||||
|       <LocationUri>http://dian.gov.co/ubl/os-ubl-2.0/cl/gc/default/TipoOperacion-2.1.gc</LocationUri> |  | ||||||
|       <Agency> |  | ||||||
|          <LongName xml:lang="es">DIAN (Dirección de Impuestos y Aduanas Nacionales)</LongName> |  | ||||||
|          <Identifier>195</Identifier> |  | ||||||
|       </Agency> |  | ||||||
|    </Identification> |  | ||||||
|    <ColumnSet> |  | ||||||
|       <Column Id="code" Use="required"> |  | ||||||
|          <ShortName>Code</ShortName> |  | ||||||
|          <Data Type="normalizedString"/> |  | ||||||
|       </Column> |  | ||||||
|       <Column Id="name" Use="required"> |  | ||||||
|          <ShortName>Nombre</ShortName> |  | ||||||
|          <Data Type="normalizedString"/> |  | ||||||
|       </Column> |  | ||||||
|       <Key Id="codeKey"> |  | ||||||
|          <ShortName>CodeKey</ShortName> |  | ||||||
|          <ColumnRef Ref="code"/> |  | ||||||
|       </Key> |  | ||||||
|    </ColumnSet> |  | ||||||
|    <SimpleCodeList> |  | ||||||
|       <Row> |  | ||||||
|          <Value ColumnRef="code"> |  | ||||||
|             <SimpleValue>10</SimpleValue> |  | ||||||
|          </Value> |  | ||||||
|          <Value ColumnRef="name"> |  | ||||||
|             <SimpleValue>Residente</SimpleValue> |  | ||||||
|          </Value> |  | ||||||
|       </Row> |  | ||||||
|       <Row> |  | ||||||
|          <Value ColumnRef="code"> |  | ||||||
|             <SimpleValue>11</SimpleValue> |  | ||||||
|          </Value> |  | ||||||
|          <Value ColumnRef="name"> |  | ||||||
|             <SimpleValue>No Residente</SimpleValue> |  | ||||||
|          </Value> |  | ||||||
|       </Row> |  | ||||||
|    </SimpleCodeList> |  | ||||||
| </gc:CodeList> |  | ||||||
| @@ -30,6 +30,46 @@ | |||||||
| 		</Key> | 		</Key> | ||||||
| 	</ColumnSet> | 	</ColumnSet> | ||||||
| 	<SimpleCodeList> | 	<SimpleCodeList> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>O-99</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Otro tipo de obligado</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>O-06</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Ingresos y patrimonio</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>O-07</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Retención en la fuente a título de renta</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>O-08</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Retención timbre nacional</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>O-09</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Retención en la fuente en el impuesto sobre las ventas</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
| 		<Row> | 		<Row> | ||||||
| 			<Value ColumnRef="code"> | 			<Value ColumnRef="code"> | ||||||
| 				<SimpleValue>O-13</SimpleValue> | 				<SimpleValue>O-13</SimpleValue> | ||||||
| @@ -38,6 +78,14 @@ | |||||||
| 				<SimpleValue>Gran contribuyente</SimpleValue> | 				<SimpleValue>Gran contribuyente</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 		</Row> | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>O-14</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Informante de exógena</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
| 		<Row> | 		<Row> | ||||||
| 			<Value ColumnRef="code"> | 			<Value ColumnRef="code"> | ||||||
| 				<SimpleValue>O-15</SimpleValue> | 				<SimpleValue>O-15</SimpleValue> | ||||||
| @@ -46,6 +94,38 @@ | |||||||
| 				<SimpleValue>Autorretenedor</SimpleValue> | 				<SimpleValue>Autorretenedor</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 		</Row> | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>O-16</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Obligación de facturar por ingresos de bienes y/o servicios excluidos</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>O-17</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Profesionales de compra y venta de divisas</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>O-19</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Productor y/o exportador de bienes exentos</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>O-22</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Obligado a cumplir deberes formales a nombre de terceros</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
| 		<Row> | 		<Row> | ||||||
| 			<Value ColumnRef="code"> | 			<Value ColumnRef="code"> | ||||||
| 				<SimpleValue>O-23</SimpleValue> | 				<SimpleValue>O-23</SimpleValue> | ||||||
| @@ -54,6 +134,62 @@ | |||||||
| 				<SimpleValue>Agente de retención en el impuesto sobre las ventas</SimpleValue> | 				<SimpleValue>Agente de retención en el impuesto sobre las ventas</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 		</Row> | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>O-32</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Impuesto Nacional a la Gasolina y al ACPM</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>O-33</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Impuesto Nacional al consumo</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>O-34</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Régimen simplificado impuesto nacional consumo rest y bares</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>O-36</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Establecimiento Permanente</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>O-37</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Obligado a Facturar Electrónicamente Modelo 2242</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>O-38</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Facturación Electrónica Voluntaria Modelo 2242</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>O-39</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Proveedor de Servicios Tecnológicos PST Modelo 2242</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
| 		<Row> | 		<Row> | ||||||
| 			<Value ColumnRef="code"> | 			<Value ColumnRef="code"> | ||||||
| 				<SimpleValue>O-47</SimpleValue> | 				<SimpleValue>O-47</SimpleValue> | ||||||
| @@ -78,6 +214,782 @@ | |||||||
| 				<SimpleValue>No responsable de IVA</SimpleValue> | 				<SimpleValue>No responsable de IVA</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 		</Row> | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>O-52</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Facturador electrónico</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>O-99</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Otro tipo de obligado</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>R-00-PN</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Clientes del Exterior</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>R-12-PN</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Factor PN</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>R-16-PN</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Mandatario</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>R-25-PN</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Agente Interventor</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>R-99-PN</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>No responsable</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>R-06-PJ</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Apoderado especial</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>R-07-PJ</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Apoderado general</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>R-12-PJ</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Factor</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>R-16-PJ</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Mandatario</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>R-99-PJ</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Otro tipo de responsable</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-01</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Agente de carga internacional</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-02</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Agente marítimo</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-03</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Almacén general de depósito</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-04</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Comercializadora internacional (C.I.)</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-05</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Comerciante de la zona aduanera especial de Inírida, Puerto Carreño, Cumaribo y Primavera</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-06</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Comerciantes de la zona de régimen aduanero especial de Leticia</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-07</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Comerciantes de la zona de régimen aduanero especial de Maicao, Uribia y Manaure</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-08</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Comerciantes de la zona de régimen aduanero especial de Urabá, Tumaco y Guapí</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-09</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Comerciantes del puerto libre de San Andrés, Providencia y Santa Catalina</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-10</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Depósito público de apoyo logístico internacional</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-11</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Depósito privado para procesamiento industrial</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-12</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Depósito privado de transformación o ensamble</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-13</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Depósito franco</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-14</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Depósito privado aeronáutico</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-15</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Depósito privado para distribución internacional</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-16</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Depósito privado de provisiones de a bordo para consumo y para llevar</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-17</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Depósito privado para envíos urgentes</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-18</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Depósito privado</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-19</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Depósito público</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-20</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Depósito público para distribución internacional</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-21</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Exportador de café</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-22</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Exportador</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-23</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Importador</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-24</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Intermediario de tráfico postal y envíos urgentes</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-25</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Operador de transporte multimodal</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-26</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Sociedad de intermediación aduanera</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-27</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Titular de puertos y muelles de servicio público o privado</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-28</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Transportador 263nfor régimen de importación y/o exportación</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-29</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Transportista nacional para operaciones del régimen de tránsito aduanero</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-30</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Usuario comercial zona franca</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-32</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Usuario industrial de bienes zona franca</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-34</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Usuario industrial de servicios zona franca</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-36</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Usuario operador de zona franca</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-37</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Usuario aduanero permanente</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-38</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Usuario altamente exportador</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-39</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Usuario de zonas económicas especiales de exportación</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-40</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Deposito privado de instalaciones industriales</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-41</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Beneficiarios de programas especiales de exportación PEX</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-42</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Depósitos privados para mercancías en tránsito San Andrés</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-43</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Observadores de las operaciones de importación</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-44</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Usuarios sistemas especiales Importación exportación</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-46</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Transportador 263nformac régimen de importación y/o exportación</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-47</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Transportador terrestre régimen de importación y/o exportación</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-48</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Aeropuerto de servicio publico o privado</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-49</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Transportador fluvial régimen de importación</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-50</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Usuario industrial zona franca especial</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-53</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Agencias de aduanas 1</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-54</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Usuario Operador Zona Franca Especial</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-55</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Agencias de aduanas 2</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-56</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Agencias de aduanas 3</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-57</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Agencias de aduanas 4</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-58</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Transportador aéreo nacional</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-60</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Transportador aéreo, marítimo o fluvial modalidad Cabotaje</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-61</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Importador de alimentos de consumo humano y animal</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-62</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Importador Ocasional</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-63</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Importador de maquinaría y sus partes Decreto 2261 de 2012</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-64</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Beneficiario Programa de Fomento Industria Automotriz-PROFIA</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>A-99</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Otro tipo de agente aduanero</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>E-01</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Agencia</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>E-02</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Establecimiento de comercio</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>E-03</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Centro de explotación agrícola</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>E-04</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Centro de explotación animal</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>E-05</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Centro de explotación minera</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>E-06</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Centro de explotación de transformación</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>E-07</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Centro de explotación de servicios</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>E-08</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Oficina</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>E-09</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Sede</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>E-10</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Sucursal</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>E-11</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Consultorio</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>E-12</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Administraciones</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>E-13</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Seccionales</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>E-14</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Regionales</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>E-15</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Intendencias</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>E-16</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Local o negocio</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>E-17</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Punto de venta</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>E-18</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Fábrica</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>E-19</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Taller</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>E-20</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Cantera</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>E-21</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Pozo de Petróleo y Gas</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>E-22</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Otro lug de tipo de extrac explotación de recursos naturales</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>E-99</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Otro tipo de establecimiento</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>O-13</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Gran contribuyente</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>O-15</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Autorretenedor</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>O-23</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Agente de retención IVA</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>O-47</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Régimen simple de tributación</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
| 		<Row> | 		<Row> | ||||||
| 			<Value ColumnRef="code"> | 			<Value ColumnRef="code"> | ||||||
| 				<SimpleValue>R-99-PN</SimpleValue> | 				<SimpleValue>R-99-PN</SimpleValue> | ||||||
|   | |||||||
| @@ -61,30 +61,6 @@ | |||||||
| 			<Value ColumnRef="name"> | 			<Value ColumnRef="name"> | ||||||
| 				<SimpleValue>Régimen simple de tributación</SimpleValue> | 				<SimpleValue>Régimen simple de tributación</SimpleValue> | ||||||
| 			</Value> | 			</Value> | ||||||
| 		</Row> |  | ||||||
| 				<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>O-48</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Impuesto sobre las ventas – IVA</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>O-49</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>No responsable de IVA</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>R-99-PN</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>No responsable</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> | 		</Row> | ||||||
| 	</SimpleCodeList> | 	</SimpleCodeList> | ||||||
| </gc:CodeList> | </gc:CodeList> | ||||||
|   | |||||||
| @@ -1,156 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> |  | ||||||
| <!-- |  | ||||||
|      creado por facho, la dian tiene oficial? |  | ||||||
|      poblar usando anexo tecnico 5.5.3 |  | ||||||
| --> |  | ||||||
| <gc:CodeList xmlns:gc="http://docs.oasis-open.org/codelist/ns/genericode/1.0/"> |  | ||||||
| 	<Identification> |  | ||||||
| 		<ShortName>TipoTrabajador</ShortName> |  | ||||||
| 		<LongName xml:lang="es">Tipos de trabajadores</LongName> |  | ||||||
| 		<Version>1</Version> |  | ||||||
| 	</Identification> |  | ||||||
| 	<ColumnSet> |  | ||||||
| 		<Column Id="code" Use="required"> |  | ||||||
| 			<ShortName>Code</ShortName> |  | ||||||
| 			<Data Type="normalizedString"/> |  | ||||||
| 		</Column> |  | ||||||
| 		<Column Id="name" Use="required"> |  | ||||||
| 			<ShortName>Nombre</ShortName> |  | ||||||
| 			<Data Type="normalizedString"/> |  | ||||||
| 		</Column> |  | ||||||
| 		<Key Id="codeKey"> |  | ||||||
| 			<ShortName>CodeKey</ShortName> |  | ||||||
| 			<ColumnRef Ref="code"/> |  | ||||||
| 		</Key> |  | ||||||
| 	</ColumnSet> |  | ||||||
| 	<SimpleCodeList> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>01</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Dependiente</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>02</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Servicio domestico</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>04</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Madre comunitaria</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>12</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Aprendices del Sena en etapa lectiva</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>18</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Funcionarios públicos sin tope máximo de ibc</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>19</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Aprendices del SENA en etapa productiva</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>21</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Estudiantes de postgrado en salud</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>22</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Profesor de establecimiento particular</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>23</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Estudiantes aportes solo riesgos laborales</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>30</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Dependiente entidades o universidades públicas con régimen especial en salud</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>31</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Cooperados o pre cooperativas de trabajo asociado</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>47</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Trabajador dependiente de entidad beneficiaria del sistema general de participaciones ‐ aportes patronales</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>51</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Trabajador de tiempo parcial</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>54</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Pre pensionado de entidad en liquidación.</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>56</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Pre pensionado con aporte voluntario a salud</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
| 		<Row> |  | ||||||
| 			<Value ColumnRef="code"> |  | ||||||
| 				<SimpleValue>58</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 			<Value ColumnRef="name"> |  | ||||||
| 				<SimpleValue>Estudiantes de prácticas laborales en el sector público</SimpleValue> |  | ||||||
| 			</Value> |  | ||||||
| 		</Row> |  | ||||||
|         </SimpleCodeList> |  | ||||||
| </gc:CodeList> |  | ||||||
| @@ -12,6 +12,9 @@ class CodeList: | |||||||
|         self.short_name = '' |         self.short_name = '' | ||||||
|         self.long_name = '' |         self.long_name = '' | ||||||
|         self.version = 1 |         self.version = 1 | ||||||
|  |         self.canonical_uri = '' | ||||||
|  |         self.canonical_version_uri = '' | ||||||
|  |         self.location_uri = '' | ||||||
|  |  | ||||||
|         self.name_column = name_column |         self.name_column = name_column | ||||||
|         self.rows = {} |         self.rows = {} | ||||||
| @@ -24,6 +27,9 @@ class CodeList: | |||||||
|         self.short_name = tree.find('./Identification/ShortName').text |         self.short_name = tree.find('./Identification/ShortName').text | ||||||
|         self.long_name = tree.find('./Identification/LongName').text |         self.long_name = tree.find('./Identification/LongName').text | ||||||
|         self.version = tree.find('./Identification/Version').text |         self.version = tree.find('./Identification/Version').text | ||||||
|  |         self.canonical_uri = tree.find('./Identification/CanonicalUri').text | ||||||
|  |         self.canonical_version_uri = tree.find('./Identification/CanonicalVersionUri').text | ||||||
|  |         self.location_uri = tree.find('./Identification/LocationUri').text | ||||||
|  |  | ||||||
|         #obtener registros... |         #obtener registros... | ||||||
|         for row in tree.findall('./SimpleCodeList/Row'): |         for row in tree.findall('./SimpleCodeList/Row'): | ||||||
| @@ -82,16 +88,10 @@ TipoAmbiente = CodeList(path_for_codelist('TipoAmbiente-2.1.gc'), 'code', 'name' | |||||||
| TipoDocumento = CodeList(path_for_codelist('TipoDocumento-2.1.gc'), 'code', 'name') | TipoDocumento = CodeList(path_for_codelist('TipoDocumento-2.1.gc'), 'code', 'name') | ||||||
| TipoImpuesto = CodeList(path_for_codelist('TipoImpuesto-2.1.gc'), 'code', 'name')\ | TipoImpuesto = CodeList(path_for_codelist('TipoImpuesto-2.1.gc'), 'code', 'name')\ | ||||||
|     .update(CodeList(path_for_codelist('TipoImpuesto-2.1.custom.gc'), 'code', 'name')) |     .update(CodeList(path_for_codelist('TipoImpuesto-2.1.custom.gc'), 'code', 'name')) | ||||||
| TarifaImpuesto = CodeList(path_for_codelist('TarifaImpuestoINC-2.1.gc'), 'code', 'name')\ |  | ||||||
|         .update(CodeList(path_for_codelist('TarifaImpuestoIVA-2.1.gc'), 'code', 'name'))\ |  | ||||||
|         .update(CodeList(path_for_codelist('TarifaImpuestoReteIVA-2.1.gc'), 'code', 'name'))\ |  | ||||||
|         .update(CodeList(path_for_codelist('TarifaImpuestoReteRenta-2.1.gc'), 'code', 'name')) |  | ||||||
| CodigoPrecioReferencia = CodeList(path_for_codelist('CodigoPrecioReferencia-2.1.gc'), 'code', 'name') | CodigoPrecioReferencia = CodeList(path_for_codelist('CodigoPrecioReferencia-2.1.gc'), 'code', 'name') | ||||||
| MediosPago = CodeList(path_for_codelist('MediosPago-2.1.gc'), 'code', 'name') | MediosPago = CodeList(path_for_codelist('MediosPago-2.1.gc'), 'code', 'name') | ||||||
| FormasPago = CodeList(path_for_codelist('FormasPago-2.1.gc'), 'code', 'name') |  | ||||||
| RegimenFiscal = CodeList(path_for_codelist('RegimenFiscal-2.1.custom.gc'), 'code', 'name') | RegimenFiscal = CodeList(path_for_codelist('RegimenFiscal-2.1.custom.gc'), 'code', 'name') | ||||||
| TipoOperacionNC = CodeList(path_for_codelist('TipoOperacionNC-2.1.gc'), 'code', 'name') | TipoOperacionNC = CodeList(path_for_codelist('TipoOperacionNC-2.1.gc'), 'code', 'name') | ||||||
| TipoOperacionNCDS = CodeList(path_for_codelist('TipoOperacionNCDS-2.1.gc'), 'code', 'name') |  | ||||||
| TipoOperacionND = CodeList(path_for_codelist('TipoOperacionND-2.1 - copia.gc'), 'code', 'name') | TipoOperacionND = CodeList(path_for_codelist('TipoOperacionND-2.1 - copia.gc'), 'code', 'name') | ||||||
| TipoOperacionF = CodeList(path_for_codelist('TipoOperacionF-2.1.gc'), 'code', 'name')\ | TipoOperacionF = CodeList(path_for_codelist('TipoOperacionF-2.1.gc'), 'code', 'name')\ | ||||||
|     .update(CodeList(path_for_codelist('TipoOperacionF-2.1.custom.gc'), 'code', 'name')) |     .update(CodeList(path_for_codelist('TipoOperacionF-2.1.custom.gc'), 'code', 'name')) | ||||||
| @@ -101,9 +101,3 @@ Paises = CodeList(path_for_codelist('Paises-2.1.gc'), 'code', 'name') | |||||||
| TipoIdFiscal = CodeList(path_for_codelist('TipoIdFiscal-2.1.gc'), 'code', 'name') | TipoIdFiscal = CodeList(path_for_codelist('TipoIdFiscal-2.1.gc'), 'code', 'name') | ||||||
| CodigoDescuento = CodeList(path_for_codelist('CodigoDescuento-2.1.gc'), 'code', 'name') | CodigoDescuento = CodeList(path_for_codelist('CodigoDescuento-2.1.gc'), 'code', 'name') | ||||||
| UnidadesMedida = CodeList(path_for_codelist('UnidadesMedida-2.1.gc'), 'code', 'name') | UnidadesMedida = CodeList(path_for_codelist('UnidadesMedida-2.1.gc'), 'code', 'name') | ||||||
| TipoTrabajador = CodeList(path_for_codelist('TipoTrabajador-2.1.gc'), 'code', 'name') |  | ||||||
| SubTipoTrabajador = CodeList(path_for_codelist('SubTipoTrabajador-2.1.gc'), 'code', 'name') |  | ||||||
| TipoContrato = CodeList(path_for_codelist('TipoContrato-2.1.gc'), 'code', 'name') |  | ||||||
| PeriodoNomina = CodeList(path_for_codelist('PeriodoNomina-2.1.gc'), 'code', 'name') |  | ||||||
| TipoMoneda = CodeList(path_for_codelist('TipoMoneda-2.1.gc'), 'code', 'name') |  | ||||||
| IdiomaISO6391 = CodeList(path_for_codelist('Idioma-2.1.gc'), 'iso-639-1', 'name') |  | ||||||
|   | |||||||
							
								
								
									
										191
									
								
								facho/fe/fe.py
									
									
									
									
									
								
							
							
						
						
									
										191
									
								
								facho/fe/fe.py
									
									
									
									
									
								
							| @@ -14,7 +14,6 @@ from contextlib import contextmanager | |||||||
| from .data.dian import codelist | from .data.dian import codelist | ||||||
| from . import form | from . import form | ||||||
| from collections import defaultdict | from collections import defaultdict | ||||||
| from pathlib import Path |  | ||||||
|  |  | ||||||
| AMBIENTE_PRUEBAS = codelist.TipoAmbiente.by_name('Pruebas')['code'] | AMBIENTE_PRUEBAS = codelist.TipoAmbiente.by_name('Pruebas')['code'] | ||||||
| AMBIENTE_PRODUCCION = codelist.TipoAmbiente.by_name('Producción')['code'] | AMBIENTE_PRODUCCION = codelist.TipoAmbiente.by_name('Producción')['code'] | ||||||
| @@ -31,46 +30,27 @@ POLICY_ID = 'https://facturaelectronica.dian.gov.co/politicadefirma/v2/politicad | |||||||
| POLICY_NAME = u'Política de firma para facturas electrónicas de la República de Colombia.' | POLICY_NAME = u'Política de firma para facturas electrónicas de la República de Colombia.' | ||||||
|  |  | ||||||
|  |  | ||||||
| # NAMESPACES = { |  | ||||||
| #     'atd': 'urn:oasis:names:specification:ubl:schema:xsd:AttachedDocument-2', |  | ||||||
| #     'nomina': 'dian:gov:co:facturaelectronica:NominaIndividual', |  | ||||||
| #     'nominaajuste': 'dian:gov:co:facturaelectronica:NominaIndividualDeAjuste',     |  | ||||||
| #     'fe': 'http://www.dian.gov.co/contratos/facturaelectronica/v1', |  | ||||||
| #     'xs': 'http://www.w3.org/2001/XMLSchema-instance',     |  | ||||||
| #     'cac': 'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2', |  | ||||||
| #     'cbc': 'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2', |  | ||||||
| #     'cdt': 'urn:DocumentInformation:names:specification:ubl:colombia:schema:xsd:DocumentInformationAggregateComponents-1', |  | ||||||
| #     'clm54217': 'urn:un:unece:uncefact:codelist:specification:54217:2001', |  | ||||||
| #     'clmIANAMIMEMediaType': 'urn:un:unece:uncefact:codelist:specification:IANAMIMEMediaType:2003', |  | ||||||
| #     'ext': 'urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2', |  | ||||||
| #     'qdt': 'urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2', |  | ||||||
| #     'sts': 'dian:gov:co:facturaelectronica:Structures-2-1', |  | ||||||
| #     'udt': 'urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2', |  | ||||||
| #     'xsi': 'http://www.w3.org/2001/XMLSchema-instance', |  | ||||||
| #     'xades': 'http://uri.etsi.org/01903/v1.3.2#', |  | ||||||
| #     'xades141': 'http://uri.etsi.org/01903/v1.4.1#',     |  | ||||||
| #     'ds': 'http://www.w3.org/2000/09/xmldsig#', |  | ||||||
| #     'sig': 'http://www.w3.org/2000/09/xmldsig#', |  | ||||||
| # } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| NAMESPACES = { | NAMESPACES = { | ||||||
|  |     'facho': 'http://git.disroot.org/Etrivial/facho', | ||||||
|     'fe': 'http://www.dian.gov.co/contratos/facturaelectronica/v1', |     'fe': 'http://www.dian.gov.co/contratos/facturaelectronica/v1', | ||||||
|     'cac': 'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2', |     'cac': 'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2', | ||||||
|     'cbc': 'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2', |     'cbc': 'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2', | ||||||
|  |     'cdt': 'urn:DocumentInformation:names:specification:ubl:colombia:schema:xsd:DocumentInformationAggregateComponents-1', | ||||||
|  |     'clm54217': 'urn:un:unece:uncefact:codelist:specification:54217:2001', | ||||||
|  |     'clmIANAMIMEMediaType': 'urn:un:unece:uncefact:codelist:specification:IANAMIMEMediaType:2003', | ||||||
|     'ext': 'urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2', |     'ext': 'urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2', | ||||||
|     'qdt': 'urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2', |     'qdt': 'urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2', | ||||||
|     'sts': 'dian:gov:co:facturaelectronica:Structures-2-1', |     'sts': 'dian:gov:co:facturaelectronica:Structures-2-1', | ||||||
|     'udt': 'urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2',  |     'udt': 'urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2', | ||||||
|     'xsi': 'http://www.w3.org/2001/XMLSchema-instance', |     'xsi': 'http://www.w3.org/2001/XMLSchema-instance', | ||||||
|     'ds': 'http://www.w3.org/2000/09/xmldsig#', |  | ||||||
|     'xades': 'http://uri.etsi.org/01903/v1.3.2#', |     'xades': 'http://uri.etsi.org/01903/v1.3.2#', | ||||||
|  |     'ds': 'http://www.w3.org/2000/09/xmldsig#', | ||||||
|  |     'sig': 'http://www.w3.org/2000/09/xmldsig#', | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def fe_from_string(document: str) -> FachoXML: | def fe_from_string(document: str) -> FachoXML: | ||||||
|     return FeXML.from_string(document) |     xml = LXMLBuilder.from_string(document) | ||||||
|  |     return FachoXML(xml, nsmap=NAMESPACES) | ||||||
|  |  | ||||||
| from contextlib import contextmanager | from contextlib import contextmanager | ||||||
| @contextmanager | @contextmanager | ||||||
| @@ -80,7 +60,6 @@ def mock_xades_policy(): | |||||||
|     with patch('xades.policy.urllib.urlopen') as mock: |     with patch('xades.policy.urllib.urlopen') as mock: | ||||||
|         class UrllibPolicyMock: |         class UrllibPolicyMock: | ||||||
|             def read(self): |             def read(self): | ||||||
|                 # Usamos contenido de archivo local |  | ||||||
|                 cur_dir = os.path.dirname(os.path.abspath(__file__)) |                 cur_dir = os.path.dirname(os.path.abspath(__file__)) | ||||||
|                 data_dir = os.path.join(cur_dir, 'data', 'dian') |                 data_dir = os.path.join(cur_dir, 'data', 'dian') | ||||||
|                 policy_file = os.path.join(data_dir, 'politicadefirmav2.pdf') |                 policy_file = os.path.join(data_dir, 'politicadefirmav2.pdf') | ||||||
| @@ -90,31 +69,21 @@ def mock_xades_policy(): | |||||||
|         mock.return_value = UrllibPolicyMock() |         mock.return_value = UrllibPolicyMock() | ||||||
|         yield |         yield | ||||||
|  |  | ||||||
|          |  | ||||||
| class FeXML(FachoXML): | class FeXML(FachoXML): | ||||||
|  |  | ||||||
|     def __init__(self, root, namespace): |     def __init__(self, root, namespace): | ||||||
|         # raise Exception(namespace) |  | ||||||
|         super().__init__("{%s}%s" % (namespace, root), |         super().__init__("{%s}%s" % (namespace, root), | ||||||
|                          nsmap=NAMESPACES) |                          nsmap=NAMESPACES) | ||||||
|  |  | ||||||
|     @classmethod |         self._cn = root.rstrip('/') | ||||||
|     def from_string(cls, document: str) -> 'FeXML': |         #self.find_or_create_element(self._cn) | ||||||
|         return super().from_string(document, namespaces=NAMESPACES) |  | ||||||
|  |  | ||||||
|     def tostring(self, **kw): |     def tostring(self, **kw): | ||||||
|         # MACHETE(bit4bit) la DIAN espera que la etiqueta raiz no este en un namespace |  | ||||||
|         root_namespace = self.root_namespace() |  | ||||||
|         root_localname = self.root_localname() |  | ||||||
|         xmlns_name = {v: k for k, v in NAMESPACES.items()}[root_namespace] |  | ||||||
|         if root_localname == 'Invoice': |  | ||||||
|             urn_oasis = 'urn:oasis:names:specification:ubl:schema:xsd:Invoice-2' |  | ||||||
|         if root_localname == 'CreditNote': |  | ||||||
|             urn_oasis = 'urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2' |  | ||||||
|         return super().tostring(**kw)\ |         return super().tostring(**kw)\ | ||||||
|                         .replace(xmlns_name + ':', '')\ |             .replace("fe:", "")\ | ||||||
|                         .replace('xmlns:'+xmlns_name, 'xmlns')\ |             .replace("xmlns:fe", "xmlns") | ||||||
|                         .replace(root_namespace, urn_oasis) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class DianXMLExtensionCUDFE(FachoXMLExtension): | class DianXMLExtensionCUDFE(FachoXMLExtension): | ||||||
| @@ -144,19 +113,7 @@ class DianXMLExtensionCUDFE(FachoXMLExtension): | |||||||
|         fachoxml.set_element('./cbc:UUID', cufe, |         fachoxml.set_element('./cbc:UUID', cufe, | ||||||
|                              schemeID=self.tipo_ambiente, |                              schemeID=self.tipo_ambiente, | ||||||
|                              schemeName=self.schemeName()) |                              schemeName=self.schemeName()) | ||||||
|  |         fachoxml.set_element('./cbc:ProfileID', 'DIAN 2.1') | ||||||
|         if self.schemeName() == "CUDS-SHA384": |  | ||||||
|             if fachoxml.tag_document() == 'Invoice': |  | ||||||
|                 fachoxml.set_element('./cbc:ProfileID', |  | ||||||
|                         'DIAN 2.1: documento soporte en adquisiciones efectuadas a no obligados a facturar.') |  | ||||||
|             else: |  | ||||||
|                 fachoxml.set_element('./cbc:ProfileID', |  | ||||||
|                         'DIAN 2.1: Nota de ajuste al documento soporte en adquisiciones efectuadas a sujetos no obligados a expedir factura o documento equivalente') |  | ||||||
|         else: |  | ||||||
|             fachoxml.set_element('./cbc:ProfileID', 'DIAN 2.1: Factura Electrónica de Venta') |  | ||||||
|  |  | ||||||
|         # #DIAN 1.8.-2021: FAD03 |  | ||||||
|         # fachoxml.set_element('./cbc:ProfileID', 'DIAN 2.1: Factura Electrónica de Venta') |  | ||||||
|         fachoxml.set_element('./cbc:ProfileExecutionID', self._tipo_ambiente_int()) |         fachoxml.set_element('./cbc:ProfileExecutionID', self._tipo_ambiente_int()) | ||||||
|         #DIAN 1.7.-2020: FAB36 |         #DIAN 1.7.-2020: FAB36 | ||||||
|         fachoxml.set_element('./ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent/sts:DianExtensions/sts:QRCode', |         fachoxml.set_element('./ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent/sts:DianExtensions/sts:QRCode', | ||||||
| @@ -228,14 +185,14 @@ class DianXMLExtensionCUFE(DianXMLExtensionCUDFE): | |||||||
|             '%s' % build_vars['NumFac'], |             '%s' % build_vars['NumFac'], | ||||||
|             '%s' % build_vars['FecFac'], |             '%s' % build_vars['FecFac'], | ||||||
|             '%s' % build_vars['HoraFac'], |             '%s' % build_vars['HoraFac'], | ||||||
|             form.Amount(build_vars['ValorBruto']).truncate_as_string(2), |             form.Amount(build_vars['ValorBruto']).format('%.02f'), | ||||||
|             CodImpuesto1, |             CodImpuesto1, | ||||||
|             build_vars['ValorImpuestoPara'].get(CodImpuesto1, form.Amount(0.0)).truncate_as_string(2), |             form.Amount(build_vars['ValorImpuestoPara'].get(CodImpuesto1, 0.0)).format('%.02f'), | ||||||
|             CodImpuesto2, |             CodImpuesto2, | ||||||
|             build_vars['ValorImpuestoPara'].get(CodImpuesto2, form.Amount(0.0)).truncate_as_string(2), |             form.Amount(build_vars['ValorImpuestoPara'].get(CodImpuesto2, 0.0)).format('%.02f'), | ||||||
|             CodImpuesto3, |             CodImpuesto3, | ||||||
|             build_vars['ValorImpuestoPara'].get(CodImpuesto3, form.Amount(0.0)).truncate_as_string(2), |             form.Amount(build_vars['ValorImpuestoPara'].get(CodImpuesto3, 0.0)).format('%.02f'), | ||||||
|             build_vars['ValorTotalPagar'].truncate_as_string(2), |             form.Amount(build_vars['ValorTotalPagar']).format('%.02f'), | ||||||
|             '%s' % build_vars['NitOFE'], |             '%s' % build_vars['NitOFE'], | ||||||
|             '%s' % build_vars['NumAdq'], |             '%s' % build_vars['NumAdq'], | ||||||
|             '%s' % build_vars['ClTec'], |             '%s' % build_vars['ClTec'], | ||||||
| @@ -265,53 +222,20 @@ class DianXMLExtensionCUDE(DianXMLExtensionCUDFE): | |||||||
|             '%s' % build_vars['NumFac'], |             '%s' % build_vars['NumFac'], | ||||||
|             '%s' % build_vars['FecFac'], |             '%s' % build_vars['FecFac'], | ||||||
|             '%s' % build_vars['HoraFac'], |             '%s' % build_vars['HoraFac'], | ||||||
|             form.Amount(build_vars['ValorBruto']).truncate_as_string(2), |             form.Amount(build_vars['ValorBruto']).format('%.02f'), | ||||||
|             CodImpuesto1, |             CodImpuesto1, | ||||||
|             form.Amount(build_vars['ValorImpuestoPara'].get(CodImpuesto1, 0.0)).truncate_as_string(2), |             form.Amount(build_vars['ValorImpuestoPara'].get(CodImpuesto1, 0.0)).format('%.02f'), | ||||||
|             CodImpuesto2, |             CodImpuesto2, | ||||||
|             form.Amount(build_vars['ValorImpuestoPara'].get(CodImpuesto2, 0.0)).truncate_as_string(2), |             form.Amount(build_vars['ValorImpuestoPara'].get(CodImpuesto2, 0.0)).format('%.02f'), | ||||||
|             CodImpuesto3, |             CodImpuesto3, | ||||||
|             form.Amount(build_vars['ValorImpuestoPara'].get(CodImpuesto3, 0.0)).truncate_as_string(2), |             form.Amount(build_vars['ValorImpuestoPara'].get(CodImpuesto3, 0.0)).format('%.02f'), | ||||||
|             form.Amount(build_vars['ValorTotalPagar']).truncate_as_string(2), |             form.Amount(build_vars['ValorTotalPagar']).format('%.02f'), | ||||||
|             '%s' % build_vars['NitOFE'], |             '%s' % build_vars['NitOFE'], | ||||||
|             '%s' % build_vars['NumAdq'], |             '%s' % build_vars['NumAdq'], | ||||||
|             '%s' % build_vars['Software-PIN'], |             '%s' % build_vars['Software-PIN'], | ||||||
|             '%d' % build_vars['TipoAmb'], |             '%d' % build_vars['TipoAmb'], | ||||||
|         ] |         ] | ||||||
|  |  | ||||||
| class DianXMLExtensionCUDS(DianXMLExtensionCUDFE): |  | ||||||
|     def __init__(self, invoice, software_pin, tipo_ambiente = AMBIENTE_PRUEBAS): |  | ||||||
|         self.tipo_ambiente = tipo_ambiente |  | ||||||
|         self.software_pin = software_pin |  | ||||||
|         self.invoice = invoice |  | ||||||
|  |  | ||||||
|     def schemeName(self): |  | ||||||
|         return 'CUDS-SHA384' |  | ||||||
|  |  | ||||||
|     def buildVars(self): |  | ||||||
|         build_vars = super().buildVars() |  | ||||||
|         build_vars['Software-PIN'] = str(self.software_pin) |  | ||||||
|         return build_vars |  | ||||||
|  |  | ||||||
|     def formatVars(self): |  | ||||||
|         build_vars = self.buildVars() |  | ||||||
|         CodImpuesto1 = build_vars['CodImpuesto1'] |  | ||||||
|         CodImpuesto2 = build_vars['CodImpuesto2'] |  | ||||||
|         CodImpuesto3 = build_vars['CodImpuesto3'] |  | ||||||
|         return [ |  | ||||||
|             '%s' % build_vars['NumFac'], |  | ||||||
|             '%s' % build_vars['FecFac'], |  | ||||||
|             '%s' % build_vars['HoraFac'], |  | ||||||
|             form.Amount(build_vars['ValorBruto']).truncate_as_string(2), |  | ||||||
|             CodImpuesto1, |  | ||||||
|             form.Amount(build_vars['ValorImpuestoPara'].get(CodImpuesto1, 0.0)).truncate_as_string(2), |  | ||||||
|             form.Amount(build_vars['ValorTotalPagar']).truncate_as_string(2), |  | ||||||
|             '%s' % build_vars['NitOFE'], |  | ||||||
|             '%s' % build_vars['NumAdq'],             |  | ||||||
|             '%s' % build_vars['Software-PIN'], |  | ||||||
|             '%d' % build_vars['TipoAmb'], |  | ||||||
|         ] |  | ||||||
|      |  | ||||||
| class DianXMLExtensionSoftwareProvider(FachoXMLExtension): | class DianXMLExtensionSoftwareProvider(FachoXMLExtension): | ||||||
|     # RESOLUCION 0004: pagina 108 |     # RESOLUCION 0004: pagina 108 | ||||||
|  |  | ||||||
| @@ -352,27 +276,16 @@ class DianXMLExtensionSoftwareSecurityCode(FachoXMLExtension): | |||||||
|  |  | ||||||
| class DianXMLExtensionSigner: | class DianXMLExtensionSigner: | ||||||
|  |  | ||||||
|     def __init__(self, pkcs12_path, passphrase=None, localpolicy=True): |     def __init__(self, pkcs12_path, passphrase=None, mockpolicy=False): | ||||||
|         self._pkcs12_data = open(pkcs12_path, 'rb').read() |         self._pkcs12_path = pkcs12_path | ||||||
|         self._passphrase = None |         self._passphrase = None | ||||||
|         self._localpolicy = localpolicy |         self._mockpolicy = mockpolicy | ||||||
|         if passphrase: |         if passphrase: | ||||||
|             self._passphrase = passphrase.encode('utf-8') |             self._passphrase = passphrase.encode('utf-8') | ||||||
|  |  | ||||||
|     @classmethod |     @classmethod | ||||||
|     def from_bytes(cls, data, passphrase=None, localpolicy=True): |     def from_pkcs12(self, filepath, password=None): | ||||||
|         self = cls.__new__(cls) |         p12 = OpenSSL.crypto.load_pkcs12(open(filepath, 'rb').read(), password) | ||||||
|          |  | ||||||
|         self._pkcs12_data = data |  | ||||||
|         self._passphrase = None |  | ||||||
|         self._localpolicy = localpolicy |  | ||||||
|         if passphrase: |  | ||||||
|             self._passphrase = passphrase.encode('utf-8') |  | ||||||
|              |  | ||||||
|         return self |  | ||||||
|  |  | ||||||
|     def _element_extension_content(self, fachoxml): |  | ||||||
|         return fachoxml.builder.xpath(fachoxml.root, './ext:UBLExtensions/ext:UBLExtension[2]/ext:ExtensionContent') |  | ||||||
|  |  | ||||||
|     def sign_xml_string(self, document): |     def sign_xml_string(self, document): | ||||||
|         xml = LXMLBuilder.from_string(document) |         xml = LXMLBuilder.from_string(document) | ||||||
| @@ -380,7 +293,7 @@ class DianXMLExtensionSigner: | |||||||
|  |  | ||||||
|         fachoxml = FachoXML(xml,nsmap=NAMESPACES) |         fachoxml = FachoXML(xml,nsmap=NAMESPACES) | ||||||
|         #DIAN 1.7.-2020: FAB01 |         #DIAN 1.7.-2020: FAB01 | ||||||
|         extcontent = self._element_extension_content(fachoxml) |         extcontent = fachoxml.builder.xpath(fachoxml.root, './ext:UBLExtensions/ext:UBLExtension[2]/ext:ExtensionContent') | ||||||
|         fachoxml.append_element(extcontent, signature) |         fachoxml.append_element(extcontent, signature) | ||||||
|  |  | ||||||
|         return fachoxml.tostring(xml_declaration=True, encoding='UTF-8') |         return fachoxml.tostring(xml_declaration=True, encoding='UTF-8') | ||||||
| @@ -428,10 +341,10 @@ class DianXMLExtensionSigner: | |||||||
|             POLICY_NAME, |             POLICY_NAME, | ||||||
|             xmlsig.constants.TransformSha256) |             xmlsig.constants.TransformSha256) | ||||||
|         ctx = xades.XAdESContext(policy) |         ctx = xades.XAdESContext(policy) | ||||||
|         ctx.load_pkcs12(OpenSSL.crypto.load_pkcs12(self._pkcs12_data, |         ctx.load_pkcs12(OpenSSL.crypto.load_pkcs12(open(self._pkcs12_path, 'rb').read(), | ||||||
|                                                    self._passphrase)) |                                                    self._passphrase)) | ||||||
|  |  | ||||||
|         if self._localpolicy: |         if self._mockpolicy: | ||||||
|             with mock_xades_policy(): |             with mock_xades_policy(): | ||||||
|                 ctx.sign(signature) |                 ctx.sign(signature) | ||||||
|                 ctx.verify(signature) |                 ctx.verify(signature) | ||||||
| @@ -444,10 +357,9 @@ class DianXMLExtensionSigner: | |||||||
|  |  | ||||||
|     def build(self, fachoxml): |     def build(self, fachoxml): | ||||||
|         signature = self.sign_xml_element(fachoxml.root) |         signature = self.sign_xml_element(fachoxml.root) | ||||||
|         extcontent = self._element_extension_content(fachoxml) |         extcontent = fachoxml.builder.xpath(fachoxml.root, './ext:UBLExtensions/ext:UBLExtension[2]/ext:ExtensionContent') | ||||||
|         fachoxml.append_element(extcontent, signature) |         fachoxml.append_element(extcontent, signature) | ||||||
|  |  | ||||||
|          |  | ||||||
| class DianXMLExtensionAuthorizationProvider(FachoXMLExtension): | class DianXMLExtensionAuthorizationProvider(FachoXMLExtension): | ||||||
|     # RESOLUCION 0004: pagina 176 |     # RESOLUCION 0004: pagina 176 | ||||||
|  |  | ||||||
| @@ -517,10 +429,10 @@ class DianZIP: | |||||||
|     MAX_FILES = 50 |     MAX_FILES = 50 | ||||||
|  |  | ||||||
|     def __init__(self, file_like): |     def __init__(self, file_like): | ||||||
|         self.zipfile = zipfile.ZipFile(file_like, mode='w', compression=zipfile.ZIP_DEFLATED) |         self.zipfile = zipfile.ZipFile(file_like, mode='w') | ||||||
|         self.num_files = 0 |         self.num_files = 0 | ||||||
|  |  | ||||||
|     def add_xml(self, name, xml_data): |     def add_invoice_xml(self, name, xml_data): | ||||||
|         self.num_files += 1 |         self.num_files += 1 | ||||||
|         # TODO cual es la norma para los nombres de archivos? |         # TODO cual es la norma para los nombres de archivos? | ||||||
|         m = hashlib.sha256() |         m = hashlib.sha256() | ||||||
| @@ -531,18 +443,7 @@ class DianZIP: | |||||||
|  |  | ||||||
|         return filename |         return filename | ||||||
|  |  | ||||||
|     # DEPRECATED usar add_xml |  | ||||||
|     def add_invoice_xml(self, name, xml_data): |  | ||||||
|         return self.add_xml(name, xml_data) |  | ||||||
|  |  | ||||||
|     def __enter__(self): |     def __enter__(self): | ||||||
|         """ |  | ||||||
|         Facilita el uso de esta manera: |  | ||||||
|          |  | ||||||
|         f = open('xxx', 'rb') |  | ||||||
|         with DianZIP(f) as zip: |  | ||||||
|           zip.add_invoice_xml('name', 'data xml') |  | ||||||
|         """ |  | ||||||
|         return self |         return self | ||||||
|  |  | ||||||
|     def __exit__(self, type, value, traceback): |     def __exit__(self, type, value, traceback): | ||||||
| @@ -551,35 +452,29 @@ class DianZIP: | |||||||
|  |  | ||||||
| class DianXMLExtensionSignerVerifier: | class DianXMLExtensionSignerVerifier: | ||||||
|  |  | ||||||
|     def __init__(self, pkcs12_path_or_bytes, passphrase=None, localpolicy=True): |     def __init__(self, pkcs12_path, passphrase=None, mockpolicy=False): | ||||||
|         self._pkcs12_path_or_bytes = pkcs12_path_or_bytes |         self._pkcs12_path = pkcs12_path | ||||||
|         self._passphrase = None |         self._passphrase = None | ||||||
|         self._localpolicy = localpolicy |         self._mockpolicy = mockpolicy | ||||||
|         if passphrase: |         if passphrase: | ||||||
|             self._passphrase = passphrase.encode('utf-8') |             self._passphrase = passphrase.encode('utf-8') | ||||||
|  |  | ||||||
|     def verify_string(self, document): |     def verify_string(self, document): | ||||||
|         # Obtener FachoXML |  | ||||||
|         xml = LXMLBuilder.from_string(document) |         xml = LXMLBuilder.from_string(document) | ||||||
|         fachoxml = FachoXML(xml,nsmap=NAMESPACES) |         fachoxml = FachoXML(xml,nsmap=NAMESPACES) | ||||||
|  |  | ||||||
|         # Obtener Signature |  | ||||||
|         signature = fachoxml.builder.xpath(fachoxml.root, '//ds:Signature') |         signature = fachoxml.builder.xpath(fachoxml.root, '//ds:Signature') | ||||||
|         assert signature is not None |         assert signature is not None | ||||||
|  |  | ||||||
|         # Se mueve Signature a elemento raiz para realizar verificaion |  | ||||||
|         signature.getparent().remove(signature) |         signature.getparent().remove(signature) | ||||||
|         fachoxml.root.append(signature) |         fachoxml.root.append(signature) | ||||||
|  |  | ||||||
|         # Verificar archivo usando Signature |  | ||||||
|         pkcs12_data = self._pkcs12_path_or_bytes |  | ||||||
|         if isinstance(self._pkcs12_path_or_bytes, str): |  | ||||||
|             pkcs12_data = open(self._pkcs12_path_or_bytes, 'rb').read() |  | ||||||
|         ctx = xades.XAdESContext() |         ctx = xades.XAdESContext() | ||||||
|         ctx.load_pkcs12(OpenSSL.crypto.load_pkcs12(pkcs12_data, |         ctx.load_pkcs12(OpenSSL.crypto.load_pkcs12(open(self._pkcs12_path, 'rb').read(), | ||||||
|                                                    self._passphrase)) |                                                    self._passphrase)) | ||||||
|  |  | ||||||
|         try: |         try: | ||||||
|             if self._localpolicy: |             if self._mockpolicy: | ||||||
|                 with mock_xades_policy(): |                 with mock_xades_policy(): | ||||||
|                     ctx.verify(signature) |                     ctx.verify(signature) | ||||||
|             else: |             else: | ||||||
|   | |||||||
| @@ -1,15 +1,16 @@ | |||||||
| # This file is part of facho.  The COPYRIGHT file at the top level of | # This file is part of facho.  The COPYRIGHT file at the top level of | ||||||
| # this repository contains the full copyright notices and license terms. | # this repository contains the full copyright notices and license terms. | ||||||
|  |  | ||||||
| import hashlib | import hashlib | ||||||
| from functools import reduce | from functools import reduce | ||||||
| import copy | import copy | ||||||
| import dataclasses |  | ||||||
| from dataclasses import dataclass | from dataclasses import dataclass | ||||||
| from datetime import datetime, date | from datetime import datetime, date | ||||||
| from collections import defaultdict | from collections import defaultdict | ||||||
| import decimal | import decimal | ||||||
| from decimal import Decimal | from decimal import Decimal | ||||||
| import typing | import typing | ||||||
|  |  | ||||||
| from ..data.dian import codelist | from ..data.dian import codelist | ||||||
|  |  | ||||||
| DECIMAL_PRECISION = 6 | DECIMAL_PRECISION = 6 | ||||||
| @@ -52,7 +53,7 @@ class AmountCollection(Collection): | |||||||
|         return total |         return total | ||||||
|  |  | ||||||
| class Amount: | class Amount: | ||||||
|     def __init__(self, amount: int or float or str or Amount, currency: Currency = Currency('COP')): |     def __init__(self, amount: int or float or Amount, currency: Currency = Currency('COP')): | ||||||
|  |  | ||||||
|         #DIAN 1.7.-2020: 1.2.3.1 |         #DIAN 1.7.-2020: 1.2.3.1 | ||||||
|         if isinstance(amount, Amount): |         if isinstance(amount, Amount): | ||||||
| @@ -62,7 +63,7 @@ class Amount: | |||||||
|             self.amount = amount.amount |             self.amount = amount.amount | ||||||
|             self.currency = amount.currency |             self.currency = amount.currency | ||||||
|         else: |         else: | ||||||
|             if float(amount) < 0: |             if amount < 0: | ||||||
|                 raise ValueError('amount must be positive >= 0') |                 raise ValueError('amount must be positive >= 0') | ||||||
|  |  | ||||||
|             self.amount = Decimal(amount, decimal.Context(prec=DECIMAL_PRECISION, |             self.amount = Decimal(amount, decimal.Context(prec=DECIMAL_PRECISION, | ||||||
| @@ -70,17 +71,12 @@ class Amount: | |||||||
|                                                           rounding=decimal.ROUND_HALF_EVEN )) |                                                           rounding=decimal.ROUND_HALF_EVEN )) | ||||||
|             self.currency = currency |             self.currency = currency | ||||||
|  |  | ||||||
|     def fromNumber(self, val): |  | ||||||
|         return Amount(val, currency=self.currency) |  | ||||||
|      |  | ||||||
|     def round(self, prec): |  | ||||||
|         return Amount(round(self.amount, prec), currency=self.currency) |  | ||||||
|  |  | ||||||
|     def __round__(self, prec): |     def __round__(self, prec): | ||||||
|         return round(self.amount, prec) |         return round(self.amount, prec) | ||||||
|  |  | ||||||
|     def __str__(self): |     def __str__(self): | ||||||
|         return str(self.float()) |         return '%.06f' % self.amount | ||||||
|  |  | ||||||
|     def __lt__(self, other): |     def __lt__(self, other): | ||||||
|         if not self.is_same_currency(other): |         if not self.is_same_currency(other): | ||||||
| @@ -92,27 +88,17 @@ class Amount: | |||||||
|             raise AmountCurrencyError() |             raise AmountCurrencyError() | ||||||
|         return round(self.amount, DECIMAL_PRECISION) == round(other.amount, DECIMAL_PRECISION) |         return round(self.amount, DECIMAL_PRECISION) == round(other.amount, DECIMAL_PRECISION) | ||||||
|  |  | ||||||
|     def _cast(self, val): |     def __add__(self, other): | ||||||
|         if type(val) in [int, float]: |  | ||||||
|             return self.fromNumber(val) |  | ||||||
|         if isinstance(val, Amount): |  | ||||||
|             return val |  | ||||||
|         raise TypeError("cant cast to amount") |  | ||||||
|      |  | ||||||
|     def __add__(self, rother): |  | ||||||
|         other = self._cast(rother) |  | ||||||
|         if not self.is_same_currency(other): |         if not self.is_same_currency(other): | ||||||
|             raise AmountCurrencyError() |             raise AmountCurrencyError() | ||||||
|         return Amount(self.amount + other.amount, self.currency) |         return Amount(self.amount + other.amount, self.currency) | ||||||
|  |  | ||||||
|     def __sub__(self, rother): |     def __sub__(self, other): | ||||||
|         other = self._cast(rother) |  | ||||||
|         if not self.is_same_currency(other): |         if not self.is_same_currency(other): | ||||||
|             raise AmountCurrencyError() |             raise AmountCurrencyError() | ||||||
|         return Amount(self.amount - other.amount, self.currency) |         return Amount(self.amount - other.amount, self.currency) | ||||||
|  |  | ||||||
|     def __mul__(self, rother): |     def __mul__(self, other): | ||||||
|         other = self._cast(rother) |  | ||||||
|         if not self.is_same_currency(other): |         if not self.is_same_currency(other): | ||||||
|             raise AmountCurrencyError() |             raise AmountCurrencyError() | ||||||
|         return Amount(self.amount * other.amount, self.currency) |         return Amount(self.amount * other.amount, self.currency) | ||||||
| @@ -120,9 +106,8 @@ class Amount: | |||||||
|     def is_same_currency(self, other): |     def is_same_currency(self, other): | ||||||
|         return self.currency == other.currency |         return self.currency == other.currency | ||||||
|  |  | ||||||
|     def truncate_as_string(self, prec): |     def format(self, formatter): | ||||||
|         parts = str(self.float()).split('.', 1) |         return formatter % self.float() | ||||||
|         return '%s.%s' % (parts[0], parts[1][0:prec].ljust(prec,'0')) |  | ||||||
|  |  | ||||||
|     def float(self): |     def float(self): | ||||||
|         return float(round(self.amount, DECIMAL_PRECISION)) |         return float(round(self.amount, DECIMAL_PRECISION)) | ||||||
| @@ -131,25 +116,27 @@ class Amount: | |||||||
| class Quantity: | class Quantity: | ||||||
|      |      | ||||||
|     def __init__(self, val, code): |     def __init__(self, val, code): | ||||||
|         if type(val) not in [float, int]: |         if not isinstance(val, int): | ||||||
|             raise ValueError('val expected int or float') |             raise ValueError('val expected int') | ||||||
|         if code not in codelist.UnidadesMedida: |         if code not in codelist.UnidadesMedida: | ||||||
|             raise ValueError("code [%s] not found" % (code)) |             raise ValueError("code [%s] not found" % (code)) | ||||||
|  |  | ||||||
|         self.value = Amount(val) |         self.value = val | ||||||
|         self.code = code |         self.code = code | ||||||
|  |  | ||||||
|     def __mul__(self, other): |     def __mul__(self, other): | ||||||
|  |         if isinstance(other, Amount): | ||||||
|  |             return Amount(self.value) * other | ||||||
|         return self.value * other |         return self.value * other | ||||||
|  |  | ||||||
|     def __lt__(self, other): |     def __lt__(self, other): | ||||||
|  |         if isinstance(other, Amount): | ||||||
|  |             return Amount(self.value) < other | ||||||
|         return self.value < other |         return self.value < other | ||||||
|  |  | ||||||
|     def __str__(self): |     def __str__(self): | ||||||
|         return str(self.value) |         return str(self.value) | ||||||
|  |  | ||||||
|     def __repr__(self): |  | ||||||
|         return str(self) |  | ||||||
|  |  | ||||||
| @dataclass | @dataclass | ||||||
| class Item: | class Item: | ||||||
| @@ -161,10 +148,10 @@ class Item: | |||||||
|  |  | ||||||
|  |  | ||||||
| class StandardItem(Item): | class StandardItem(Item): | ||||||
|     def __init__(self, id_: str, description: str = '', name: str = ''): |     def __init__(self, id_: str, description: str = ''): | ||||||
|         super().__init__(id=id_, |         super().__init__(id=id_, | ||||||
|                          description=description, |                          description=description, | ||||||
|                          scheme_name=name, |                          scheme_name='', | ||||||
|                          scheme_id='999', |                          scheme_id='999', | ||||||
|                          scheme_agency_id='') |                          scheme_agency_id='') | ||||||
|  |  | ||||||
| @@ -208,10 +195,6 @@ class City: | |||||||
|             raise ValueError("code [%s] not found" % (self.code)) |             raise ValueError("code [%s] not found" % (self.code)) | ||||||
|         self.name = codelist.Municipio[self.code]['name'] |         self.name = codelist.Municipio[self.code]['name'] | ||||||
|  |  | ||||||
| @dataclass |  | ||||||
| class PostalZone: |  | ||||||
|     code: str = '' |  | ||||||
|          |  | ||||||
| @dataclass | @dataclass | ||||||
| class Address: | class Address: | ||||||
|     name: str |     name: str | ||||||
| @@ -219,7 +202,6 @@ class Address: | |||||||
|     city: City = City('05001') |     city: City = City('05001') | ||||||
|     country: Country = Country('CO') |     country: Country = Country('CO') | ||||||
|     countrysubentity: CountrySubentity = CountrySubentity('05') |     countrysubentity: CountrySubentity = CountrySubentity('05') | ||||||
|     postalzone: PostalZone = PostalZone('') |  | ||||||
|  |  | ||||||
| @dataclass | @dataclass | ||||||
| class PartyIdentification: | class PartyIdentification: | ||||||
| @@ -264,6 +246,7 @@ class TaxScheme: | |||||||
|     code: str |     code: str | ||||||
|     name: str = '' |     name: str = '' | ||||||
|  |  | ||||||
|  |  | ||||||
|     def __post_init__(self): |     def __post_init__(self): | ||||||
|         if self.code not in codelist.TipoImpuesto: |         if self.code not in codelist.TipoImpuesto: | ||||||
|             raise ValueError("code not found") |             raise ValueError("code not found") | ||||||
| @@ -322,6 +305,7 @@ class TaxTotal: | |||||||
|  |  | ||||||
|     def calculate(self, invline): |     def calculate(self, invline): | ||||||
|         self.taxable_amount = invline.total_amount |         self.taxable_amount = invline.total_amount | ||||||
|  |  | ||||||
|         for subtax in self.subtotals: |         for subtax in self.subtotals: | ||||||
|             subtax.calculate(invline) |             subtax.calculate(invline) | ||||||
|             self.tax_amount += subtax.tax_amount |             self.tax_amount += subtax.tax_amount | ||||||
| @@ -334,50 +318,16 @@ class TaxTotalOmit(TaxTotal): | |||||||
|     def calculate(self, invline): |     def calculate(self, invline): | ||||||
|         pass |         pass | ||||||
|  |  | ||||||
| @dataclass |  | ||||||
| class WithholdingTaxSubTotal: |  | ||||||
|     percent: float |  | ||||||
|     scheme: typing.Optional[TaxScheme] = None |  | ||||||
|     tax_amount: Amount = Amount(0.0) |  | ||||||
|  |  | ||||||
|     def calculate(self, invline): |  | ||||||
|         if self.percent is not None: |  | ||||||
|             self.tax_amount = invline.total_amount * Amount(self.percent / 100) |  | ||||||
|          |  | ||||||
| @dataclass |  | ||||||
| class WithholdingTaxTotal: |  | ||||||
|     subtotals: list |  | ||||||
|     tax_amount: Amount = Amount(0.0) |  | ||||||
|     taxable_amount: Amount = Amount(0.0) |  | ||||||
|  |  | ||||||
|     def calculate(self, invline): |  | ||||||
|         self.taxable_amount = invline.total_amount |  | ||||||
|  |  | ||||||
|         for subtax in self.subtotals: |  | ||||||
|             subtax.calculate(invline) |  | ||||||
|             self.tax_amount += subtax.tax_amount |  | ||||||
|      |  | ||||||
| class WithholdingTaxTotalOmit(WithholdingTaxTotal): |  | ||||||
|     def __init__(self): |  | ||||||
|         super().__init__([]) |  | ||||||
|  |  | ||||||
|     def calculate(self, invline): |  | ||||||
|         pass |  | ||||||
|  |  | ||||||
| @dataclass | @dataclass | ||||||
| class Price: | class Price: | ||||||
|     amount: Amount |     amount: Amount | ||||||
|     type_code: str |     type_code: str | ||||||
|     type: str |     type: str | ||||||
|     quantity: int = 1 |  | ||||||
|  |  | ||||||
|     def __post_init__(self): |     def __post_init__(self): | ||||||
|         if self.type_code not in codelist.CodigoPrecioReferencia: |         if self.type_code not in codelist.CodigoPrecioReferencia: | ||||||
|             raise ValueError("type_code [%s] not found" % (self.type_code)) |             raise ValueError("type_code [%s] not found" % (self.type_code)) | ||||||
|         if not isinstance(self.quantity, int): |  | ||||||
|             raise ValueError("quantity must be int") |  | ||||||
|  |  | ||||||
|         self.amount *= self.quantity |  | ||||||
|  |  | ||||||
| @dataclass | @dataclass | ||||||
| class PaymentMean: | class PaymentMean: | ||||||
| @@ -399,21 +349,6 @@ class PrePaidPayment: | |||||||
|     #DIAN 1.7.-2020: FBD03 |     #DIAN 1.7.-2020: FBD03 | ||||||
|     paid_amount: Amount = Amount(0.0) |     paid_amount: Amount = Amount(0.0) | ||||||
|  |  | ||||||
| @dataclass |  | ||||||
| class BillingResponse: |  | ||||||
|     id: str |  | ||||||
|     code: str |  | ||||||
|     description: str |  | ||||||
|  |  | ||||||
| class SupportDocumentCreditNoteResponse(BillingResponse): |  | ||||||
|     """ |  | ||||||
|     ReferenceID: Identifica la sección del Documento |  | ||||||
|     Soporte original a la cual se aplica la corrección. |  | ||||||
|     ResponseCode: Código de descripción de la corrección. |  | ||||||
|     Description: Descripción de la naturaleza de la corrección. |  | ||||||
|     """ |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| @dataclass | @dataclass | ||||||
| class BillingReference: | class BillingReference: | ||||||
| @@ -428,6 +363,7 @@ class CreditNoteDocumentReference(BillingReference): | |||||||
|     date: fecha de emision de la factura relacionada |     date: fecha de emision de la factura relacionada | ||||||
|     """ |     """ | ||||||
|  |  | ||||||
|  |  | ||||||
| class DebitNoteDocumentReference(BillingReference): | class DebitNoteDocumentReference(BillingReference): | ||||||
|     """ |     """ | ||||||
|     ident: Prefijo + Numero de la factura relacionada |     ident: Prefijo + Numero de la factura relacionada | ||||||
| @@ -442,52 +378,6 @@ class InvoiceDocumentReference(BillingReference): | |||||||
|     date: fecha de emision de la nota credito relacionada |     date: fecha de emision de la nota credito relacionada | ||||||
|     """ |     """ | ||||||
|  |  | ||||||
| @dataclass |  | ||||||
| class AllowanceChargeReason: |  | ||||||
|     code: str |  | ||||||
|     reason: str |  | ||||||
|  |  | ||||||
|     def __post_init__(self): |  | ||||||
|         if self.code not in codelist.CodigoDescuento: |  | ||||||
|             raise ValueError("code [%s] not found" % (self.code)) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| @dataclass |  | ||||||
| class AllowanceCharge: |  | ||||||
|     #DIAN 1.7.-2020: FAQ03 |  | ||||||
|     charge_indicator: bool = True |  | ||||||
|     amount: Amount = Amount(0.0) |  | ||||||
|     reason: AllowanceChargeReason = None |  | ||||||
|  |  | ||||||
|     #Valor Base para calcular el descuento o el cargo |  | ||||||
|     base_amount: typing.Optional[Amount] = Amount(0.0) |  | ||||||
|      |  | ||||||
|     # Porcentaje: Porcentaje que aplicar. |  | ||||||
|     multiplier_factor_numeric: Amount = Amount(1.0) |  | ||||||
|      |  | ||||||
|     def isCharge(self): |  | ||||||
|         return self.charge_indicator == True |  | ||||||
|  |  | ||||||
|     def isDiscount(self): |  | ||||||
|         return self.charge_indicator == False |  | ||||||
|  |  | ||||||
|     def asCharge(self): |  | ||||||
|         self.charge_indicator = True |  | ||||||
|  |  | ||||||
|     def asDiscount(self): |  | ||||||
|         self.charge_indicator = False |  | ||||||
|  |  | ||||||
|     def hasReason(self): |  | ||||||
|         return self.reason is not None |  | ||||||
|  |  | ||||||
|     def set_base_amount(self, amount): |  | ||||||
|         self.base_amount = amount |  | ||||||
|  |  | ||||||
| class AllowanceChargeAsDiscount(AllowanceCharge): |  | ||||||
|     def __init__(self, amount: Amount = Amount(0.0)): |  | ||||||
|         self.charge_indicator = False |  | ||||||
|         self.amount = amount |  | ||||||
|  |  | ||||||
| @dataclass | @dataclass | ||||||
| class InvoiceLine: | class InvoiceLine: | ||||||
|     # RESOLUCION 0004: pagina 155 |     # RESOLUCION 0004: pagina 155 | ||||||
| @@ -500,32 +390,10 @@ class InvoiceLine: | |||||||
|     # la factura y el percent es unico por type_code |     # la factura y el percent es unico por type_code | ||||||
|     # de subtotal |     # de subtotal | ||||||
|     tax: typing.Optional[TaxTotal] |     tax: typing.Optional[TaxTotal] | ||||||
|     withholding: typing.Optional[WithholdingTaxTotal] |  | ||||||
|     allowance_charge: typing.List[AllowanceCharge] = dataclasses.field(default_factory=list) |  | ||||||
|  |  | ||||||
|     def add_allowance_charge(self, charge): |  | ||||||
|         if not isinstance(charge, AllowanceCharge): |  | ||||||
|             raise TypeError('charge invalid type expected AllowanceCharge') |  | ||||||
|         charge.set_base_amount(self.total_amount_without_charge) |  | ||||||
|         self.allowance_charge.add(charge) |  | ||||||
|  |  | ||||||
|     @property |  | ||||||
|     def total_amount_without_charge(self): |  | ||||||
|         return (self.quantity * self.price.amount) |  | ||||||
|      |  | ||||||
|     @property |     @property | ||||||
|     def total_amount(self): |     def total_amount(self): | ||||||
|         charge = AmountCollection(self.allowance_charge)\ |         return self.quantity * self.price.amount | ||||||
|             .filter(lambda charge: charge.isCharge())\ |  | ||||||
|             .map(lambda charge: charge.amount)\ |  | ||||||
|             .sum() |  | ||||||
|  |  | ||||||
|         discount = AmountCollection(self.allowance_charge)\ |  | ||||||
|             .filter(lambda charge: charge.isDiscount())\ |  | ||||||
|             .map(lambda charge: charge.amount)\ |  | ||||||
|             .sum() |  | ||||||
|  |  | ||||||
|         return self.total_amount_without_charge + charge - discount |  | ||||||
|  |  | ||||||
|     @property |     @property | ||||||
|     def total_tax_inclusive_amount(self): |     def total_tax_inclusive_amount(self): | ||||||
| @@ -544,17 +412,8 @@ class InvoiceLine: | |||||||
|     def taxable_amount(self): |     def taxable_amount(self): | ||||||
|         return self.tax.taxable_amount |         return self.tax.taxable_amount | ||||||
|  |  | ||||||
|     @property |  | ||||||
|     def withholding_amount(self): |  | ||||||
|         return self.withholding.tax_amount |  | ||||||
|  |  | ||||||
|     @property |  | ||||||
|     def withholding_taxable_amount(self): |  | ||||||
|         return self.withholding.taxable_amount |  | ||||||
|  |  | ||||||
|     def calculate(self): |     def calculate(self): | ||||||
|         self.tax.calculate(self) |         self.tax.calculate(self) | ||||||
|         self.withholding.calculate(self) |  | ||||||
|  |  | ||||||
|     def __post_init__(self): |     def __post_init__(self): | ||||||
|         if not isinstance(self.quantity, Quantity): |         if not isinstance(self.quantity, Quantity): | ||||||
| @@ -562,9 +421,6 @@ class InvoiceLine: | |||||||
|  |  | ||||||
|         if self.tax is None: |         if self.tax is None: | ||||||
|             self.tax = TaxTotalOmit() |             self.tax = TaxTotalOmit() | ||||||
|              |  | ||||||
|         if self.withholding is None: |  | ||||||
|             self.withholding = WithholdingTaxTotalOmit() |  | ||||||
|  |  | ||||||
| @dataclass | @dataclass | ||||||
| class LegalMonetaryTotal: | class LegalMonetaryTotal: | ||||||
| @@ -585,6 +441,37 @@ class LegalMonetaryTotal: | |||||||
|             - self.prepaid_amount |             - self.prepaid_amount | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @dataclass | ||||||
|  | class AllowanceChargeReason: | ||||||
|  |     code: str | ||||||
|  |     reason: str | ||||||
|  |  | ||||||
|  |     def __post_init__(self): | ||||||
|  |         if self.code not in codelist.CodigoDescuento: | ||||||
|  |             raise ValueError("code [%s] not found" % (self.code)) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @dataclass | ||||||
|  | class AllowanceCharge: | ||||||
|  |     #DIAN 1.7.-2020: FAQ03 | ||||||
|  |     charge_indicator: bool = True | ||||||
|  |     amount: Amount = Amount(0.0) | ||||||
|  |     reason: AllowanceChargeReason = None | ||||||
|  |  | ||||||
|  |     def isCharge(self): | ||||||
|  |         return self.charge_indicator == True | ||||||
|  |  | ||||||
|  |     def isDiscount(self): | ||||||
|  |         return self.charge_indicator == False | ||||||
|  |  | ||||||
|  |     def asCharge(self): | ||||||
|  |         self.charge_indicator = True | ||||||
|  |  | ||||||
|  |     def asDiscount(self): | ||||||
|  |         self.charge_indicator = False | ||||||
|  |  | ||||||
|  |     def hasReason(self): | ||||||
|  |         return self.reason is not None | ||||||
|  |  | ||||||
| class NationalSalesInvoiceDocumentType(str): | class NationalSalesInvoiceDocumentType(str): | ||||||
|     def __str__(self): |     def __str__(self): | ||||||
| @@ -601,10 +488,6 @@ class DebitNoteDocumentType(str): | |||||||
|         # 6.1.3 |         # 6.1.3 | ||||||
|         return '92' |         return '92' | ||||||
|  |  | ||||||
| class CreditNoteSupportDocumentType(str): |  | ||||||
|     def __str__(self): |  | ||||||
|         return '95' |  | ||||||
|  |  | ||||||
| class Invoice: | class Invoice: | ||||||
|     def __init__(self, type_code: str): |     def __init__(self, type_code: str): | ||||||
|         if str(type_code) not in codelist.TipoDocumento: |         if str(type_code) not in codelist.TipoDocumento: | ||||||
| @@ -624,7 +507,6 @@ class Invoice: | |||||||
|         self.invoice_allowance_charge = [] |         self.invoice_allowance_charge = [] | ||||||
|         self.invoice_prepaid_payment = [] |         self.invoice_prepaid_payment = [] | ||||||
|         self.invoice_billing_reference = None |         self.invoice_billing_reference = None | ||||||
|         self.invoice_discrepancy_response = None |  | ||||||
|         self.invoice_type_code = str(type_code) |         self.invoice_type_code = str(type_code) | ||||||
|         self.invoice_ident_prefix = None |         self.invoice_ident_prefix = None | ||||||
|  |  | ||||||
| @@ -688,7 +570,7 @@ class Invoice: | |||||||
|  |  | ||||||
|         self.invoice_operation_type = operation |         self.invoice_operation_type = operation | ||||||
|  |  | ||||||
|     def add_allowance_charge(self, charge: AllowanceCharge): |     def add_allownace_charge(self, charge: AllowanceCharge): | ||||||
|         self.invoice_allowance_charge.append(charge) |         self.invoice_allowance_charge.append(charge) | ||||||
|  |  | ||||||
|     def add_invoice_line(self, line: InvoiceLine): |     def add_invoice_line(self, line: InvoiceLine): | ||||||
| @@ -700,10 +582,6 @@ class Invoice: | |||||||
|     def set_billing_reference(self, billing_reference: BillingReference): |     def set_billing_reference(self, billing_reference: BillingReference): | ||||||
|         self.invoice_billing_reference = billing_reference |         self.invoice_billing_reference = billing_reference | ||||||
|  |  | ||||||
|     def set_discrepancy_response(self, billing_response: BillingResponse): |  | ||||||
|         self.invoice_discrepancy_response = billing_response |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     def accept(self, visitor): |     def accept(self, visitor): | ||||||
|         visitor.visit_payment_mean(self.invoice_payment_mean) |         visitor.visit_payment_mean(self.invoice_payment_mean) | ||||||
|         visitor.visit_customer(self.invoice_customer) |         visitor.visit_customer(self.invoice_customer) | ||||||
| @@ -740,22 +618,11 @@ class Invoice: | |||||||
|         #DIAN 1.7.-2020: FAU14 |         #DIAN 1.7.-2020: FAU14 | ||||||
|         self.invoice_legal_monetary_total.calculate() |         self.invoice_legal_monetary_total.calculate() | ||||||
|  |  | ||||||
|     def _refresh_charges_base_amount(self): |  | ||||||
|         if self.invoice_allowance_charge: |  | ||||||
|             for invline in self.invoice_lines: |  | ||||||
|                 if invline.allowance_charge: |  | ||||||
|                     # TODO actualmente solo uno de los cargos es permitido |  | ||||||
|                     raise ValueError('allowance charge in invoice exclude invoice line') |  | ||||||
|              |  | ||||||
|         # cargos a nivel de factura |  | ||||||
|         for charge in self.invoice_allowance_charge: |  | ||||||
|             charge.set_base_amount(self.invoice_legal_monetary_total.line_extension_amount) |  | ||||||
|          |  | ||||||
|     def calculate(self): |     def calculate(self): | ||||||
|         for invline in self.invoice_lines: |         for invline in self.invoice_lines: | ||||||
|             invline.calculate() |             invline.calculate() | ||||||
|         self._calculate_legal_monetary_total() |         self._calculate_legal_monetary_total() | ||||||
|         self._refresh_charges_base_amount() |  | ||||||
|  |  | ||||||
| class NationalSalesInvoice(Invoice): | class NationalSalesInvoice(Invoice): | ||||||
|     def __init__(self): |     def __init__(self): | ||||||
| @@ -801,27 +668,3 @@ class DebitNote(Invoice): | |||||||
|         if not self.invoice_ident_prefix: |         if not self.invoice_ident_prefix: | ||||||
|             self.invoice_ident_prefix = self.invoice_ident[0:6] |             self.invoice_ident_prefix = self.invoice_ident[0:6] | ||||||
|  |  | ||||||
| class SupportDocument(Invoice): |  | ||||||
|     pass |  | ||||||
|  |  | ||||||
| class SupportDocumentCreditNote(SupportDocument): |  | ||||||
|     def __init__(self, invoice_document_reference: BillingReference, |  | ||||||
|                 invoice_discrepancy_response: BillingResponse): |  | ||||||
|         super().__init__(CreditNoteSupportDocumentType()) |  | ||||||
|  |  | ||||||
|         if not isinstance(invoice_document_reference, BillingReference): |  | ||||||
|             raise TypeError('invoice_document_reference invalid type') |  | ||||||
|         self.invoice_billing_reference = invoice_document_reference |  | ||||||
|         self.invoice_discrepancy_response = invoice_discrepancy_response |  | ||||||
|  |  | ||||||
|     def _get_codelist_tipo_operacion(self): |  | ||||||
|         return codelist.TipoOperacionNCDS |  | ||||||
|  |  | ||||||
|     def _check_ident_prefix(self, prefix): |  | ||||||
|         if len(prefix) != 6: |  | ||||||
|             raise ValueError('prefix must be 6 length') |  | ||||||
|  |  | ||||||
|     def _set_ident_prefix_automatic(self): |  | ||||||
|         if not self.invoice_ident_prefix: |  | ||||||
|             self.invoice_ident_prefix = self.invoice_ident[0:6] |  | ||||||
|     pass |  | ||||||
|   | |||||||
| @@ -2,6 +2,3 @@ from .invoice import * | |||||||
| from .credit_note import * | from .credit_note import * | ||||||
| from .debit_note import * | from .debit_note import * | ||||||
| from .utils import * | from .utils import * | ||||||
| from .attached_document import * |  | ||||||
| from .support_document import * |  | ||||||
| from .support_document_credit_note import * |  | ||||||
|   | |||||||
| @@ -1,14 +0,0 @@ | |||||||
| from .. import fe |  | ||||||
|  |  | ||||||
| __all__ = ['AttachedDocument'] |  | ||||||
|  |  | ||||||
| class AttachedDocument(): |  | ||||||
|  |  | ||||||
|     def __init__(self, id): |  | ||||||
|         schema = 'urn:oasis:names:specification:ubl:schema:xsd:AttachedDocument-2' |  | ||||||
|         self.fexml = fe.FeXML('AttachedDocument', schema) |  | ||||||
|         self.fexml.set_element('./cbc:ID', id) |  | ||||||
|  |  | ||||||
|     def toFachoXML(self): |  | ||||||
|         return self.fexml |  | ||||||
|          |  | ||||||
| @@ -147,6 +147,7 @@ class DIANInvoiceXML(fe.FeXML): | |||||||
|         fexml.set_element('./cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cac:TaxScheme/cbc:ID', |         fexml.set_element('./cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cac:TaxScheme/cbc:ID', | ||||||
|                           invoice.invoice_customer.tax_scheme.code) |                           invoice.invoice_customer.tax_scheme.code) | ||||||
|  |  | ||||||
|  |  | ||||||
|         #DIAN 1.7.-2020: CAJ41 |         #DIAN 1.7.-2020: CAJ41 | ||||||
|         fexml.set_element('./cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cac:TaxScheme/cbc:Name', |         fexml.set_element('./cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cac:TaxScheme/cbc:Name', | ||||||
|                           invoice.invoice_customer.tax_scheme.name) |                           invoice.invoice_customer.tax_scheme.name) | ||||||
| @@ -420,55 +421,42 @@ class DIANInvoiceXML(fe.FeXML): | |||||||
|  |  | ||||||
|     def set_invoice_totals(fexml, invoice): |     def set_invoice_totals(fexml, invoice): | ||||||
|         tax_amount_for = defaultdict(lambda: defaultdict(lambda: Amount(0.0))) |         tax_amount_for = defaultdict(lambda: defaultdict(lambda: Amount(0.0))) | ||||||
|         withholding_amount_for = defaultdict(lambda: defaultdict(lambda: Amount(0.0))) |  | ||||||
|         percent_for = defaultdict(lambda: None) |         percent_for = defaultdict(lambda: None) | ||||||
|  |  | ||||||
|         #requeridos para CUFE |         #requeridos para CUFE | ||||||
|         #tax_amount_for['01']['tax_amount'] = Amount(0.0) |         #tax_amount_for['01']['tax_amount'] = Amount(0.0) | ||||||
|         #tax_amount_for['01']['taxable_amount'] = Amount(0.0) |         #tax_amount_for['01']['taxable_amount'] = Amount(0.0) | ||||||
|         #DIAN 1.7.-2020: FAS07 => Se debe construir estrategia para  su manejo |         #DIAN 1.7.-2020: FAS07 => Se debe construir estrategia para  su manejo | ||||||
|         #tax_amount_for['04']['tax_amount'] += 0.0 |         #tax_amount_for['04']['tax_amount'] = 0.0 | ||||||
|         #tax_amount_for['04']['taxable_amount'] += 0.0 |         #tax_amount_for['04']['taxable_amount'] = 0.0 | ||||||
|         #tax_amount_for['03']['tax_amount'] += 0.0 |         #tax_amount_for['03']['tax_amount'] = 0.0 | ||||||
|         #tax_amount_for['03']['taxable_amount'] += 0.0 |         #tax_amount_for['03']['taxable_amount'] = 0.0 | ||||||
|  |  | ||||||
|         total_tax_amount = Amount(0.0) |         total_tax_amount = Amount(0.0) | ||||||
|         total_withholding_amount = Amount(0.0) |  | ||||||
|  |  | ||||||
|         for invoice_line in invoice.invoice_lines: |         for invoice_line in invoice.invoice_lines: | ||||||
|             for subtotal in invoice_line.tax.subtotals: |             for subtotal in invoice_line.tax.subtotals: | ||||||
|                 if subtotal.scheme is not None: |                 if subtotal.scheme is not None: | ||||||
|                     tax_amount_for[subtotal.scheme.code]['tax_amount'] += subtotal.tax_amount |                     tax_amount_for[subtotal.scheme.code]['tax_amount'] += subtotal.tax_amount | ||||||
|                     tax_amount_for[subtotal.scheme.code]['taxable_amount'] += invoice_line.taxable_amount |                     tax_amount_for[subtotal.scheme.code]['taxable_amount'] += invoice_line.taxable_amount | ||||||
|                     tax_amount_for[subtotal.scheme.code]['name'] = subtotal.scheme.name |  | ||||||
|  |  | ||||||
|                     # MACHETE ojo InvoiceLine.tax pasar a Invoice |                     # MACHETE ojo InvoiceLine.tax pasar a Invoice | ||||||
|                     percent_for[subtotal.scheme.code] = subtotal.percent |                     percent_for[subtotal.scheme.code] = subtotal.percent | ||||||
|  |  | ||||||
|                 total_tax_amount += subtotal.tax_amount |                 total_tax_amount += subtotal.tax_amount | ||||||
|  |  | ||||||
|             for subtotal_withholding in invoice_line.withholding.subtotals: |         fexml.placeholder_for('./cac:TaxTotal') | ||||||
|                 if subtotal_withholding.scheme is not None: |         fexml.set_element_amount('./cac:TaxTotal/cbc:TaxAmount', | ||||||
|                     withholding_amount_for[subtotal_withholding.scheme.code]['tax_amount'] += subtotal_withholding.tax_amount |                                 total_tax_amount) | ||||||
|                     withholding_amount_for[subtotal_withholding.scheme.code]['taxable_amount'] += invoice_line.withholding_taxable_amount |  | ||||||
|  |  | ||||||
|                     # MACHETE ojo InvoiceLine.tax pasar a Invoice |  | ||||||
|                      |  | ||||||
|                     percent_for[subtotal_withholding.scheme.code] = subtotal_withholding.percent |  | ||||||
|  |  | ||||||
|                 total_withholding_amount += subtotal_withholding.tax_amount |  | ||||||
|  |  | ||||||
|         if total_tax_amount != Amount(0.0): |  | ||||||
|             fexml.placeholder_for('./cac:TaxTotal') |  | ||||||
|             fexml.set_element_amount('./cac:TaxTotal/cbc:TaxAmount', |  | ||||||
|                     total_tax_amount) |  | ||||||
|          |  | ||||||
|         for index, item in enumerate(tax_amount_for.items()): |         for index, item in enumerate(tax_amount_for.items()): | ||||||
|             cod_impuesto, amount_of = item |             cod_impuesto, amount_of = item | ||||||
|             next_append = index > 0 |             next_append = index > 0 | ||||||
|  |  | ||||||
|             #DIAN 1.7.-2020: FAS01 |             #DIAN 1.7.-2020: FAS01 | ||||||
|             line = fexml.fragment('./cac:TaxTotal', append=next_append) |             line = fexml.fragment('./cac:TaxTotal', append=next_append) | ||||||
|  |  | ||||||
|             #DIAN 1.7.-2020: FAU06 |             #DIAN 1.7.-2020: FAU06 | ||||||
|             tax_amount = amount_of['tax_amount'] |             tax_amount = amount_of['tax_amount'] | ||||||
|             fexml.set_element_amount_for(line, |             fexml.set_element_amount_for(line, | ||||||
| @@ -494,48 +482,8 @@ class DIANInvoiceXML(fe.FeXML): | |||||||
|             if percent_for[cod_impuesto]: |             if percent_for[cod_impuesto]: | ||||||
|                 line.set_element('/cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cbc:Percent', |                 line.set_element('/cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cbc:Percent', | ||||||
|                                  percent_for[cod_impuesto]) |                                  percent_for[cod_impuesto]) | ||||||
|                  |  | ||||||
|             line.set_element('/cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cac:TaxScheme/cbc:ID', |             line.set_element('/cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cac:TaxScheme/cbc:ID', | ||||||
|                     cod_impuesto) |                              cod_impuesto) | ||||||
|             line.set_element('/cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cac:TaxScheme/cbc:Name', |  | ||||||
|                              amount_of['name']) |  | ||||||
|              |  | ||||||
|         for index, item in enumerate(withholding_amount_for.items()): |  | ||||||
|             cod_impuesto, amount_of = item |  | ||||||
|             next_append = index > 0 |  | ||||||
|  |  | ||||||
|             #DIAN 1.7.-2020: FAS01 |  | ||||||
|             line = fexml.fragment('./cac:WithholdingTaxTotal', append=next_append) |  | ||||||
|             #DIAN 1.7.-2020: FAU06 |  | ||||||
|             tax_amount = amount_of['tax_amount'] |  | ||||||
|             fexml.set_element_amount_for(line, |  | ||||||
|                                          '/cac:WithholdingTaxTotal/cbc:TaxAmount', |  | ||||||
|                                          tax_amount) |  | ||||||
|  |  | ||||||
|             #DIAN 1.7.-2020: FAS05 |  | ||||||
|             fexml.set_element_amount_for(line, |  | ||||||
|                                          '/cac:WithholdingTaxTotal/cac:TaxSubtotal/cbc:TaxableAmount', |  | ||||||
|                                          amount_of['taxable_amount']) |  | ||||||
|  |  | ||||||
|             #DIAN 1.7.-2020: FAU06 |  | ||||||
|             fexml.set_element_amount_for(line, |  | ||||||
|                                          '/cac:WithholdingTaxTotal/cac:TaxSubtotal/cbc:TaxAmount', |  | ||||||
|                                          amount_of['tax_amount']) |  | ||||||
|  |  | ||||||
|             #DIAN 1.7.-2020: FAS07 |  | ||||||
|             if percent_for[cod_impuesto]: |  | ||||||
|                 line.set_element('/cac:WithholdingTaxTotal/cac:TaxSubtotal/cbc:Percent', |  | ||||||
|                                  percent_for[cod_impuesto]) |  | ||||||
|  |  | ||||||
|  |  | ||||||
|             if percent_for[cod_impuesto]: |  | ||||||
|                 line.set_element('/cac:WithholdingTaxTotal/cac:TaxSubtotal/cac:TaxCategory/cbc:Percent', |  | ||||||
|                                  percent_for[cod_impuesto]) |  | ||||||
|                  |  | ||||||
|             line.set_element('/cac:WithholdingTaxTotal/cac:TaxSubtotal/cac:TaxCategory/cac:TaxScheme/cbc:ID', |  | ||||||
|                     cod_impuesto) |  | ||||||
|             line.set_element('/cac:WithholdingTaxTotal/cac:TaxSubtotal/cac:TaxCategory/cac:TaxScheme/cbc:Name', |  | ||||||
|                     'ReteRenta') |  | ||||||
|  |  | ||||||
|     # abstract method |     # abstract method | ||||||
|     def tag_document(fexml): |     def tag_document(fexml): | ||||||
| @@ -554,6 +502,7 @@ class DIANInvoiceXML(fe.FeXML): | |||||||
|         fexml.set_element_amount_for(line, |         fexml.set_element_amount_for(line, | ||||||
|                                      './cac:TaxTotal/cac:TaxSubtotal/cbc:TaxableAmount', |                                      './cac:TaxTotal/cac:TaxSubtotal/cbc:TaxableAmount', | ||||||
|                                      invoice_line.taxable_amount) |                                      invoice_line.taxable_amount) | ||||||
|  |  | ||||||
|         for subtotal in invoice_line.tax.subtotals: |         for subtotal in invoice_line.tax.subtotals: | ||||||
|             line.set_element('./cac:TaxTotal/cac:TaxSubtotal/cbc:TaxAmount', subtotal.tax_amount, currencyID='COP') |             line.set_element('./cac:TaxTotal/cac:TaxSubtotal/cbc:TaxAmount', subtotal.tax_amount, currencyID='COP') | ||||||
|  |  | ||||||
| @@ -565,28 +514,6 @@ class DIANInvoiceXML(fe.FeXML): | |||||||
|                 line.set_element('./cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cac:TaxScheme/cbc:ID', subtotal.scheme.code) |                 line.set_element('./cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cac:TaxScheme/cbc:ID', subtotal.scheme.code) | ||||||
|                 line.set_element('./cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cac:TaxScheme/cbc:Name', subtotal.scheme.name) |                 line.set_element('./cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cac:TaxScheme/cbc:Name', subtotal.scheme.name) | ||||||
|  |  | ||||||
|  |  | ||||||
|     def set_invoice_line_withholding(fexml, line, invoice_line): |  | ||||||
|         fexml.set_element_amount_for(line, |  | ||||||
|                                      './cac:WithholdingTaxTotal/cbc:TaxAmount', |  | ||||||
|                                      invoice_line.withholding_amount) |  | ||||||
|         #DIAN 1.7.-2020: FAX05 |  | ||||||
|         fexml.set_element_amount_for(line, |  | ||||||
|                                      './cac:WithholdingTaxTotal/cac:TaxSubtotal/cbc:TaxableAmount', |  | ||||||
|                                      invoice_line.withholding_taxable_amount) |  | ||||||
|  |  | ||||||
|         for subtotal in invoice_line.withholding.subtotals: |  | ||||||
|             line.set_element('./cac:WithholdingTaxTotal/cac:TaxSubtotal/cbc:TaxAmount', subtotal.tax_amount, currencyID='COP') |  | ||||||
|  |  | ||||||
|             if subtotal.percent is not None: |  | ||||||
|                 line.set_element('./cac:WithholdingTaxTotal/cac:TaxSubtotal/cac:TaxCategory/cbc:Percent', '%0.2f' % round(subtotal.percent, 2)) |  | ||||||
|  |  | ||||||
|             if subtotal.scheme is not None: |  | ||||||
|                 #DIAN 1.7.-2020: FAX15 |  | ||||||
|                 line.set_element('./cac:WithholdingTaxTotal/cac:TaxSubtotal/cac:TaxCategory/cac:TaxScheme/cbc:ID', subtotal.scheme.code) |  | ||||||
|                 line.set_element('./cac:WithholdingTaxTotal/cac:TaxSubtotal/cac:TaxCategory/cac:TaxScheme/cbc:Name', subtotal.scheme.name) |  | ||||||
|  |  | ||||||
|                  |  | ||||||
|     def set_invoice_lines(fexml, invoice): |     def set_invoice_lines(fexml, invoice): | ||||||
|         next_append = False |         next_append = False | ||||||
|         for index, invoice_line in enumerate(invoice.invoice_lines): |         for index, invoice_line in enumerate(invoice.invoice_lines): | ||||||
| @@ -602,9 +529,6 @@ class DIANInvoiceXML(fe.FeXML): | |||||||
|             if not isinstance(invoice_line.tax, TaxTotalOmit): |             if not isinstance(invoice_line.tax, TaxTotalOmit): | ||||||
|                 fexml.set_invoice_line_tax(line, invoice_line) |                 fexml.set_invoice_line_tax(line, invoice_line) | ||||||
|  |  | ||||||
|             if not isinstance(invoice_line.withholding, WithholdingTaxTotalOmit): |  | ||||||
|                 fexml.set_invoice_line_withholding(line, invoice_line) |  | ||||||
|  |  | ||||||
|             line.set_element('./cac:Item/cbc:Description', invoice_line.item.description) |             line.set_element('./cac:Item/cbc:Description', invoice_line.item.description) | ||||||
|  |  | ||||||
|             line.set_element('./cac:Item/cac:StandardItemIdentification/cbc:ID', |             line.set_element('./cac:Item/cac:StandardItemIdentification/cbc:ID', | ||||||
| @@ -616,31 +540,10 @@ class DIANInvoiceXML(fe.FeXML): | |||||||
|             line.set_element('./cac:Price/cbc:PriceAmount', invoice_line.price.amount, currencyID=invoice_line.price.amount.currency.code) |             line.set_element('./cac:Price/cbc:PriceAmount', invoice_line.price.amount, currencyID=invoice_line.price.amount.currency.code) | ||||||
|             #DIAN 1.7.-2020: FBB04 |             #DIAN 1.7.-2020: FBB04 | ||||||
|             line.set_element('./cac:Price/cbc:BaseQuantity', |             line.set_element('./cac:Price/cbc:BaseQuantity', | ||||||
|                              invoice_line.price.quantity, |                              invoice_line.quantity, | ||||||
|                              unitCode=invoice_line.quantity.code) |                              unitCode=invoice_line.quantity.code) | ||||||
|  |  | ||||||
|             for idx, charge in enumerate(invoice_line.allowance_charge): |  | ||||||
|                 next_append_charge = idx > 0 |  | ||||||
|                 fexml.append_allowance_charge(line, index + 1, charge, append=next_append_charge) |  | ||||||
|                  |  | ||||||
|     def set_allowance_charge(fexml, invoice): |  | ||||||
|         for idx, charge in enumerate(invoice.invoice_allowance_charge): |  | ||||||
|             next_append = idx > 0 |  | ||||||
|             fexml.append_allowance_charge(fexml, idx + 1, charge, append=next_append) |  | ||||||
|  |  | ||||||
|     def append_allowance_charge(fexml, parent, idx, charge, append=False): |  | ||||||
|             line = parent.fragment('./cac:AllowanceCharge', append=append) |  | ||||||
|             #DIAN 1.7.-2020: FAQ02 |  | ||||||
|             line.set_element('./cbc:ID', idx) |  | ||||||
|             #DIAN 1.7.-2020: FAQ03 |  | ||||||
|             line.set_element('./cbc:ChargeIndicator', str(charge.charge_indicator).lower()) |  | ||||||
|             if charge.reason: |  | ||||||
|                 line.set_element('./cbc:AllowanceChargeReasonCode', charge.reason.code) |  | ||||||
|                 line.set_element('./cbc:allowanceChargeReason', charge.reason.reason) |  | ||||||
|             line.set_element('./cbc:MultiplierFactorNumeric', str(round(charge.multiplier_factor_numeric, 2))) |  | ||||||
|             fexml.set_element_amount_for(line, './cbc:Amount', charge.amount) |  | ||||||
|             fexml.set_element_amount_for(line, './cbc:BaseAmount', charge.base_amount) |  | ||||||
|              |  | ||||||
|     def attach_invoice(fexml, invoice): |     def attach_invoice(fexml, invoice): | ||||||
|         """adiciona etiquetas a FEXML y retorna FEXML |         """adiciona etiquetas a FEXML y retorna FEXML | ||||||
|         en caso de fallar validacion retorna None""" |         en caso de fallar validacion retorna None""" | ||||||
| @@ -652,6 +555,7 @@ class DIANInvoiceXML(fe.FeXML): | |||||||
|         fexml.placeholder_for('./cbc:ProfileExecutionID') |         fexml.placeholder_for('./cbc:ProfileExecutionID') | ||||||
|         fexml.set_element('./cbc:ID', invoice.invoice_ident) |         fexml.set_element('./cbc:ID', invoice.invoice_ident) | ||||||
|         fexml.placeholder_for('./cbc:UUID') |         fexml.placeholder_for('./cbc:UUID') | ||||||
|  |         fexml.set_element('./cbc:DocumentCurrencyCode', 'COP') | ||||||
|         fexml.set_element('./cbc:IssueDate', invoice.invoice_issue.strftime('%Y-%m-%d')) |         fexml.set_element('./cbc:IssueDate', invoice.invoice_issue.strftime('%Y-%m-%d')) | ||||||
|         #DIAN 1.7.-2020: FAD10 |         #DIAN 1.7.-2020: FAD10 | ||||||
|         fexml.set_element('./cbc:IssueTime', invoice.invoice_issue.strftime('%H:%M:%S-05:00')) |         fexml.set_element('./cbc:IssueTime', invoice.invoice_issue.strftime('%H:%M:%S-05:00')) | ||||||
| @@ -660,25 +564,23 @@ class DIANInvoiceXML(fe.FeXML): | |||||||
|                         listAgencyID='195', |                         listAgencyID='195', | ||||||
|                         listAgencyName='No matching global declaration available for the validation root', |                         listAgencyName='No matching global declaration available for the validation root', | ||||||
|                         listURI='http://www.dian.gov.co') |                         listURI='http://www.dian.gov.co') | ||||||
|         fexml.set_element('./cbc:DocumentCurrencyCode', 'COP') |  | ||||||
|         fexml.set_element('./cbc:LineCountNumeric', len(invoice.invoice_lines)) |         fexml.set_element('./cbc:LineCountNumeric', len(invoice.invoice_lines)) | ||||||
|         if fexml.tag_document() == 'Invoice': |         fexml.set_element('./cac:%sPeriod/cbc:StartDate' % (fexml.tag_document()), | ||||||
|             fexml.set_element('./cac:%sPeriod/cbc:StartDate' % ( |                           invoice.invoice_period_start.strftime('%Y-%m-%d')) | ||||||
|                 fexml.tag_document()), |  | ||||||
|                               invoice.invoice_period_start.strftime('%Y-%m-%d')) |         fexml.set_element('./cac:%sPeriod/cbc:EndDate' % (fexml.tag_document()), | ||||||
|  |                           invoice.invoice_period_end.strftime('%Y-%m-%d')) | ||||||
|  |  | ||||||
|             fexml.set_element('./cac:%sPeriod/cbc:EndDate' % ( |  | ||||||
|                 fexml.tag_document()), |  | ||||||
|                               invoice.invoice_period_end.strftime('%Y-%m-%d')) |  | ||||||
|         fexml.set_billing_reference(invoice) |  | ||||||
|         fexml.customize(invoice) |         fexml.customize(invoice) | ||||||
|  |  | ||||||
|         fexml.set_supplier(invoice) |         fexml.set_supplier(invoice) | ||||||
|         fexml.set_customer(invoice) |         fexml.set_customer(invoice) | ||||||
|         fexml.set_payment_mean(invoice) |  | ||||||
|         fexml.set_invoice_totals(invoice) |  | ||||||
|         fexml.set_legal_monetary(invoice) |         fexml.set_legal_monetary(invoice) | ||||||
|  |         fexml.set_invoice_totals(invoice) | ||||||
|         fexml.set_invoice_lines(invoice) |         fexml.set_invoice_lines(invoice) | ||||||
|         fexml.set_allowance_charge(invoice) |         fexml.set_payment_mean(invoice) | ||||||
|  |         fexml.set_billing_reference(invoice) | ||||||
|  |  | ||||||
|         return fexml |         return fexml | ||||||
|  |  | ||||||
|     def customize(fexml, invoice): |     def customize(fexml, invoice): | ||||||
|   | |||||||
| @@ -1,529 +0,0 @@ | |||||||
| from .. import fe |  | ||||||
| from ..form import * |  | ||||||
| from datetime import datetime, date |  | ||||||
| from .attached_document import * |  | ||||||
|  |  | ||||||
| __all__ = ['DIANSupportDocumentXML'] |  | ||||||
|  |  | ||||||
| class DIANSupportDocumentXML(fe.FeXML): |  | ||||||
|     """ |  | ||||||
|     DianSupportDocumentXML mapea objeto form.Invoice a XML segun |  | ||||||
|     lo indicado para él Documento soporte en adquisiciones efectuadas con sujetos no obligados a expedir factura de venta o documento equivalente. |  | ||||||
|     """ |  | ||||||
|  |  | ||||||
|     def __init__(self, invoice, tag_document = 'Invoice'): |  | ||||||
|         super().__init__(tag_document, 'http://www.dian.gov.co/contratos/facturaelectronica/v1') |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAB03 |  | ||||||
|         #DIAN 1.1.-2021: NSAB03 |  | ||||||
|         self.placeholder_for('./ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent/sts:DianExtensions/sts:InvoiceControl') |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAB13 |  | ||||||
|         #DIAN 1.1.-2021: NSAB13         |  | ||||||
|         self.placeholder_for('./ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent/sts:DianExtensions/sts:InvoiceSource') |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAB18 |  | ||||||
|         #DIAN 1.1.-2021: NSAB18                 |  | ||||||
|         self.placeholder_for('./ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent/sts:DianExtensions/sts:SoftwareProvider') |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAB27 |  | ||||||
|         #DIAN 1.1.-2021: NSAB27         |  | ||||||
|         self.placeholder_for('./ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent/sts:DianExtensions/sts:SoftwareSecurityCode') |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAB30 DSAB31 |  | ||||||
|         #DIAN 1.1.-2021: NSAB30 NSAB31 |  | ||||||
|         self.placeholder_for('./ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent/sts:DianExtensions/sts:AuthorizationProvider/sts:AuthorizationProviderID') |  | ||||||
|          |  | ||||||
|         #ZE02 se requiere existencia para firmar |  | ||||||
|         #DIAN 1.1.-2021: DSAA02 DSAB01 |  | ||||||
|         #DIAN 1.1.-2021: NSAA02 NSAB01         |  | ||||||
|         ublextension = self.fragment('./ext:UBLExtensions/ext:UBLExtension', append=True) |  | ||||||
|         #DIAN 1.1.-2021: DSAB02 |  | ||||||
|         #DIAN 1.1.-2021: NSAB02         |  | ||||||
|         extcontent = ublextension.find_or_create_element('/ext:UBLExtension/ext:ExtensionContent') |  | ||||||
|         self.attach_invoice(invoice) |  | ||||||
|  |  | ||||||
|     def set_supplier(fexml, invoice): |  | ||||||
|         #DIAN 1.1.-2021: DSAJ01        |  | ||||||
|         #DIAN 1.1.-2021: NSAB01 |  | ||||||
|         fexml.placeholder_for('./cac:AccountingSupplierParty') |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAJ02 |  | ||||||
|         #DIAN 1.1.-2021: NSAJ02 |  | ||||||
|         fexml.set_element('./cac:AccountingSupplierParty/cbc:AdditionalAccountID', |  | ||||||
|                           invoice.invoice_supplier.organization_code) |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAJ07 DSAJ08 |  | ||||||
|         #DIAN 1.1.-2021: NSAJ07 NSAJ08         |  | ||||||
|         fexml.placeholder_for('./cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address') |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAJ09 |  | ||||||
|         #DIAN 1.1.-2021: NSAJ09         |  | ||||||
|         fexml.set_element('./cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:ID', |  | ||||||
|                           invoice.invoice_supplier.address.city.code) |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAJ10 |  | ||||||
|         #DIAN 1.1.-2021: NSAJ10         |  | ||||||
|         fexml.set_element('./cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:CityName', |  | ||||||
|                           invoice.invoice_supplier.address.city.name) |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAJ73 |  | ||||||
|         #DIAN 1.1.-2021: NSAJ73         |  | ||||||
|         fexml.set_element('./cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:PostalZone', |  | ||||||
|                           invoice.invoice_supplier.address.postalzone.code) |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAJ11 |  | ||||||
|         #DIAN 1.1.-2021: NSAJ11  |  | ||||||
|         fexml.set_element('./cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:CountrySubentity', |  | ||||||
|                           invoice.invoice_supplier.address.countrysubentity.name) |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAJ12 |  | ||||||
|         #DIAN 1.1.-2021: NSAJ12 |  | ||||||
|         fexml.set_element('./cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:CountrySubentityCode', |  | ||||||
|                           invoice.invoice_supplier.address.countrysubentity.code) |  | ||||||
|         #DIAN 1.1.-2021: NSAJ13 NSAJ14 |  | ||||||
|         fexml.set_element('./cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cac:AddressLine/cbc:Line', |  | ||||||
|                           invoice.invoice_supplier.address.street) |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAJ15 DSAJ16 |  | ||||||
|         #DIAN 1.1.-2021: NSAJ15 NSAJ16 |  | ||||||
|         fexml.set_element('./cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cac:Country/cbc:IdentificationCode', |  | ||||||
|                           invoice.invoice_supplier.address.country.code) |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAJ17 |  | ||||||
|         #DIAN 1.1.-2021: NSAJ17 |  | ||||||
|         fexml.set_element('./cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cac:Country/cbc:Name', |  | ||||||
|                           invoice.invoice_supplier.address.country.name, |  | ||||||
|                           #DIAN 1.1.-2021: DSAJ18 |  | ||||||
|                           #DIAN 1.1.-2021: NSAJ18 |  | ||||||
|                           languageID = 'es') |  | ||||||
|  |  | ||||||
|  |  | ||||||
|         supplier_company_id_attrs = fe.SCHEME_AGENCY_ATTRS.copy() |  | ||||||
|         supplier_company_id_attrs.update({'schemeID': invoice.invoice_supplier.ident.dv, |  | ||||||
|                                           'schemeName': invoice.invoice_supplier.ident.type_fiscal}) |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAJ19 |  | ||||||
|         #DIAN 1.1.-2021: NSAJ19 |  | ||||||
|         fexml.placeholder_for('./cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme') |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAJ20 |  | ||||||
|         #DIAN 1.1.-2021: NSAJ20 |  | ||||||
|         fexml.set_element('./cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cbc:RegistrationName', |  | ||||||
|                           invoice.invoice_supplier.legal_name) |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAJ21 |  | ||||||
|         #DIAN 1.1.-2021: NSAJ21 |  | ||||||
|         fexml.set_element('./cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID', |  | ||||||
|                           invoice.invoice_supplier.ident, |  | ||||||
|                           #DIAN 1.1.-2021: DSAJ22 DSAJ23 DSAJ24 DSAJ25 |  | ||||||
|                           #DIAN 1.1.-2021: NSAJ22 NSAJ23 NSAJ24 NSAJ25 |  | ||||||
|                           **supplier_company_id_attrs) |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAJ26 |  | ||||||
|         #DIAN 1.1.-2021: NSAJ26         |  | ||||||
|         fexml.set_element('./cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cbc:TaxLevelCode', |  | ||||||
|                           invoice.invoice_supplier.responsability_code, |  | ||||||
|                           listName=invoice.invoice_supplier.responsability_regime_code) |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAJ39 |  | ||||||
|         #DIAN 1.1.-2021: NSAJ39 |  | ||||||
|         fexml.placeholder_for('./cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cac:TaxScheme') |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAJ40 |  | ||||||
|         #DIAN 1.1.-2021: NSAJ40 |  | ||||||
|         fexml.set_element('./cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cac:TaxScheme/cbc:ID', |  | ||||||
|                           invoice.invoice_customer.tax_scheme.code) |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAJ41 |  | ||||||
|         #DIAN 1.1.-2021: NSAJ41         |  | ||||||
|         fexml.set_element('./cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cac:TaxScheme/cbc:Name', |  | ||||||
|                           invoice.invoice_customer.tax_scheme.name) |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     def set_customer(fexml, invoice): |  | ||||||
|         #DIAN 1.1.-2021: DSAK01 |  | ||||||
|         #DIAN 1.1.-2021: NSAK01 |  | ||||||
|         fexml.placeholder_for('./cac:AccountingCustomerParty') |  | ||||||
|          |  | ||||||
|         #DIAN 1.1.-2021: DSAK02 |  | ||||||
|         #DIAN 1.1.-2021: NSAK02 |  | ||||||
|         fexml.set_element('./cac:AccountingCustomerParty/cbc:AdditionalAccountID', |  | ||||||
|                           invoice.invoice_customer.organization_code) |  | ||||||
|          |  | ||||||
|         #DIAN 1.1.-2021: DSAK03 |  | ||||||
|         #DIAN 1.1.-2021: NSAK03 |  | ||||||
|         fexml.placeholder_for('./cac:AccountingCustomerParty/cac:Party') |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAK19 |  | ||||||
|         #DIAN 1.1.-2021: NSAK19         |  | ||||||
|         fexml.placeholder_for('./cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme') |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAK20 |  | ||||||
|         #DIAN 1.1.-2021: NSAK20 |  | ||||||
|         fexml.set_element('./cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cbc:RegistrationName', |  | ||||||
|                           invoice.invoice_customer.legal_name) |  | ||||||
|  |  | ||||||
|         customer_company_id_attrs = fe.SCHEME_AGENCY_ATTRS.copy() |  | ||||||
|         customer_company_id_attrs.update({'schemeID': invoice.invoice_customer.ident.dv, |  | ||||||
|                                            'schemeName': invoice.invoice_customer.ident.type_fiscal}) |  | ||||||
|          |  | ||||||
|         #DIAN 1.1.-2021: DSAK21 |  | ||||||
|         #DIAN 1.1.-2021: NSAK21 |  | ||||||
|         fexml.set_element('./cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID', |  | ||||||
|                           invoice.invoice_customer.ident, |  | ||||||
|                           #DIAN 1.1.-2021: DSAK22 DSAK23 DSAK24 DSAK25 |  | ||||||
|                           #DIAN 1.1.-2021: NSAK22 NSAK23 NSAK24 NSAK25 |  | ||||||
|                           **customer_company_id_attrs) |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAK26 |  | ||||||
|         #DIAN 1.1.-2021: NSAK26 |  | ||||||
|         fexml.set_element('./cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cbc:TaxLevelCode', |  | ||||||
|                           invoice.invoice_customer.responsability_code) |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAK39 |  | ||||||
|         #DIAN 1.1.-2021: NSAK39 |  | ||||||
|         fexml.placeholder_for('./cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cac:TaxScheme') |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAK40 |  | ||||||
|         #DIAN 1.1.-2021: NSAK40 |  | ||||||
|         fexml.set_element('./cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cac:TaxScheme/cbc:ID', |  | ||||||
|                           invoice.invoice_customer.tax_scheme.code) |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAK41 |  | ||||||
|         #DIAN 1.1.-2021: NSAK41 |  | ||||||
|         fexml.set_element('./cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cac:TaxScheme/cbc:Name', |  | ||||||
|                           invoice.invoice_customer.tax_scheme.name) |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     def set_payment_mean(fexml, invoice): |  | ||||||
|         payment_mean = invoice.invoice_payment_mean |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAN01 DSAN02 |  | ||||||
|         #DIAN 1.1.-2021: NSAN02 NSAN02 |  | ||||||
|         fexml.set_element('./cac:PaymentMeans/cbc:ID', payment_mean.id) |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAN03 |  | ||||||
|         #DIAN 1.1.-2021: NSAN03 |  | ||||||
|         fexml.set_element('./cac:PaymentMeans/cbc:PaymentMeansCode', payment_mean.code) |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAN04 |  | ||||||
|         #DIAN 1.1.-2021: NSAN04         |  | ||||||
|         fexml.set_element('./cac:PaymentMeans/cbc:PaymentDueDate', payment_mean.due_at.strftime('%Y-%m-%d')) |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAN05 |  | ||||||
|         #DIAN 1.1.-2021: NSAN05 |  | ||||||
|         fexml.set_element('./cac:PaymentMeans/cbc:PaymentID', payment_mean.payment_id) |  | ||||||
|  |  | ||||||
|     def set_element_amount_for(fexml, xml, xpath, amount): |  | ||||||
|         if not isinstance(amount, Amount): |  | ||||||
|             raise TypeError("amount not is Amount") |  | ||||||
|  |  | ||||||
|         xml.set_element(xpath, amount, currencyID=amount.currency.code) |  | ||||||
|  |  | ||||||
|     def set_element_amount(fexml, xpath, amount): |  | ||||||
|         if not isinstance(amount, Amount): |  | ||||||
|             raise TypeError("amount not is Amount") |  | ||||||
|  |  | ||||||
|         fexml.set_element(xpath, amount, currencyID=amount.currency.code) |  | ||||||
|  |  | ||||||
|     def set_legal_monetary(fexml, invoice): |  | ||||||
|         #DIAN 1.1.-2021: DSAU01 DSAU02 DSAU03 |  | ||||||
|         #DIAN 1.1.-2021: NSAU01 NSAU02 NSAU03 |  | ||||||
|         fexml.set_element_amount('./cac:LegalMonetaryTotal/cbc:LineExtensionAmount', |  | ||||||
|                                  invoice.invoice_legal_monetary_total.line_extension_amount) |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAU04 DSAU05 |  | ||||||
|         #DIAN 1.1.-2021: NSAU04 NSAU05 |  | ||||||
|         fexml.set_element_amount('./cac:LegalMonetaryTotal/cbc:TaxExclusiveAmount', |  | ||||||
|                                 invoice.invoice_legal_monetary_total.tax_exclusive_amount) |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAU06 DSAU07 |  | ||||||
|         #DIAN 1.1.-2021: NSAU06 DSAU07 |  | ||||||
|         fexml.set_element_amount('./cac:LegalMonetaryTotal/cbc:TaxInclusiveAmount', |  | ||||||
|                                 invoice.invoice_legal_monetary_total.tax_inclusive_amount) |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAU10 DSAU11 |  | ||||||
|         #DIAN 1.1.-2021: NSAU10 DSAU11 |  | ||||||
|         fexml.set_element_amount('./cac:LegalMonetaryTotal/cbc:ChargeTotalAmount', |  | ||||||
|                                 invoice.invoice_legal_monetary_total.charge_total_amount) |  | ||||||
|  |  | ||||||
|         #DIAN 1.1.-2021: DSAU14 DSAU15 |  | ||||||
|         #DIAN 1.1.-2021: NSAU14 DSAU15 |  | ||||||
|         fexml.set_element_amount('./cac:LegalMonetaryTotal/cbc:PayableAmount', |  | ||||||
|                                 invoice.invoice_legal_monetary_total.payable_amount) |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     def _set_invoice_document_reference(fexml, reference): |  | ||||||
|         fexml._do_set_billing_reference(reference, 'cac:InvoiceDocumentReference') |  | ||||||
|  |  | ||||||
|     def _set_credit_note_document_reference(fexml, reference): |  | ||||||
|         fexml._do_set_billing_reference(reference, 'cac:CreditNoteDocumentReference') |  | ||||||
|  |  | ||||||
|     def _set_debit_note_document_reference(fexml, reference): |  | ||||||
|         fexml._do_set_billing_reference(reference, 'cac:DebitNoteDocumentReference') |  | ||||||
|  |  | ||||||
|     def _do_set_billing_reference(fexml, reference, tag_document): |  | ||||||
|  |  | ||||||
|         if tag_document == 'Invoice': |  | ||||||
|             schemeName = 'CUFE-SHA384' |  | ||||||
|         else: |  | ||||||
|             schemeName = 'CUDS-SHA384' |  | ||||||
|              |  | ||||||
|         fexml.set_element('./cac:BillingReference/%s/cbc:ID' %(tag_document), |  | ||||||
|                           reference.ident) |  | ||||||
|         fexml.set_element('./cac:BillingReference/cac:InvoiceDocumentReference/cbc:UUID', |  | ||||||
|                           reference.uuid, |  | ||||||
|                           schemeName=schemeName) |  | ||||||
|         fexml.set_element('./cac:BillingReference/cac:InvoiceDocumentReference/cbc:IssueDate', |  | ||||||
|                           reference.date.strftime("%Y-%m-%d")) |  | ||||||
|  |  | ||||||
|     def set_billing_reference(fexml, invoice): |  | ||||||
|         reference = invoice.invoice_billing_reference |  | ||||||
|         if reference is None: |  | ||||||
|             return |  | ||||||
|  |  | ||||||
|         if isinstance(reference, DebitNoteDocumentReference): |  | ||||||
|             return fexml._set_debit_note_document_reference(reference) |  | ||||||
|         if isinstance(reference, CreditNoteDocumentReference): |  | ||||||
|             return fexml._set_credit_note_document_reference(reference) |  | ||||||
|  |  | ||||||
|         if isinstance(reference, InvoiceDocumentReference): |  | ||||||
|             return fexml._set_invoice_document_reference(reference) |  | ||||||
|  |  | ||||||
|     def set_discrepancy_response(fexml, invoice): |  | ||||||
|         reference = invoice.invoice_discrepancy_response |  | ||||||
|         if reference is None: |  | ||||||
|             return |  | ||||||
|         if isinstance(reference, DebitNoteDocumentReference): |  | ||||||
|             return fexml._set_debit_note_document_reference(reference) |  | ||||||
|         if isinstance(reference, CreditNoteDocumentReference): |  | ||||||
|             return fexml._set_credit_note_document_reference(reference) |  | ||||||
|  |  | ||||||
|         if isinstance(reference, InvoiceDocumentReference): |  | ||||||
|             return fexml._set_invoice_document_reference(reference) |  | ||||||
|  |  | ||||||
|         fexml.set_element('./cac:DiscrepancyResponse/cbc:ReferenceID', |  | ||||||
|                 reference.id) |  | ||||||
|         fexml.set_element('./cac:DiscrepancyResponse/cbc:ResponseCode', |  | ||||||
|                 reference.code) |  | ||||||
|         fexml.set_element('./cac:DiscrepancyResponse/cbc:Description', |  | ||||||
|                 reference.description)         |  | ||||||
|  |  | ||||||
|     def set_invoice_totals(fexml, invoice): |  | ||||||
|         tax_amount_for = defaultdict(lambda: defaultdict(lambda: Amount(0.0))) |  | ||||||
|         percent_for = defaultdict(lambda: None) |  | ||||||
|  |  | ||||||
|         total_tax_amount = Amount(0.0) |  | ||||||
|  |  | ||||||
|         for invoice_line in invoice.invoice_lines: |  | ||||||
|             for subtotal in invoice_line.tax.subtotals: |  | ||||||
|                 if subtotal.scheme is not None: |  | ||||||
|                     tax_amount_for[subtotal.scheme.code]['tax_amount'] += subtotal.tax_amount |  | ||||||
|                     tax_amount_for[subtotal.scheme.code]['taxable_amount'] += invoice_line.taxable_amount |  | ||||||
|  |  | ||||||
|                     # MACHETE ojo InvoiceLine.tax pasar a Invoice |  | ||||||
|                     percent_for[subtotal.scheme.code] = subtotal.percent |  | ||||||
|  |  | ||||||
|                 total_tax_amount += subtotal.tax_amount |  | ||||||
|  |  | ||||||
|  |  | ||||||
|         if total_tax_amount != Amount(0.0): |  | ||||||
|             fexml.placeholder_for('./cac:TaxTotal') |  | ||||||
|             fexml.set_element_amount('./cac:TaxTotal/cbc:TaxAmount', |  | ||||||
|                     total_tax_amount) |  | ||||||
|  |  | ||||||
|          |  | ||||||
|         for index, item in enumerate(tax_amount_for.items()): |  | ||||||
|             cod_impuesto, amount_of = item |  | ||||||
|             next_append = index > 0 |  | ||||||
|  |  | ||||||
|             #DIAN 1.7.-2020: FAS01 |  | ||||||
|             line = fexml.fragment('./cac:TaxTotal', append=next_append) |  | ||||||
|             #DIAN 1.7.-2020: FAU06 |  | ||||||
|             tax_amount = amount_of['tax_amount'] |  | ||||||
|             fexml.set_element_amount_for(line, |  | ||||||
|                                          '/cac:TaxTotal/cbc:TaxAmount', |  | ||||||
|                                          tax_amount) |  | ||||||
|  |  | ||||||
|             #DIAN 1.7.-2020: FAS05 |  | ||||||
|             fexml.set_element_amount_for(line, |  | ||||||
|                                          '/cac:TaxTotal/cac:TaxSubtotal/cbc:TaxableAmount', |  | ||||||
|                                          amount_of['taxable_amount']) |  | ||||||
|  |  | ||||||
|             #DIAN 1.7.-2020: FAU06 |  | ||||||
|             fexml.set_element_amount_for(line, |  | ||||||
|                                          '/cac:TaxTotal/cac:TaxSubtotal/cbc:TaxAmount', |  | ||||||
|                                          amount_of['tax_amount']) |  | ||||||
|  |  | ||||||
|             #DIAN 1.7.-2020: FAS07 |  | ||||||
|             if percent_for[cod_impuesto]: |  | ||||||
|                 line.set_element('/cac:TaxTotal/cac:TaxSubtotal/cbc:Percent', |  | ||||||
|                                  percent_for[cod_impuesto]) |  | ||||||
|  |  | ||||||
|  |  | ||||||
|             if percent_for[cod_impuesto]: |  | ||||||
|                 line.set_element('/cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cbc:Percent', |  | ||||||
|                                  percent_for[cod_impuesto]) |  | ||||||
|                  |  | ||||||
|             line.set_element('/cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cac:TaxScheme/cbc:ID', |  | ||||||
|                     cod_impuesto) |  | ||||||
|             line.set_element('/cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cac:TaxScheme/cbc:Name', |  | ||||||
|                     'IVA') |  | ||||||
|  |  | ||||||
|                  |  | ||||||
|     # abstract method |  | ||||||
|     def tag_document(fexml): |  | ||||||
|         return 'Invoice' |  | ||||||
|  |  | ||||||
|     # abstract method |  | ||||||
|     def tag_document_concilied(fexml): |  | ||||||
|         return 'Invoiced' |  | ||||||
|  |  | ||||||
|     def set_invoice_line_withholding(fexml, line, invoice_line): |  | ||||||
|         fexml.set_element_amount_for(line, |  | ||||||
|                                      './cac:WithholdingTaxTotal/cbc:TaxAmount', |  | ||||||
|                                      invoice_line.withholding_amount) |  | ||||||
|         #DIAN 1.7.-2020: FAX05 |  | ||||||
|         fexml.set_element_amount_for(line, |  | ||||||
|                                      './cac:WithholdingTaxTotal/cac:TaxSubtotal/cbc:TaxableAmount', |  | ||||||
|                                      invoice_line.withholding_taxable_amount) |  | ||||||
|  |  | ||||||
|         for subtotal in invoice_line.withholding.subtotals: |  | ||||||
|             line.set_element('./cac:WithholdingTaxTotal/cac:TaxSubtotal/cbc:TaxAmount', subtotal.tax_amount, currencyID='COP') |  | ||||||
|  |  | ||||||
|             if subtotal.percent is not None: |  | ||||||
|                 line.set_element('./cac:WithholdingTaxTotal/cac:TaxSubtotal/cac:TaxCategory/cbc:Percent', '%0.2f' % round(subtotal.percent, 2)) |  | ||||||
|  |  | ||||||
|             if subtotal.scheme is not None: |  | ||||||
|                 #DIAN 1.7.-2020: FAX15 |  | ||||||
|                 line.set_element('./cac:WithholdingTaxTotal/cac:TaxSubtotal/cac:TaxCategory/cac:TaxScheme/cbc:ID', subtotal.scheme.code) |  | ||||||
|                 line.set_element('./cac:WithholdingTaxTotal/cac:TaxSubtotal/cac:TaxCategory/cac:TaxScheme/cbc:Name', subtotal.scheme.name) |  | ||||||
|  |  | ||||||
|     def set_invoice_line_tax(fexml, line, invoice_line): |  | ||||||
|         fexml.set_element_amount_for(line, |  | ||||||
|                                      './cac:TaxTotal/cbc:TaxAmount', |  | ||||||
|                                      invoice_line.tax_amount) |  | ||||||
|  |  | ||||||
|         #DIAN 1.7.-2020: FAX05 |  | ||||||
|         fexml.set_element_amount_for(line, |  | ||||||
|                                      './cac:TaxTotal/cac:TaxSubtotal/cbc:TaxableAmount', |  | ||||||
|                                      invoice_line.taxable_amount) |  | ||||||
|         for subtotal in invoice_line.tax.subtotals: |  | ||||||
|             line.set_element('./cac:TaxTotal/cac:TaxSubtotal/cbc:TaxAmount', subtotal.tax_amount, currencyID='COP') |  | ||||||
|  |  | ||||||
|             if subtotal.percent is not None: |  | ||||||
|                 line.set_element('./cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cbc:Percent', '%0.2f' % round(subtotal.percent, 2)) |  | ||||||
|  |  | ||||||
|             if subtotal.scheme is not None: |  | ||||||
|                 #DIAN 1.7.-2020: FAX15 |  | ||||||
|                 line.set_element('./cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cac:TaxScheme/cbc:ID', subtotal.scheme.code) |  | ||||||
|                 line.set_element('./cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cac:TaxScheme/cbc:Name', subtotal.scheme.name) |  | ||||||
|      |  | ||||||
|     def set_invoice_lines(fexml, invoice): |  | ||||||
|         next_append = False |  | ||||||
|         for index, invoice_line in enumerate(invoice.invoice_lines): |  | ||||||
|             line = fexml.fragment('./cac:%sLine' % (fexml.tag_document()), append=next_append) |  | ||||||
|             next_append = True |  | ||||||
|  |  | ||||||
|             line.set_element('./cbc:ID', index + 1) |  | ||||||
|             line.set_element('./cbc:%sQuantity' % (fexml.tag_document_concilied()), invoice_line.quantity, unitCode = 'NAR') |  | ||||||
|             fexml.set_element_amount_for(line, |  | ||||||
|                                          './cbc:LineExtensionAmount', |  | ||||||
|                                          invoice_line.total_amount) |  | ||||||
|  |  | ||||||
|             period = line.fragment('./cac:InvoicePeriod') |  | ||||||
|             period.set_element('./cbc:StartDate', |  | ||||||
|                                datetime.now().strftime('%Y-%m-%d')) |  | ||||||
|             period.set_element('./cbc:DescriptionCode', |  | ||||||
|                                '1') |  | ||||||
|             period.set_element('./cbc:Description', |  | ||||||
|                                'Por operación') |  | ||||||
|  |  | ||||||
|             if not isinstance(invoice_line.tax, TaxTotalOmit): |  | ||||||
|                 fexml.set_invoice_line_tax(line, invoice_line) |  | ||||||
|                  |  | ||||||
|             if not isinstance(invoice_line.withholding, WithholdingTaxTotalOmit): |  | ||||||
|                 fexml.set_invoice_line_withholding(line, invoice_line) |  | ||||||
|  |  | ||||||
|  |  | ||||||
|             line.set_element('./cac:Item/cbc:Description', invoice_line.item.description) |  | ||||||
|  |  | ||||||
|             line.set_element('./cac:Item/cac:StandardItemIdentification/cbc:ID', |  | ||||||
|                              invoice_line.item.id, |  | ||||||
|                              schemeID=invoice_line.item.scheme_id, |  | ||||||
|                              schemeName=invoice_line.item.scheme_name, |  | ||||||
|                              schemeAgencyID=invoice_line.item.scheme_agency_id) |  | ||||||
|  |  | ||||||
|             line.set_element('./cac:Price/cbc:PriceAmount', invoice_line.price.amount, currencyID=invoice_line.price.amount.currency.code) |  | ||||||
|             #DIAN 1.7.-2020: FBB04 |  | ||||||
|             line.set_element('./cac:Price/cbc:BaseQuantity', |  | ||||||
|                              invoice_line.quantity, |  | ||||||
|                              unitCode=invoice_line.quantity.code) |  | ||||||
|  |  | ||||||
|             for idx, charge in enumerate(invoice_line.allowance_charge): |  | ||||||
|                 next_append_charge = idx > 0 |  | ||||||
|                 fexml.append_allowance_charge(line, index + 1, charge, append=next_append_charge) |  | ||||||
|                  |  | ||||||
|     def set_allowance_charge(fexml, invoice): |  | ||||||
|         for idx, charge in enumerate(invoice.invoice_allowance_charge): |  | ||||||
|             next_append = idx > 0 |  | ||||||
|             fexml.append_allowance_charge(fexml, idx + 1, charge, append=next_append) |  | ||||||
|  |  | ||||||
|     def append_allowance_charge(fexml, parent, idx, charge, append=False): |  | ||||||
|             line = parent.fragment('./cac:AllowanceCharge', append=append) |  | ||||||
|             #DIAN 1.7.-2020: FAQ02 |  | ||||||
|             line.set_element('./cbc:ID', idx) |  | ||||||
|             #DIAN 1.7.-2020: FAQ03 |  | ||||||
|             line.set_element('./cbc:ChargeIndicator', str(charge.charge_indicator).lower()) |  | ||||||
|             if charge.reason: |  | ||||||
|                 line.set_element('./cbc:AllowanceChargeReasonCode', charge.reason.code) |  | ||||||
|                 line.set_element('./cbc:allowanceChargeReason', charge.reason.reason) |  | ||||||
|             line.set_element('./cbc:MultiplierFactorNumeric', str(round(charge.multiplier_factor_numeric, 2))) |  | ||||||
|             fexml.set_element_amount_for(line, './cbc:Amount', charge.amount) |  | ||||||
|             fexml.set_element_amount_for(line, './cbc:BaseAmount', charge.base_amount) |  | ||||||
|              |  | ||||||
|     def attach_invoice(fexml, invoice): |  | ||||||
|         """adiciona etiquetas a FEXML y retorna FEXML |  | ||||||
|         en caso de fallar validacion retorna None""" |  | ||||||
|  |  | ||||||
|         fexml.placeholder_for('./ext:UBLExtensions') |  | ||||||
|         fexml.set_element('./cbc:UBLVersionID', 'UBL 2.1') |  | ||||||
|         fexml.set_element('./cbc:CustomizationID', invoice.invoice_operation_type) |  | ||||||
|         fexml.placeholder_for('./cbc:ProfileID') |  | ||||||
|         fexml.placeholder_for('./cbc:ProfileExecutionID') |  | ||||||
|         fexml.set_element('./cbc:ID', invoice.invoice_ident) |  | ||||||
|         fexml.placeholder_for('./cbc:UUID') |  | ||||||
|         fexml.set_element('./cbc:DocumentCurrencyCode', 'COP') |  | ||||||
|         fexml.set_element('./cbc:IssueDate', invoice.invoice_issue.strftime('%Y-%m-%d')) |  | ||||||
|         #DIAN 1.7.-2020: FAD10 |  | ||||||
|         fexml.set_element('./cbc:IssueTime', invoice.invoice_issue.strftime('%H:%M:%S-05:00')) |  | ||||||
|         fexml.set_element('./cbc:%sTypeCode' % (fexml.tag_document()), |  | ||||||
|                         invoice.invoice_type_code, |  | ||||||
|                         listAgencyID='195', |  | ||||||
|                         listAgencyName='No matching global declaration available for the validation root', |  | ||||||
|                         listURI='http://www.dian.gov.co') |  | ||||||
|         fexml.set_element('./cbc:LineCountNumeric', len(invoice.invoice_lines)) |  | ||||||
|         fexml.set_element('./cac:%sPeriod/cbc:StartDate' % (fexml.tag_document()), |  | ||||||
|                           invoice.invoice_period_start.strftime('%Y-%m-%d')) |  | ||||||
|  |  | ||||||
|         fexml.set_element('./cac:%sPeriod/cbc:EndDate' % (fexml.tag_document()), |  | ||||||
|                           invoice.invoice_period_end.strftime('%Y-%m-%d')) |  | ||||||
|  |  | ||||||
|         fexml.customize(invoice) |  | ||||||
|  |  | ||||||
|         fexml.set_supplier(invoice) |  | ||||||
|         fexml.set_customer(invoice) |  | ||||||
|         fexml.set_legal_monetary(invoice) |  | ||||||
|         fexml.set_invoice_totals(invoice) |  | ||||||
|         fexml.set_invoice_lines(invoice) |  | ||||||
|         fexml.set_payment_mean(invoice) |  | ||||||
|         fexml.set_allowance_charge(invoice) |  | ||||||
|         fexml.set_discrepancy_response(invoice)         |  | ||||||
|         fexml.set_billing_reference(invoice) |  | ||||||
|       |  | ||||||
|         return fexml |  | ||||||
|  |  | ||||||
|     def customize(fexml, invoice): |  | ||||||
|         """adiciona etiquetas a FEXML y retorna FEXML |  | ||||||
|         en caso de fallar validacion retorna None""" |  | ||||||
| @@ -1,21 +0,0 @@ | |||||||
| from .. import fe |  | ||||||
| from ..form import * |  | ||||||
| from .support_document import DIANSupportDocumentXML |  | ||||||
|  |  | ||||||
| __all__ = ['DIANSupportDocumentCreditNoteXML'] |  | ||||||
|  |  | ||||||
| class DIANSupportDocumentCreditNoteXML(DIANSupportDocumentXML): |  | ||||||
|     """ |  | ||||||
|     DianInvoiceXML mapea objeto form.Invoice a XML segun |  | ||||||
|     lo indicado para la facturacion electronica. |  | ||||||
|     """ |  | ||||||
|  |  | ||||||
|     def __init__(self, invoice): |  | ||||||
|         super(DIANSupportDocumentCreditNoteXML, self).__init__(invoice, 'CreditNote')         |  | ||||||
|  |  | ||||||
|     def tag_document(fexml): |  | ||||||
|         return 'CreditNote' |  | ||||||
|  |  | ||||||
|     def tag_document_concilied(fexml): |  | ||||||
|         return 'Credited' |  | ||||||
|  |  | ||||||
| @@ -8,12 +8,8 @@ def DIANWrite(xml, filename): | |||||||
|         f.write(document) |         f.write(document) | ||||||
|  |  | ||||||
|          |          | ||||||
| def DIANWriteSigned(xml, filename, private_key, passphrase, use_cache_policy=False, dian_signer=None): | def DIANWriteSigned(xml, filename, private_key, passphrase, use_cache_policy=False): | ||||||
|     document = xml.tostring(xml_declaration=True, encoding='UTF-8').encode('utf-8') |     document = xml.tostring(xml_declaration=True, encoding='UTF-8').encode('utf-8') | ||||||
|     if dian_signer is None: |     signer = fe.DianXMLExtensionSigner(private_key, passphrase=passphrase, mockpolicy=use_cache_policy) | ||||||
|         dian_signer = fe.DianXMLExtensionSigner |  | ||||||
|  |  | ||||||
|     signer = dian_signer(private_key, passphrase=passphrase, localpolicy=use_cache_policy) |  | ||||||
|  |  | ||||||
|     with open(filename, 'w') as f: |     with open(filename, 'w') as f: | ||||||
|         f.write(signer.sign_xml_string(document)) |         f.write(signer.sign_xml_string(document)) | ||||||
|   | |||||||
| @@ -1,651 +0,0 @@ | |||||||
| # |  | ||||||
| # Para esta implementacion se usa BDD |  | ||||||
| # ver **test_nomina.py**. |  | ||||||
| # |  | ||||||
| # La idea en general es validar comportamiento desde el XML, |  | ||||||
| # creando las estructuras minimas necesaras. |  | ||||||
|  |  | ||||||
| from dataclasses import dataclass |  | ||||||
| from datetime import datetime |  | ||||||
| import hashlib |  | ||||||
| import typing |  | ||||||
|  |  | ||||||
| from .. import fe |  | ||||||
| from .. import form |  | ||||||
| from ..data.dian import codelist |  | ||||||
|  |  | ||||||
| from .devengado import * |  | ||||||
| from .deduccion import * |  | ||||||
| from .trabajador import * |  | ||||||
| from .empleador import * |  | ||||||
| from .pago import * |  | ||||||
| from .lugar import Lugar |  | ||||||
|  |  | ||||||
| from .amount import Amount |  | ||||||
| from .exception import * |  | ||||||
|  |  | ||||||
| class Fecha: |  | ||||||
|     def __init__(self, fecha): |  | ||||||
|         try: |  | ||||||
|             datetime.strptime(fecha, "%Y-%m-%d") |  | ||||||
|         except ValueError: |  | ||||||
|             raise ValueError("fecha debe ser formato YYYY-MM-DD") |  | ||||||
|         self.value = fecha |  | ||||||
|  |  | ||||||
|     @classmethod |  | ||||||
|     def cast(cls, data, optional=False): |  | ||||||
|         if isinstance(data, str): |  | ||||||
|             return cls(data) |  | ||||||
|         elif isinstance(data, cls): |  | ||||||
|             return data |  | ||||||
|         elif data is None and optional: |  | ||||||
|             return None |  | ||||||
|         else: |  | ||||||
|             raise ValueError('no se logra hacer casting a Fecha') |  | ||||||
|  |  | ||||||
|     def __str__(self): |  | ||||||
|         return self.value |  | ||||||
|  |  | ||||||
| class FechaPago(Fecha): |  | ||||||
|     def apply(self, fragment): |  | ||||||
|         fragment.set_element('./FechaPago', self.value) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| @dataclass |  | ||||||
| class Novedad: |  | ||||||
|     # cune de nomina a relacionar |  | ||||||
|     # NIE204 |  | ||||||
|     cune: str |  | ||||||
|     # NIE199 |  | ||||||
|     activa: bool = False |  | ||||||
|  |  | ||||||
|     def apply(self, fragment): |  | ||||||
|         if self.cune != "": |  | ||||||
|             fragment.set_attributes('./Novedad', |  | ||||||
|                                     CUNENov=self.cune, |  | ||||||
|                                     ) |  | ||||||
|  |  | ||||||
|     def post_apply(self, fexml, scopexml, fragment): |  | ||||||
|         scopexml.set_element('./Novedad', self.activa) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| @dataclass |  | ||||||
| class NumeroSecuencia: |  | ||||||
|     consecutivo: int |  | ||||||
|     prefijo: str |  | ||||||
|  |  | ||||||
|     def apply(self, fragment): |  | ||||||
|         numero = f"{self.prefijo}{self.consecutivo}" |  | ||||||
|         fragment.set_attributes('./NumeroSecuenciaXML', |  | ||||||
|                                 # NIE010 |  | ||||||
|                                 Prefijo=self.prefijo, |  | ||||||
|                                 # NIE011 |  | ||||||
|                                 Consecutivo=self.consecutivo, |  | ||||||
|                                 # NIE012 |  | ||||||
|                                 Numero = numero) |  | ||||||
|  |  | ||||||
| @dataclass |  | ||||||
| class Periodo: |  | ||||||
|     fecha_ingreso: typing.Union[str, Fecha] |  | ||||||
|     fecha_liquidacion_inicio: typing.Union[str, Fecha] |  | ||||||
|     fecha_liquidacion_fin: typing.Union[str, Fecha] |  | ||||||
|     fecha_generacion: typing.Union[str, Fecha] |  | ||||||
|  |  | ||||||
|     tiempo_laborado: int = 1 |  | ||||||
|     fecha_retiro: typing.Union[str, Fecha] = None |  | ||||||
|  |  | ||||||
|     def __post_init__(self): |  | ||||||
|         self.fecha_ingreso = Fecha.cast(self.fecha_ingreso) |  | ||||||
|         self.fecha_liquidacion_inicio = Fecha.cast(self.fecha_liquidacion_inicio) |  | ||||||
|         self.fecha_liquidacion_fin = Fecha.cast(self.fecha_liquidacion_fin) |  | ||||||
|         self.fecha_retiro = Fecha.cast(self.fecha_retiro, optional=True) |  | ||||||
|          |  | ||||||
|     def apply(self, fragment): |  | ||||||
|         fragment.set_attributes('./Periodo', |  | ||||||
|                                 #NIE002 |  | ||||||
|                                 FechaIngreso=self.fecha_ingreso, |  | ||||||
|                                 #NIE003 |  | ||||||
|                                 FechaRetiro=self.fecha_retiro, |  | ||||||
|                                 #NIE004 |  | ||||||
|                                 FechaLiquidacionInicio=self.fecha_liquidacion_inicio, |  | ||||||
|                                 #NIE005 |  | ||||||
|                                 FechaLiquidacionFin=self.fecha_liquidacion_fin, |  | ||||||
|                                 #NIE006 |  | ||||||
|                                 TiempoLaborado=self.tiempo_laborado, |  | ||||||
|                                 #NIE008 |  | ||||||
|                                 FechaGen=self.fecha_generacion) |  | ||||||
|          |  | ||||||
| @dataclass |  | ||||||
| class Proveedor: |  | ||||||
|     razon_social: str |  | ||||||
|     nit: str |  | ||||||
|     dv: int |  | ||||||
|     software_id: str |  | ||||||
|     software_pin: str |  | ||||||
|  |  | ||||||
|     def apply(self, fragment): |  | ||||||
|         fragment.set_attributes('./ProveedorXML', |  | ||||||
|                                 # NIE017 |  | ||||||
|                                 NIT=self.nit, |  | ||||||
|                                 # NIE018 |  | ||||||
|                                 DV=self.dv, |  | ||||||
|                                 # NIE019 |  | ||||||
|                                 SoftwareID=self.software_id, |  | ||||||
|  |  | ||||||
|                                 SoftwareSC=None, |  | ||||||
|                                 # NIE025 |  | ||||||
|                                 RazonSocial=self.razon_social |  | ||||||
|                                 ) |  | ||||||
|  |  | ||||||
|     def post_apply(self, fexml, scopexml, fragment): |  | ||||||
|         cune_xpath = scopexml.xpath_from_root('/InformacionGeneral') |  | ||||||
|         cune = fexml.get_element_attribute(cune_xpath, 'CUNE') |  | ||||||
|          |  | ||||||
|         ambiente = fexml.get_element_attribute(scopexml.xpath_from_root('/InformacionGeneral'), 'Ambiente') |  | ||||||
|         codigo_qr = f"https://catalogo-vpfe.dian.gov.co/document/searchqr?documentkey={cune}" |  | ||||||
|  |  | ||||||
|         if InformacionGeneral.AMBIENTE_PRUEBAS == ambiente: |  | ||||||
|             codigo_qr = f"https://catalogo-vpfe-hab.dian.gov.co/document/searchqr?documentkey={cune}" |  | ||||||
|         elif ambiente is None: |  | ||||||
|             raise RuntimeError('fail to get InformacionGeneral/@Ambiente') |  | ||||||
|          |  | ||||||
|         scopexml.set_element('./CodigoQR', codigo_qr) |  | ||||||
|  |  | ||||||
|         # NIE020 |  | ||||||
|         software_code = self._software_security_code(fexml, scopexml) |  | ||||||
|         fexml.set_attributes(scopexml.xpath_from_root('/ProveedorXML'), SoftwareSC=software_code) |  | ||||||
|  |  | ||||||
|     def _software_security_code(self, fexml, scopexml): |  | ||||||
|          |  | ||||||
|  |  | ||||||
|         # 8.2 |  | ||||||
|         numero = fexml.get_element_attribute(scopexml.xpath_from_root('/NumeroSecuenciaXML'), 'Numero') |  | ||||||
|         if numero is None: |  | ||||||
|             raise RuntimeError('fallo obtener NumeroSequenciaXML/@Numero') |  | ||||||
|          |  | ||||||
|         id_software = self.software_id |  | ||||||
|         software_pin = self.software_pin |  | ||||||
|  |  | ||||||
|         code = "".join([id_software, software_pin, numero]) |  | ||||||
|  |  | ||||||
|         fexml.set_attributes(scopexml.xpath_from_root('/ProveedorXML')) |  | ||||||
|         h = hashlib.sha384() |  | ||||||
|         h.update(code.encode('utf-8')) |  | ||||||
|         return h.hexdigest() |  | ||||||
|      |  | ||||||
| @dataclass |  | ||||||
| class Metadata: |  | ||||||
|     novedad: Novedad |  | ||||||
|     secuencia: NumeroSecuencia |  | ||||||
|     # NIE013, NIE014, NIE015, NIE016 |  | ||||||
|     lugar_generacion: Lugar |  | ||||||
|     proveedor: Proveedor |  | ||||||
|  |  | ||||||
|     def apply(self, novedad, numero_secuencia_xml, lugar_generacion_xml, proveedor_xml): |  | ||||||
|         if novedad: |  | ||||||
|             self.novedad.apply(novedad) |  | ||||||
|         self.secuencia.apply(numero_secuencia_xml) |  | ||||||
|         self.lugar_generacion.apply(lugar_generacion_xml, './LugarGeneracionXML') |  | ||||||
|         self.proveedor.apply(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) |  | ||||||
|         if novedad: |  | ||||||
|             self.novedad.post_apply(fexml, scopexml, proveedor_xml)         |  | ||||||
|          |  | ||||||
| @dataclass |  | ||||||
| class PeriodoNomina: |  | ||||||
|     code: str |  | ||||||
|     name: str = '' |  | ||||||
|  |  | ||||||
|     def __post_init__(self): |  | ||||||
|         if self.code not in codelist.PeriodoNomina: |  | ||||||
|             raise ValueError("code [%s] not found" % (self.code)) |  | ||||||
|         self.name = codelist.PeriodoNomina[self.code]['name'] |  | ||||||
|  |  | ||||||
| @dataclass |  | ||||||
| class TipoMoneda: |  | ||||||
|     code: str |  | ||||||
|     name: str = '' |  | ||||||
|  |  | ||||||
|     def __post_init__(self): |  | ||||||
|         if self.code not in codelist.TipoMoneda: |  | ||||||
|             raise ValueError("code [%s] not found" % (self.code)) |  | ||||||
|         self.name = codelist.TipoMoneda[self.code]['name'] |  | ||||||
|  |  | ||||||
| @dataclass |  | ||||||
| class InformacionGeneral: |  | ||||||
|     @dataclass |  | ||||||
|     class TIPO_AMBIENTE: |  | ||||||
|         valor: str |  | ||||||
|  |  | ||||||
|         def __eq__(self, other): |  | ||||||
|             return self.valor == str(other) |  | ||||||
|  |  | ||||||
|     # TABLA 5.1.1 |  | ||||||
|     @dataclass |  | ||||||
|     class AMBIENTE_PRODUCCION(TIPO_AMBIENTE): |  | ||||||
|         valor: str = '1' |  | ||||||
|  |  | ||||||
|         def __str__(self): |  | ||||||
|             self.valor |  | ||||||
|  |  | ||||||
|     @dataclass |  | ||||||
|     class AMBIENTE_PRUEBAS(TIPO_AMBIENTE): |  | ||||||
|         valor: str = '2' |  | ||||||
|  |  | ||||||
|         def __str__(self): |  | ||||||
|             self.valor             |  | ||||||
|  |  | ||||||
|     # TABLA 5.5.7 |  | ||||||
|     @dataclass |  | ||||||
|     class TIPO_XML: |  | ||||||
|         valor: str |  | ||||||
|  |  | ||||||
|         def __eq__(self, other): |  | ||||||
|             return self.valor == str(other) |  | ||||||
|  |  | ||||||
|     @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] |  | ||||||
|     hora_generacion: str |  | ||||||
|     periodo_nomina: PeriodoNomina |  | ||||||
|     tipo_moneda: TipoMoneda |  | ||||||
|     tipo_ambiente: TIPO_AMBIENTE |  | ||||||
|     tipo_xml: TIPO_XML |  | ||||||
|     software_pin: str |  | ||||||
|  |  | ||||||
|     def __post_init__(self): |  | ||||||
|         self.fecha_generacion = Fecha.cast(self.fecha_generacion) |  | ||||||
|  |  | ||||||
|     def apply(self, fragment, version): |  | ||||||
|         fragment.set_attributes('./InformacionGeneral', |  | ||||||
|                                 # NIE022 |  | ||||||
|                                 Version = version, |  | ||||||
|                                 # NIE023 |  | ||||||
|                                 Ambiente = self.tipo_ambiente.valor, |  | ||||||
|                                 # NIE202 |  | ||||||
|                                 # TABLA 5.5.2 |  | ||||||
|                                 # TODO(bit4bit) solo NominaIndividual |  | ||||||
|                                 TipoXML = self.tipo_xml.valor, |  | ||||||
|                                 # NIE024 |  | ||||||
|                                 CUNE = None, |  | ||||||
|                                 # NIE025 |  | ||||||
|                                 EncripCUNE = 'CUNE-SHA384', |  | ||||||
|                                 # NIE026 |  | ||||||
|                                 FechaGen = self.fecha_generacion, |  | ||||||
|                                 # NIE027 |  | ||||||
|                                 HoraGen = self.hora_generacion, |  | ||||||
|                                 # NIE029 |  | ||||||
|                                 PeriodoNomina = self.periodo_nomina.code, |  | ||||||
|                                 # NIE030 |  | ||||||
|                                 TipoMoneda = self.tipo_moneda.code, |  | ||||||
|                                 TRM = 0 |  | ||||||
|                                 # TODO(bit4bit) resto... |  | ||||||
|                                 # ..... |  | ||||||
|                                 ) |  | ||||||
|  |  | ||||||
|     def post_apply(self, fexml, scopexml, fragment): |  | ||||||
|         # generar cune |  | ||||||
|         # ver 8.1.1.1 |  | ||||||
|         xpaths = [ |  | ||||||
|             scopexml.xpath_from_root('/NumeroSecuenciaXML/@Numero'), |  | ||||||
|             scopexml.xpath_from_root('/InformacionGeneral/@FechaGen'), |  | ||||||
|             scopexml.xpath_from_root('/InformacionGeneral/@HoraGen'), |  | ||||||
|             scopexml.xpath_from_root('/DevengadosTotal'), |  | ||||||
|             scopexml.xpath_from_root('/DeduccionesTotal'), |  | ||||||
|             scopexml.xpath_from_root('/ComprobanteTotal'), |  | ||||||
|             scopexml.xpath_from_root('/Empleador/@NIT'), |  | ||||||
|             scopexml.xpath_from_root('/Trabajador/@NumeroDocumento'), |  | ||||||
|             scopexml.xpath_from_root('/InformacionGeneral/@TipoXML'), |  | ||||||
|             tuple([self.software_pin]), |  | ||||||
|             scopexml.xpath_from_root('/InformacionGeneral/@Ambiente') |  | ||||||
|         ] |  | ||||||
|  |  | ||||||
|         campos = fexml.get_elements_text_or_attributes(xpaths) |  | ||||||
|  |  | ||||||
|         cune = "".join(campos) |  | ||||||
|  |  | ||||||
|         h = hashlib.sha384() |  | ||||||
|         h.update(cune.encode('utf-8')) |  | ||||||
|         cune_hash = h.hexdigest() |  | ||||||
|      |  | ||||||
|         fragment.set_attributes( |  | ||||||
|             './InformacionGeneral', |  | ||||||
|             # NIE024 |  | ||||||
|             CUNE = cune_hash |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
| class DianXMLExtensionSigner(fe.DianXMLExtensionSigner): |  | ||||||
|  |  | ||||||
|     def __init__(self, pkcs12_path, passphrase=None, localpolicy=True): |  | ||||||
|         super().__init__(pkcs12_path, passphrase=passphrase, localpolicy=localpolicy) |  | ||||||
|  |  | ||||||
|     def _element_extension_content(self, fachoxml): |  | ||||||
|         return fachoxml.builder.xpath(fachoxml.root, './ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent') |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class DIANNominaXML: |  | ||||||
|     def __init__(self, tag_document, xpath_ajuste=None, schemaLocation=None, namespace_ajuste=None): |  | ||||||
|         self.informacion_general_version = None |  | ||||||
|  |  | ||||||
|         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.root.set("SchemaLocation", "") |  | ||||||
|         self.fexml.root.set("schemaLocation", schemaLocation) |  | ||||||
|  |  | ||||||
|         # layout, la dian requiere que los elementos |  | ||||||
|         # esten ordenados segun el anexo tecnico |  | ||||||
|         self.fexml.placeholder_for('./ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent') |  | ||||||
|         self.fexml.placeholder_for('./TipoNota', optional=True) |  | ||||||
|  |  | ||||||
|         self.root_fragment = self.fexml |  | ||||||
|         if xpath_ajuste is not None: |  | ||||||
|             self.root_fragment = self.fexml.fragment(xpath_ajuste) |  | ||||||
|         self.root_fragment.placeholder_for('./ReemplazandoPredecesor', 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('./Periodo') |  | ||||||
|         self.root_fragment.placeholder_for('./NumeroSecuenciaXML') |  | ||||||
|         self.root_fragment.placeholder_for('./LugarGeneracionXML') |  | ||||||
|         self.root_fragment.placeholder_for('./ProveedorXML') |  | ||||||
|         self.root_fragment.placeholder_for('./CodigoQR') |  | ||||||
|         self.root_fragment.placeholder_for('./InformacionGeneral') |  | ||||||
|         self.root_fragment.placeholder_for('./Empleador') |  | ||||||
|         self.root_fragment.placeholder_for('./Trabajador') |  | ||||||
|         self.root_fragment.placeholder_for('./Pago') |  | ||||||
|         self.root_fragment.placeholder_for('./FechasPagos') |  | ||||||
|         self.root_fragment.placeholder_for('./Devengados/Basico') |  | ||||||
|         self.root_fragment.placeholder_for('./Devengados/Transporte', optional=True) |  | ||||||
|         if not namespace_ajuste: |  | ||||||
|             self.novedad = self.root_fragment.fragment('./Novedad') |  | ||||||
|         else: |  | ||||||
|             self.novedad = None |  | ||||||
|         self.informacion_general_xml = self.root_fragment.fragment('./InformacionGeneral') |  | ||||||
|         self.periodo_xml = self.root_fragment.fragment('./Periodo') |  | ||||||
|         self.fecha_pagos_xml = self.root_fragment.fragment('./FechasPagos') |  | ||||||
|         self.numero_secuencia_xml = self.root_fragment.fragment('./NumeroSecuenciaXML') |  | ||||||
|         self.lugar_generacion_xml = self.root_fragment.fragment('./LugarGeneracionXML') |  | ||||||
|         self.proveedor_xml = self.root_fragment.fragment('./ProveedorXML') |  | ||||||
|         self.empleador = self.root_fragment.fragment('./Empleador') |  | ||||||
|         self.trabajador = self.root_fragment.fragment('./Trabajador') |  | ||||||
|         self.pago_xml = self.root_fragment.fragment('./Pago') |  | ||||||
|         self.devengados = self.root_fragment.fragment('./Devengados') |  | ||||||
|         self.deducciones = self.root_fragment.fragment('./Deducciones') |  | ||||||
|  |  | ||||||
|         self.informacion_general = None |  | ||||||
|         self.metadata = None |  | ||||||
|  |  | ||||||
|     def asignar_metadata(self, metadata): |  | ||||||
|         if not isinstance(metadata, Metadata): |  | ||||||
|             raise ValueError('se espera tipo Metadata') |  | ||||||
|         self.metadata = metadata |  | ||||||
|                  |  | ||||||
|         self.metadata.apply(self.novedad, self.numero_secuencia_xml, self.lugar_generacion_xml, self.proveedor_xml) |  | ||||||
|          |  | ||||||
|     def asignar_informacion_general(self, general): |  | ||||||
|         if not isinstance(general, InformacionGeneral): |  | ||||||
|             raise ValueError('se espera tipo InformacionGeneral') |  | ||||||
|         self.informacion_general = general |  | ||||||
|         self.informacion_general.apply(self.informacion_general_xml, self.informacion_general_version) |  | ||||||
|  |  | ||||||
|     def asignar_periodo(self, periodo): |  | ||||||
|         if not isinstance(periodo, Periodo): |  | ||||||
|             raise ValueError('se espera tipo Periodo') |  | ||||||
|  |  | ||||||
|         periodo.apply(self.periodo_xml) |  | ||||||
|  |  | ||||||
|     def asignar_pago(self, pago): |  | ||||||
|         if not isinstance(pago, Pago): |  | ||||||
|             raise ValueError('se espera tipo Pago') |  | ||||||
|         pago.apply(self.pago_xml) |  | ||||||
|  |  | ||||||
|     def asignar_fecha_pago(self, data): |  | ||||||
|         if isinstance(data, str): |  | ||||||
|             fecha = FechaPago(data) |  | ||||||
|         elif isinstance(data, FechaPago): |  | ||||||
|             fecha = data |  | ||||||
|  |  | ||||||
|         fecha.apply(self.fecha_pagos_xml) |  | ||||||
|  |  | ||||||
|     def asignar_empleador(self, empleador): |  | ||||||
|         if not isinstance(empleador, Empleador): |  | ||||||
|             raise ValueError('se espera tipo Empleador') |  | ||||||
|         empleador.apply(self.empleador) |  | ||||||
|  |  | ||||||
|     def asignar_trabajador(self, trabajador): |  | ||||||
|         if not isinstance(trabajador, Trabajador): |  | ||||||
|             raise ValueError('se espera tipo Trabajador') |  | ||||||
|         trabajador.apply(self.trabajador) |  | ||||||
|          |  | ||||||
|     def adicionar_devengado(self, devengado): |  | ||||||
|         if not isinstance(devengado, Devengado): |  | ||||||
|             raise ValueError('se espera tipo Devengado') |  | ||||||
|  |  | ||||||
|         devengado.apply(self.devengados) |  | ||||||
|  |  | ||||||
|     def adicionar_deduccion(self, deduccion): |  | ||||||
|         if not isinstance(deduccion, Deduccion): |  | ||||||
|             raise ValueError('se espera tipo Devengado') |  | ||||||
|  |  | ||||||
|         deduccion.apply(self.deducciones) |  | ||||||
|  |  | ||||||
|     def validate(self): |  | ||||||
|         """ |  | ||||||
|         Valida requisitos segun anexo tecnico |  | ||||||
|         """ |  | ||||||
|         errors = [] |  | ||||||
|  |  | ||||||
|         def check_element(xpath, msg): |  | ||||||
|             if not self.fexml.exist_element(xpath): |  | ||||||
|                 errors.append(DIANNominaIndividualError(msg)) |  | ||||||
|  |  | ||||||
|         def check_attribute(xpath, key, msg): |  | ||||||
|             err = DIANNominaIndividualError(msg) |  | ||||||
|             elem = self.fexml.get_element(xpath) |  | ||||||
|  |  | ||||||
|             if elem is None: |  | ||||||
|                 return errors.append(err) |  | ||||||
|  |  | ||||||
|             if elem.get(key, None) is None: |  | ||||||
|                 return errors.append(err) |  | ||||||
|  |  | ||||||
|         check_attribute( |  | ||||||
|             self.fexml.xpath_from_root('/Periodo'), |  | ||||||
|             'FechaIngreso', |  | ||||||
|             'se requiere Periodo') |  | ||||||
|  |  | ||||||
|         check_element( |  | ||||||
|             self.fexml.xpath_from_root('/Pago'), |  | ||||||
|             'se requiere Pago' |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         check_element( |  | ||||||
|             self.fexml.xpath_from_root('/Devengados/Basico'), |  | ||||||
|             'se requiere DevengadoBasico' |  | ||||||
|         ) |  | ||||||
|          |  | ||||||
|         check_element( |  | ||||||
|             self.fexml.xpath_from_root('/Deducciones/Salud'), |  | ||||||
|             'se requiere DeduccionSalud' |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         check_element( |  | ||||||
|             self.fexml.xpath_from_root('/Deducciones/FondoPension'), |  | ||||||
|             'se requiere DeduccionFondoPension' |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         return errors |  | ||||||
|  |  | ||||||
|     def informacion_general(self): |  | ||||||
|         xpath = self.root_fragment.xpath_from_root('/InformacionGeneral') |  | ||||||
|         return { |  | ||||||
|             'cune': self.fexml.get_element_attribute(cune_xpath, 'CUNE'), |  | ||||||
|             'fecha_generacion': self.fexml.get_element_attribute(xpath, 'FechaGen'), |  | ||||||
|             'numero': self.fexml.get_element_attribute(self.root_fragment('/NumeroSecuenciaXML', 'Numero')) |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     def toFachoXML(self): |  | ||||||
|         self._devengados_total() |  | ||||||
|         self._deducciones_total() |  | ||||||
|         self._comprobante_total() |  | ||||||
|  |  | ||||||
|         if self.informacion_general is not None: |  | ||||||
|             #TODO(bit4bit) acoplamiento temporal |  | ||||||
|             # es importante el orden de ejecucion |  | ||||||
|  |  | ||||||
|             self.informacion_general.post_apply(self.fexml, self.root_fragment, self.informacion_general_xml) |  | ||||||
|  |  | ||||||
|         if self.metadata is not None: |  | ||||||
|             self.metadata.post_apply(self.fexml, self.root_fragment, self.novedad, self.numero_secuencia_xml, self.lugar_generacion_xml, self.proveedor_xml) |  | ||||||
|  |  | ||||||
|         return self.fexml |  | ||||||
|  |  | ||||||
|     def _comprobante_total(self): |  | ||||||
|         devengados_total = self.root_fragment.get_element_text_or_attribute('./DevengadosTotal', '0.0') |  | ||||||
|         deducciones_total = self.root_fragment.get_element_text_or_attribute('./DeduccionesTotal', '0.0') |  | ||||||
|  |  | ||||||
|         comprobante_total = Amount(devengados_total) - Amount(deducciones_total) |  | ||||||
|  |  | ||||||
|         self.root_fragment.set_element('./ComprobanteTotal', str(round(comprobante_total, 2))) |  | ||||||
|  |  | ||||||
|     def _deducciones_total(self): |  | ||||||
|         xpaths = [ |  | ||||||
|             self.root_fragment.xpath_from_root('/Deducciones/Salud/@Deduccion'), |  | ||||||
|             self.root_fragment.xpath_from_root('/Deducciones/FondoPension/@Deduccion') |  | ||||||
|         ] |  | ||||||
|         deducciones = map(lambda valor: Amount(valor), |  | ||||||
|                           self._values_of_xpaths(xpaths)) |  | ||||||
|  |  | ||||||
|         deducciones_total = Amount(0.0) |  | ||||||
|          |  | ||||||
|         for deduccion in deducciones: |  | ||||||
|             deducciones_total += deduccion |  | ||||||
|  |  | ||||||
|         self.root_fragment.set_element('./DeduccionesTotal', str(round(deducciones_total, 2))) |  | ||||||
|  |  | ||||||
|     def _devengados_total(self): |  | ||||||
|         xpaths = [ |  | ||||||
|             self.root_fragment.xpath_from_root('/Devengados/Basico/@SueldoTrabajado'), |  | ||||||
|             self.root_fragment.xpath_from_root('/Devengados/Transporte/@AuxilioTransporte'), |  | ||||||
|             self.root_fragment.xpath_from_root('/Devengados/Transporte/@ViaticoManuAlojS'), |  | ||||||
|             self.root_fragment.xpath_from_root('/Devengados/Transporte/@ViaticoManuAlojNS') |  | ||||||
|         ] |  | ||||||
|         devengados = map(lambda valor: Amount(valor), |  | ||||||
|                          self._values_of_xpaths(xpaths)) |  | ||||||
|          |  | ||||||
|         devengados_total = Amount(0.0) |  | ||||||
|         for devengado in devengados: |  | ||||||
|             devengados_total += devengado |  | ||||||
|         # TODO(bit4bit) nque valor va redondeado? |  | ||||||
|         # NIE186 |  | ||||||
|         self.root_fragment.set_element('./Redondeo', str(round(0,2)))           |  | ||||||
|         self.root_fragment.set_element('./DevengadosTotal', str(round(devengados_total,2))) |  | ||||||
|  |  | ||||||
|     def _values_of_xpaths(self, xpaths): |  | ||||||
|         xpaths_values_of_values = map(lambda val: self.fexml.get_element_text_or_attribute(val, multiple=True), xpaths) |  | ||||||
|         xpaths_values = [] |  | ||||||
|         # toda esta carreta para hacer un aplano de lista |  | ||||||
|         for xpath_values in xpaths_values_of_values: |  | ||||||
|             if xpath_values is None: |  | ||||||
|                 continue |  | ||||||
|  |  | ||||||
|             for xpath_value in xpath_values: |  | ||||||
|                 xpaths_values.append(xpath_value) |  | ||||||
|  |  | ||||||
|         return filter(lambda val: val is not None, xpaths_values) |  | ||||||
|  |  | ||||||
| class DIANNominaIndividual(DIANNominaXML): |  | ||||||
|  |  | ||||||
|     def __init__(self): |  | ||||||
|         schema = "dian:gov:co:facturaelectronica:NominaIndividual NominaIndividualElectronicaXSD.xsd" |  | ||||||
|  |  | ||||||
|         super().__init__('NominaIndividual', schemaLocation=schema) |  | ||||||
|         self.informacion_general_version = 'V1.0: Documento Soporte de Pago de Nómina Electrónica' |  | ||||||
|  |  | ||||||
| # TODO(bit4bit) confirmar que no tienen en comun con NominaIndividual |  | ||||||
| class DIANNominaIndividualDeAjuste(DIANNominaXML): |  | ||||||
|  |  | ||||||
|     class Reemplazar(DIANNominaXML): |  | ||||||
|         @dataclass |  | ||||||
|         class Predecesor: |  | ||||||
|             numero: str |  | ||||||
|             cune: str |  | ||||||
|             fecha_generacion: str |  | ||||||
|  |  | ||||||
|             def apply(self, fragment): |  | ||||||
|                 # NIAE214 |  | ||||||
|                 fragment.set_element('./TipoNota', '1')                 |  | ||||||
|                 fragment.set_element('./Reemplazar/ReemplazandoPredecesor', None, |  | ||||||
|                                      # NIAE090 |  | ||||||
|                                      NumeroPred = self.numero, |  | ||||||
|                                      # NIAE191 |  | ||||||
|                                      CUNEPred = self.cune, |  | ||||||
|                                      # NIAE192 |  | ||||||
|                                      FechaGenPred = self.fecha_generacion |  | ||||||
|                                      ) |  | ||||||
|  |  | ||||||
|         def __init__(self): |  | ||||||
|             schema = "dian:gov:co:facturaelectronica:NominaIndividualDeAjuste NominaIndividualDeAjusteElectronicaXSD.xsd" |  | ||||||
|              |  | ||||||
|             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): |  | ||||||
|             if not isinstance(predecesor, self.Predecesor): |  | ||||||
|                 raise ValueError("se espera tipo Predecesor") |  | ||||||
|             predecesor.apply(self.fexml) |  | ||||||
|  |  | ||||||
|          |  | ||||||
|     class Eliminar(DIANNominaXML): |  | ||||||
|          |  | ||||||
|         @dataclass |  | ||||||
|         class Predecesor: |  | ||||||
|             numero: str |  | ||||||
|             cune: str |  | ||||||
|             fecha_generacion: str |  | ||||||
|  |  | ||||||
|             def apply(self, fragment): |  | ||||||
|                 fragment.set_element('./TipoNota', '2') |  | ||||||
|                 fragment.set_element('./Eliminar/EliminandoPredecesor', None, |  | ||||||
|                                      # NIAE090 |  | ||||||
|                                      NumeroPred = self.numero, |  | ||||||
|                                      # NIAE191 |  | ||||||
|                                      CUNEPred = self.cune, |  | ||||||
|                                      # NIAE192 |  | ||||||
|                                      FechaGenPred = self.fecha_generacion |  | ||||||
|                                      ) |  | ||||||
|  |  | ||||||
|         def __init__(self): |  | ||||||
|             schema = "dian:gov:co:facturaelectronica:NominaIndividualDeAjuste NominaIndividualDeAjusteElectronicaXSD.xsd"             |  | ||||||
|             super().__init__('NominaIndividualDeAjuste', './Eliminar', 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): |  | ||||||
|             if not isinstance(predecesor, self.Predecesor): |  | ||||||
|                 raise ValueError("se espera tipo Eliminar.Predecesor") |  | ||||||
|             predecesor.apply(self.fexml) |  | ||||||
|              |  | ||||||
|     def __init__(self): |  | ||||||
|         super().__init__('NominaIndividualDeAjuste') |  | ||||||
|  |  | ||||||
| @@ -1,4 +0,0 @@ | |||||||
| from .. import form |  | ||||||
|  |  | ||||||
| class Amount(form.Amount): |  | ||||||
|     pass |  | ||||||
| @@ -1,3 +0,0 @@ | |||||||
| # contributing |  | ||||||
|  |  | ||||||
| crear nuevo objeto de valor y exportar en **__init__.py** atributo **__all__**. |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| # |  | ||||||
| # al crear objetos de valor |  | ||||||
| # se debe exportar en __all__ |  | ||||||
|  |  | ||||||
| from .deduccion import * |  | ||||||
| from .salud import * |  | ||||||
| from .fondo_pension import * |  | ||||||
|  |  | ||||||
| __all__ = [ |  | ||||||
|     'Deduccion', |  | ||||||
|     'DeduccionSalud', |  | ||||||
|     'DeduccionFondoPension' |  | ||||||
| ] |  | ||||||
| @@ -1,2 +0,0 @@ | |||||||
| class Deduccion: |  | ||||||
|     pass |  | ||||||
| @@ -1,18 +0,0 @@ | |||||||
| from dataclasses import dataclass |  | ||||||
|  |  | ||||||
| from ..amount import Amount |  | ||||||
| from .deduccion import Deduccion |  | ||||||
|  |  | ||||||
| @dataclass |  | ||||||
| class DeduccionFondoPension(Deduccion): |  | ||||||
|     porcentaje: Amount |  | ||||||
|     deduccion: Amount |  | ||||||
|  |  | ||||||
|     def apply(self, fragment): |  | ||||||
|         fragment.set_element('./FondoPension', None, |  | ||||||
|                              append_ = True, |  | ||||||
|                              # NIE164 |  | ||||||
|                              Porcentaje = str(round(self.porcentaje, 2)), |  | ||||||
|                              #  NIE166 |  | ||||||
|                              Deduccion = self.deduccion |  | ||||||
|                              ) |  | ||||||
| @@ -1,19 +0,0 @@ | |||||||
| from dataclasses import dataclass |  | ||||||
|  |  | ||||||
| from ..amount import Amount |  | ||||||
| from .deduccion import Deduccion |  | ||||||
|  |  | ||||||
| @dataclass |  | ||||||
| class DeduccionSalud(Deduccion): |  | ||||||
|     porcentaje: Amount |  | ||||||
|     deduccion: Amount |  | ||||||
|  |  | ||||||
|     def apply(self, fragment): |  | ||||||
|         fragment.set_element('./Salud', None, |  | ||||||
|                              append_ = True, |  | ||||||
|                              # NIE161 |  | ||||||
|                              Porcentaje = str(round(self.porcentaje, 2)), |  | ||||||
|                              #  NIE163 |  | ||||||
|                              Deduccion = self.deduccion |  | ||||||
|                              ) |  | ||||||
|  |  | ||||||
| @@ -1,4 +0,0 @@ | |||||||
| from .. import form |  | ||||||
|  |  | ||||||
| class Departamento(form.CountrySubentity): |  | ||||||
|     pass |  | ||||||
| @@ -1,3 +0,0 @@ | |||||||
| # contributing |  | ||||||
|  |  | ||||||
| crear nuevo objeto de valor y exportar en **__init__.py** atributo **__all__**. |  | ||||||
| @@ -1,19 +0,0 @@ | |||||||
|  |  | ||||||
| from .basico import * |  | ||||||
| from .transporte import * |  | ||||||
| from .devengado import * |  | ||||||
| from .horas_extras import * |  | ||||||
|  |  | ||||||
| __all__ = [ |  | ||||||
|     'Devengado', |  | ||||||
|     'DevengadoBasico', |  | ||||||
|     'DevengadoTransporte', |  | ||||||
|     'DevengadoHoraExtra', |  | ||||||
|     'DevengadoHorasExtrasDiarias', |  | ||||||
|     'DevengadoHorasExtrasNocturnas', |  | ||||||
|     'DevengadoHorasRecargoNocturno', |  | ||||||
|     'DevengadoHorasExtrasDiariasDominicalesYFestivos', |  | ||||||
|     'DevengadoHorasRecargoDiariasDominicalesYFestivos', |  | ||||||
|     'DevengadoHorasExtrasNocturnasDominicalesYFestivos', |  | ||||||
|     'DevengadoHorasRecargoNocturnoDominicalesYFestivos' |  | ||||||
| ] |  | ||||||
| @@ -1,20 +0,0 @@ | |||||||
| from dataclasses import dataclass |  | ||||||
|  |  | ||||||
| from ..amount import Amount |  | ||||||
| from .devengado import Devengado |  | ||||||
|  |  | ||||||
|  |  | ||||||
| @dataclass |  | ||||||
| class DevengadoBasico(Devengado): |  | ||||||
|     dias_trabajados: int |  | ||||||
|     sueldo_trabajado: Amount |  | ||||||
|  |  | ||||||
|     def apply(self, fragment): |  | ||||||
|         fragment.find_or_create_element('./Basico') |  | ||||||
|          |  | ||||||
|         fragment.set_attributes('/Basico', |  | ||||||
|                                 # NIE069 |  | ||||||
|                                 DiasTrabajados = str(self.dias_trabajados), |  | ||||||
|                                 # NIE070 |  | ||||||
|                                 SueldoTrabajado = round(self.sueldo_trabajado, 2) |  | ||||||
|                                 ) |  | ||||||
| @@ -1,2 +0,0 @@ | |||||||
| class Devengado: |  | ||||||
|     pass |  | ||||||
| @@ -1,93 +0,0 @@ | |||||||
| from dataclasses import dataclass |  | ||||||
| from typing import List |  | ||||||
|  |  | ||||||
| from ..amount import Amount |  | ||||||
| from .devengado import Devengado |  | ||||||
|  |  | ||||||
|  |  | ||||||
| @dataclass |  | ||||||
| class DevengadoHoraExtra: |  | ||||||
|     hora_inicio: str |  | ||||||
|     hora_fin: str |  | ||||||
|     cantidad: int |  | ||||||
|     porcentaje: Amount |  | ||||||
|     pago: Amount |  | ||||||
|  |  | ||||||
|     def apply(self, child_path, fragment): |  | ||||||
|         fragment.set_element(child_path, None, |  | ||||||
|                              append_=True, |  | ||||||
|                              # NIE074 |  | ||||||
|                              HoraInicio=self.hora_inicio, |  | ||||||
|                              # NIE075 |  | ||||||
|                              HoraFin=self.hora_fin, |  | ||||||
|                              # NIE076 |  | ||||||
|                              Cantidad=self.cantidad, |  | ||||||
|                              # NIE077 |  | ||||||
|                              Porcentaje=str(round(self.porcentaje, 2)), |  | ||||||
|                              # NIE078 |  | ||||||
|                              Pago=str(round(self.pago, 2))) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| @dataclass |  | ||||||
| class DevengadoHorasExtrasDiarias(Devengado): |  | ||||||
|     horas_extras: List[DevengadoHoraExtra] |  | ||||||
|      |  | ||||||
|     def apply(self, fragment): |  | ||||||
|         hora_extra_xml = fragment.fragment('./HEDs') |  | ||||||
|         for hora_extra in self.horas_extras: |  | ||||||
|             hora_extra.apply('./HED', hora_extra_xml) |  | ||||||
|  |  | ||||||
| @dataclass |  | ||||||
| class DevengadoHorasExtrasNocturnas(Devengado): |  | ||||||
|     horas_extras: List[DevengadoHoraExtra] |  | ||||||
|      |  | ||||||
|     def apply(self, fragment): |  | ||||||
|         hora_extra_xml = fragment.fragment('./HENs') |  | ||||||
|         for hora_extra in self.horas_extras: |  | ||||||
|             hora_extra.apply('./HEN', hora_extra_xml) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| @dataclass |  | ||||||
| class DevengadoHorasRecargoNocturno(Devengado): |  | ||||||
|     horas_extras: List[DevengadoHoraExtra] |  | ||||||
|      |  | ||||||
|     def apply(self, fragment): |  | ||||||
|         hora_extra_xml = fragment.fragment('./HRNs') |  | ||||||
|         for hora_extra in self.horas_extras: |  | ||||||
|             hora_extra.apply('./HRN', hora_extra_xml) |  | ||||||
|  |  | ||||||
| @dataclass |  | ||||||
| class DevengadoHorasExtrasDiariasDominicalesYFestivos(Devengado): |  | ||||||
|     horas_extras: List[DevengadoHoraExtra] |  | ||||||
|      |  | ||||||
|     def apply(self, fragment): |  | ||||||
|         hora_extra_xml = fragment.fragment('./HEDDFs') |  | ||||||
|         for hora_extra in self.horas_extras: |  | ||||||
|             hora_extra.apply('./HEDDF', hora_extra_xml) |  | ||||||
|  |  | ||||||
| @dataclass |  | ||||||
| class DevengadoHorasRecargoDiariasDominicalesYFestivos(Devengado): |  | ||||||
|     horas_extras: List[DevengadoHoraExtra] |  | ||||||
|      |  | ||||||
|     def apply(self, fragment): |  | ||||||
|         hora_extra_xml = fragment.fragment('./HRDDFs') |  | ||||||
|         for hora_extra in self.horas_extras: |  | ||||||
|             hora_extra.apply('./HRDDF', hora_extra_xml) |  | ||||||
|  |  | ||||||
| @dataclass |  | ||||||
| class DevengadoHorasExtrasNocturnasDominicalesYFestivos(Devengado): |  | ||||||
|     horas_extras: List[DevengadoHoraExtra] |  | ||||||
|      |  | ||||||
|     def apply(self, fragment): |  | ||||||
|         hora_extra_xml = fragment.fragment('./HENDFs') |  | ||||||
|         for hora_extra in self.horas_extras: |  | ||||||
|             hora_extra.apply('./HENDF', hora_extra_xml) |  | ||||||
|  |  | ||||||
| @dataclass |  | ||||||
| class DevengadoHorasRecargoNocturnoDominicalesYFestivos(Devengado): |  | ||||||
|     horas_extras: List[DevengadoHoraExtra] |  | ||||||
|      |  | ||||||
|     def apply(self, fragment): |  | ||||||
|         hora_extra_xml = fragment.fragment('./HRNDFs') |  | ||||||
|         for hora_extra in self.horas_extras: |  | ||||||
|             hora_extra.apply('./HRNDF', hora_extra_xml) |  | ||||||
| @@ -1,21 +0,0 @@ | |||||||
| from dataclasses import dataclass |  | ||||||
|  |  | ||||||
| from ..amount import Amount |  | ||||||
| from .devengado import Devengado |  | ||||||
|  |  | ||||||
| @dataclass |  | ||||||
| class DevengadoTransporte(Devengado): |  | ||||||
|     auxilio_transporte: Amount = None |  | ||||||
|     viatico_manutencion: Amount = None |  | ||||||
|     viatico_manutencion_no_salarial: Amount = None |  | ||||||
|  |  | ||||||
|     def apply(self, fragment): |  | ||||||
|         fragment.set_element('./Transporte', None, |  | ||||||
|                              append_ = True, |  | ||||||
|                              # NIE071 |  | ||||||
|                              AuxilioTransporte = self.auxilio_transporte, |  | ||||||
|                              # NIE072 |  | ||||||
|                              ViaticoManuAlojS = self.viatico_manutencion, |  | ||||||
|                              # NIE073 |  | ||||||
|                              ViaticoManuAlojNS = self.viatico_manutencion_no_salarial |  | ||||||
|                              ) |  | ||||||
| @@ -1,35 +0,0 @@ | |||||||
| from dataclasses import dataclass |  | ||||||
|  |  | ||||||
| from ..pais import Pais |  | ||||||
| from ..departamento import Departamento |  | ||||||
| from ..municipio import Municipio |  | ||||||
|  |  | ||||||
| @dataclass |  | ||||||
| class Empleador: |  | ||||||
|     razon_social: str |  | ||||||
|     nit: str |  | ||||||
|     dv: str |  | ||||||
|     pais: Pais |  | ||||||
|     departamento: Departamento |  | ||||||
|     municipio: Municipio |  | ||||||
|     direccion: str |  | ||||||
|  |  | ||||||
|     def apply(self, fragment): |  | ||||||
|         fragment.set_attributes('./Empleador', |  | ||||||
|                                 # NIE033 |  | ||||||
|                                 NIT = self.nit, |  | ||||||
|                                 # NIE034 |  | ||||||
|                                 DV = self.dv, |  | ||||||
|                                 # NIE035 |  | ||||||
|                                 Pais = self.pais.code, |  | ||||||
|                                 # NIE036 |  | ||||||
|                                 DepartamentoEstado = self.departamento.code, |  | ||||||
|                                 # NIE037 |  | ||||||
|                                 MunicipioCiudad = self.municipio.code, |  | ||||||
|                                 # NIE038 |  | ||||||
|                                 Direccion = self.direccion, |  | ||||||
|  |  | ||||||
|                                 RazonSocial=self.razon_social |  | ||||||
|                                 ) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -1,2 +0,0 @@ | |||||||
| class DIANNominaIndividualError(Exception): |  | ||||||
|     pass |  | ||||||
| @@ -1,155 +0,0 @@ | |||||||
| from dataclasses import dataclass |  | ||||||
| import datetime |  | ||||||
|  |  | ||||||
| from facho import fe |  | ||||||
|  |  | ||||||
| class Habilitacion: |  | ||||||
|  |  | ||||||
|     @dataclass |  | ||||||
|     class Metadata: |  | ||||||
|         software_pin: str |  | ||||||
|         software_id: str |  | ||||||
|         nit: str |  | ||||||
|         dv: str |  | ||||||
|  |  | ||||||
|     def __init__(self, metadata): |  | ||||||
|         self.metadata = metadata |  | ||||||
|  |  | ||||||
|     def generar(self, zipname, fecha): |  | ||||||
|         nominas = [] |  | ||||||
|         dianzip = fe.DianZIP(open(zipname, 'w')) |  | ||||||
|  |  | ||||||
|         fechabase = datetime.datetime.now() |  | ||||||
|         consecutivo = 0 |  | ||||||
|         for _ in range(1, 11): |  | ||||||
|             consecutivo += 1 |  | ||||||
|             fechabase += datetime.timedelta(days=1) |  | ||||||
|             nomina = self._crear_nomina_individual() |  | ||||||
|  |  | ||||||
|             # pag 96 |  | ||||||
|             nombre = "nie%010d%s%08x.xml" % (int(self.nit), fecha.strftime('%s'), consecutivo) |  | ||||||
|          |  | ||||||
|     def _crear_nomina_individual_reemplazar(self, nomina, fechabase): |  | ||||||
|         metadata = self.metadata |  | ||||||
|  |  | ||||||
|         fecha = fechabase.strftime('%Y-%m-%d') |  | ||||||
|  |  | ||||||
|         nomina_ajuste = fe.nomina.DIANNominaIndividualDeAjuste.Reemplazar() |  | ||||||
|         self._poblar_nomina(nomina_ajuste, metadata, fecha, prefijo='R') |  | ||||||
|         informacion_general = nomina.informacion_general() |  | ||||||
|          |  | ||||||
|          |  | ||||||
|     def _poblar_nomina(self, nomina, metadata, fecha, prefijo='N', consecutivo='0001'): |  | ||||||
|         nomina.asignar_fecha_pago(fecha) |  | ||||||
|  |  | ||||||
|         nomina.asignar_metadata(fe.nomina.Metadata( |  | ||||||
|             secuencia=fe.nomina.NumeroSecuencia( |  | ||||||
|                 prefijo=prefijo, |  | ||||||
|                 consecutivo=consecutivo |  | ||||||
|             ), |  | ||||||
|             lugar_generacion=fe.nomina.Lugar( |  | ||||||
|                 pais = fe.nomina.Pais( |  | ||||||
|                     code = 'CO' |  | ||||||
|                 ), |  | ||||||
|                 departamento = fe.nomina.Departamento( |  | ||||||
|                     code = '05' |  | ||||||
|                 ), |  | ||||||
|                 municipio = fe.nomina.Municipio( |  | ||||||
|                     code = '05001' |  | ||||||
|                 ), |  | ||||||
|             ), |  | ||||||
|             proveedor=fe.nomina.Proveedor( |  | ||||||
|                 nit=metadata.nit, |  | ||||||
|                 dv=metadata.dv, |  | ||||||
|                 software_id=metadata.software_id, |  | ||||||
|                 software_pin=metadata.software_pin |  | ||||||
|             ) |  | ||||||
|         )) |  | ||||||
|  |  | ||||||
|         nomina.asignar_periodo(fe.nomina.Periodo( |  | ||||||
|             fecha_ingreso=fecha, |  | ||||||
|             fecha_liquidacion_inicio=fecha, |  | ||||||
|             fecha_liquidacion_fin=fecha, |  | ||||||
|             fecha_generacion=fecha, |  | ||||||
|         )) |  | ||||||
|          |  | ||||||
|         nomina.asignar_informacion_general(fe.nomina.InformacionGeneral( |  | ||||||
|             fecha_generacion = fecha, |  | ||||||
|             hora_generacion = '20:09:00-05:00', |  | ||||||
|             tipo_ambiente = fe.nomina.InformacionGeneral.AMBIENTE_PRUEBAS, |  | ||||||
|             software_pin = metadata.software_pin, |  | ||||||
|             periodo_nomina = fe.nomina.PeriodoNomina(code='1'), |  | ||||||
|             tipo_moneda = fe.nomina.TipoMoneda(code='COP') |  | ||||||
|         )) |  | ||||||
|  |  | ||||||
|         nomina.asignar_pago(fe.nomina.Pago( |  | ||||||
|             forma=fe.nomina.FormaPago( |  | ||||||
|                 code='1', |  | ||||||
|             ), |  | ||||||
|             metodo=fe.nomina.MetodoPago( |  | ||||||
|                 code='10' |  | ||||||
|             ) |  | ||||||
|         )) |  | ||||||
|         nomina.asignar_empleador(fe.nomina.Empleador( |  | ||||||
|             nit = metadata.nit, |  | ||||||
|             dv = '0', |  | ||||||
|             pais = fe.nomina.Pais( |  | ||||||
|                 code = 'CO' |  | ||||||
|             ), |  | ||||||
|             departamento = fe.nomina.Departamento( |  | ||||||
|                 code = '05' |  | ||||||
|             ), |  | ||||||
|             municipio = fe.nomina.Municipio( |  | ||||||
|                 code = '05001' |  | ||||||
|             ), |  | ||||||
|             direccion = 'calle etrivial' |  | ||||||
|         )) |  | ||||||
|  |  | ||||||
|         nomina.asignar_trabajador(fe.nomina.Trabajador( |  | ||||||
|             tipo_contrato = fe.nomina.TipoContrato( |  | ||||||
|                 code = '1' |  | ||||||
|             ), |  | ||||||
|             alto_riesgo = False, |  | ||||||
|             tipo_documento = fe.nomina.TipoDocumento( |  | ||||||
|                 code = '11' |  | ||||||
|             ), |  | ||||||
|             primer_apellido = 'gnu', |  | ||||||
|             segundo_apellido = 'emacs', |  | ||||||
|             primer_nombre = 'facho', |  | ||||||
|             lugar_trabajo = fe.nomina.LugarTrabajo( |  | ||||||
|                 pais = fe.nomina.Pais(code='CO'), |  | ||||||
|                 departamento = fe.nomina.Departamento(code='05'), |  | ||||||
|                 municipio = fe.nomina.Municipio(code='05001'), |  | ||||||
|                 direccion = 'calle facho' |  | ||||||
|             ), |  | ||||||
|             numero_documento = metadata.nit, |  | ||||||
|             tipo = fe.nomina.TipoTrabajador( |  | ||||||
|                 code = '01' |  | ||||||
|             ), |  | ||||||
|             salario_integral = True, |  | ||||||
|             sueldo = fe.nomina.Amount(1_500_000) |  | ||||||
|         )) |  | ||||||
|          |  | ||||||
|         nomina.adicionar_devengado(fe.nomina.DevengadoBasico( |  | ||||||
|             dias_trabajados = 60, |  | ||||||
|             sueldo_trabajado = fe.nomina.Amount(3_500_000) |  | ||||||
|         )) |  | ||||||
|  |  | ||||||
|         nomina.adicionar_deduccion(fe.nomina.DeduccionSalud( |  | ||||||
|             porcentaje = fe.nomina.Amount(19), |  | ||||||
|             deduccion = fe.nomina.Amount(1_000_000) |  | ||||||
|         )) |  | ||||||
|  |  | ||||||
|         nomina.adicionar_deduccion(fe.nomina.DeduccionFondoPension( |  | ||||||
|             porcentaje=fe.nomina.Amount(1), |  | ||||||
|             deduccion=fe.nomina.Amount(10) |  | ||||||
|         )) |  | ||||||
|  |  | ||||||
|     def _crear_nomina_individual(self, fechabase): |  | ||||||
|         metadata = self.metadata |  | ||||||
|  |  | ||||||
|         fecha = fechabase.strftime('%Y-%m-%d') |  | ||||||
|  |  | ||||||
|         nomina = fe.nomina.DIANNominaIndividual() |  | ||||||
|         self._poblar_nomina(nomina, metadata, fecha) |  | ||||||
|                  |  | ||||||
| @@ -1,25 +0,0 @@ | |||||||
| from dataclasses import dataclass |  | ||||||
|  |  | ||||||
| from .pais import Pais |  | ||||||
| from .departamento import Departamento |  | ||||||
| from .municipio import Municipio |  | ||||||
| from facho.fe.data.dian import codelist |  | ||||||
|  |  | ||||||
| @dataclass |  | ||||||
| class Lugar: |  | ||||||
|     pais: Pais |  | ||||||
|     departamento: Departamento |  | ||||||
|     municipio: Municipio |  | ||||||
|     idioma: str = 'es' |  | ||||||
|  |  | ||||||
|     def __post_init__(self): |  | ||||||
|         if self.idioma not in codelist.IdiomaISO6391: |  | ||||||
|             raise ValueError("idioma [%s] not found" % (self.code)) |  | ||||||
|         codelist.IdiomaISO6391[self.idioma]['iso-639-1'] |  | ||||||
|  |  | ||||||
|     def apply(self, fragment, root): |  | ||||||
|         fragment.set_attributes(root, |  | ||||||
|                                 Pais=self.pais.code, |  | ||||||
|                                 DepartamentoEstado=self.departamento.code, |  | ||||||
|                                 MunicipioCiudad=self.municipio.code, |  | ||||||
|                                 Idioma=self.idioma) |  | ||||||
| @@ -1,5 +0,0 @@ | |||||||
| from .. import form |  | ||||||
|  |  | ||||||
| class Municipio(form.City): |  | ||||||
|     pass |  | ||||||
|  |  | ||||||
| @@ -1,16 +0,0 @@ | |||||||
| from dataclasses import dataclass |  | ||||||
|  |  | ||||||
| from .forma_pago import FormaPago |  | ||||||
| from .metodo_pago import MetodoPago |  | ||||||
|  |  | ||||||
| @dataclass |  | ||||||
| class Pago: |  | ||||||
|     forma: FormaPago |  | ||||||
|     metodo: MetodoPago |  | ||||||
|  |  | ||||||
|     def apply(self, fragment): |  | ||||||
|         fragment.set_attributes('./Pago', |  | ||||||
|                                 # NIE064 |  | ||||||
|                                 Forma = self.forma.code, |  | ||||||
|                                 # NIE065 |  | ||||||
|                                 Metodo = self.metodo.code) |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| from dataclasses import dataclass |  | ||||||
|  |  | ||||||
| from facho.fe.data.dian import codelist |  | ||||||
|  |  | ||||||
| @dataclass |  | ||||||
| class FormaPago: |  | ||||||
|     code: str |  | ||||||
|     name: str = '' |  | ||||||
|  |  | ||||||
|     def __post_init__(self): |  | ||||||
|         if self.code not in codelist.FormasPago: |  | ||||||
|             raise ValueError("code [%s] not found" % (self.code)) |  | ||||||
|         self.name = codelist.FormasPago[self.code]['name'] |  | ||||||
| @@ -1,14 +0,0 @@ | |||||||
| from dataclasses import dataclass |  | ||||||
|  |  | ||||||
| from facho.fe.data.dian import codelist |  | ||||||
|  |  | ||||||
| @dataclass |  | ||||||
| class MetodoPago: |  | ||||||
|     code: str |  | ||||||
|     name: str = '' |  | ||||||
|  |  | ||||||
|     def __post_init__(self): |  | ||||||
|         if self.code not in codelist.MediosPago: |  | ||||||
|             raise ValueError("code [%s] not found" % (self.code)) |  | ||||||
|         self.name = codelist.MediosPago[self.code]['name'] |  | ||||||
|  |  | ||||||
| @@ -1,4 +0,0 @@ | |||||||
| from .. import form |  | ||||||
|  |  | ||||||
| class Pais(form.Country): |  | ||||||
|     pass |  | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user