diff --git a/docs/conf.py b/docs/conf.py index bcd2ee8..747bdaa 100755 --- a/docs/conf.py +++ b/docs/conf.py @@ -18,11 +18,11 @@ # relative to the documentation root, use os.path.abspath to make it # absolute, like shown here. # +import facho import os import sys sys.path.insert(0, os.path.abspath('..')) -import facho # -- General configuration --------------------------------------------- diff --git a/examples/generate-invoice-from-cli.py b/examples/generate-invoice-from-cli.py index a2d6351..b53f9f2 100644 --- a/examples/generate-invoice-from-cli.py +++ b/examples/generate-invoice-from-cli.py @@ -11,13 +11,18 @@ from facho.fe import form_xml from facho.fe import fe # importar otras necesarias -from datetime import datetime, date +from datetime import datetime # 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 +# Número suministrado por la Dian en el momento de la creación del SET de +# Pruebas +INVOICE_AUTHORIZATION = '181360000001' +# Id suministrado por la Dian en el momento de la creación del SET de Pruebas +ID_SOFTWARE = '57bcb6d1-c591-5a90-b80a-cb030ec91440' +# Número creado por la empresa para poder crear el SET de pruebas +PIN = '19642' +# Id suministrado por la Dian en el momento de la creación del SET de Pruebas +CLAVE_TECNICA = 'fc9eac422eba16e21ffd8c5f94b3f30a6e38162d' # callback que retonar las extensiones XML necesarias @@ -26,15 +31,24 @@ CLAVE_TECNICA = 'fc9eac422eba16e21ffd8c5f94b3f30a6e38162d' ##Id suministrado por # 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) + 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] + software_provider = fe.DianXMLExtensionSoftwareProvider( + 'nit_empresa', 'dígito_verificación', ID_SOFTWARE) + inv_authorization = fe.DianXMLExtensionInvoiceAuthorization( + INVOICE_AUTHORIZATION, + # Datos tomados de la configuración + datetime(2019, 1, 19), + datetime(2030, 1, 19), + 'SETP', 990000000, 995000000) # del SET de pruebas + return [ + security_code, + authorization_provider, + cufe, + software_provider, + inv_authorization] def invoice(): @@ -49,7 +63,7 @@ def invoice(): # 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', + legal_name='Nombre registrado de la empresa', name='Nombre comercial o él mismo nombre registrado', ident=form.PartyIdentification( 'nit_empresa', 'digito_verificación', '31'), @@ -65,22 +79,22 @@ def invoice(): form.Country('CO', 'Colombia'), form.CountrySubentity('05', 'Antioquia')), )) - #Tercero a quien se le factura + # 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( + 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 + # asignar metodo de pago inv.set_payment_mean(form.PaymentMean( # metodo de pago ver DIAN:3.4.1 id='1', diff --git a/examples/generate-nomina-from-cli.py b/examples/generate-nomina-from-cli.py index 05fccbe..41e8dd5 100644 --- a/examples/generate-nomina-from-cli.py +++ b/examples/generate-nomina-from-cli.py @@ -1,26 +1,28 @@ 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', + numero='N00001', consecutivo=232 ), lugar_generacion=fe.nomina.Lugar( - pais = fe.nomina.Pais( - code = 'CO' + pais=fe.nomina.Pais( + code='CO' ), - departamento = fe.nomina.Departamento( - code = '05' + departamento=fe.nomina.Departamento( + code='05' ), - municipio = fe.nomina.Municipio( - code = '05001' + municipio=fe.nomina.Municipio( + code='05001' ), ), proveedor=fe.nomina.Proveedor( @@ -32,62 +34,62 @@ def nomina(): )) 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') + 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' + nit='700085371', + dv='1', + pais=fe.nomina.Pais( + code='CO' ), - departamento = fe.nomina.Departamento( - code = '05' + departamento=fe.nomina.Departamento( + code='05' ), - municipio = fe.nomina.Municipio( - code = '05001' + municipio=fe.nomina.Municipio( + code='05001' ), - direccion = 'calle etrivial' + direccion='calle etrivial' )) nomina.asignar_trabajador(fe.nomina.Trabajador( - tipo_contrato = fe.nomina.TipoContrato( - code = '1' + tipo_contrato=fe.nomina.TipoContrato( + code='1' ), - alto_riesgo = False, - tipo_documento = fe.nomina.TipoDocumento( - code = '11' + 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' + 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' + numero_documento='800199436', + tipo=fe.nomina.TipoTrabajador( + code='01' ), - salario_integral = True, - sueldo = fe.nomina.Amount(1_500_000) + 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) + 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) + porcentaje=fe.nomina.Amount(19), + deduccion=fe.nomina.Amount(1_000_000) )) return nomina diff --git a/tests/fixtures.py b/tests/fixtures.py index 574e3ac..8b32db6 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -2,6 +2,7 @@ import pytest import facho.fe.form as form from datetime import datetime + @pytest.fixture def simple_debit_note_without_lines(): inv = form.DebitNote(form.InvoiceDocumentReference( @@ -15,7 +16,7 @@ def simple_debit_note_without_lines(): inv.set_supplier(form.Party( name='facho-supplier', ident=form.PartyIdentification('123', '', '31'), - responsability_code = form.Responsability(['ZZ']), + responsability_code=form.Responsability(['ZZ']), responsability_regime_code='48', organization_code='1', address=form.Address( @@ -36,38 +37,47 @@ def simple_debit_note_without_lines(): )) return inv + @pytest.fixture def simple_credit_note_without_lines(): - inv = form.CreditNote(form.InvoiceDocumentReference('1234', 'xx', datetime.now())) + inv = form.CreditNote( + form.InvoiceDocumentReference( + '1234', 'xx', datetime.now())) inv.set_period(datetime.now(), datetime.now()) inv.set_issue(datetime.now()) inv.set_ident('ABC123') inv.set_operation_type('20') - inv.set_payment_mean(form.PaymentMean(form.PaymentMean.DEBIT, '41', datetime.now(), '1234')) + inv.set_payment_mean( + form.PaymentMean( + form.PaymentMean.DEBIT, + '41', + datetime.now(), + '1234')) inv.set_supplier(form.Party( - name = 'facho-supplier', - ident = form.PartyIdentification('123','', '31'), - responsability_code = form.Responsability(['ZZ']), - responsability_regime_code = '48', - organization_code = '1', - address = form.Address( + name='facho-supplier', + ident=form.PartyIdentification('123', '', '31'), + responsability_code=form.Responsability(['ZZ']), + responsability_regime_code='48', + organization_code='1', + address=form.Address( '', '', form.City('05001', 'Medellín'), form.Country('CO', 'Colombia'), form.CountrySubentity('05', 'Antioquia')) )) inv.set_customer(form.Party( - name = 'facho-customer', - ident = form.PartyIdentification('321', '', '31'), - responsability_code = form.Responsability(['ZZ']), - responsability_regime_code = '48', - organization_code = '1', - address = form.Address( + name='facho-customer', + ident=form.PartyIdentification('321', '', '31'), + responsability_code=form.Responsability(['ZZ']), + responsability_regime_code='48', + organization_code='1', + address=form.Address( '', '', form.City('05001', 'Medellín'), form.Country('CO', 'Colombia'), form.CountrySubentity('05', 'Antioquia')) )) return inv + @pytest.fixture def simple_invoice_without_lines(): inv = form.NationalSalesInvoice() @@ -75,25 +85,30 @@ def simple_invoice_without_lines(): inv.set_issue(datetime.now()) inv.set_ident('ABC123') inv.set_operation_type('10') - inv.set_payment_mean(form.PaymentMean(form.PaymentMean.DEBIT, '41', datetime.now(), '1234')) + inv.set_payment_mean( + form.PaymentMean( + form.PaymentMean.DEBIT, + '41', + datetime.now(), + '1234')) inv.set_supplier(form.Party( - name = 'facho-supplier', - ident = form.PartyIdentification('123','', '31'), - responsability_code = form.Responsability(['ZZ']), - responsability_regime_code = '48', - organization_code = '1', - address = form.Address( + name='facho-supplier', + ident=form.PartyIdentification('123', '', '31'), + responsability_code=form.Responsability(['ZZ']), + responsability_regime_code='48', + organization_code='1', + address=form.Address( '', '', form.City('05001', 'Medellín'), form.Country('CO', 'Colombia'), form.CountrySubentity('05', 'Antioquia')) )) inv.set_customer(form.Party( - name = 'facho-customer', - ident = form.PartyIdentification('321', '', '31'), - responsability_code = form.Responsability(['ZZ']), - responsability_regime_code = '48', - organization_code = '1', - address = form.Address( + name='facho-customer', + ident=form.PartyIdentification('321', '', '31'), + responsability_code=form.Responsability(['ZZ']), + responsability_regime_code='48', + organization_code='1', + address=form.Address( '', '', form.City('05001', 'Medellín'), form.Country('CO', 'Colombia'), form.CountrySubentity('05', 'Antioquia')) @@ -108,25 +123,30 @@ def simple_invoice(): inv.set_issue(datetime.now()) inv.set_ident('ABC123') inv.set_operation_type('10') - inv.set_payment_mean(form.PaymentMean(form.PaymentMean.DEBIT, '41', datetime.now(), ' 1234')) + inv.set_payment_mean( + form.PaymentMean( + form.PaymentMean.DEBIT, + '41', + datetime.now(), + ' 1234')) inv.set_supplier(form.Party( - name = 'facho-supplier', - ident = form.PartyIdentification('123','', '31'), - responsability_code = form.Responsability(['ZZ']), - responsability_regime_code = '48', - organization_code = '1', - address = form.Address( + name='facho-supplier', + ident=form.PartyIdentification('123', '', '31'), + responsability_code=form.Responsability(['ZZ']), + responsability_regime_code='48', + organization_code='1', + address=form.Address( '', '', form.City('05001', 'Medellín'), form.Country('CO', 'Colombia'), form.CountrySubentity('05', 'Antioquia')) )) inv.set_customer(form.Party( - name = 'facho-customer', - ident = form.PartyIdentification('321','', '31'), - responsability_code = form.Responsability(['ZZ']), - responsability_regime_code = '48', - organization_code = '1', - address = form.Address( + name='facho-customer', + ident=form.PartyIdentification('321', '', '31'), + responsability_code=form.Responsability(['ZZ']), + responsability_regime_code='48', + organization_code='1', + address=form.Address( '', '', form.City('05001', 'Medellín'), form.Country('CO', 'Colombia'), form.CountrySubentity('05', 'Antioquia')) @@ -136,7 +156,7 @@ def simple_invoice(): quantity=form.Quantity(1, '94'), description='productofacho', item=form.StandardItem(9999), - price=form.Price(form.Amount(100.0),'01',''), + price=form.Price(form.Amount(100.0), '01', ''), tax=form.TaxTotal( tax_amount=form.Amount(0.0), taxable_amount=form.Amount(0.0), diff --git a/tests/test_amount.py b/tests/test_amount.py index b95cf8d..f8fbf5c 100644 --- a/tests/test_amount.py +++ b/tests/test_amount.py @@ -14,6 +14,7 @@ def test_amount_positive(): with pytest.raises(ValueError): form.Amount(-1.0) + def test_amount_equals(): price1 = form.Amount(110.0) price2 = form.Amount(100 + 10.0) @@ -22,6 +23,7 @@ def test_amount_equals(): assert price1 == form.Amount(10) * form.Amount(10) + form.Amount(10) assert form.Amount(110) == (form.Amount(1.10) * form.Amount(100)) + def test_round_half_even(): # https://www.w3.org/TR/xpath-functions-31/#func-round-half-to-even assert form.Amount(0.5).round(0).float() == 0.0 @@ -30,16 +32,20 @@ def test_round_half_even(): assert form.Amount(3.567812e+3).round(2).float() == 3567.81e0 assert form.Amount(4.7564e-3).round(2).float() == 0.0e0 + def test_round(): # Entre 0 y 5 Mantener el dígito menos significativo assert form.Amount(1.133).round(2) == form.Amount(1.13) # Entre 6 y 9 Incrementar el dígito menos significativo assert form.Amount(1.166).round(2) == form.Amount(1.17) - # 5, y el segundo dígito siguiente al dígito menos significativo es cero o par Mantener el dígito menos significativo + # 5, y el segundo dígito siguiente al dígito menos significativo es cero o + # par Mantener el dígito menos significativo assert str(form.Amount(1.1542).round(2)) == str(form.Amount(1.15)) - # 5, y el segundo dígito siguiente al dígito menos significativo es impar Incrementar el dígito menos significativo + # 5, y el segundo dígito siguiente al dígito menos significativo es impar + # Incrementar el dígito menos significativo assert str(form.Amount(1.1563).round(2)) == str(form.Amount(1.16)) + def test_amount_truncate(): assert form.Amount(1.1569).truncate_as_string(2) == '1.15' assert form.Amount(587.0700).truncate_as_string(2) == '587.07' @@ -49,5 +55,6 @@ def test_amount_truncate(): assert form.Amount(10000.02245).truncate_as_string(2) == '10000.02' assert form.Amount(10000.02357).truncate_as_string(2) == '10000.02' + def test_amount_format(): - assert str(round(form.Amount(1.1569),2)) == '1.16' + assert str(round(form.Amount(1.1569), 2)) == '1.16' diff --git a/tests/test_client_dian.py b/tests/test_client_dian.py index 5b9a816..ab3309b 100644 --- a/tests/test_client_dian.py +++ b/tests/test_client_dian.py @@ -4,12 +4,7 @@ # this repository contains the full copyright notices and license terms. from facho.fe.client import dian -from facho import facho -import pytest - - -from datetime import datetime class FakeDianClient(dian.DianClient): def __init__(self, username, password, resp): diff --git a/tests/test_facho.py b/tests/test_facho.py index 765b894..4ac764c 100644 --- a/tests/test_facho.py +++ b/tests/test_facho.py @@ -7,10 +7,10 @@ import pytest -#from click.testing import CliRunner +# from click.testing import CliRunner from facho import facho -#from facho import cli +# from facho import cli def test_facho_xml(): @@ -20,18 +20,19 @@ def test_facho_xml(): invoice.text = 'Test' assert xml.tostring() == 'Test' - invoice_line = xml.find_or_create_element('/root/Invoice/Line') + xml.find_or_create_element('/root/Invoice/Line') assert xml.tostring() == 'Test' def test_facho_xml_with_attr(): xml = facho.FachoXML('root') - invoice = xml.find_or_create_element('/root/Invoice[id=123]') + xml.find_or_create_element('/root/Invoice[id=123]') assert xml.tostring() == '' + def test_facho_xml_idempotent(): xml = facho.FachoXML('root') - invoice = xml.find_or_create_element('/root/Invoice') + xml.find_or_create_element('/root/Invoice') assert xml.tostring() == '' xml.find_or_create_element('/root/Invoice') @@ -46,6 +47,7 @@ def test_facho_xml_idempotent(): xml.find_or_create_element('/root/Invoice/Line') assert xml.tostring() == '' + def test_facho_xml_aliases(): xml = facho.FachoXML('root') xml.register_alias_xpath('Invoice', '/root/Invoice') @@ -54,31 +56,42 @@ def test_facho_xml_aliases(): invoice.text = 'Test' assert xml.tostring() == 'Test' + def test_facho_xmlns(): xml = facho.FachoXML('root', nsmap={ 'ext': 'https://ext', 'sts': 'https://sts', }) - invoiceAuthorization = xml.find_or_create_element('/root/ext:UBLExtensions/ext:UBLExtension/' - 'ext:ExtensionContent/sts:DianExtensions/' - 'sts:InvoiceControl/sts:InvoiceAuthorization') - assert xml.tostring().strip() == ''\ - ''\ - ''\ - ''\ - ''\ - ''\ - '' + invoiceAuthorization = xml.find_or_create_element( + '/root/ext:UBLExtensions/ext:UBLExtension/' + 'ext:ExtensionContent/sts:DianExtensions/' + 'sts:InvoiceControl/sts:InvoiceAuthorization') + assert xml.tostring().strip() == ( + '' + '' + '' + '' + '' + '' + '' + '' + '' + '') invoiceAuthorization.text = '123456789' - assert xml.tostring().strip() == ''\ - ''\ - ''\ - ''\ - ''\ - '123456789'\ - '' + assert xml.tostring().strip() == ( + '' + '' + '' + '' + '' + '' + '123456789' + '' + '' + '') + def test_facho_xmlns_idempotent(): xml = facho.FachoXML('root', nsmap={ @@ -87,16 +100,22 @@ def test_facho_xmlns_idempotent(): }) xml.find_or_create_element('/root/ext:Extension/sts:Sotoros') - assert xml.tostring() == '' + assert xml.tostring() == ( + '' + '') xml.find_or_create_element('/root/ext:Extension/sts:Sotoros') - assert xml.tostring() == '' + assert xml.tostring() == ( + '' + '') + def test_facho_xml_set_element_with_format(): xml = facho.FachoXML('root') - invoice = xml.set_element('/root/Invoice', 1, format_='%02d') + xml.set_element('/root/Invoice', 1, format_='%02d') assert xml.tostring() == '01' + def test_facho_xml_fragment(): xml = facho.FachoXML('root') invoice = xml.fragment('/root/Invoice') @@ -116,7 +135,10 @@ def test_facho_xml_fragments(): line = xml.fragment('/Invoice/Line', append=True) line.set_element('/Line/Id', 3) - assert xml.tostring() == '123' + assert xml.tostring() == ( + '12' + '3') + def test_facho_xml_nested_fragments(): xml = facho.FachoXML('Invoice') @@ -128,15 +150,20 @@ def test_facho_xml_nested_fragments(): party.set_element('/Party/LastName', 'test') - assert xml.tostring() == 'test
line 1
test
' + assert xml.tostring() == ( + 'test' + '
line 1
' + 'test
') + def test_facho_xml_get_element_text_of_fragment(): xml = facho.FachoXML('root') invoice = xml.fragment('/root/Invoice') invoice.set_element('/Invoice/Id', 1) - + assert invoice.get_element_text('/Invoice/Id') == '1' + def test_facho_xml_get_element_text(): xml = facho.FachoXML('Invoice') xml.set_element('/Invoice/ID', 'ABC123') @@ -147,6 +174,7 @@ def test_facho_xml_get_element_text(): line.set_element('/Line/Quantity', 5) assert line.get_element_text('/Line/Quantity', format_=int) == 5 + def test_facho_xml_get_element_text_next_child(): xml = facho.FachoXML('Invoice') xml.set_element('/Invoice/ID', 'ABC123') @@ -166,25 +194,32 @@ def test_facho_xml_set_element_relative(): assert xml.get_element_text('/Invoice/ID') == 'ABC123' + def test_facho_xml_set_element_relative_with_namespace(): - xml = facho.FachoXML('{%s}Invoice' % ('http://www.dian.gov.co/contratos/facturaelectronica/v1'), - nsmap={'fe': 'http://www.dian.gov.co/contratos/facturaelectronica/v1'}) + xml = facho.FachoXML( + '{%s}Invoice' % + ('http://www.dian.gov.co/contratos/facturaelectronica/v1'), + nsmap={ + 'fe': 'http://www.dian.gov.co/contratos/facturaelectronica/v1'}) xml.set_element('./ID', 'ABC123') assert xml.get_element_text('/fe:Invoice/ID') == 'ABC123' + def test_facho_xml_fragment_relative(): xml = facho.FachoXML('root') invoice = xml.fragment('./Invoice') invoice.set_element('./Id', 1) assert xml.tostring() == '1' + def test_facho_xml_get_element_fragment_relative(): xml = facho.FachoXML('root') invoice = xml.fragment('./Invoice') invoice.set_element('./Id', 1) assert invoice.get_element_text('./Id') == '1' + def test_facho_xml_replacement_for(): xml = facho.FachoXML('root') xml.placeholder_for('./child/type') @@ -192,37 +227,47 @@ def test_facho_xml_replacement_for(): './child/code', 'test') assert xml.tostring() == 'test' + def test_facho_xml_set_element_content_invalid_validation(): xml = facho.FachoXML('root') - with pytest.raises(facho.FachoValueInvalid) as e: + with pytest.raises(facho.FachoValueInvalid): xml.set_element_validator('./Id', lambda text, attrs: text == 'mero') xml.set_element('./Id', 'bad') + def test_facho_xml_set_element_content_valid_validation(): xml = facho.FachoXML('root') xml.set_element_validator('./Id', lambda text, attrs: text == 'mero') xml.set_element('./Id', 'mero') + def test_facho_xml_set_element_attribute_invalid_validation(): xml = facho.FachoXML('root') - with pytest.raises(facho.FachoValueInvalid) as e: - xml.set_element_validator('./Id', lambda text, attrs: attrs['code'] == 'ABC') - xml.set_element('./Id', 'mero', code = 'CBA') + with pytest.raises(facho.FachoValueInvalid): + xml.set_element_validator( + './Id', lambda text, attrs: attrs['code'] == 'ABC') + xml.set_element('./Id', 'mero', code='CBA') + def test_facho_xml_set_element_attribute_valid_validation(): xml = facho.FachoXML('root') - xml.set_element_validator('./Id', lambda text, attrs: attrs['code'] == 'ABC') - xml.set_element('./Id', 'mero', code = 'ABC') + xml.set_element_validator( + './Id', + lambda text, + attrs: attrs['code'] == 'ABC') + xml.set_element('./Id', 'mero', code='ABC') + def test_facho_xml_get_element_attribute(): xml = facho.FachoXML('root') - xml.set_element('./Id', 'mero', code = 'ABC') + xml.set_element('./Id', 'mero', code='ABC') assert xml.get_element_attribute('/root/Id', 'code') == 'ABC' + def test_facho_xml_keep_orden_slibing(): xml = facho.FachoXML('root') xml.find_or_create_element('./A') @@ -233,14 +278,16 @@ def test_facho_xml_keep_orden_slibing(): assert xml.tostring() == '' + def test_facho_xml_placeholder_optional(): xml = facho.FachoXML('root') xml.placeholder_for('./A') xml.placeholder_for('./B', optional=True) xml.placeholder_for('./C') - + assert xml.tostring() == '' + def test_facho_xml_placeholder_append_to_optional(): xml = facho.FachoXML('root') xml.placeholder_for('./A') @@ -250,6 +297,7 @@ def test_facho_xml_placeholder_append_to_optional(): xml.find_or_create_element('./B') assert xml.tostring() == '' + def test_facho_xml_placeholder_set_element_to_optional(): xml = facho.FachoXML('root') xml.placeholder_for('./A') @@ -259,6 +307,7 @@ def test_facho_xml_placeholder_set_element_to_optional(): xml.set_element('./B', '2') assert xml.tostring() == '2' + def test_facho_xml_placeholder_set_element_to_optional_with_append(): xml = facho.FachoXML('root') xml.placeholder_for('./A') @@ -275,8 +324,8 @@ def test_facho_xml_set_attributes(): xml.find_or_create_element('./A') xml.set_attributes('./A', - value1 = '1', - value2 = '2' + value1='1', + value2='2' ) assert xml.get_element_attribute('/root/A', 'value1') == '1' assert xml.get_element_attribute('/root/A', 'value2') == '2' @@ -287,13 +336,14 @@ def test_facho_xml_set_attributes_not_set_optional(): xml.find_or_create_element('./A') xml.set_attributes('./A', - value1 = None, - value2 = '2' + value1=None, + value2='2' ) with pytest.raises(KeyError): xml.get_element_attribute('/root/A', 'value1') assert xml.get_element_attribute('/root/A', 'value2') == '2' + def test_facho_xml_placeholder_with_fragment(): xml = facho.FachoXML('root') xml.placeholder_for('./A') @@ -305,8 +355,10 @@ def test_facho_xml_placeholder_with_fragment(): AA.find_or_create_element('./B', append=True) AA = xml.fragment('./AA/Child', append=True) - - assert xml.tostring() == '' + + assert xml.tostring() == ( + '') + def test_facho_xml_create_on_first_append(): xml = facho.FachoXML('root') @@ -314,6 +366,7 @@ def test_facho_xml_create_on_first_append(): xml.find_or_create_element('./A', append=True) assert xml.tostring() == '' + def test_facho_xml_create_on_first_append_multiple_appends(): xml = facho.FachoXML('root') @@ -324,6 +377,7 @@ def test_facho_xml_create_on_first_append_multiple_appends(): xml.find_or_create_element('./C', append=True) assert xml.tostring() == '' + def test_facho_xml_fragment_create_on_first_append(): xml = facho.FachoXML('root') @@ -333,6 +387,7 @@ def test_facho_xml_fragment_create_on_first_append(): A.find_or_create_element('./C') assert xml.tostring() == '' + def test_facho_xml_placeholder_optional_and_fragment(): xml = facho.FachoXML('root') @@ -346,6 +401,7 @@ def test_facho_xml_placeholder_optional_and_fragment(): assert xml.tostring() == '' + def test_facho_xml_placeholder_optional_and_set_attributes(): xml = facho.FachoXML('root') xml.placeholder_for('./A') @@ -354,6 +410,7 @@ def test_facho_xml_placeholder_optional_and_set_attributes(): assert xml.get_element_attribute('/root/A', 'prueba') == 'OK' assert xml.tostring() == '' + def test_facho_xml_placeholder_optional_and_fragment_with_set_element(): xml = facho.FachoXML('root') @@ -365,17 +422,19 @@ def test_facho_xml_placeholder_optional_and_fragment_with_set_element(): assert xml.tostring() == '' assert xml.get_element_attribute('/root/A/AA', 'prueba') == 'OK' + def test_facho_xml_exist_element(): xml = facho.FachoXML('root') xml.placeholder_for('./A') - assert xml.exist_element('/root/A') == False + assert xml.exist_element('/root/A') is False assert xml.tostring() == '' - + xml.find_or_create_element('./A') - assert xml.exist_element('/root/A') == True + assert xml.exist_element('/root/A') assert xml.tostring() == '' + def test_facho_xml_query_element_text_or_attribute(): xml = facho.FachoXML('root') @@ -384,6 +443,7 @@ def test_facho_xml_query_element_text_or_attribute(): assert xml.get_element_text_or_attribute('/root/A') == 'contenido' assert xml.get_element_text_or_attribute('/root/A/@clave') == 'valor' + def test_facho_xml_query_element_text_or_attribute_from_fragment(): xml = facho.FachoXML('root') @@ -392,6 +452,7 @@ def test_facho_xml_query_element_text_or_attribute_from_fragment(): assert invoice.get_element_text_or_attribute('/Invoice/A') == 'contenido' + def test_facho_xml_build_xml_absolute(): xml = facho.FachoXML('root') @@ -400,18 +461,23 @@ def test_facho_xml_build_xml_absolute(): def test_facho_xml_build_xml_absolute_namespace(): - xml = facho.FachoXML('{%s}root' % ('http://www.dian.gov.co/contratos/facturaelectronica/v1'), - nsmap={'fe': 'http://www.dian.gov.co/contratos/facturaelectronica/v1'}) + xml = facho.FachoXML( + '{%s}root' % + ('http://www.dian.gov.co/contratos/facturaelectronica/v1'), + nsmap={ + 'fe': 'http://www.dian.gov.co/contratos/facturaelectronica/v1'}) xpath = xml.xpath_from_root('/A') assert xpath == '/fe:root/A' def test_facho_xml_build_xml_absolute_namespace_from_fragment(): - xml = facho.FachoXML('{%s}root' % ('http://www.dian.gov.co/contratos/facturaelectronica/v1'), - nsmap={'fe': 'http://www.dian.gov.co/contratos/facturaelectronica/v1'}) + xml = facho.FachoXML( + '{%s}root' % + ('http://www.dian.gov.co/contratos/facturaelectronica/v1'), + nsmap={ + 'fe': 'http://www.dian.gov.co/contratos/facturaelectronica/v1'}) invoice = xml.fragment('/root/Invoice') - + xpath = invoice.xpath_from_root('/A') assert xpath == '/fe:root/Invoice/A' - diff --git a/tests/test_fe.py b/tests/test_fe.py index 29aca4b..6c84e91 100644 --- a/tests/test_fe.py +++ b/tests/test_fe.py @@ -4,16 +4,14 @@ # this repository contains the full copyright notices and license terms. from datetime import datetime -import pytest - from facho import fe -import helpers - def test_xmlsigned_build(monkeypatch): - # openssl req -x509 -sha256 -nodes -subj "/CN=test" -days 1 -newkey rsa:2048 -keyout example.key -out example.pem - # openssl pkcs12 -export -out example.p12 -inkey example.key -in example.pem + # openssl req -x509 -sha256 -nodes -subj "/CN=test" -days 1 + # -newkey rsa:2048 -keyout example.key -out example.pem + # openssl pkcs12 -export -out example.p12 -inkey example.key -in + # example.pem signer = fe.DianXMLExtensionSigner('./tests/example.p12') xml = fe.FeXML('Invoice', @@ -21,68 +19,90 @@ def test_xmlsigned_build(monkeypatch): signer.sign_xml_element(xml.root) - elem = xml.find_or_create_element('/fe:Invoice/ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent/ds:Signature') + elem = xml.find_or_create_element( + '/fe:Invoice/ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent' + '/ds:Signature') assert elem is not None - #assert elem.findall('ds:SignedInfo', fe.NAMESPACES) is not None + # assert elem.findall('ds:SignedInfo', fe.NAMESPACES) is not None def test_xmlsigned_with_passphrase_build(monkeypatch): - #openssl req -x509 -sha256 -nodes -subj "/CN=test" -days 1 -newkey rsa:2048 -keyout example.key -out example.pem - #openssl pkcs12 -export -out example.p12 -inkey example.key -in example.pem - signer = fe.DianXMLExtensionSigner('./tests/example-with-passphrase.p12', 'test') + # openssl req -x509 -sha256 -nodes -subj "/CN=test" -days 1 + # -newkey rsa:2048 -keyout example.key -out example.pem + # openssl pkcs12 -export -out example.p12 -inkey example.key -in + # example.pem + signer = fe.DianXMLExtensionSigner( + './tests/example-with-passphrase.p12', 'test') xml = fe.FeXML('Invoice', 'http://www.dian.gov.co/contratos/facturaelectronica/v1') signer.sign_xml_element(xml.root) - elem = xml.find_or_create_element('/fe:Invoice/ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent/ds:Signature') + elem = xml.find_or_create_element( + '/fe:Invoice/ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent' + '/ds:Signature') assert elem is not None - #assert elem.findall('ds:SignedInfo', fe.NAMESPACES) is not None + # assert elem.findall('ds:SignedInfo', fe.NAMESPACES) is not None def test_dian_extension_software_security_code(): - security_code = fe.DianXMLExtensionSoftwareSecurityCode('idsoftware', '1234', '1') + security_code = fe.DianXMLExtensionSoftwareSecurityCode( + 'idsoftware', '1234', '1') xml = fe.FeXML('Invoice', 'http://www.dian.gov.co/contratos/facturaelectronica/v1') xml.add_extension(security_code) - content = xml.get_element_text('/fe:Invoice/ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent/sts:DianExtensions/sts:SoftwareSecurityCode') + content = xml.get_element_text( + '/fe:Invoice/ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent' + '/sts:DianExtensions/sts:SoftwareSecurityCode') assert content is not None + def test_dian_extension_invoice_authorization(): invoice_authorization = '18762002346472' - inv_auth_ext = fe.DianXMLExtensionInvoiceAuthorization(invoice_authorization, - datetime(2017, 2, 23), - datetime(2019, 8, 23), - 'MD', 100001, 174999) + inv_auth_ext = fe.DianXMLExtensionInvoiceAuthorization( + invoice_authorization, datetime( + 2017, 2, 23), datetime( + 2019, 8, 23), 'MD', 100001, 174999) xml = fe.FeXML('Invoice', 'http://www.dian.gov.co/contratos/facturaelectronica/v1') xml.add_extension(inv_auth_ext) - auth = xml.get_element_text('/fe:Invoice/ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent/sts:DianExtensions/sts:InvoiceControl/sts:InvoiceAuthorization') + auth = xml.get_element_text( + '/fe:Invoice/ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent' + '/sts:DianExtensions/sts:InvoiceControl/sts:InvoiceAuthorization') assert auth == invoice_authorization + def test_dian_extension_software_provider(): nit = '123456789' id_software = 'ABCDASDF123' - software_provider_extension = fe.DianXMLExtensionSoftwareProvider(nit, '', id_software) + software_provider_extension = fe.DianXMLExtensionSoftwareProvider( + nit, '', id_software) xml = fe.FeXML('Invoice', 'http://www.dian.gov.co/contratos/facturaelectronica/v1') xml.add_extension(software_provider_extension) - give_nit = xml.get_element_text('/fe:Invoice/ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent/sts:DianExtensions/sts:SoftwareProvider/sts:ProviderID') + give_nit = xml.get_element_text( + '/fe:Invoice/ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent' + '/sts:DianExtensions/sts:SoftwareProvider/sts:ProviderID') assert nit == give_nit + def test_dian_extension_authorization_provider(): auth_provider_extension = fe.DianXMLExtensionAuthorizationProvider() xml = fe.FeXML('Invoice', 'http://www.dian.gov.co/contratos/facturaelectronica/v1') xml.add_extension(auth_provider_extension) - dian_nit = xml.get_element_text('/fe:Invoice/ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent/sts:DianExtensions/sts:AuthorizationProvider/sts:AuthorizationProviderID') + dian_nit = xml.get_element_text( + '/fe:Invoice/ext:UBLExtensions/ext:UBLExtension/' + 'ext:ExtensionContent/sts:DianExtensions/sts:AuthorizationProvider/' + 'sts:AuthorizationProviderID') assert dian_nit == '800197268' + def test_dian_invoice_without_namespace_in_root(): xml = fe.FeXML('Invoice', 'http://www.dian.gov.co/contratos/facturaelectronica/v1') @@ -92,10 +112,14 @@ def test_dian_invoice_without_namespace_in_root(): def test_xml_sign_dian(monkeypatch): xml = fe.FeXML('Invoice', - 'http://www.dian.gov.co/contratos/facturaelectronica/v1') - xml.find_or_create_element('/fe:Invoice/ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent') - ublextension = xml.fragment('/fe:Invoice/ext:UBLExtensions/ext:UBLExtension', append=True) - extcontent = ublextension.find_or_create_element('/ext:UBLExtension/ext:ExtensionContent') + 'http://www.dian.gov.co/contratos/facturaelectronica/v1') + xml.find_or_create_element( + '/fe:Invoice/ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent') + ublextension = xml.fragment( + '/fe:Invoice/ext:UBLExtensions/ext:UBLExtension', + append=True) + ublextension.find_or_create_element( + '/ext:UBLExtension/ext:ExtensionContent') xmlstring = xml.tostring() print(xmlstring) @@ -103,12 +127,17 @@ def test_xml_sign_dian(monkeypatch): xmlsigned = signer.sign_xml_string(xmlstring) assert "Signature" in xmlsigned + def test_xml_sign_dian_using_bytes(monkeypatch): xml = fe.FeXML('Invoice', - 'http://www.dian.gov.co/contratos/facturaelectronica/v1') - xml.find_or_create_element('/fe:Invoice/ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent') - ublextension = xml.fragment('/fe:Invoice/ext:UBLExtensions/ext:UBLExtension', append=True) - extcontent = ublextension.find_or_create_element('/ext:UBLExtension/ext:ExtensionContent') + 'http://www.dian.gov.co/contratos/facturaelectronica/v1') + xml.find_or_create_element( + '/fe:Invoice/ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent') + ublextension = xml.fragment( + '/fe:Invoice/ext:UBLExtensions/ext:UBLExtension', + append=True) + ublextension.find_or_create_element( + '/ext:UBLExtension/ext:ExtensionContent') xmlstring = xml.tostring() p12_data = open('./tests/example.p12', 'rb').read() @@ -117,6 +146,7 @@ def test_xml_sign_dian_using_bytes(monkeypatch): xmlsigned = signer.sign_xml_string(xmlstring) assert "Signature" in xmlsigned + def test_xml_signature_timestamp(monkeypatch): xml = fe.FeXML( 'Invoice', @@ -132,4 +162,4 @@ def test_xml_signature_timestamp(monkeypatch): xmlsigned = signer.sign_xml_string(xmlstring) with open('invoice.xml', 'w') as file_: - file_.write(xmlsigned) \ No newline at end of file + file_.write(xmlsigned) diff --git a/tests/test_fe_form.py b/tests/test_fe_form.py index cfbc060..b4c226c 100644 --- a/tests/test_fe_form.py +++ b/tests/test_fe_form.py @@ -41,11 +41,13 @@ def test_invoicesimple_build(simple_invoice): xml = DIANInvoiceXML(simple_invoice) supplier_name = xml.get_element_text( - '/fe:Invoice/cac:AccountingSupplierParty/cac:Party/cac:PartyName/cbc:Name') + '/fe:Invoice/cac:AccountingSupplierParty/cac:Party/cac:PartyName/cbc' + ':Name') assert supplier_name == simple_invoice.invoice_supplier.name customer_name = xml.get_element_text( - '/fe:Invoice/cac:AccountingCustomerParty/cac:Party/cac:PartyName/cbc:Name') + '/fe:Invoice/cac:AccountingCustomerParty/cac:Party/cac:PartyName/cbc' + ':Name') assert customer_name == simple_invoice.invoice_customer.name @@ -66,7 +68,8 @@ def test_invoicesimple_xml_signed(monkeypatch, simple_invoice): xml.add_extension(signer) elem = xml.get_element( - '/fe:Invoice/ext:UBLExtensions/ext:UBLExtension[2]/ext:ExtensionContent/ds:Signature') + '/fe:Invoice/ext:UBLExtensions/ext:UBLExtension[2]/ext' + ':ExtensionContent/ds:Signature') assert elem.text is not None @@ -75,14 +78,16 @@ def test_invoicesimple_zip(simple_invoice): zipdata = io.BytesIO() with fe.DianZIP(zipdata) as dianzip: - name_invoice = dianzip.add_invoice_xml(simple_invoice.invoice_ident, str(xml_invoice)) + name_invoice = dianzip.add_invoice_xml( + simple_invoice.invoice_ident, str(xml_invoice)) # el zip ademas de archivar debe comprimir los archivos # de lo contrario la DIAN lo rechaza with zipfile.ZipFile(zipdata) as dianzip: dianzip.testzip() for zipinfo in dianzip.infolist(): - assert zipinfo.compress_type == zipfile.ZIP_DEFLATED, "se espera el zip comprimido" + assert zipinfo.compress_type == zipfile.ZIP_DEFLATED, ( + "se espera el zip comprimido") with zipfile.ZipFile(zipdata) as dianzip: xml_data = dianzip.open(name_invoice).read().decode('utf-8') @@ -122,7 +127,8 @@ def test_invoice_invoice_type_code(simple_invoice): def test_invoice_totals(simple_invoice_without_lines): simple_invoice = simple_invoice_without_lines simple_invoice.invoice_ident = '323200000129' - simple_invoice.invoice_issue = datetime.strptime('2019-01-16 10:53:10-05:00', '%Y-%m-%d %H:%M:%S%z') + simple_invoice.invoice_issue = datetime.strptime( + '2019-01-16 10:53:10-05:00', '%Y-%m-%d %H:%M:%S%z') simple_invoice.invoice_supplier.ident = '700085371' simple_invoice.invoice_customer.ident = '800199436' simple_invoice.add_invoice_line(form.InvoiceLine( @@ -222,7 +228,8 @@ def test_invoice_cufe(simple_invoice_without_lines): assert formatVars[12] == '800199436', "NumAdq" # ClTec - assert formatVars[13] == '693ff6f2a553c3646a063436fd4dd9ded0311471', "ClTec" + assert formatVars[13] == ( + '693ff6f2a553c3646a063436fd4dd9ded0311471'), "ClTec" # TipoAmbiente assert formatVars[14] == '1', "TipoAmbiente" @@ -323,8 +330,13 @@ def test_debit_note_cude(simple_debit_note_without_lines): assert build_vars['TipoAmb'] == 2 cude_composicion = "".join(cude_extension.formatVars()) - assert cude_composicion == 'ND10012019-01-1810:58:00-05:0030000.00010.00042400.00030.0032400.0090019726410254102102012' + assert cude_composicion == ( + 'ND10012019-01-1810:58:00-05:0030000.00010.00042400.00030.0032400.009' + '001' + '9726410254102102012') xml_invoice.add_extension(cude_extension) cude = xml_invoice.get_element_text('/fe:DebitNote/cbc:UUID') - assert cude == '3fa73a86d57d9341c536afde1f85c4efd9d4591c2c22bce4dfb0e6b0d2e83b8f047a8bde7098292e9d2493e60d1c31da' + assert cude == ( + '3fa73a86d57d9341c536afde1f85c4efd9d4591c2c22bce4dfb0e6b0d2e83b8f047a8' + 'bde7098292e9d2493e60d1c31da') diff --git a/tests/test_form.py b/tests/test_form.py index 2e2559a..713a0eb 100644 --- a/tests/test_form.py +++ b/tests/test_form.py @@ -121,7 +121,9 @@ def test_FAU14(): wants = form.Amount(119.0 + 19.0 - 50.0) - assert inv.invoice_legal_monetary_total.payable_amount == wants, "got %s want %s" % (inv.invoice_legal_monetary_total.payable_amount, wants) + assert inv.invoice_legal_monetary_total.payable_amount == wants, ( + "got %s want %s" % ( + inv.invoice_legal_monetary_total.payable_amount, wants)) def test_invalid_tipo_operacion_nota_debito(): diff --git a/tests/test_form_xml.py b/tests/test_form_xml.py index 44a4ccc..aa83439 100644 --- a/tests/test_form_xml.py +++ b/tests/test_form_xml.py @@ -6,10 +6,7 @@ """Tests for `facho` package.""" import pytest -# from datetime import datetime -import copy -from facho.fe import form from facho.fe import form_xml # from fixtures import * diff --git a/tests/test_nomina.py b/tests/test_nomina.py index 961bb77..a130b9a 100644 --- a/tests/test_nomina.py +++ b/tests/test_nomina.py @@ -28,8 +28,12 @@ # )) # xml = nomina.toFachoXML() -# assert xml.get_element_attribute('/nomina:NominaIndividual/Devengados/Basico', 'DiasTrabajados') == '30' -# assert xml.get_element_attribute('/nomina:NominaIndividual/Devengados/Basico', 'SueldoTrabajado') == '1000000.00' +# assert +# xml.get_element_attribute('/nomina:NominaIndividual/Devengados/Basico', +# 'DiasTrabajados') == '30' +# assert +# xml.get_element_attribute('/nomina:NominaIndividual/Devengados/Basico', +# 'SueldoTrabajado') == '1000000.00' # def test_adicionar_devengado_transporte(): # nomina = fe.nomina.DIANNominaIndividual() @@ -40,7 +44,9 @@ # xml = nomina.toFachoXML() -# assert xml.get_element_attribute('/nomina:NominaIndividual/Devengados/Transporte', 'AuxilioTransporte') == '2000000.0' +# assert +# xml.get_element_attribute('/nomina:NominaIndividual/Devengados/Transporte', +# 'AuxilioTransporte') == '2000000.0' # def test_adicionar_devengado_comprobante_total(): # nomina = fe.nomina.DIANNominaIndividual() @@ -58,7 +64,9 @@ # xml = nomina.toFachoXML() -# assert xml.get_element_text('/nomina:NominaIndividual/ComprobanteTotal') == '1000000.00' +# assert +# xml.get_element_text('/nomina:NominaIndividual/ComprobanteTotal') == +# '1000000.00' # def test_adicionar_devengado_comprobante_total_cero(): # nomina = fe.nomina.DIANNominaIndividual() @@ -75,7 +83,8 @@ # xml = nomina.toFachoXML() -# assert xml.get_element_text('/nomina:NominaIndividual/ComprobanteTotal') == '0.00' +# assert +# xml.get_element_text('/nomina:NominaIndividual/ComprobanteTotal') == '0.00' # def test_adicionar_devengado_transporte_muchos(): # nomina = fe.nomina.DIANNominaIndividual() @@ -90,7 +99,8 @@ # xml = nomina.toFachoXML() # print(xml) -# assert xml.get_element_text('/nomina:NominaIndividual/DevengadosTotal') == '5000000.00' +# assert xml.get_element_text('/nomina:NominaIndividual/DevengadosTotal') +# == '5000000.00' # def test_adicionar_deduccion_salud(): # nomina = fe.nomina.DIANNominaIndividual() @@ -107,7 +117,9 @@ # xml = nomina.toFachoXML() # print(xml) -# assert xml.get_element_text('/nomina:NominaIndividual/DeduccionesTotal') == '1000.00' +# assert +# xml.get_element_text('/nomina:NominaIndividual/DeduccionesTotal') == +# '1000.00' # def test_nomina_obligatorios_segun_anexo_tecnico(): # nomina = fe.nomina.DIANNominaIndividual() @@ -213,26 +225,62 @@ # )) # xml = nomina.toFachoXML() -# expected_cune = 'b8f9b6c24de07ffd92ea5467433a3b69357cfaffa7c19722db94b2e0eca41d057085a54f484b5da15ff585e773b0b0ab' -# assert xml.get_element_attribute('/nomina:NominaIndividual/InformacionGeneral', 'CUNE') == expected_cune -# assert xml.get_element_attribute('/nomina:NominaIndividual/InformacionGeneral', 'TipoXML') == '102' -# assert xml.get_element_text_or_attribute('/nomina:NominaIndividual/NumeroSecuenciaXML/@Numero') == 'N00001' -# assert xml.get_element_text_or_attribute('/nomina:NominaIndividual/NumeroSecuenciaXML/@Consecutivo') == '00001' -# assert xml.get_element_text_or_attribute('/nomina:NominaIndividual/LugarGeneracionXML/@Pais') == 'CO' -# assert xml.get_element_text_or_attribute('/nomina:NominaIndividual/LugarGeneracionXML/@DepartamentoEstado') == '05' -# assert xml.get_element_text_or_attribute('/nomina:NominaIndividual/LugarGeneracionXML/@MunicipioCiudad') == '05001' -# assert xml.get_element_text_or_attribute('/nomina:NominaIndividual/ProveedorXML/@NIT') == '999999' -# assert xml.get_element_text_or_attribute('/nomina:NominaIndividual/ProveedorXML/@DV') == '2' -# assert xml.get_element_text_or_attribute('/nomina:NominaIndividual/ProveedorXML/@SoftwareID') == 'xx' -# assert xml.get_element_text_or_attribute('/nomina:NominaIndividual/ProveedorXML/@SoftwareSC') is not None -# assert xml.get_element_text_or_attribute('/nomina:NominaIndividual/CodigoQR') == f"https://catalogo-vpfe.dian.gov.co/document/searchqr?documentkey={expected_cune}" -# assert xml.get_element_text_or_attribute('/nomina:NominaIndividual/Empleador/@NIT') == '700085371' -# assert xml.get_element_text_or_attribute('/nomina:NominaIndividual/Trabajador/@NumeroDocumento') == '800199436' -# assert xml.get_element_text_or_attribute('/nomina:NominaIndividual/Novedad') == 'True' -# assert xml.get_element_text_or_attribute('/nomina:NominaIndividual/Novedad/@CUNENov') == 'N0111' +# expected_cune = +# 'b8f9b6c24de07ffd92ea5467433a3b69357cfaffa7c19722db94b2e0eca41d057085a54f484 +# b5da15ff585e773b0b0ab' +# assert +# xml.get_element_attribute('/nomina:NominaIndividual/InformacionGeneral', +# 'CUNE') == expected_cune +# assert +# xml.get_element_attribute('/nomina:NominaIndividual/InformacionGeneral', +# 'TipoXML') == '102' +# assert +# xml.get_element_text_or_attribute('/nomina:NominaIndividual/NumeroSecuenciaX +# ML/@Numero') == 'N00001' +# assert +# xml.get_element_text_or_attribute('/nomina:NominaIndividual/NumeroSecuenciaX +# ML/@Consecutivo') == '00001' +# assert +# xml.get_element_text_or_attribute('/nomina:NominaIndividual/LugarGeneracionX +# ML/@Pais') == 'CO' +# assert +# xml.get_element_text_or_attribute('/nomina:NominaIndividual/LugarGeneracionX +# ML/@DepartamentoEstado') == '05' +# assert +# xml.get_element_text_or_attribute('/nomina:NominaIndividual/LugarGeneracionX +# ML/@MunicipioCiudad') == '05001' +# assert +# xml.get_element_text_or_attribute('/nomina:NominaIndividual/ProveedorXML/@NI +# T') == '999999' +# assert +# xml.get_element_text_or_attribute('/nomina:NominaIndividual/ProveedorXML/@DV +# ') == '2' +# assert +# xml.get_element_text_or_attribute('/nomina:NominaIndividual/ProveedorXML/@So +# ftwareID') == 'xx' +# assert +# xml.get_element_text_or_attribute('/nomina:NominaIndividual/ProveedorXML/@So +# ftwareSC') is not None +# assert +# xml.get_element_text_or_attribute('/nomina:NominaIndividual/CodigoQR') == +# f"https://catalogo-vpfe.dian.gov.co/document/searchqr?documentkey={expected_ +# cune}" +# assert +# xml.get_element_text_or_attribute('/nomina:NominaIndividual/Empleador/@NIT') +# == '700085371' +# assert +# xml.get_element_text_or_attribute('/nomina:NominaIndividual/Trabajador/@Nume +# roDocumento') == '800199436' +# assert +# xml.get_element_text_or_attribute('/nomina:NominaIndividual/Novedad') == +# 'True' +# assert +# xml.get_element_text_or_attribute('/nomina:NominaIndividual/Novedad/@CUNENov +# ') == 'N0111' # # confirmar el namespace -# assert 'xmlns="dian:gov:co:facturaelectronica:NominaIndividual"' in xml.tostring() +# assert 'xmlns="dian:gov:co:facturaelectronica:NominaIndividual"' in +# xml.tostring() # def test_asignar_pago(): # nomina = fe.nomina.DIANNominaIndividual() @@ -249,11 +297,11 @@ # xml.add_extension(signer) # print(xml.tostring()) -# elem = xml.get_element('/nomina:NominaIndividual/ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent/ds:Signature') +# elem = +# xml.get_element('/nomina:NominaIndividual/ext:UBLExtensions/ext:UBLExtension +# /ext:ExtensionContent/ds:Signature') # assert elem is not None - - # def test_nomina_devengado_horas_extras_nocturnas(): # nomina = fe.nomina.DIANNominaIndividual() @@ -277,7 +325,9 @@ # )) # xml = nomina.toFachoXML() -# extras = xml.get_element('/nomina:NominaIndividual/Devengados/HENs/HEN', multiple=True) +# extras = +# xml.get_element('/nomina:NominaIndividual/Devengados/HENs/HEN', +# multiple=True) # assert extras[0].get('HoraInicio') == '2021-11-30T19:09:55' # assert extras[0].get('HoraFin') == '2021-11-30T20:09:55' # assert extras[0].get('Cantidad') == '1' @@ -312,7 +362,9 @@ # )) # xml = nomina.toFachoXML() -# extras = xml.get_element('/nomina:NominaIndividual/Devengados/HRNs/HRN', multiple=True) +# extras = +# xml.get_element('/nomina:NominaIndividual/Devengados/HRNs/HRN', +# multiple=True) # assert extras[0].get('HoraInicio') == '2021-11-30T19:09:55' # assert extras[0].get('HoraFin') == '2021-11-30T20:09:55' # assert extras[0].get('Cantidad') == '1' @@ -327,7 +379,9 @@ # def test_nomina_devengado_horas_extras_diarias_dominicales_y_festivos(): # nomina = fe.nomina.DIANNominaIndividual() -# nomina.adicionar_devengado(fe.nomina.DevengadoHorasExtrasDiariasDominicalesYFestivos( +# +# nomina.adicionar_devengado(fe.nomina.DevengadoHorasExtrasDiariasDominicalesY +# Festivos( # horas_extras=[ # fe.nomina.DevengadoHoraExtra( # hora_inicio='2021-11-30T19:09:55', @@ -347,7 +401,9 @@ # )) # xml = nomina.toFachoXML() -# extras = xml.get_element('/nomina:NominaIndividual/Devengados/HEDDFs/HEDDF', multiple=True) +# extras = +# xml.get_element('/nomina:NominaIndividual/Devengados/HEDDFs/HEDDF', +# multiple=True) # assert extras[0].get('HoraInicio') == '2021-11-30T19:09:55' # assert extras[0].get('HoraFin') == '2021-11-30T20:09:55' # assert extras[0].get('Cantidad') == '1' @@ -362,7 +418,9 @@ # def test_nomina_devengado_horas_recargo_diarias_dominicales_y_festivos(): # nomina = fe.nomina.DIANNominaIndividual() -# nomina.adicionar_devengado(fe.nomina.DevengadoHorasRecargoDiariasDominicalesYFestivos( +# +# nomina.adicionar_devengado(fe.nomina.DevengadoHorasRecargoDiariasDominicales +# YFestivos( # horas_extras=[ # fe.nomina.DevengadoHoraExtra( # hora_inicio='2021-11-30T19:09:55', @@ -382,7 +440,9 @@ # )) # xml = nomina.toFachoXML() -# extras = xml.get_element('/nomina:NominaIndividual/Devengados/HRDDFs/HRDDF', multiple=True) +# extras = +# xml.get_element('/nomina:NominaIndividual/Devengados/HRDDFs/HRDDF', +# multiple=True) # assert extras[0].get('HoraInicio') == '2021-11-30T19:09:55' # assert extras[0].get('HoraFin') == '2021-11-30T20:09:55' # assert extras[0].get('Cantidad') == '1' @@ -398,7 +458,9 @@ # def test_nomina_devengado_horas_extras_nocturnas_dominicales_y_festivos(): # nomina = fe.nomina.DIANNominaIndividual() -# nomina.adicionar_devengado(fe.nomina.DevengadoHorasExtrasNocturnasDominicalesYFestivos( +# +# nomina.adicionar_devengado(fe.nomina.DevengadoHorasExtrasNocturnasDominicale +# sYFestivos( # horas_extras=[ # fe.nomina.DevengadoHoraExtra( # hora_inicio='2021-11-30T19:09:55', @@ -418,7 +480,9 @@ # )) # xml = nomina.toFachoXML() -# extras = xml.get_element('/nomina:NominaIndividual/Devengados/HENDFs/HENDF', multiple=True) +# extras = +# xml.get_element('/nomina:NominaIndividual/Devengados/HENDFs/HENDF', +# multiple=True) # assert extras[0].get('HoraInicio') == '2021-11-30T19:09:55' # assert extras[0].get('HoraFin') == '2021-11-30T20:09:55' # assert extras[0].get('Cantidad') == '1' @@ -433,7 +497,9 @@ # def test_nomina_devengado_horas_recargo_nocturno_dominicales_y_festivos(): # nomina = fe.nomina.DIANNominaIndividual() -# nomina.adicionar_devengado(fe.nomina.DevengadoHorasRecargoNocturnoDominicalesYFestivos( +# +# nomina.adicionar_devengado(fe.nomina.DevengadoHorasRecargoNocturnoDominicale +# sYFestivos( # horas_extras=[ # fe.nomina.DevengadoHoraExtra( # hora_inicio='2021-11-30T19:09:55', @@ -453,7 +519,9 @@ # )) # xml = nomina.toFachoXML() -# extras = xml.get_element('/nomina:NominaIndividual/Devengados/HRNDFs/HRNDF', multiple=True) +# extras = +# xml.get_element('/nomina:NominaIndividual/Devengados/HRNDFs/HRNDF', +# multiple=True) # assert extras[0].get('HoraInicio') == '2021-11-30T19:09:55' # assert extras[0].get('HoraFin') == '2021-11-30T20:09:55' # assert extras[0].get('Cantidad') == '1' diff --git a/tests/test_nomina_ajuste.py b/tests/test_nomina_ajuste.py index a20c159..a263260 100644 --- a/tests/test_nomina_ajuste.py +++ b/tests/test_nomina_ajuste.py @@ -101,7 +101,9 @@ # xml = nomina.toFachoXML() -# assert xml.get_element_attribute('/nominaajuste:NominaIndividualDeAjuste/Reemplazar/InformacionGeneral', 'TipoXML') == '103' +# assert +# xml.get_element_attribute('/nominaajuste:NominaIndividualDeAjuste/Reemplazar +# /InformacionGeneral', 'TipoXML') == '103' # def test_adicionar_reemplazar_devengado_comprobante_total(): @@ -119,13 +121,17 @@ # xml = nomina.toFachoXML() -# assert xml.get_element_text('/nominaajuste:NominaIndividualDeAjuste/Reemplazar/ComprobanteTotal') == '1000000.00' +# assert +# xml.get_element_text('/nominaajuste:NominaIndividualDeAjuste/Reemplazar/Comp +# robanteTotal') == '1000000.00' # def test_adicionar_reemplazar_asignar_predecesor(): # nomina = fe.nomina.DIANNominaIndividualDeAjuste.Reemplazar() -# nomina.asignar_predecesor(fe.nomina.DIANNominaIndividualDeAjuste.Reemplazar.Predecesor( +# +# nomina.asignar_predecesor(fe.nomina.DIANNominaIndividualDeAjuste.Reemplazar. +# Predecesor( # numero = '123456', # cune = 'ABC123456', # fecha_generacion = '2021-11-16' @@ -133,15 +139,23 @@ # xml = nomina.toFachoXML() # print(xml.tostring()) -# assert xml.get_element_text_or_attribute('/nominaajuste:NominaIndividualDeAjuste/Reemplazar/ReemplazandoPredecesor/@NumeroPred') == '123456' -# assert xml.get_element_text_or_attribute('/nominaajuste:NominaIndividualDeAjuste/Reemplazar/ReemplazandoPredecesor/@CUNEPred') == 'ABC123456' -# assert xml.get_element_text_or_attribute('/nominaajuste:NominaIndividualDeAjuste/Reemplazar/ReemplazandoPredecesor/@FechaGenPred') == '2021-11-16' +# assert +# xml.get_element_text_or_attribute('/nominaajuste:NominaIndividualDeAjuste/Re +# emplazar/ReemplazandoPredecesor/@NumeroPred') == '123456' +# assert +# xml.get_element_text_or_attribute('/nominaajuste:NominaIndividualDeAjuste/Re +# emplazar/ReemplazandoPredecesor/@CUNEPred') == 'ABC123456' +# assert +# xml.get_element_text_or_attribute('/nominaajuste:NominaIndividualDeAjuste/Re +# emplazar/ReemplazandoPredecesor/@FechaGenPred') == '2021-11-16' # def test_adicionar_reemplazar_eliminar_predecesor_opcional(): # nomina = fe.nomina.DIANNominaIndividualDeAjuste.Reemplazar() -# nomina.asignar_predecesor(fe.nomina.DIANNominaIndividualDeAjuste.Reemplazar.Predecesor( +# +# nomina.asignar_predecesor(fe.nomina.DIANNominaIndividualDeAjuste.Reemplazar. +# Predecesor( # numero = '123456', # cune = 'ABC123456', # fecha_generacion = '2021-11-16' @@ -150,13 +164,19 @@ # xml = nomina.toFachoXML() # print(xml.tostring()) -# assert xml.get_element('/nominaajuste:NominaIndividualDeAjuste/Reemplazar/ReemplazandoPredecesor') is not None -# assert xml.get_element('/nominaajuste:NominaIndividualDeAjuste/Eliminar/EliminandoPredecesor') is None +# assert +# xml.get_element('/nominaajuste:NominaIndividualDeAjuste/Reemplazar/Reemplaza +# ndoPredecesor') is not None +# assert +# xml.get_element('/nominaajuste:NominaIndividualDeAjuste/Eliminar/EliminandoP +# redecesor') is None # def test_adicionar_eliminar_reemplazar_predecesor_opcional(): # nomina = fe.nomina.DIANNominaIndividualDeAjuste.Eliminar() -# nomina.asignar_predecesor(fe.nomina.DIANNominaIndividualDeAjuste.Eliminar.Predecesor( +# +# nomina.asignar_predecesor(fe.nomina.DIANNominaIndividualDeAjuste.Eliminar.Pr +# edecesor( # numero = '123456', # cune = 'ABC123456', # fecha_generacion = '2021-11-16' @@ -164,8 +184,12 @@ # xml = nomina.toFachoXML() # print(xml.tostring()) -# assert xml.get_element('/nominaajuste:NominaIndividualDeAjuste/Eliminar/EliminandoPredecesor') is not None -# assert xml.get_element('/nominaajuste:NominaIndividualDeAjuste/Reemplazar/ReemplazandoPredecesor') is None +# assert +# xml.get_element('/nominaajuste:NominaIndividualDeAjuste/Eliminar/EliminandoP +# redecesor') is not None +# assert +# xml.get_element('/nominaajuste:NominaIndividualDeAjuste/Reemplazar/Reemplaza +# ndoPredecesor') is None # def test_adicionar_eliminar_devengado_comprobante_total(): # nomina = fe.nomina.DIANNominaIndividualDeAjuste.Eliminar() @@ -182,12 +206,16 @@ # xml = nomina.toFachoXML() -# assert xml.get_element_text('/nominaajuste:NominaIndividualDeAjuste/Eliminar/ComprobanteTotal') == '1000000.00' +# assert +# xml.get_element_text('/nominaajuste:NominaIndividualDeAjuste/Eliminar/Compro +# banteTotal') == '1000000.00' # def test_adicionar_eliminar_asignar_predecesor(): # nomina = fe.nomina.DIANNominaIndividualDeAjuste.Eliminar() -# nomina.asignar_predecesor(fe.nomina.DIANNominaIndividualDeAjuste.Eliminar.Predecesor( +# +# nomina.asignar_predecesor(fe.nomina.DIANNominaIndividualDeAjuste.Eliminar.Pr +# edecesor( # numero = '123456', # cune = 'ABC123456', # fecha_generacion = '2021-11-16' @@ -195,9 +223,15 @@ # xml = nomina.toFachoXML() # print(xml.tostring()) -# assert xml.get_element_text_or_attribute('/nominaajuste:NominaIndividualDeAjuste/Eliminar/EliminandoPredecesor/@NumeroPred') == '123456' -# assert xml.get_element_text_or_attribute('/nominaajuste:NominaIndividualDeAjuste/Eliminar/EliminandoPredecesor/@CUNEPred') == 'ABC123456' -# assert xml.get_element_text_or_attribute('/nominaajuste:NominaIndividualDeAjuste/Eliminar/EliminandoPredecesor/@FechaGenPred') == '2021-11-16' +# assert +# xml.get_element_text_or_attribute('/nominaajuste:NominaIndividualDeAjuste/El +# iminar/EliminandoPredecesor/@NumeroPred') == '123456' +# assert +# xml.get_element_text_or_attribute('/nominaajuste:NominaIndividualDeAjuste/El +# iminar/EliminandoPredecesor/@CUNEPred') == 'ABC123456' +# assert +# xml.get_element_text_or_attribute('/nominaajuste:NominaIndividualDeAjuste/El +# iminar/EliminandoPredecesor/@FechaGenPred') == '2021-11-16' # def test_nomina_devengado_horas_extras_diarias(): # nomina = fe.nomina.DIANNominaIndividual()