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() == 'testline 1test'
+ 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()