Fix: Formateo PEP8 (79 cols) y limpieza flake8 en tests y examples

- Líneas >79 cols reajustadas (asserts, strings CUDE/CUDS, comentarios)
- Elimina imports y variables muertas (F401/F841), E712 (== False -> is False)
- Reordena imports en docs/conf.py
This commit is contained in:
2026-08-12 19:56:33 -05:00
parent 4a7c2e2947
commit c4a29e4a6f
13 changed files with 518 additions and 271 deletions

View File

@@ -18,11 +18,11 @@
# relative to the documentation root, use os.path.abspath to make it # relative to the documentation root, use os.path.abspath to make it
# absolute, like shown here. # absolute, like shown here.
# #
import facho
import os import os
import sys import sys
sys.path.insert(0, os.path.abspath('..')) sys.path.insert(0, os.path.abspath('..'))
import facho
# -- General configuration --------------------------------------------- # -- General configuration ---------------------------------------------

View File

@@ -11,13 +11,18 @@ from facho.fe import form_xml
from facho.fe import fe from facho.fe import fe
# importar otras necesarias # importar otras necesarias
from datetime import datetime, date from datetime import datetime
# Datos del fomulario del SET de pruebas # 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 # Número suministrado por la Dian en el momento de la creación del SET de
ID_SOFTWARE = '57bcb6d1-c591-5a90-b80a-cb030ec91440' #Id suministrado por la Dian en el momento de la creación del SET de Pruebas # Pruebas
PIN = '19642' #Número creado por la empresa para poder crear el SET de pruebas INVOICE_AUTHORIZATION = '181360000001'
CLAVE_TECNICA = 'fc9eac422eba16e21ffd8c5f94b3f30a6e38162d' ##Id suministrado por la Dian en el momento de la creación del SET de Pruebas # 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 # callback que retonar las extensiones XML necesarias
@@ -26,15 +31,24 @@ CLAVE_TECNICA = 'fc9eac422eba16e21ffd8c5f94b3f30a6e38162d' ##Id suministrado por
# muchos de los valores usados son obtenidos # muchos de los valores usados son obtenidos
# del servicio web de la DIAN. # del servicio web de la DIAN.
def extensions(inv): 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() authorization_provider = fe.DianXMLExtensionAuthorizationProvider()
cufe = fe.DianXMLExtensionCUFE(inv, CLAVE_TECNICA, fe.AMBIENTE_PRUEBAS) cufe = fe.DianXMLExtensionCUFE(inv, CLAVE_TECNICA, fe.AMBIENTE_PRUEBAS)
software_provider = fe.DianXMLExtensionSoftwareProvider('nit_empresa', 'dígito_verificación', ID_SOFTWARE) software_provider = fe.DianXMLExtensionSoftwareProvider(
inv_authorization = fe.DianXMLExtensionInvoiceAuthorization(INVOICE_AUTHORIZATION, 'nit_empresa', 'dígito_verificación', ID_SOFTWARE)
datetime(2019, 1, 19),#Datos toamdos de inv_authorization = fe.DianXMLExtensionInvoiceAuthorization(
datetime(2030, 1, 19),#la configuración INVOICE_AUTHORIZATION,
# Datos tomados de la configuración
datetime(2019, 1, 19),
datetime(2030, 1, 19),
'SETP', 990000000, 995000000) # del SET de pruebas 'SETP', 990000000, 995000000) # del SET de pruebas
return [security_code, authorization_provider, cufe, software_provider, inv_authorization] return [
security_code,
authorization_provider,
cufe,
software_provider,
inv_authorization]
def invoice(): def invoice():

View File

@@ -1,9 +1,11 @@
from facho import fe from facho import fe
def extensions(nomina): def extensions(nomina):
return [] return []
def nomina(): def nomina():
nomina = fe.nomina.DIANNominaIndividual() nomina = fe.nomina.DIANNominaIndividual()

View File

@@ -2,6 +2,7 @@ import pytest
import facho.fe.form as form import facho.fe.form as form
from datetime import datetime from datetime import datetime
@pytest.fixture @pytest.fixture
def simple_debit_note_without_lines(): def simple_debit_note_without_lines():
inv = form.DebitNote(form.InvoiceDocumentReference( inv = form.DebitNote(form.InvoiceDocumentReference(
@@ -36,14 +37,22 @@ def simple_debit_note_without_lines():
)) ))
return inv return inv
@pytest.fixture @pytest.fixture
def simple_credit_note_without_lines(): 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_period(datetime.now(), datetime.now())
inv.set_issue(datetime.now()) inv.set_issue(datetime.now())
inv.set_ident('ABC123') inv.set_ident('ABC123')
inv.set_operation_type('20') 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( inv.set_supplier(form.Party(
name='facho-supplier', name='facho-supplier',
ident=form.PartyIdentification('123', '', '31'), ident=form.PartyIdentification('123', '', '31'),
@@ -68,6 +77,7 @@ def simple_credit_note_without_lines():
)) ))
return inv return inv
@pytest.fixture @pytest.fixture
def simple_invoice_without_lines(): def simple_invoice_without_lines():
inv = form.NationalSalesInvoice() inv = form.NationalSalesInvoice()
@@ -75,7 +85,12 @@ def simple_invoice_without_lines():
inv.set_issue(datetime.now()) inv.set_issue(datetime.now())
inv.set_ident('ABC123') inv.set_ident('ABC123')
inv.set_operation_type('10') 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( inv.set_supplier(form.Party(
name='facho-supplier', name='facho-supplier',
ident=form.PartyIdentification('123', '', '31'), ident=form.PartyIdentification('123', '', '31'),
@@ -108,7 +123,12 @@ def simple_invoice():
inv.set_issue(datetime.now()) inv.set_issue(datetime.now())
inv.set_ident('ABC123') inv.set_ident('ABC123')
inv.set_operation_type('10') 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( inv.set_supplier(form.Party(
name='facho-supplier', name='facho-supplier',
ident=form.PartyIdentification('123', '', '31'), ident=form.PartyIdentification('123', '', '31'),

View File

@@ -14,6 +14,7 @@ def test_amount_positive():
with pytest.raises(ValueError): with pytest.raises(ValueError):
form.Amount(-1.0) form.Amount(-1.0)
def test_amount_equals(): def test_amount_equals():
price1 = form.Amount(110.0) price1 = form.Amount(110.0)
price2 = form.Amount(100 + 10.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 price1 == form.Amount(10) * form.Amount(10) + form.Amount(10)
assert form.Amount(110) == (form.Amount(1.10) * form.Amount(100)) assert form.Amount(110) == (form.Amount(1.10) * form.Amount(100))
def test_round_half_even(): def test_round_half_even():
# https://www.w3.org/TR/xpath-functions-31/#func-round-half-to-even # https://www.w3.org/TR/xpath-functions-31/#func-round-half-to-even
assert form.Amount(0.5).round(0).float() == 0.0 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(3.567812e+3).round(2).float() == 3567.81e0
assert form.Amount(4.7564e-3).round(2).float() == 0.0e0 assert form.Amount(4.7564e-3).round(2).float() == 0.0e0
def test_round(): def test_round():
# Entre 0 y 5 Mantener el dígito menos significativo # Entre 0 y 5 Mantener el dígito menos significativo
assert form.Amount(1.133).round(2) == form.Amount(1.13) assert form.Amount(1.133).round(2) == form.Amount(1.13)
# Entre 6 y 9 Incrementar el dígito menos significativo # Entre 6 y 9 Incrementar el dígito menos significativo
assert form.Amount(1.166).round(2) == form.Amount(1.17) 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)) 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)) assert str(form.Amount(1.1563).round(2)) == str(form.Amount(1.16))
def test_amount_truncate(): def test_amount_truncate():
assert form.Amount(1.1569).truncate_as_string(2) == '1.15' assert form.Amount(1.1569).truncate_as_string(2) == '1.15'
assert form.Amount(587.0700).truncate_as_string(2) == '587.07' 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.02245).truncate_as_string(2) == '10000.02'
assert form.Amount(10000.02357).truncate_as_string(2) == '10000.02' assert form.Amount(10000.02357).truncate_as_string(2) == '10000.02'
def test_amount_format(): def test_amount_format():
assert str(round(form.Amount(1.1569), 2)) == '1.16' assert str(round(form.Amount(1.1569), 2)) == '1.16'

View File

@@ -4,12 +4,7 @@
# this repository contains the full copyright notices and license terms. # this repository contains the full copyright notices and license terms.
from facho.fe.client import dian from facho.fe.client import dian
from facho import facho
import pytest
from datetime import datetime
class FakeDianClient(dian.DianClient): class FakeDianClient(dian.DianClient):
def __init__(self, username, password, resp): def __init__(self, username, password, resp):

View File

@@ -20,18 +20,19 @@ def test_facho_xml():
invoice.text = 'Test' invoice.text = 'Test'
assert xml.tostring() == '<root><Invoice>Test</Invoice></root>' assert xml.tostring() == '<root><Invoice>Test</Invoice></root>'
invoice_line = xml.find_or_create_element('/root/Invoice/Line') xml.find_or_create_element('/root/Invoice/Line')
assert xml.tostring() == '<root><Invoice>Test<Line/></Invoice></root>' assert xml.tostring() == '<root><Invoice>Test<Line/></Invoice></root>'
def test_facho_xml_with_attr(): def test_facho_xml_with_attr():
xml = facho.FachoXML('root') 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() == '<root><Invoice id="123"/></root>' assert xml.tostring() == '<root><Invoice id="123"/></root>'
def test_facho_xml_idempotent(): def test_facho_xml_idempotent():
xml = facho.FachoXML('root') xml = facho.FachoXML('root')
invoice = xml.find_or_create_element('/root/Invoice') xml.find_or_create_element('/root/Invoice')
assert xml.tostring() == '<root><Invoice/></root>' assert xml.tostring() == '<root><Invoice/></root>'
xml.find_or_create_element('/root/Invoice') xml.find_or_create_element('/root/Invoice')
@@ -46,6 +47,7 @@ def test_facho_xml_idempotent():
xml.find_or_create_element('/root/Invoice/Line') xml.find_or_create_element('/root/Invoice/Line')
assert xml.tostring() == '<root><Invoice><Line/></Invoice></root>' assert xml.tostring() == '<root><Invoice><Line/></Invoice></root>'
def test_facho_xml_aliases(): def test_facho_xml_aliases():
xml = facho.FachoXML('root') xml = facho.FachoXML('root')
xml.register_alias_xpath('Invoice', '/root/Invoice') xml.register_alias_xpath('Invoice', '/root/Invoice')
@@ -54,31 +56,42 @@ def test_facho_xml_aliases():
invoice.text = 'Test' invoice.text = 'Test'
assert xml.tostring() == '<root><Invoice>Test</Invoice></root>' assert xml.tostring() == '<root><Invoice>Test</Invoice></root>'
def test_facho_xmlns(): def test_facho_xmlns():
xml = facho.FachoXML('root', nsmap={ xml = facho.FachoXML('root', nsmap={
'ext': 'https://ext', 'ext': 'https://ext',
'sts': 'https://sts', 'sts': 'https://sts',
}) })
invoiceAuthorization = xml.find_or_create_element('/root/ext:UBLExtensions/ext:UBLExtension/' invoiceAuthorization = xml.find_or_create_element(
'/root/ext:UBLExtensions/ext:UBLExtension/'
'ext:ExtensionContent/sts:DianExtensions/' 'ext:ExtensionContent/sts:DianExtensions/'
'sts:InvoiceControl/sts:InvoiceAuthorization') 'sts:InvoiceControl/sts:InvoiceAuthorization')
assert xml.tostring().strip() == '<root xmlns:ext="https://ext" xmlns:sts="https://sts"><ext:UBLExtensions>'\ assert xml.tostring().strip() == (
'<ext:UBLExtension>'\ '<root xmlns:ext="https://ext" xmlns:sts="https://sts">'
'<ext:ExtensionContent>'\ '<ext:UBLExtensions>'
'<sts:DianExtensions>'\ '<ext:UBLExtension>'
'<sts:InvoiceControl>'\ '<ext:ExtensionContent>'
'<sts:InvoiceAuthorization/>'\ '<sts:DianExtensions>'
'</sts:InvoiceControl></sts:DianExtensions></ext:ExtensionContent></ext:UBLExtension></ext:UBLExtensions></root>' '<sts:InvoiceControl>'
'<sts:InvoiceAuthorization/>'
'</sts:InvoiceControl></sts:DianExtensions>'
'</ext:ExtensionContent></ext:UBLExtension>'
'</ext:UBLExtensions></root>')
invoiceAuthorization.text = '123456789' invoiceAuthorization.text = '123456789'
assert xml.tostring().strip() == '<root xmlns:ext="https://ext" xmlns:sts="https://sts"><ext:UBLExtensions>'\ assert xml.tostring().strip() == (
'<ext:UBLExtension>'\ '<root xmlns:ext="https://ext" xmlns:sts="https://sts">'
'<ext:ExtensionContent>'\ '<ext:UBLExtensions>'
'<sts:DianExtensions>'\ '<ext:UBLExtension>'
'<sts:InvoiceControl>'\ '<ext:ExtensionContent>'
'<sts:InvoiceAuthorization>123456789</sts:InvoiceAuthorization>'\ '<sts:DianExtensions>'
'</sts:InvoiceControl></sts:DianExtensions></ext:ExtensionContent></ext:UBLExtension></ext:UBLExtensions></root>' '<sts:InvoiceControl>'
'<sts:InvoiceAuthorization>123456789</sts:InvoiceAuthorization>'
'</sts:InvoiceControl></sts:DianExtensions>'
'</ext:ExtensionContent></ext:UBLExtension>'
'</ext:UBLExtensions></root>')
def test_facho_xmlns_idempotent(): def test_facho_xmlns_idempotent():
xml = facho.FachoXML('root', nsmap={ xml = facho.FachoXML('root', nsmap={
@@ -87,16 +100,22 @@ def test_facho_xmlns_idempotent():
}) })
xml.find_or_create_element('/root/ext:Extension/sts:Sotoros') xml.find_or_create_element('/root/ext:Extension/sts:Sotoros')
assert xml.tostring() == '<root xmlns:ext="https://ext" xmlns:sts="https://sts"><ext:Extension><sts:Sotoros/></ext:Extension></root>' assert xml.tostring() == (
'<root xmlns:ext="https://ext" xmlns:sts="https://sts">'
'<ext:Extension><sts:Sotoros/></ext:Extension></root>')
xml.find_or_create_element('/root/ext:Extension/sts:Sotoros') xml.find_or_create_element('/root/ext:Extension/sts:Sotoros')
assert xml.tostring() == '<root xmlns:ext="https://ext" xmlns:sts="https://sts"><ext:Extension><sts:Sotoros/></ext:Extension></root>' assert xml.tostring() == (
'<root xmlns:ext="https://ext" xmlns:sts="https://sts">'
'<ext:Extension><sts:Sotoros/></ext:Extension></root>')
def test_facho_xml_set_element_with_format(): def test_facho_xml_set_element_with_format():
xml = facho.FachoXML('root') xml = facho.FachoXML('root')
invoice = xml.set_element('/root/Invoice', 1, format_='%02d') xml.set_element('/root/Invoice', 1, format_='%02d')
assert xml.tostring() == '<root><Invoice>01</Invoice></root>' assert xml.tostring() == '<root><Invoice>01</Invoice></root>'
def test_facho_xml_fragment(): def test_facho_xml_fragment():
xml = facho.FachoXML('root') xml = facho.FachoXML('root')
invoice = xml.fragment('/root/Invoice') invoice = xml.fragment('/root/Invoice')
@@ -116,7 +135,10 @@ def test_facho_xml_fragments():
line = xml.fragment('/Invoice/Line', append=True) line = xml.fragment('/Invoice/Line', append=True)
line.set_element('/Line/Id', 3) line.set_element('/Line/Id', 3)
assert xml.tostring() == '<Invoice><Line><Id>1</Id></Line><Line><Id>2</Id></Line><Line><Id>3</Id></Line></Invoice>' assert xml.tostring() == (
'<Invoice><Line><Id>1</Id></Line><Line><Id>2</Id></Line>'
'<Line><Id>3</Id></Line></Invoice>')
def test_facho_xml_nested_fragments(): def test_facho_xml_nested_fragments():
xml = facho.FachoXML('Invoice') xml = facho.FachoXML('Invoice')
@@ -128,7 +150,11 @@ def test_facho_xml_nested_fragments():
party.set_element('/Party/LastName', 'test') party.set_element('/Party/LastName', 'test')
assert xml.tostring() == '<Invoice><Party><Name>test</Name><Address><Line>line 1</Line></Address><LastName>test</LastName></Party></Invoice>' assert xml.tostring() == (
'<Invoice><Party><Name>test</Name>'
'<Address><Line>line 1</Line></Address>'
'<LastName>test</LastName></Party></Invoice>')
def test_facho_xml_get_element_text_of_fragment(): def test_facho_xml_get_element_text_of_fragment():
xml = facho.FachoXML('root') xml = facho.FachoXML('root')
@@ -137,6 +163,7 @@ def test_facho_xml_get_element_text_of_fragment():
assert invoice.get_element_text('/Invoice/Id') == '1' assert invoice.get_element_text('/Invoice/Id') == '1'
def test_facho_xml_get_element_text(): def test_facho_xml_get_element_text():
xml = facho.FachoXML('Invoice') xml = facho.FachoXML('Invoice')
xml.set_element('/Invoice/ID', 'ABC123') xml.set_element('/Invoice/ID', 'ABC123')
@@ -147,6 +174,7 @@ def test_facho_xml_get_element_text():
line.set_element('/Line/Quantity', 5) line.set_element('/Line/Quantity', 5)
assert line.get_element_text('/Line/Quantity', format_=int) == 5 assert line.get_element_text('/Line/Quantity', format_=int) == 5
def test_facho_xml_get_element_text_next_child(): def test_facho_xml_get_element_text_next_child():
xml = facho.FachoXML('Invoice') xml = facho.FachoXML('Invoice')
xml.set_element('/Invoice/ID', 'ABC123') 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' assert xml.get_element_text('/Invoice/ID') == 'ABC123'
def test_facho_xml_set_element_relative_with_namespace(): def test_facho_xml_set_element_relative_with_namespace():
xml = facho.FachoXML('{%s}Invoice' % ('http://www.dian.gov.co/contratos/facturaelectronica/v1'), xml = facho.FachoXML(
nsmap={'fe': 'http://www.dian.gov.co/contratos/facturaelectronica/v1'}) '{%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') xml.set_element('./ID', 'ABC123')
assert xml.get_element_text('/fe:Invoice/ID') == 'ABC123' assert xml.get_element_text('/fe:Invoice/ID') == 'ABC123'
def test_facho_xml_fragment_relative(): def test_facho_xml_fragment_relative():
xml = facho.FachoXML('root') xml = facho.FachoXML('root')
invoice = xml.fragment('./Invoice') invoice = xml.fragment('./Invoice')
invoice.set_element('./Id', 1) invoice.set_element('./Id', 1)
assert xml.tostring() == '<root><Invoice><Id>1</Id></Invoice></root>' assert xml.tostring() == '<root><Invoice><Id>1</Id></Invoice></root>'
def test_facho_xml_get_element_fragment_relative(): def test_facho_xml_get_element_fragment_relative():
xml = facho.FachoXML('root') xml = facho.FachoXML('root')
invoice = xml.fragment('./Invoice') invoice = xml.fragment('./Invoice')
invoice.set_element('./Id', 1) invoice.set_element('./Id', 1)
assert invoice.get_element_text('./Id') == '1' assert invoice.get_element_text('./Id') == '1'
def test_facho_xml_replacement_for(): def test_facho_xml_replacement_for():
xml = facho.FachoXML('root') xml = facho.FachoXML('root')
xml.placeholder_for('./child/type') xml.placeholder_for('./child/type')
@@ -192,37 +227,47 @@ def test_facho_xml_replacement_for():
'./child/code', 'test') './child/code', 'test')
assert xml.tostring() == '<root><child><code>test</code></child></root>' assert xml.tostring() == '<root><child><code>test</code></child></root>'
def test_facho_xml_set_element_content_invalid_validation(): def test_facho_xml_set_element_content_invalid_validation():
xml = facho.FachoXML('root') 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_validator('./Id', lambda text, attrs: text == 'mero')
xml.set_element('./Id', 'bad') xml.set_element('./Id', 'bad')
def test_facho_xml_set_element_content_valid_validation(): def test_facho_xml_set_element_content_valid_validation():
xml = facho.FachoXML('root') xml = facho.FachoXML('root')
xml.set_element_validator('./Id', lambda text, attrs: text == 'mero') xml.set_element_validator('./Id', lambda text, attrs: text == 'mero')
xml.set_element('./Id', 'mero') xml.set_element('./Id', 'mero')
def test_facho_xml_set_element_attribute_invalid_validation(): def test_facho_xml_set_element_attribute_invalid_validation():
xml = facho.FachoXML('root') xml = facho.FachoXML('root')
with pytest.raises(facho.FachoValueInvalid) as e: with pytest.raises(facho.FachoValueInvalid):
xml.set_element_validator('./Id', lambda text, attrs: attrs['code'] == 'ABC') xml.set_element_validator(
'./Id', lambda text, attrs: attrs['code'] == 'ABC')
xml.set_element('./Id', 'mero', code='CBA') xml.set_element('./Id', 'mero', code='CBA')
def test_facho_xml_set_element_attribute_valid_validation(): def test_facho_xml_set_element_attribute_valid_validation():
xml = facho.FachoXML('root') xml = facho.FachoXML('root')
xml.set_element_validator('./Id', lambda text, attrs: attrs['code'] == 'ABC') xml.set_element_validator(
'./Id',
lambda text,
attrs: attrs['code'] == 'ABC')
xml.set_element('./Id', 'mero', code='ABC') xml.set_element('./Id', 'mero', code='ABC')
def test_facho_xml_get_element_attribute(): def test_facho_xml_get_element_attribute():
xml = facho.FachoXML('root') 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' assert xml.get_element_attribute('/root/Id', 'code') == 'ABC'
def test_facho_xml_keep_orden_slibing(): def test_facho_xml_keep_orden_slibing():
xml = facho.FachoXML('root') xml = facho.FachoXML('root')
xml.find_or_create_element('./A') xml.find_or_create_element('./A')
@@ -233,6 +278,7 @@ def test_facho_xml_keep_orden_slibing():
assert xml.tostring() == '<root><A/><A/><B/><B/><C/></root>' assert xml.tostring() == '<root><A/><A/><B/><B/><C/></root>'
def test_facho_xml_placeholder_optional(): def test_facho_xml_placeholder_optional():
xml = facho.FachoXML('root') xml = facho.FachoXML('root')
xml.placeholder_for('./A') xml.placeholder_for('./A')
@@ -241,6 +287,7 @@ def test_facho_xml_placeholder_optional():
assert xml.tostring() == '<root><A/><C/></root>' assert xml.tostring() == '<root><A/><C/></root>'
def test_facho_xml_placeholder_append_to_optional(): def test_facho_xml_placeholder_append_to_optional():
xml = facho.FachoXML('root') xml = facho.FachoXML('root')
xml.placeholder_for('./A') xml.placeholder_for('./A')
@@ -250,6 +297,7 @@ def test_facho_xml_placeholder_append_to_optional():
xml.find_or_create_element('./B') xml.find_or_create_element('./B')
assert xml.tostring() == '<root><A/><B/><C/></root>' assert xml.tostring() == '<root><A/><B/><C/></root>'
def test_facho_xml_placeholder_set_element_to_optional(): def test_facho_xml_placeholder_set_element_to_optional():
xml = facho.FachoXML('root') xml = facho.FachoXML('root')
xml.placeholder_for('./A') xml.placeholder_for('./A')
@@ -259,6 +307,7 @@ def test_facho_xml_placeholder_set_element_to_optional():
xml.set_element('./B', '2') xml.set_element('./B', '2')
assert xml.tostring() == '<root><A/><B>2</B><C/></root>' assert xml.tostring() == '<root><A/><B>2</B><C/></root>'
def test_facho_xml_placeholder_set_element_to_optional_with_append(): def test_facho_xml_placeholder_set_element_to_optional_with_append():
xml = facho.FachoXML('root') xml = facho.FachoXML('root')
xml.placeholder_for('./A') xml.placeholder_for('./A')
@@ -294,6 +343,7 @@ def test_facho_xml_set_attributes_not_set_optional():
xml.get_element_attribute('/root/A', 'value1') xml.get_element_attribute('/root/A', 'value1')
assert xml.get_element_attribute('/root/A', 'value2') == '2' assert xml.get_element_attribute('/root/A', 'value2') == '2'
def test_facho_xml_placeholder_with_fragment(): def test_facho_xml_placeholder_with_fragment():
xml = facho.FachoXML('root') xml = facho.FachoXML('root')
xml.placeholder_for('./A') xml.placeholder_for('./A')
@@ -306,7 +356,9 @@ def test_facho_xml_placeholder_with_fragment():
AA = xml.fragment('./AA/Child', append=True) AA = xml.fragment('./AA/Child', append=True)
assert xml.tostring() == '<root><A/><AA><Child><B/><B/></Child><Child/></AA><AAA/></root>' assert xml.tostring() == (
'<root><A/><AA><Child><B/><B/></Child><Child/></AA><AAA/></root>')
def test_facho_xml_create_on_first_append(): def test_facho_xml_create_on_first_append():
xml = facho.FachoXML('root') xml = facho.FachoXML('root')
@@ -314,6 +366,7 @@ def test_facho_xml_create_on_first_append():
xml.find_or_create_element('./A', append=True) xml.find_or_create_element('./A', append=True)
assert xml.tostring() == '<root><A/></root>' assert xml.tostring() == '<root><A/></root>'
def test_facho_xml_create_on_first_append_multiple_appends(): def test_facho_xml_create_on_first_append_multiple_appends():
xml = facho.FachoXML('root') 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) xml.find_or_create_element('./C', append=True)
assert xml.tostring() == '<root><B/><A/><A/><A/><C/></root>' assert xml.tostring() == '<root><B/><A/><A/><A/><C/></root>'
def test_facho_xml_fragment_create_on_first_append(): def test_facho_xml_fragment_create_on_first_append():
xml = facho.FachoXML('root') xml = facho.FachoXML('root')
@@ -333,6 +387,7 @@ def test_facho_xml_fragment_create_on_first_append():
A.find_or_create_element('./C') A.find_or_create_element('./C')
assert xml.tostring() == '<root><A><B/></A><A><C/></A></root>' assert xml.tostring() == '<root><A><B/></A><A><C/></A></root>'
def test_facho_xml_placeholder_optional_and_fragment(): def test_facho_xml_placeholder_optional_and_fragment():
xml = facho.FachoXML('root') xml = facho.FachoXML('root')
@@ -346,6 +401,7 @@ def test_facho_xml_placeholder_optional_and_fragment():
assert xml.tostring() == '<root><A><AA><B/><C/></AA></A></root>' assert xml.tostring() == '<root><A><AA><B/><C/></AA></A></root>'
def test_facho_xml_placeholder_optional_and_set_attributes(): def test_facho_xml_placeholder_optional_and_set_attributes():
xml = facho.FachoXML('root') xml = facho.FachoXML('root')
xml.placeholder_for('./A') 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.get_element_attribute('/root/A', 'prueba') == 'OK'
assert xml.tostring() == '<root><A prueba="OK"/></root>' assert xml.tostring() == '<root><A prueba="OK"/></root>'
def test_facho_xml_placeholder_optional_and_fragment_with_set_element(): def test_facho_xml_placeholder_optional_and_fragment_with_set_element():
xml = facho.FachoXML('root') xml = facho.FachoXML('root')
@@ -365,17 +422,19 @@ def test_facho_xml_placeholder_optional_and_fragment_with_set_element():
assert xml.tostring() == '<root><A><AA prueba="OK"/></A></root>' assert xml.tostring() == '<root><A><AA prueba="OK"/></A></root>'
assert xml.get_element_attribute('/root/A/AA', 'prueba') == 'OK' assert xml.get_element_attribute('/root/A/AA', 'prueba') == 'OK'
def test_facho_xml_exist_element(): def test_facho_xml_exist_element():
xml = facho.FachoXML('root') xml = facho.FachoXML('root')
xml.placeholder_for('./A') xml.placeholder_for('./A')
assert xml.exist_element('/root/A') == False assert xml.exist_element('/root/A') is False
assert xml.tostring() == '<root><A/></root>' assert xml.tostring() == '<root><A/></root>'
xml.find_or_create_element('./A') xml.find_or_create_element('./A')
assert xml.exist_element('/root/A') == True assert xml.exist_element('/root/A')
assert xml.tostring() == '<root><A/></root>' assert xml.tostring() == '<root><A/></root>'
def test_facho_xml_query_element_text_or_attribute(): def test_facho_xml_query_element_text_or_attribute():
xml = facho.FachoXML('root') 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') == 'contenido'
assert xml.get_element_text_or_attribute('/root/A/@clave') == 'valor' assert xml.get_element_text_or_attribute('/root/A/@clave') == 'valor'
def test_facho_xml_query_element_text_or_attribute_from_fragment(): def test_facho_xml_query_element_text_or_attribute_from_fragment():
xml = facho.FachoXML('root') 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' assert invoice.get_element_text_or_attribute('/Invoice/A') == 'contenido'
def test_facho_xml_build_xml_absolute(): def test_facho_xml_build_xml_absolute():
xml = facho.FachoXML('root') xml = facho.FachoXML('root')
@@ -400,18 +461,23 @@ def test_facho_xml_build_xml_absolute():
def test_facho_xml_build_xml_absolute_namespace(): def test_facho_xml_build_xml_absolute_namespace():
xml = facho.FachoXML('{%s}root' % ('http://www.dian.gov.co/contratos/facturaelectronica/v1'), xml = facho.FachoXML(
nsmap={'fe': 'http://www.dian.gov.co/contratos/facturaelectronica/v1'}) '{%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') xpath = xml.xpath_from_root('/A')
assert xpath == '/fe:root/A' assert xpath == '/fe:root/A'
def test_facho_xml_build_xml_absolute_namespace_from_fragment(): def test_facho_xml_build_xml_absolute_namespace_from_fragment():
xml = facho.FachoXML('{%s}root' % ('http://www.dian.gov.co/contratos/facturaelectronica/v1'), xml = facho.FachoXML(
nsmap={'fe': 'http://www.dian.gov.co/contratos/facturaelectronica/v1'}) '{%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') invoice = xml.fragment('/root/Invoice')
xpath = invoice.xpath_from_root('/A') xpath = invoice.xpath_from_root('/A')
assert xpath == '/fe:root/Invoice/A' assert xpath == '/fe:root/Invoice/A'

View File

@@ -4,16 +4,14 @@
# this repository contains the full copyright notices and license terms. # this repository contains the full copyright notices and license terms.
from datetime import datetime from datetime import datetime
import pytest
from facho import fe from facho import fe
import helpers
def test_xmlsigned_build(monkeypatch): 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 req -x509 -sha256 -nodes -subj "/CN=test" -days 1
# openssl pkcs12 -export -out example.p12 -inkey example.key -in example.pem # -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') signer = fe.DianXMLExtensionSigner('./tests/example.p12')
xml = fe.FeXML('Invoice', xml = fe.FeXML('Invoice',
@@ -21,68 +19,90 @@ def test_xmlsigned_build(monkeypatch):
signer.sign_xml_element(xml.root) 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 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): 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 req -x509 -sha256 -nodes -subj "/CN=test" -days 1
#openssl pkcs12 -export -out example.p12 -inkey example.key -in example.pem # -newkey rsa:2048 -keyout example.key -out example.pem
signer = fe.DianXMLExtensionSigner('./tests/example-with-passphrase.p12', 'test') # 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', xml = fe.FeXML('Invoice',
'http://www.dian.gov.co/contratos/facturaelectronica/v1') 'http://www.dian.gov.co/contratos/facturaelectronica/v1')
signer.sign_xml_element(xml.root) 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 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(): 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', xml = fe.FeXML('Invoice',
'http://www.dian.gov.co/contratos/facturaelectronica/v1') 'http://www.dian.gov.co/contratos/facturaelectronica/v1')
xml.add_extension(security_code) 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 assert content is not None
def test_dian_extension_invoice_authorization(): def test_dian_extension_invoice_authorization():
invoice_authorization = '18762002346472' invoice_authorization = '18762002346472'
inv_auth_ext = fe.DianXMLExtensionInvoiceAuthorization(invoice_authorization, inv_auth_ext = fe.DianXMLExtensionInvoiceAuthorization(
datetime(2017, 2, 23), invoice_authorization, datetime(
datetime(2019, 8, 23), 2017, 2, 23), datetime(
'MD', 100001, 174999) 2019, 8, 23), 'MD', 100001, 174999)
xml = fe.FeXML('Invoice', xml = fe.FeXML('Invoice',
'http://www.dian.gov.co/contratos/facturaelectronica/v1') 'http://www.dian.gov.co/contratos/facturaelectronica/v1')
xml.add_extension(inv_auth_ext) 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 assert auth == invoice_authorization
def test_dian_extension_software_provider(): def test_dian_extension_software_provider():
nit = '123456789' nit = '123456789'
id_software = 'ABCDASDF123' id_software = 'ABCDASDF123'
software_provider_extension = fe.DianXMLExtensionSoftwareProvider(nit, '', id_software) software_provider_extension = fe.DianXMLExtensionSoftwareProvider(
nit, '', id_software)
xml = fe.FeXML('Invoice', xml = fe.FeXML('Invoice',
'http://www.dian.gov.co/contratos/facturaelectronica/v1') 'http://www.dian.gov.co/contratos/facturaelectronica/v1')
xml.add_extension(software_provider_extension) 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 assert nit == give_nit
def test_dian_extension_authorization_provider(): def test_dian_extension_authorization_provider():
auth_provider_extension = fe.DianXMLExtensionAuthorizationProvider() auth_provider_extension = fe.DianXMLExtensionAuthorizationProvider()
xml = fe.FeXML('Invoice', xml = fe.FeXML('Invoice',
'http://www.dian.gov.co/contratos/facturaelectronica/v1') 'http://www.dian.gov.co/contratos/facturaelectronica/v1')
xml.add_extension(auth_provider_extension) 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' assert dian_nit == '800197268'
def test_dian_invoice_without_namespace_in_root(): def test_dian_invoice_without_namespace_in_root():
xml = fe.FeXML('Invoice', xml = fe.FeXML('Invoice',
'http://www.dian.gov.co/contratos/facturaelectronica/v1') 'http://www.dian.gov.co/contratos/facturaelectronica/v1')
@@ -93,9 +113,13 @@ def test_dian_invoice_without_namespace_in_root():
def test_xml_sign_dian(monkeypatch): def test_xml_sign_dian(monkeypatch):
xml = fe.FeXML('Invoice', xml = fe.FeXML('Invoice',
'http://www.dian.gov.co/contratos/facturaelectronica/v1') 'http://www.dian.gov.co/contratos/facturaelectronica/v1')
xml.find_or_create_element('/fe:Invoice/ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent') xml.find_or_create_element(
ublextension = xml.fragment('/fe:Invoice/ext:UBLExtensions/ext:UBLExtension', append=True) '/fe:Invoice/ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent')
extcontent = ublextension.find_or_create_element('/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() xmlstring = xml.tostring()
print(xmlstring) print(xmlstring)
@@ -103,12 +127,17 @@ def test_xml_sign_dian(monkeypatch):
xmlsigned = signer.sign_xml_string(xmlstring) xmlsigned = signer.sign_xml_string(xmlstring)
assert "Signature" in xmlsigned assert "Signature" in xmlsigned
def test_xml_sign_dian_using_bytes(monkeypatch): def test_xml_sign_dian_using_bytes(monkeypatch):
xml = fe.FeXML('Invoice', xml = fe.FeXML('Invoice',
'http://www.dian.gov.co/contratos/facturaelectronica/v1') 'http://www.dian.gov.co/contratos/facturaelectronica/v1')
xml.find_or_create_element('/fe:Invoice/ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent') xml.find_or_create_element(
ublextension = xml.fragment('/fe:Invoice/ext:UBLExtensions/ext:UBLExtension', append=True) '/fe:Invoice/ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent')
extcontent = ublextension.find_or_create_element('/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() xmlstring = xml.tostring()
p12_data = open('./tests/example.p12', 'rb').read() 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) xmlsigned = signer.sign_xml_string(xmlstring)
assert "Signature" in xmlsigned assert "Signature" in xmlsigned
def test_xml_signature_timestamp(monkeypatch): def test_xml_signature_timestamp(monkeypatch):
xml = fe.FeXML( xml = fe.FeXML(
'Invoice', 'Invoice',

View File

@@ -41,11 +41,13 @@ def test_invoicesimple_build(simple_invoice):
xml = DIANInvoiceXML(simple_invoice) xml = DIANInvoiceXML(simple_invoice)
supplier_name = xml.get_element_text( 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 assert supplier_name == simple_invoice.invoice_supplier.name
customer_name = xml.get_element_text( 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 assert customer_name == simple_invoice.invoice_customer.name
@@ -66,7 +68,8 @@ def test_invoicesimple_xml_signed(monkeypatch, simple_invoice):
xml.add_extension(signer) xml.add_extension(signer)
elem = xml.get_element( 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 assert elem.text is not None
@@ -75,14 +78,16 @@ def test_invoicesimple_zip(simple_invoice):
zipdata = io.BytesIO() zipdata = io.BytesIO()
with fe.DianZIP(zipdata) as dianzip: 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 # el zip ademas de archivar debe comprimir los archivos
# de lo contrario la DIAN lo rechaza # de lo contrario la DIAN lo rechaza
with zipfile.ZipFile(zipdata) as dianzip: with zipfile.ZipFile(zipdata) as dianzip:
dianzip.testzip() dianzip.testzip()
for zipinfo in dianzip.infolist(): 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: with zipfile.ZipFile(zipdata) as dianzip:
xml_data = dianzip.open(name_invoice).read().decode('utf-8') 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): def test_invoice_totals(simple_invoice_without_lines):
simple_invoice = simple_invoice_without_lines simple_invoice = simple_invoice_without_lines
simple_invoice.invoice_ident = '323200000129' 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_supplier.ident = '700085371'
simple_invoice.invoice_customer.ident = '800199436' simple_invoice.invoice_customer.ident = '800199436'
simple_invoice.add_invoice_line(form.InvoiceLine( simple_invoice.add_invoice_line(form.InvoiceLine(
@@ -222,7 +228,8 @@ def test_invoice_cufe(simple_invoice_without_lines):
assert formatVars[12] == '800199436', "NumAdq" assert formatVars[12] == '800199436', "NumAdq"
# ClTec # ClTec
assert formatVars[13] == '693ff6f2a553c3646a063436fd4dd9ded0311471', "ClTec" assert formatVars[13] == (
'693ff6f2a553c3646a063436fd4dd9ded0311471'), "ClTec"
# TipoAmbiente # TipoAmbiente
assert formatVars[14] == '1', "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 assert build_vars['TipoAmb'] == 2
cude_composicion = "".join(cude_extension.formatVars()) 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) xml_invoice.add_extension(cude_extension)
cude = xml_invoice.get_element_text('/fe:DebitNote/cbc:UUID') cude = xml_invoice.get_element_text('/fe:DebitNote/cbc:UUID')
assert cude == '3fa73a86d57d9341c536afde1f85c4efd9d4591c2c22bce4dfb0e6b0d2e83b8f047a8bde7098292e9d2493e60d1c31da' assert cude == (
'3fa73a86d57d9341c536afde1f85c4efd9d4591c2c22bce4dfb0e6b0d2e83b8f047a8'
'bde7098292e9d2493e60d1c31da')

View File

@@ -121,7 +121,9 @@ def test_FAU14():
wants = form.Amount(119.0 + 19.0 - 50.0) 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(): def test_invalid_tipo_operacion_nota_debito():

View File

@@ -6,10 +6,7 @@
"""Tests for `facho` package.""" """Tests for `facho` package."""
import pytest import pytest
# from datetime import datetime
import copy
from facho.fe import form
from facho.fe import form_xml from facho.fe import form_xml
# from fixtures import * # from fixtures import *

View File

@@ -28,8 +28,12 @@
# )) # ))
# xml = nomina.toFachoXML() # xml = nomina.toFachoXML()
# assert xml.get_element_attribute('/nomina:NominaIndividual/Devengados/Basico', 'DiasTrabajados') == '30' # assert
# assert xml.get_element_attribute('/nomina:NominaIndividual/Devengados/Basico', 'SueldoTrabajado') == '1000000.00' # 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(): # def test_adicionar_devengado_transporte():
# nomina = fe.nomina.DIANNominaIndividual() # nomina = fe.nomina.DIANNominaIndividual()
@@ -40,7 +44,9 @@
# xml = nomina.toFachoXML() # 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(): # def test_adicionar_devengado_comprobante_total():
# nomina = fe.nomina.DIANNominaIndividual() # nomina = fe.nomina.DIANNominaIndividual()
@@ -58,7 +64,9 @@
# xml = nomina.toFachoXML() # 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(): # def test_adicionar_devengado_comprobante_total_cero():
# nomina = fe.nomina.DIANNominaIndividual() # nomina = fe.nomina.DIANNominaIndividual()
@@ -75,7 +83,8 @@
# xml = nomina.toFachoXML() # 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(): # def test_adicionar_devengado_transporte_muchos():
# nomina = fe.nomina.DIANNominaIndividual() # nomina = fe.nomina.DIANNominaIndividual()
@@ -90,7 +99,8 @@
# xml = nomina.toFachoXML() # xml = nomina.toFachoXML()
# print(xml) # 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(): # def test_adicionar_deduccion_salud():
# nomina = fe.nomina.DIANNominaIndividual() # nomina = fe.nomina.DIANNominaIndividual()
@@ -107,7 +117,9 @@
# xml = nomina.toFachoXML() # xml = nomina.toFachoXML()
# print(xml) # 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(): # def test_nomina_obligatorios_segun_anexo_tecnico():
# nomina = fe.nomina.DIANNominaIndividual() # nomina = fe.nomina.DIANNominaIndividual()
@@ -213,26 +225,62 @@
# )) # ))
# xml = nomina.toFachoXML() # xml = nomina.toFachoXML()
# expected_cune = 'b8f9b6c24de07ffd92ea5467433a3b69357cfaffa7c19722db94b2e0eca41d057085a54f484b5da15ff585e773b0b0ab' # expected_cune =
# assert xml.get_element_attribute('/nomina:NominaIndividual/InformacionGeneral', 'CUNE') == expected_cune # 'b8f9b6c24de07ffd92ea5467433a3b69357cfaffa7c19722db94b2e0eca41d057085a54f484
# assert xml.get_element_attribute('/nomina:NominaIndividual/InformacionGeneral', 'TipoXML') == '102' # b5da15ff585e773b0b0ab'
# assert xml.get_element_text_or_attribute('/nomina:NominaIndividual/NumeroSecuenciaXML/@Numero') == 'N00001' # assert
# assert xml.get_element_text_or_attribute('/nomina:NominaIndividual/NumeroSecuenciaXML/@Consecutivo') == '00001' # xml.get_element_attribute('/nomina:NominaIndividual/InformacionGeneral',
# assert xml.get_element_text_or_attribute('/nomina:NominaIndividual/LugarGeneracionXML/@Pais') == 'CO' # 'CUNE') == expected_cune
# assert xml.get_element_text_or_attribute('/nomina:NominaIndividual/LugarGeneracionXML/@DepartamentoEstado') == '05' # assert
# assert xml.get_element_text_or_attribute('/nomina:NominaIndividual/LugarGeneracionXML/@MunicipioCiudad') == '05001' # xml.get_element_attribute('/nomina:NominaIndividual/InformacionGeneral',
# assert xml.get_element_text_or_attribute('/nomina:NominaIndividual/ProveedorXML/@NIT') == '999999' # 'TipoXML') == '102'
# assert xml.get_element_text_or_attribute('/nomina:NominaIndividual/ProveedorXML/@DV') == '2' # assert
# assert xml.get_element_text_or_attribute('/nomina:NominaIndividual/ProveedorXML/@SoftwareID') == 'xx' # xml.get_element_text_or_attribute('/nomina:NominaIndividual/NumeroSecuenciaX
# assert xml.get_element_text_or_attribute('/nomina:NominaIndividual/ProveedorXML/@SoftwareSC') is not None # ML/@Numero') == 'N00001'
# assert xml.get_element_text_or_attribute('/nomina:NominaIndividual/CodigoQR') == f"https://catalogo-vpfe.dian.gov.co/document/searchqr?documentkey={expected_cune}" # assert
# assert xml.get_element_text_or_attribute('/nomina:NominaIndividual/Empleador/@NIT') == '700085371' # xml.get_element_text_or_attribute('/nomina:NominaIndividual/NumeroSecuenciaX
# assert xml.get_element_text_or_attribute('/nomina:NominaIndividual/Trabajador/@NumeroDocumento') == '800199436' # ML/@Consecutivo') == '00001'
# assert xml.get_element_text_or_attribute('/nomina:NominaIndividual/Novedad') == 'True' # assert
# assert xml.get_element_text_or_attribute('/nomina:NominaIndividual/Novedad/@CUNENov') == 'N0111' # 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 # # 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(): # def test_asignar_pago():
# nomina = fe.nomina.DIANNominaIndividual() # nomina = fe.nomina.DIANNominaIndividual()
@@ -249,11 +297,11 @@
# xml.add_extension(signer) # xml.add_extension(signer)
# print(xml.tostring()) # 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 # assert elem is not None
# def test_nomina_devengado_horas_extras_nocturnas(): # def test_nomina_devengado_horas_extras_nocturnas():
# nomina = fe.nomina.DIANNominaIndividual() # nomina = fe.nomina.DIANNominaIndividual()
@@ -277,7 +325,9 @@
# )) # ))
# xml = nomina.toFachoXML() # 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('HoraInicio') == '2021-11-30T19:09:55'
# assert extras[0].get('HoraFin') == '2021-11-30T20:09:55' # assert extras[0].get('HoraFin') == '2021-11-30T20:09:55'
# assert extras[0].get('Cantidad') == '1' # assert extras[0].get('Cantidad') == '1'
@@ -312,7 +362,9 @@
# )) # ))
# xml = nomina.toFachoXML() # 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('HoraInicio') == '2021-11-30T19:09:55'
# assert extras[0].get('HoraFin') == '2021-11-30T20:09:55' # assert extras[0].get('HoraFin') == '2021-11-30T20:09:55'
# assert extras[0].get('Cantidad') == '1' # assert extras[0].get('Cantidad') == '1'
@@ -327,7 +379,9 @@
# def test_nomina_devengado_horas_extras_diarias_dominicales_y_festivos(): # def test_nomina_devengado_horas_extras_diarias_dominicales_y_festivos():
# nomina = fe.nomina.DIANNominaIndividual() # nomina = fe.nomina.DIANNominaIndividual()
# nomina.adicionar_devengado(fe.nomina.DevengadoHorasExtrasDiariasDominicalesYFestivos( #
# nomina.adicionar_devengado(fe.nomina.DevengadoHorasExtrasDiariasDominicalesY
# Festivos(
# horas_extras=[ # horas_extras=[
# fe.nomina.DevengadoHoraExtra( # fe.nomina.DevengadoHoraExtra(
# hora_inicio='2021-11-30T19:09:55', # hora_inicio='2021-11-30T19:09:55',
@@ -347,7 +401,9 @@
# )) # ))
# xml = nomina.toFachoXML() # 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('HoraInicio') == '2021-11-30T19:09:55'
# assert extras[0].get('HoraFin') == '2021-11-30T20:09:55' # assert extras[0].get('HoraFin') == '2021-11-30T20:09:55'
# assert extras[0].get('Cantidad') == '1' # assert extras[0].get('Cantidad') == '1'
@@ -362,7 +418,9 @@
# def test_nomina_devengado_horas_recargo_diarias_dominicales_y_festivos(): # def test_nomina_devengado_horas_recargo_diarias_dominicales_y_festivos():
# nomina = fe.nomina.DIANNominaIndividual() # nomina = fe.nomina.DIANNominaIndividual()
# nomina.adicionar_devengado(fe.nomina.DevengadoHorasRecargoDiariasDominicalesYFestivos( #
# nomina.adicionar_devengado(fe.nomina.DevengadoHorasRecargoDiariasDominicales
# YFestivos(
# horas_extras=[ # horas_extras=[
# fe.nomina.DevengadoHoraExtra( # fe.nomina.DevengadoHoraExtra(
# hora_inicio='2021-11-30T19:09:55', # hora_inicio='2021-11-30T19:09:55',
@@ -382,7 +440,9 @@
# )) # ))
# xml = nomina.toFachoXML() # 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('HoraInicio') == '2021-11-30T19:09:55'
# assert extras[0].get('HoraFin') == '2021-11-30T20:09:55' # assert extras[0].get('HoraFin') == '2021-11-30T20:09:55'
# assert extras[0].get('Cantidad') == '1' # assert extras[0].get('Cantidad') == '1'
@@ -398,7 +458,9 @@
# def test_nomina_devengado_horas_extras_nocturnas_dominicales_y_festivos(): # def test_nomina_devengado_horas_extras_nocturnas_dominicales_y_festivos():
# nomina = fe.nomina.DIANNominaIndividual() # nomina = fe.nomina.DIANNominaIndividual()
# nomina.adicionar_devengado(fe.nomina.DevengadoHorasExtrasNocturnasDominicalesYFestivos( #
# nomina.adicionar_devengado(fe.nomina.DevengadoHorasExtrasNocturnasDominicale
# sYFestivos(
# horas_extras=[ # horas_extras=[
# fe.nomina.DevengadoHoraExtra( # fe.nomina.DevengadoHoraExtra(
# hora_inicio='2021-11-30T19:09:55', # hora_inicio='2021-11-30T19:09:55',
@@ -418,7 +480,9 @@
# )) # ))
# xml = nomina.toFachoXML() # 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('HoraInicio') == '2021-11-30T19:09:55'
# assert extras[0].get('HoraFin') == '2021-11-30T20:09:55' # assert extras[0].get('HoraFin') == '2021-11-30T20:09:55'
# assert extras[0].get('Cantidad') == '1' # assert extras[0].get('Cantidad') == '1'
@@ -433,7 +497,9 @@
# def test_nomina_devengado_horas_recargo_nocturno_dominicales_y_festivos(): # def test_nomina_devengado_horas_recargo_nocturno_dominicales_y_festivos():
# nomina = fe.nomina.DIANNominaIndividual() # nomina = fe.nomina.DIANNominaIndividual()
# nomina.adicionar_devengado(fe.nomina.DevengadoHorasRecargoNocturnoDominicalesYFestivos( #
# nomina.adicionar_devengado(fe.nomina.DevengadoHorasRecargoNocturnoDominicale
# sYFestivos(
# horas_extras=[ # horas_extras=[
# fe.nomina.DevengadoHoraExtra( # fe.nomina.DevengadoHoraExtra(
# hora_inicio='2021-11-30T19:09:55', # hora_inicio='2021-11-30T19:09:55',
@@ -453,7 +519,9 @@
# )) # ))
# xml = nomina.toFachoXML() # 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('HoraInicio') == '2021-11-30T19:09:55'
# assert extras[0].get('HoraFin') == '2021-11-30T20:09:55' # assert extras[0].get('HoraFin') == '2021-11-30T20:09:55'
# assert extras[0].get('Cantidad') == '1' # assert extras[0].get('Cantidad') == '1'

View File

@@ -101,7 +101,9 @@
# xml = nomina.toFachoXML() # 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(): # def test_adicionar_reemplazar_devengado_comprobante_total():
@@ -119,13 +121,17 @@
# xml = nomina.toFachoXML() # 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(): # def test_adicionar_reemplazar_asignar_predecesor():
# nomina = fe.nomina.DIANNominaIndividualDeAjuste.Reemplazar() # nomina = fe.nomina.DIANNominaIndividualDeAjuste.Reemplazar()
# nomina.asignar_predecesor(fe.nomina.DIANNominaIndividualDeAjuste.Reemplazar.Predecesor( #
# nomina.asignar_predecesor(fe.nomina.DIANNominaIndividualDeAjuste.Reemplazar.
# Predecesor(
# numero = '123456', # numero = '123456',
# cune = 'ABC123456', # cune = 'ABC123456',
# fecha_generacion = '2021-11-16' # fecha_generacion = '2021-11-16'
@@ -133,15 +139,23 @@
# xml = nomina.toFachoXML() # xml = nomina.toFachoXML()
# print(xml.tostring()) # print(xml.tostring())
# assert xml.get_element_text_or_attribute('/nominaajuste:NominaIndividualDeAjuste/Reemplazar/ReemplazandoPredecesor/@NumeroPred') == '123456' # assert
# assert xml.get_element_text_or_attribute('/nominaajuste:NominaIndividualDeAjuste/Reemplazar/ReemplazandoPredecesor/@CUNEPred') == 'ABC123456' # xml.get_element_text_or_attribute('/nominaajuste:NominaIndividualDeAjuste/Re
# assert xml.get_element_text_or_attribute('/nominaajuste:NominaIndividualDeAjuste/Reemplazar/ReemplazandoPredecesor/@FechaGenPred') == '2021-11-16' # 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(): # def test_adicionar_reemplazar_eliminar_predecesor_opcional():
# nomina = fe.nomina.DIANNominaIndividualDeAjuste.Reemplazar() # nomina = fe.nomina.DIANNominaIndividualDeAjuste.Reemplazar()
# nomina.asignar_predecesor(fe.nomina.DIANNominaIndividualDeAjuste.Reemplazar.Predecesor( #
# nomina.asignar_predecesor(fe.nomina.DIANNominaIndividualDeAjuste.Reemplazar.
# Predecesor(
# numero = '123456', # numero = '123456',
# cune = 'ABC123456', # cune = 'ABC123456',
# fecha_generacion = '2021-11-16' # fecha_generacion = '2021-11-16'
@@ -150,13 +164,19 @@
# xml = nomina.toFachoXML() # xml = nomina.toFachoXML()
# print(xml.tostring()) # print(xml.tostring())
# assert xml.get_element('/nominaajuste:NominaIndividualDeAjuste/Reemplazar/ReemplazandoPredecesor') is not None # assert
# assert xml.get_element('/nominaajuste:NominaIndividualDeAjuste/Eliminar/EliminandoPredecesor') is None # 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(): # def test_adicionar_eliminar_reemplazar_predecesor_opcional():
# nomina = fe.nomina.DIANNominaIndividualDeAjuste.Eliminar() # nomina = fe.nomina.DIANNominaIndividualDeAjuste.Eliminar()
# nomina.asignar_predecesor(fe.nomina.DIANNominaIndividualDeAjuste.Eliminar.Predecesor( #
# nomina.asignar_predecesor(fe.nomina.DIANNominaIndividualDeAjuste.Eliminar.Pr
# edecesor(
# numero = '123456', # numero = '123456',
# cune = 'ABC123456', # cune = 'ABC123456',
# fecha_generacion = '2021-11-16' # fecha_generacion = '2021-11-16'
@@ -164,8 +184,12 @@
# xml = nomina.toFachoXML() # xml = nomina.toFachoXML()
# print(xml.tostring()) # print(xml.tostring())
# assert xml.get_element('/nominaajuste:NominaIndividualDeAjuste/Eliminar/EliminandoPredecesor') is not None # assert
# assert xml.get_element('/nominaajuste:NominaIndividualDeAjuste/Reemplazar/ReemplazandoPredecesor') is None # 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(): # def test_adicionar_eliminar_devengado_comprobante_total():
# nomina = fe.nomina.DIANNominaIndividualDeAjuste.Eliminar() # nomina = fe.nomina.DIANNominaIndividualDeAjuste.Eliminar()
@@ -182,12 +206,16 @@
# xml = nomina.toFachoXML() # 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(): # def test_adicionar_eliminar_asignar_predecesor():
# nomina = fe.nomina.DIANNominaIndividualDeAjuste.Eliminar() # nomina = fe.nomina.DIANNominaIndividualDeAjuste.Eliminar()
# nomina.asignar_predecesor(fe.nomina.DIANNominaIndividualDeAjuste.Eliminar.Predecesor( #
# nomina.asignar_predecesor(fe.nomina.DIANNominaIndividualDeAjuste.Eliminar.Pr
# edecesor(
# numero = '123456', # numero = '123456',
# cune = 'ABC123456', # cune = 'ABC123456',
# fecha_generacion = '2021-11-16' # fecha_generacion = '2021-11-16'
@@ -195,9 +223,15 @@
# xml = nomina.toFachoXML() # xml = nomina.toFachoXML()
# print(xml.tostring()) # print(xml.tostring())
# assert xml.get_element_text_or_attribute('/nominaajuste:NominaIndividualDeAjuste/Eliminar/EliminandoPredecesor/@NumeroPred') == '123456' # assert
# assert xml.get_element_text_or_attribute('/nominaajuste:NominaIndividualDeAjuste/Eliminar/EliminandoPredecesor/@CUNEPred') == 'ABC123456' # xml.get_element_text_or_attribute('/nominaajuste:NominaIndividualDeAjuste/El
# assert xml.get_element_text_or_attribute('/nominaajuste:NominaIndividualDeAjuste/Eliminar/EliminandoPredecesor/@FechaGenPred') == '2021-11-16' # 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(): # def test_nomina_devengado_horas_extras_diarias():
# nomina = fe.nomina.DIANNominaIndividual() # nomina = fe.nomina.DIANNominaIndividual()