Compare commits
11 Commits
MigrationP
...
main
Author | SHA1 | Date | |
---|---|---|---|
c49e67b8a6 | |||
7672ae4b7f | |||
25c5fda3f0 | |||
a758b8678b | |||
3a385c63e3 | |||
9b33b4486c | |||
612aae1f86 | |||
4fe82daac6 | |||
e237d1b45f | |||
8cc6146be2 | |||
|
c919d8e36c |
@ -234,9 +234,10 @@ def _append_timestamp(security, expires_dt=None):
|
|||||||
if expires_dt is None:
|
if expires_dt is None:
|
||||||
expires_dt = timedelta(seconds=6000)
|
expires_dt = timedelta(seconds=6000)
|
||||||
|
|
||||||
|
timestamp = datetime.now()
|
||||||
etimestamp = utils.WSU.Timestamp({'{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Id': utils.get_unique_id()})
|
etimestamp = utils.WSU.Timestamp({'{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Id': utils.get_unique_id()})
|
||||||
etimestamp.append(utils.WSU.Created(get_timestamp()))
|
etimestamp.append(utils.WSU.Created(get_timestamp(timestamp=timestamp)))
|
||||||
etimestamp.append(utils.WSU.Expires(get_timestamp(delta=expires_dt)))
|
etimestamp.append(utils.WSU.Expires(get_timestamp(timestamp=timestamp, delta=expires_dt)))
|
||||||
security.insert(0, etimestamp)
|
security.insert(0, etimestamp)
|
||||||
if etree.LXML_VERSION[:2] >= (3, 5):
|
if etree.LXML_VERSION[:2] >= (3, 5):
|
||||||
etree.cleanup_namespaces(security,
|
etree.cleanup_namespaces(security,
|
||||||
|
@ -57,6 +57,8 @@ Bogota = tz.gettz('America/Bogota')
|
|||||||
|
|
||||||
|
|
||||||
NAMESPACES = {
|
NAMESPACES = {
|
||||||
|
'apr': 'urn:oasis:names:specification:ubl:schema:xsd:ApplicationResponse-2',
|
||||||
|
'atd': 'urn:oasis:names:specification:ubl:schema:xsd:AttachedDocument-2',
|
||||||
'fe': 'http://www.dian.gov.co/contratos/facturaelectronica/v1',
|
'fe': 'http://www.dian.gov.co/contratos/facturaelectronica/v1',
|
||||||
'cac': 'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2',
|
'cac': 'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2',
|
||||||
'cbc': 'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2',
|
'cbc': 'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2',
|
||||||
@ -106,17 +108,21 @@ class FeXML(FachoXML):
|
|||||||
|
|
||||||
def tostring(self, **kw):
|
def tostring(self, **kw):
|
||||||
# MACHETE(bit4bit) la DIAN espera que la etiqueta raiz no este en un namespace
|
# MACHETE(bit4bit) la DIAN espera que la etiqueta raiz no este en un namespace
|
||||||
|
urn_oasis = {
|
||||||
|
'AttachedDocument': 'urn:oasis:names:specification:ubl:schema:xsd:AttachedDocument-2',
|
||||||
|
'Invoice': 'urn:oasis:names:specification:ubl:schema:xsd:Invoice-2',
|
||||||
|
'CreditNote': 'urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2',
|
||||||
|
'ApplicationResponse': 'urn:oasis:names:specification:ubl:schema:xsd:ApplicationResponse-2'
|
||||||
|
}
|
||||||
|
|
||||||
root_namespace = self.root_namespace()
|
root_namespace = self.root_namespace()
|
||||||
root_localname = self.root_localname()
|
root_localname = self.root_localname()
|
||||||
xmlns_name = {v: k for k, v in NAMESPACES.items()}[root_namespace]
|
xmlns_name = {v: k for k, v in NAMESPACES.items()}[root_namespace]
|
||||||
if root_localname == 'Invoice':
|
|
||||||
urn_oasis = 'urn:oasis:names:specification:ubl:schema:xsd:Invoice-2'
|
|
||||||
if root_localname == 'CreditNote':
|
|
||||||
urn_oasis = 'urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2'
|
|
||||||
return super().tostring(**kw)\
|
return super().tostring(**kw)\
|
||||||
.replace(xmlns_name + ':', '')\
|
.replace(xmlns_name + ':', '')\
|
||||||
.replace('xmlns:'+xmlns_name, 'xmlns')\
|
.replace('xmlns:'+xmlns_name, 'xmlns')\
|
||||||
.replace(root_namespace, urn_oasis)
|
.replace(root_namespace, urn_oasis[root_localname])
|
||||||
|
|
||||||
|
|
||||||
class DianXMLExtensionCUDFE(FachoXMLExtension):
|
class DianXMLExtensionCUDFE(FachoXMLExtension):
|
||||||
|
@ -2,6 +2,7 @@ from .invoice import *
|
|||||||
from .credit_note import *
|
from .credit_note import *
|
||||||
from .debit_note import *
|
from .debit_note import *
|
||||||
from .utils import *
|
from .utils import *
|
||||||
from .attached_document import *
|
|
||||||
from .support_document import *
|
from .support_document import *
|
||||||
from .support_document_credit_note import *
|
from .support_document_credit_note import *
|
||||||
|
from .attached_document import *
|
||||||
|
from .application_response import *
|
||||||
|
177
facho/fe/form_xml/application_response.py
Normal file
177
facho/fe/form_xml/application_response.py
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
from .. import fe
|
||||||
|
|
||||||
|
__all__ = ['ApplicationResponse']
|
||||||
|
|
||||||
|
|
||||||
|
class ApplicationResponse:
|
||||||
|
|
||||||
|
def __init__(self, invoice, tag_document='ApplicationResponse'):
|
||||||
|
self.schema =\
|
||||||
|
'urn:oasis:names:specification:ubl:schema:xsd:ApplicationResponse-2'
|
||||||
|
self.tag_document = tag_document
|
||||||
|
self.invoice = invoice
|
||||||
|
self.fexml = fe.FeXML(
|
||||||
|
self.tag_document, self.schema)
|
||||||
|
self.application_response = self.application_response()
|
||||||
|
|
||||||
|
def application_response(self):
|
||||||
|
# DIAN 1.9.-2023: AE02
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cbc:UBLVersionID', 'UBL 2.1')
|
||||||
|
|
||||||
|
# DIAN 1.9.-2023: AE03
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cbc:CustomizationID', 'Documentos adjuntos')
|
||||||
|
|
||||||
|
# DIAN 1.9.-2023: AE04
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cbc:ProfileID', 'DIAN 2.1')
|
||||||
|
|
||||||
|
# DIAN 1.9.-2023: AE04a
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cbc:ProfileExecutionID', '1')
|
||||||
|
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cbc:ID', '1')
|
||||||
|
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cbc:UUID', '1', schemeName="CUDE-SHA384")
|
||||||
|
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cbc:IssueDate',
|
||||||
|
self.invoice.invoice_issue.strftime('%Y-%m-%d'))
|
||||||
|
|
||||||
|
# DIAN 1.9.-2023: AE06
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cbc:IssueTime', self.invoice.invoice_issue.strftime(
|
||||||
|
'%H:%M:%S-05:00'))
|
||||||
|
|
||||||
|
self.set_sender_party()
|
||||||
|
self.set_receiver_party()
|
||||||
|
self.set_document_response()
|
||||||
|
|
||||||
|
def set_sender_party(self):
|
||||||
|
# DIAN 1.9.-2023: AE09
|
||||||
|
self.fexml.placeholder_for(
|
||||||
|
'./cac:SenderParty')
|
||||||
|
# DIAN 1.9.-2023: AE10
|
||||||
|
self.fexml.placeholder_for(
|
||||||
|
'./cac:SenderParty/cac:PartyTaxScheme')
|
||||||
|
# DIAN 1.9.-2023: AE11
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:SenderParty/cac:PartyTaxScheme/cbc:RegistrationName',
|
||||||
|
self.invoice.invoice_supplier.name)
|
||||||
|
# DIAN 1.9.-2023: AE12
|
||||||
|
# DIAN 1.9.-2023: AE13
|
||||||
|
# DIAN 1.9.-2023: AE14
|
||||||
|
# DIAN 1.9.-2023: AE15
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:SenderParty/cac:PartyTaxScheme/cbc:CompanyID',
|
||||||
|
self.invoice.invoice_supplier.ident,
|
||||||
|
schemeAgencyID='195',
|
||||||
|
schemeID=self.invoice.invoice_supplier.ident.dv,
|
||||||
|
schemeName=self.invoice.invoice_supplier.ident.type_fiscal)
|
||||||
|
|
||||||
|
# DIAN 1.9.-2023: AE16
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:SenderParty/cac:PartyTaxScheme/cbc:TaxLevelCode',
|
||||||
|
self.invoice.invoice_supplier.responsability_code)
|
||||||
|
|
||||||
|
# DIAN 1.9.-2023: AE18
|
||||||
|
self.fexml.placeholder_for(
|
||||||
|
'./cac:SenderParty/cac:PartyTaxScheme/cac:TaxScheme')
|
||||||
|
|
||||||
|
# DIAN 1.9.-2023: AE19
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:SenderParty/cac:PartyTaxScheme/cac:TaxScheme/cbc:ID',
|
||||||
|
self.invoice.invoice_supplier.tax_scheme.code)
|
||||||
|
|
||||||
|
# DIAN 1.9.-2023: AE20
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:SenderParty/cac:PartyTaxScheme/cac:TaxScheme/cbc:Name',
|
||||||
|
self.invoice.invoice_supplier.tax_scheme.name)
|
||||||
|
|
||||||
|
def set_receiver_party(self):
|
||||||
|
# DIAN 1.9.-2023: AE21
|
||||||
|
self.fexml.placeholder_for(
|
||||||
|
'./cac:ReceiverParty')
|
||||||
|
# DIAN 1.9.-2023: AE22
|
||||||
|
self.fexml.placeholder_for(
|
||||||
|
'./cac:ReceiverParty/cac:PartyTaxScheme')
|
||||||
|
# DIAN 1.9.-2023: AE23
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:ReceiverParty/cac:PartyTaxScheme/cbc:RegistrationName',
|
||||||
|
self.invoice.invoice_customer.name)
|
||||||
|
# DIAN 1.9.-2023: AE24
|
||||||
|
# DIAN 1.9.-2023: AE25
|
||||||
|
# DIAN 1.9.-2023: AE26
|
||||||
|
# DIAN 1.9.-2023: AE27
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:ReceiverParty/cac:PartyTaxScheme/cbc:CompanyID',
|
||||||
|
self.invoice.invoice_customer.ident,
|
||||||
|
schemeAgencyID='195',
|
||||||
|
schemeID=self.invoice.invoice_customer.ident.dv,
|
||||||
|
schemeName=self.invoice.invoice_customer.ident.type_fiscal)
|
||||||
|
# DIAN 1.9.-2023: AE28
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:ReceiverParty/cac:PartyTaxScheme/cbc:TaxLevelCode',
|
||||||
|
self.invoice.invoice_customer.responsability_code)
|
||||||
|
# DIAN 1.9.-2023: AE30
|
||||||
|
self.fexml.placeholder_for(
|
||||||
|
'./cac:ReceiverParty/cac:PartyTaxScheme/cac:TaxScheme')
|
||||||
|
# DIAN 1.9.-2023: AE31
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:ReceiverParty/cac:PartyTaxScheme/cac:TaxScheme/cbc:ID',
|
||||||
|
self.invoice.invoice_customer.tax_scheme.code)
|
||||||
|
# DIAN 1.9.-2023: AE32
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:ReceiverParty/cac:PartyTaxScheme/cac:TaxScheme/cbc:Name',
|
||||||
|
self.invoice.invoice_customer.tax_scheme.name)
|
||||||
|
|
||||||
|
def set_document_response(self):
|
||||||
|
self.fexml.placeholder_for(
|
||||||
|
'./cac:DocumentResponse')
|
||||||
|
self.fexml.placeholder_for(
|
||||||
|
'./cac:DocumentResponse/cac:Response')
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:DocumentResponse/cac:Response/cbc:ResponseCode',
|
||||||
|
'02')
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:DocumentResponse/cac:Response/cbc:Description',
|
||||||
|
'Documento validado por la DIAN')
|
||||||
|
self.set_documnent_reference()
|
||||||
|
|
||||||
|
def set_documnent_reference(self):
|
||||||
|
self.fexml.placeholder_for(
|
||||||
|
'./cac:DocumentResponse/cac:DocumentReference')
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:DocumentResponse/cac:DocumentReference/cbc:ID',
|
||||||
|
'FESS19566058')
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:DocumentResponse/cac:DocumentReference/cbc:UUID',
|
||||||
|
'f51ee529aabd19d10e39444f2f593b94d56d5885fbf433faf718d53a7e968f64bf54a6ee43c6a2df842771b54a6aae1a',
|
||||||
|
schemeName="CUFE-SHA384")
|
||||||
|
self.set_response_lines()
|
||||||
|
|
||||||
|
def set_response_lines(self):
|
||||||
|
lines = [{
|
||||||
|
'LineID': '1',
|
||||||
|
'ResponseCode': '0000',
|
||||||
|
'Description': '0',
|
||||||
|
}]
|
||||||
|
|
||||||
|
for line in lines:
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:DocumentResponse/cac:LineResponse/cac:LineReference/cbc:LineID', line[
|
||||||
|
'LineID'])
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:DocumentResponse/cac:LineResponse/cac:Response/cbc:ResponseCode', line[
|
||||||
|
'ResponseCode'])
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:DocumentResponse/cac:LineResponse/cac:Response/cbc:Description', line[
|
||||||
|
'Description'])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def toFachoXML(self):
|
||||||
|
return self.fexml
|
@ -1,15 +1,227 @@
|
|||||||
from .. import fe
|
from .. import fe
|
||||||
|
from .application_response import ApplicationResponse
|
||||||
|
|
||||||
__all__ = ['AttachedDocument']
|
__all__ = ['AttachedDocument']
|
||||||
|
|
||||||
|
|
||||||
class AttachedDocument():
|
class AttachedDocument():
|
||||||
|
|
||||||
def __init__(self, id):
|
def __init__(self, invoice, DIANInvoiceXML, id):
|
||||||
schema =\
|
self.schema =\
|
||||||
'urn:oasis:names:specification:ubl:schema:xsd:AttachedDocument-2'
|
'urn:oasis:names:specification:ubl:schema:xsd:AttachedDocument-2'
|
||||||
self.fexml = fe.FeXML('AttachedDocument', schema)
|
self.id = id
|
||||||
self.fexml.set_element('./cbc:ID', id)
|
self.invoice = invoice
|
||||||
|
self.DIANInvoiceXML = DIANInvoiceXML
|
||||||
|
self.attached_document_invoice = self.attached_document_invoice()
|
||||||
|
|
||||||
|
def attached_document_invoice(self):
|
||||||
|
self.fexml = fe.FeXML(
|
||||||
|
'AttachedDocument', self.schema)
|
||||||
|
|
||||||
|
# DIAN 1.9.-2023: AE02
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cbc:UBLVersionID', 'UBL 2.1')
|
||||||
|
|
||||||
|
# DIAN 1.9.-2023: AE03
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cbc:CustomizationID', 'Documentos adjuntos')
|
||||||
|
|
||||||
|
# DIAN 1.9.-2023: AE04
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cbc:ProfileID', 'Factura Electrónica de Venta')
|
||||||
|
|
||||||
|
# DIAN 1.9.-2023: AE04a
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cbc:ProfileExecutionID', '1')
|
||||||
|
|
||||||
|
# DIAN 1.9.-2023: AE04b
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cbc:ID', self.id)
|
||||||
|
|
||||||
|
# DIAN 1.9.-2023: AE05
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cbc:IssueDate',
|
||||||
|
self.invoice.invoice_issue.strftime('%Y-%m-%d'))
|
||||||
|
|
||||||
|
# DIAN 1.9.-2023: AE06
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cbc:IssueTime', self.invoice.invoice_issue.strftime(
|
||||||
|
'%H:%M:%S-05:00'))
|
||||||
|
|
||||||
|
# DIAN 1.9.-2023: AE08
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cbc:DocumentType', 'Contenedor de Factura Electrónica')
|
||||||
|
|
||||||
|
# DIAN 1.9.-2023: AE08a
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cbc:ParentDocumentID', self.invoice.invoice_ident)
|
||||||
|
|
||||||
|
# DIAN 1.9.-2023: AE09
|
||||||
|
self.set_sender_party()
|
||||||
|
|
||||||
|
# DIAN 1.9.-2023: AE20
|
||||||
|
self.set_receiver_party()
|
||||||
|
# DIAN 1.9.-2023: AE33
|
||||||
|
self.set_attachment()
|
||||||
|
self.set_parent_document_line_reference()
|
||||||
|
|
||||||
|
def set_sender_party(self):
|
||||||
|
# DIAN 1.9.-2023: AE09
|
||||||
|
self.fexml.placeholder_for(
|
||||||
|
'./cac:SenderParty')
|
||||||
|
# DIAN 1.9.-2023: AE10
|
||||||
|
self.fexml.placeholder_for(
|
||||||
|
'./cac:SenderParty/cac:PartyTaxScheme')
|
||||||
|
# DIAN 1.9.-2023: AE11
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:SenderParty/cac:PartyTaxScheme/cbc:RegistrationName',
|
||||||
|
self.invoice.invoice_supplier.name)
|
||||||
|
# DIAN 1.9.-2023: AE12
|
||||||
|
# DIAN 1.9.-2023: AE13
|
||||||
|
# DIAN 1.9.-2023: AE14
|
||||||
|
# DIAN 1.9.-2023: AE15
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:SenderParty/cac:PartyTaxScheme/cbc:CompanyID',
|
||||||
|
self.invoice.invoice_supplier.ident,
|
||||||
|
schemeAgencyID='195',
|
||||||
|
schemeID=self.invoice.invoice_supplier.ident.dv,
|
||||||
|
schemeName=self.invoice.invoice_supplier.ident.type_fiscal)
|
||||||
|
|
||||||
|
# DIAN 1.9.-2023: AE16
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:SenderParty/cac:PartyTaxScheme/cbc:TaxLevelCode',
|
||||||
|
self.invoice.invoice_supplier.responsability_code)
|
||||||
|
|
||||||
|
# DIAN 1.9.-2023: AE18
|
||||||
|
self.fexml.placeholder_for(
|
||||||
|
'./cac:SenderParty/cac:PartyTaxScheme/cac:TaxScheme')
|
||||||
|
|
||||||
|
# DIAN 1.9.-2023: AE19
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:SenderParty/cac:PartyTaxScheme/cac:TaxScheme/cbc:ID',
|
||||||
|
self.invoice.invoice_supplier.tax_scheme.code)
|
||||||
|
|
||||||
|
# DIAN 1.9.-2023: AE20
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:SenderParty/cac:PartyTaxScheme/cac:TaxScheme/cbc:Name',
|
||||||
|
self.invoice.invoice_supplier.tax_scheme.name)
|
||||||
|
|
||||||
|
def set_receiver_party(self):
|
||||||
|
# DIAN 1.9.-2023: AE21
|
||||||
|
self.fexml.placeholder_for(
|
||||||
|
'./cac:ReceiverParty')
|
||||||
|
# DIAN 1.9.-2023: AE22
|
||||||
|
self.fexml.placeholder_for(
|
||||||
|
'./cac:ReceiverParty/cac:PartyTaxScheme')
|
||||||
|
# DIAN 1.9.-2023: AE23
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:ReceiverParty/cac:PartyTaxScheme/cbc:RegistrationName',
|
||||||
|
self.invoice.invoice_customer.name)
|
||||||
|
# DIAN 1.9.-2023: AE24
|
||||||
|
# DIAN 1.9.-2023: AE25
|
||||||
|
# DIAN 1.9.-2023: AE26
|
||||||
|
# DIAN 1.9.-2023: AE27
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:ReceiverParty/cac:PartyTaxScheme/cbc:CompanyID',
|
||||||
|
self.invoice.invoice_customer.ident,
|
||||||
|
schemeAgencyID='195',
|
||||||
|
schemeID=self.invoice.invoice_customer.ident.dv,
|
||||||
|
schemeName=self.invoice.invoice_customer.ident.type_fiscal)
|
||||||
|
# DIAN 1.9.-2023: AE28
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:ReceiverParty/cac:PartyTaxScheme/cbc:TaxLevelCode',
|
||||||
|
self.invoice.invoice_customer.responsability_code)
|
||||||
|
# DIAN 1.9.-2023: AE30
|
||||||
|
self.fexml.placeholder_for(
|
||||||
|
'./cac:ReceiverParty/cac:PartyTaxScheme/cac:TaxScheme')
|
||||||
|
# DIAN 1.9.-2023: AE31
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:ReceiverParty/cac:PartyTaxScheme/cac:TaxScheme/cbc:ID',
|
||||||
|
self.invoice.invoice_customer.tax_scheme.code)
|
||||||
|
# DIAN 1.9.-2023: AE32
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:ReceiverParty/cac:PartyTaxScheme/cac:TaxScheme/cbc:Name',
|
||||||
|
self.invoice.invoice_customer.tax_scheme.name)
|
||||||
|
|
||||||
|
def set_attachment(self):
|
||||||
|
# DIAN 1.9.-2023: AE33
|
||||||
|
self.fexml.placeholder_for(
|
||||||
|
'./cac:Attachment')
|
||||||
|
# DIAN 1.9.-2023: AE34
|
||||||
|
self.fexml.placeholder_for(
|
||||||
|
'./cac:Attachment/cac:ExternalReference')
|
||||||
|
# DIAN 1.9.-2023: AE35
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:Attachment/cac:ExternalReference/cbc:MimeCode',
|
||||||
|
'text/xml')
|
||||||
|
# DIAN 1.9.-2023: AE36
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:Attachment/cac:ExternalReference/cbc:EncodingCode',
|
||||||
|
'UTF-8')
|
||||||
|
# DIAN 1.9.-2023: AE37
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:Attachment/cac:ExternalReference/cbc:Description',
|
||||||
|
self._build_attachment(self.DIANInvoiceXML)
|
||||||
|
)
|
||||||
|
|
||||||
|
def set_parent_document_line_reference(self):
|
||||||
|
self.fexml.placeholder_for(
|
||||||
|
'./cac:ParentDocumentLineReference')
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:ParentDocumentLineReference/cbc:LineID', 1)
|
||||||
|
self.fexml.placeholder_for(
|
||||||
|
'./cac:ParentDocumentLineReference/cac:DocumentReference')
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:ParentDocumentLineReference/cac:DocumentReference/cbc:ID',
|
||||||
|
'1234')
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:ParentDocumentLineReference/cac:DocumentReference/cbc:UUID',
|
||||||
|
'1234',
|
||||||
|
schemeName="CUFE-SHA384")
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:ParentDocumentLineReference/cac:DocumentReference/cbc:IssueDate',
|
||||||
|
'2024-11-28')
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:ParentDocumentLineReference/cac:DocumentReference/cbc:DocumentType',
|
||||||
|
'ApplicationResponse')
|
||||||
|
self.fexml.placeholder_for(
|
||||||
|
'./cac:ParentDocumentLineReference/cac:DocumentReference/cac:Attachment')
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:ParentDocumentLineReference/cac:DocumentReference/cac:Attachment/cac:ExternalReference/cbc:MimeCode',
|
||||||
|
'text/xml')
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:ParentDocumentLineReference/cac:DocumentReference/cac:Attachment/cac:ExternalReference/cbc:EncodingCode',
|
||||||
|
'UTF-8')
|
||||||
|
|
||||||
|
application_response = ApplicationResponse(
|
||||||
|
self.invoice).toFachoXML()
|
||||||
|
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:ParentDocumentLineReference/cac:DocumentReference/cac:Attachment/cac:ExternalReference/cbc:Description',
|
||||||
|
self._build_attachment(application_response))
|
||||||
|
self.fexml.placeholder_for(
|
||||||
|
'./cac:ParentDocumentLineReference/cac:DocumentReference/cac:ResultOfVerification')
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:ParentDocumentLineReference/cac:DocumentReference/cac:ResultOfVerification/cbc:ValidatorID',
|
||||||
|
'Unidad Especial Dirección de Impuestos y Aduanas Nacionales')
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:ParentDocumentLineReference/cac:DocumentReference/cac:ResultOfVerification/cbc:ValidationResultCode',
|
||||||
|
'02')
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:ParentDocumentLineReference/cac:DocumentReference/cac:ResultOfVerification/cbc:ValidationDate',
|
||||||
|
'2024-11-28')
|
||||||
|
self.fexml.set_element(
|
||||||
|
'./cac:ParentDocumentLineReference/cac:DocumentReference/cac:ResultOfVerification/cbc:ValidationTime',
|
||||||
|
'10:35:11-05:00')
|
||||||
|
|
||||||
|
def _build_attachment(self, DIANInvoiceXML):
|
||||||
|
document = (
|
||||||
|
'<?xml version="1.0" encoding="UTF-8" standalone="no"?>'
|
||||||
|
) + DIANInvoiceXML.tostring()
|
||||||
|
attachment = "<![CDATA[{}]]>".format(
|
||||||
|
document)
|
||||||
|
|
||||||
|
return attachment
|
||||||
|
|
||||||
def toFachoXML(self):
|
def toFachoXML(self):
|
||||||
return self.fexml
|
return self.fexml
|
||||||
|
File diff suppressed because it is too large
Load Diff
21
tests/test_application_response.py
Normal file
21
tests/test_application_response.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# This file is part of facho. The COPYRIGHT file at the top level of
|
||||||
|
# this repository contains the full copyright notices and license terms.
|
||||||
|
import pytest
|
||||||
|
from facho.fe import form_xml
|
||||||
|
from fixtures import simple_invoice
|
||||||
|
|
||||||
|
simple_invoice = simple_invoice
|
||||||
|
|
||||||
|
|
||||||
|
def test_application_response(simple_invoice):
|
||||||
|
|
||||||
|
doc = form_xml.ApplicationResponse(simple_invoice)
|
||||||
|
xml = doc.toFachoXML()
|
||||||
|
|
||||||
|
with open("application_response.xml", "w") as fh:
|
||||||
|
fh.write(xml.tostring())
|
||||||
|
# raise Exception(xml.tostring())
|
||||||
|
# assert xml.get_element_text(
|
||||||
|
# './apr:ApplicationResponse')
|
@ -4,13 +4,122 @@
|
|||||||
# 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
|
import pytest
|
||||||
# from facho.fe import form_xml
|
from facho.fe import form_xml
|
||||||
|
from datetime import datetime
|
||||||
|
import helpers
|
||||||
|
from fixtures import simple_invoice
|
||||||
|
|
||||||
# import helpers
|
simple_invoice = simple_invoice
|
||||||
|
|
||||||
|
def test_xml_with_required_elements(simple_invoice):
|
||||||
|
|
||||||
# def test_xml_with_required_elements():
|
xml_header = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>'
|
||||||
# doc = form_xml.AttachedDocument(id='123')
|
DIANInvoiceXML = form_xml.DIANInvoiceXML(
|
||||||
# xml = doc.toFachoXML()
|
simple_invoice)
|
||||||
# assert xml.get_element_text('/atd:AttachedDocument/cbc:ID') == '123'
|
|
||||||
|
doc = form_xml.AttachedDocument(
|
||||||
|
simple_invoice,
|
||||||
|
DIANInvoiceXML,
|
||||||
|
id='123')
|
||||||
|
|
||||||
|
xml = doc.toFachoXML()
|
||||||
|
|
||||||
|
DIANInvoiceXML = form_xml.DIANInvoiceXML(
|
||||||
|
simple_invoice, 'Invoice').attach_invoice
|
||||||
|
|
||||||
|
ApplicationResponse = xml_header + form_xml.ApplicationResponse(simple_invoice).toFachoXML().tostring()
|
||||||
|
|
||||||
|
attached_document = xml_header + DIANInvoiceXML.tostring()
|
||||||
|
|
||||||
|
assert xml.get_element_text(
|
||||||
|
'/atd:AttachedDocument/cbc:UBLVersionID') == 'UBL 2.1'
|
||||||
|
assert xml.get_element_text(
|
||||||
|
'/atd:AttachedDocument/cbc:CustomizationID') == 'Documentos adjuntos'
|
||||||
|
assert xml.get_element_text(
|
||||||
|
'/atd:AttachedDocument/cbc:ProfileID') == 'Factura Electrónica de Venta'
|
||||||
|
assert xml.get_element_text(
|
||||||
|
'/atd:AttachedDocument/cbc:ProfileExecutionID') == '1'
|
||||||
|
assert xml.get_element_text(
|
||||||
|
'/atd:AttachedDocument/cbc:ID') == '123'
|
||||||
|
assert xml.get_element_text(
|
||||||
|
'/atd:AttachedDocument/cbc:IssueDate') == str(datetime.today().date())
|
||||||
|
assert xml.get_element_text(
|
||||||
|
'/atd:AttachedDocument/cbc:IssueTime') == datetime.today(
|
||||||
|
).time().strftime(
|
||||||
|
'%H:%M:%S-05:00')
|
||||||
|
assert xml.get_element_text(
|
||||||
|
'/atd:AttachedDocument/cbc:DocumentType'
|
||||||
|
) == 'Contenedor de Factura Electrónica'
|
||||||
|
assert xml.get_element_text(
|
||||||
|
'/atd:AttachedDocument/cbc:ParentDocumentID'
|
||||||
|
) == 'ABC123'
|
||||||
|
|
||||||
|
assert xml.get_element_text(
|
||||||
|
'/atd:AttachedDocument/cac:SenderParty/cac:PartyTaxScheme/cbc:RegistrationName'
|
||||||
|
) == 'facho-supplier'
|
||||||
|
assert xml.get_element_text(
|
||||||
|
'/atd:AttachedDocument/cac:SenderParty/cac:PartyTaxScheme/cbc:CompanyID'
|
||||||
|
) == '123'
|
||||||
|
assert xml.get_element_text(
|
||||||
|
'/atd:AttachedDocument/cac:SenderParty/cac:PartyTaxScheme/cbc:TaxLevelCode'
|
||||||
|
) == 'ZZ'
|
||||||
|
assert xml.get_element_text(
|
||||||
|
'/atd:AttachedDocument/cac:SenderParty/cac:PartyTaxScheme/cac:TaxScheme/cbc:ID'
|
||||||
|
) == '01'
|
||||||
|
assert xml.get_element_text(
|
||||||
|
'/atd:AttachedDocument/cac:SenderParty/cac:PartyTaxScheme/cac:TaxScheme/cbc:Name'
|
||||||
|
) == 'IVA'
|
||||||
|
|
||||||
|
assert xml.get_element_text(
|
||||||
|
'/atd:AttachedDocument/cac:ReceiverParty/cac:PartyTaxScheme/cbc:RegistrationName'
|
||||||
|
) == 'facho-customer'
|
||||||
|
assert xml.get_element_text(
|
||||||
|
'/atd:AttachedDocument/cac:ReceiverParty/cac:PartyTaxScheme/cbc:CompanyID'
|
||||||
|
) == '321'
|
||||||
|
assert xml.get_element_text(
|
||||||
|
'/atd:AttachedDocument/cac:ReceiverParty/cac:PartyTaxScheme/cbc:TaxLevelCode'
|
||||||
|
) == 'ZZ'
|
||||||
|
assert xml.get_element_text(
|
||||||
|
'/atd:AttachedDocument/cac:ReceiverParty/cac:PartyTaxScheme/cac:TaxScheme/cbc:ID'
|
||||||
|
) == '01'
|
||||||
|
assert xml.get_element_text(
|
||||||
|
'/atd:AttachedDocument/cac:ReceiverParty/cac:PartyTaxScheme/cac:TaxScheme/cbc:Name'
|
||||||
|
) == 'IVA'
|
||||||
|
|
||||||
|
assert xml.get_element_text(
|
||||||
|
'/atd:AttachedDocument/cac:Attachment/cac:ExternalReference/cbc:MimeCode'
|
||||||
|
) == "text/xml"
|
||||||
|
assert xml.get_element_text(
|
||||||
|
'/atd:AttachedDocument/cac:Attachment/cac:ExternalReference/cbc:EncodingCode'
|
||||||
|
) == "UTF-8"
|
||||||
|
assert xml.get_element_text(
|
||||||
|
'/atd:AttachedDocument/cac:Attachment/cac:ExternalReference/cbc:Description'
|
||||||
|
) == "<![CDATA[{}]]>".format(attached_document)
|
||||||
|
|
||||||
|
assert xml.get_element_text(
|
||||||
|
'/atd:AttachedDocument/cac:ParentDocumentLineReference/cbc:LineID'
|
||||||
|
) == '1'
|
||||||
|
assert xml.get_element_text(
|
||||||
|
'/atd:AttachedDocument/cac:ParentDocumentLineReference/cac:DocumentReference/cbc:ID'
|
||||||
|
) == '1234'
|
||||||
|
assert xml.get_element_text(
|
||||||
|
'/atd:AttachedDocument/cac:ParentDocumentLineReference/cac:DocumentReference/cbc:UUID'
|
||||||
|
) == '1234'
|
||||||
|
assert xml.get_element_text(
|
||||||
|
'/atd:AttachedDocument/cac:ParentDocumentLineReference/cac:DocumentReference/cbc:IssueDate'
|
||||||
|
) == '2024-11-28'
|
||||||
|
assert xml.get_element_text(
|
||||||
|
'/atd:AttachedDocument/cac:ParentDocumentLineReference/cac:DocumentReference/cbc:DocumentType'
|
||||||
|
) == 'ApplicationResponse'
|
||||||
|
assert xml.get_element_text(
|
||||||
|
'/atd:AttachedDocument/cac:ParentDocumentLineReference/cac:DocumentReference/cac:Attachment/cac:ExternalReference/cbc:MimeCode'
|
||||||
|
) == 'text/xml'
|
||||||
|
|
||||||
|
assert xml.get_element_text(
|
||||||
|
'/atd:AttachedDocument/cac:ParentDocumentLineReference/cac:DocumentReference/cac:Attachment/cac:ExternalReference/cbc:EncodingCode'
|
||||||
|
) == "UTF-8"
|
||||||
|
|
||||||
|
assert xml.get_element_text(
|
||||||
|
'/atd:AttachedDocument/cac:ParentDocumentLineReference/cac:DocumentReference/cac:Attachment/cac:ExternalReference/cbc:Description'
|
||||||
|
) == "<![CDATA[{}]]>".format(ApplicationResponse)
|
||||||
|
@ -130,6 +130,3 @@ def test_xml_signature_timestamp(monkeypatch):
|
|||||||
xmlstring = xml.tostring()
|
xmlstring = xml.tostring()
|
||||||
signer = fe.DianXMLExtensionSigner('./tests/example.p12')
|
signer = fe.DianXMLExtensionSigner('./tests/example.p12')
|
||||||
xmlsigned = signer.sign_xml_string(xmlstring)
|
xmlsigned = signer.sign_xml_string(xmlstring)
|
||||||
|
|
||||||
with open('invoice.xml', 'w') as file_:
|
|
||||||
file_.write(xmlsigned)
|
|
Loading…
Reference in New Issue
Block a user