Fix: Facho para habilitacion de nomina python 3.9
This commit is contained in:
@@ -2,7 +2,4 @@ from .invoice import *
|
||||
from .credit_note import *
|
||||
from .debit_note import *
|
||||
from .utils import *
|
||||
from .support_document import *
|
||||
from .support_document_credit_note import *
|
||||
from .attached_document import *
|
||||
from .application_response import *
|
||||
|
||||
@@ -1,177 +0,0 @@
|
||||
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,227 +1,14 @@
|
||||
from .. import fe
|
||||
from .application_response import ApplicationResponse
|
||||
|
||||
__all__ = ['AttachedDocument']
|
||||
|
||||
|
||||
class AttachedDocument():
|
||||
|
||||
def __init__(self, invoice, DIANInvoiceXML, id):
|
||||
self.schema =\
|
||||
'urn:oasis:names:specification:ubl:schema:xsd:AttachedDocument-2'
|
||||
self.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 __init__(self, id):
|
||||
schema = 'urn:oasis:names:specification:ubl:schema:xsd:AttachedDocument-2'
|
||||
self.fexml = fe.FeXML('AttachedDocument', schema)
|
||||
self.fexml.set_element('./cbc:ID', id)
|
||||
|
||||
def toFachoXML(self):
|
||||
return self.fexml
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
# from .. import fe
|
||||
# from ..form import *
|
||||
from .. import fe
|
||||
from ..form import *
|
||||
from .invoice import DIANInvoiceXML
|
||||
|
||||
__all__ = ['DIANCreditNoteXML']
|
||||
|
||||
|
||||
class DIANCreditNoteXML(DIANInvoiceXML):
|
||||
"""
|
||||
DianInvoiceXML mapea objeto form.Invoice a XML segun
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
# from .. import fe
|
||||
# from ..form import *
|
||||
from .. import fe
|
||||
from ..form import *
|
||||
from .invoice import DIANInvoiceXML
|
||||
|
||||
__all__ = ['DIANDebitNoteXML']
|
||||
|
||||
|
||||
class DIANDebitNoteXML(DIANInvoiceXML):
|
||||
"""
|
||||
DianInvoiceXML mapea objeto form.Invoice a XML segun
|
||||
@@ -20,24 +19,19 @@ class DIANDebitNoteXML(DIANInvoiceXML):
|
||||
def tag_document_concilied(fexml):
|
||||
return 'Debited'
|
||||
|
||||
# DIAN 1.7.-2020: DAU03
|
||||
#DIAN 1.7.-2020: DAU03
|
||||
def set_legal_monetary(fexml, invoice):
|
||||
fexml.set_element_amount(
|
||||
'./cac:RequestedMonetaryTotal/cbc:LineExtensionAmount',
|
||||
invoice.invoice_legal_monetary_total.line_extension_amount)
|
||||
fexml.set_element_amount('./cac:RequestedMonetaryTotal/cbc:LineExtensionAmount',
|
||||
invoice.invoice_legal_monetary_total.line_extension_amount)
|
||||
|
||||
fexml.set_element_amount(
|
||||
'./cac:RequestedMonetaryTotal/cbc:TaxExclusiveAmount',
|
||||
invoice.invoice_legal_monetary_total.tax_exclusive_amount)
|
||||
fexml.set_element_amount('./cac:RequestedMonetaryTotal/cbc:TaxExclusiveAmount',
|
||||
invoice.invoice_legal_monetary_total.tax_exclusive_amount)
|
||||
|
||||
fexml.set_element_amount(
|
||||
'./cac:RequestedMonetaryTotal/cbc:TaxInclusiveAmount',
|
||||
invoice.invoice_legal_monetary_total.tax_inclusive_amount)
|
||||
fexml.set_element_amount('./cac:RequestedMonetaryTotal/cbc:TaxInclusiveAmount',
|
||||
invoice.invoice_legal_monetary_total.tax_inclusive_amount)
|
||||
|
||||
fexml.set_element_amount(
|
||||
'./cac:RequestedMonetaryTotal/cbc:ChargeTotalAmount',
|
||||
invoice.invoice_legal_monetary_total.charge_total_amount)
|
||||
fexml.set_element_amount('./cac:RequestedMonetaryTotal/cbc:ChargeTotalAmount',
|
||||
invoice.invoice_legal_monetary_total.charge_total_amount)
|
||||
|
||||
fexml.set_element_amount(
|
||||
'./cac:RequestedMonetaryTotal/cbc:PayableAmount',
|
||||
invoice.invoice_legal_monetary_total.payable_amount)
|
||||
fexml.set_element_amount('./cac:RequestedMonetaryTotal/cbc:PayableAmount',
|
||||
invoice.invoice_legal_monetary_total.payable_amount)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,647 +0,0 @@
|
||||
from .. import fe
|
||||
from ..form import (
|
||||
Amount, DebitNoteDocumentReference, CreditNoteDocumentReference,
|
||||
InvoiceDocumentReference, TaxTotalOmit, WithholdingTaxTotalOmit
|
||||
)
|
||||
|
||||
from collections import defaultdict
|
||||
from datetime import datetime
|
||||
# from .attached_document import *
|
||||
|
||||
__all__ = ['DIANSupportDocumentXML']
|
||||
|
||||
|
||||
class DIANSupportDocumentXML(fe.FeXML):
|
||||
"""
|
||||
DianSupportDocumentXML mapea objeto form.Invoice a XML segun
|
||||
lo indicado para él Documento soporte en adquisiciones efectuadas con sujetos no obligados a expedir factura de venta o documento equivalente.
|
||||
"""
|
||||
|
||||
def __init__(self, invoice, tag_document='Invoice'):
|
||||
super().__init__(tag_document, 'http://www.dian.gov.co/contratos/facturaelectronica/v1')
|
||||
|
||||
# DIAN 1.1.-2021: DSAB03
|
||||
# DIAN 1.1.-2021: NSAB03
|
||||
self.placeholder_for(
|
||||
'./ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent/sts:DianExtensions/sts:InvoiceControl')
|
||||
|
||||
# DIAN 1.1.-2021: DSAB13
|
||||
# DIAN 1.1.-2021: NSAB13
|
||||
self.placeholder_for(
|
||||
'./ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent/sts:DianExtensions/sts:InvoiceSource')
|
||||
|
||||
# DIAN 1.1.-2021: DSAB18
|
||||
# DIAN 1.1.-2021: NSAB18
|
||||
self.placeholder_for(
|
||||
'./ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent/sts:DianExtensions/sts:SoftwareProvider')
|
||||
|
||||
# DIAN 1.1.-2021: DSAB27
|
||||
# DIAN 1.1.-2021: NSAB27
|
||||
self.placeholder_for(
|
||||
'./ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent/sts:DianExtensions/sts:SoftwareSecurityCode')
|
||||
|
||||
# DIAN 1.1.-2021: DSAB30 DSAB31
|
||||
# DIAN 1.1.-2021: NSAB30 NSAB31
|
||||
self.placeholder_for(
|
||||
'./ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent/sts:DianExtensions/sts:AuthorizationProvider/sts:AuthorizationProviderID')
|
||||
|
||||
# ZE02 se requiere existencia para firmar
|
||||
# DIAN 1.1.-2021: DSAA02 DSAB01
|
||||
# DIAN 1.1.-2021: NSAA02 NSAB01
|
||||
ublextension = self.fragment(
|
||||
'./ext:UBLExtensions/ext:UBLExtension', append=True)
|
||||
# DIAN 1.1.-2021: DSAB02
|
||||
# DIAN 1.1.-2021: NSAB02
|
||||
extcontent = ublextension.find_or_create_element(
|
||||
'/ext:UBLExtension/ext:ExtensionContent')
|
||||
self.attach_invoice(invoice)
|
||||
|
||||
def set_supplier(fexml, invoice):
|
||||
# DIAN 1.1.-2021: DSAJ01
|
||||
# DIAN 1.1.-2021: NSAB01
|
||||
fexml.placeholder_for('./cac:AccountingSupplierParty')
|
||||
|
||||
# DIAN 1.1.-2021: DSAJ02
|
||||
# DIAN 1.1.-2021: NSAJ02
|
||||
fexml.set_element(
|
||||
'./cac:AccountingSupplierParty/cbc:AdditionalAccountID',
|
||||
invoice.invoice_supplier.organization_code)
|
||||
|
||||
# DIAN 1.1.-2021: DSAJ07 DSAJ08
|
||||
# DIAN 1.1.-2021: NSAJ07 NSAJ08
|
||||
fexml.placeholder_for(
|
||||
'./cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address')
|
||||
|
||||
# DIAN 1.1.-2021: DSAJ09
|
||||
# DIAN 1.1.-2021: NSAJ09
|
||||
fexml.set_element(
|
||||
'./cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:ID',
|
||||
invoice.invoice_supplier.address.city.code)
|
||||
|
||||
# DIAN 1.1.-2021: DSAJ10
|
||||
# DIAN 1.1.-2021: NSAJ10
|
||||
fexml.set_element(
|
||||
'./cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:CityName',
|
||||
invoice.invoice_supplier.address.city.name)
|
||||
|
||||
# DIAN 1.1.-2021: DSAJ73
|
||||
# DIAN 1.1.-2021: NSAJ73
|
||||
fexml.set_element(
|
||||
'./cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:PostalZone',
|
||||
invoice.invoice_supplier.address.postalzone.code)
|
||||
|
||||
# DIAN 1.1.-2021: DSAJ11
|
||||
# DIAN 1.1.-2021: NSAJ11
|
||||
fexml.set_element(
|
||||
'./cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:CountrySubentity',
|
||||
invoice.invoice_supplier.address.countrysubentity.name)
|
||||
|
||||
# DIAN 1.1.-2021: DSAJ12
|
||||
# DIAN 1.1.-2021: NSAJ12
|
||||
fexml.set_element(
|
||||
'./cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cbc:CountrySubentityCode',
|
||||
invoice.invoice_supplier.address.countrysubentity.code)
|
||||
# DIAN 1.1.-2021: NSAJ13 NSAJ14
|
||||
fexml.set_element(
|
||||
'./cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cac:AddressLine/cbc:Line',
|
||||
invoice.invoice_supplier.address.street)
|
||||
|
||||
# DIAN 1.1.-2021: DSAJ15 DSAJ16
|
||||
# DIAN 1.1.-2021: NSAJ15 NSAJ16
|
||||
fexml.set_element(
|
||||
'./cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cac:Country/cbc:IdentificationCode',
|
||||
invoice.invoice_supplier.address.country.code)
|
||||
|
||||
# DIAN 1.1.-2021: DSAJ17
|
||||
# DIAN 1.1.-2021: NSAJ17
|
||||
fexml.set_element('./cac:AccountingSupplierParty/cac:Party/cac:PhysicalLocation/cac:Address/cac:Country/cbc:Name',
|
||||
invoice.invoice_supplier.address.country.name,
|
||||
# DIAN 1.1.-2021: DSAJ18
|
||||
# # DIAN 1.1.-2021: NSAJ18
|
||||
languageID='es')
|
||||
|
||||
supplier_company_id_attrs = fe.SCHEME_AGENCY_ATTRS.copy()
|
||||
supplier_company_id_attrs.update(
|
||||
{
|
||||
'schemeID': invoice.invoice_supplier.ident.dv,
|
||||
'schemeName': invoice.invoice_supplier.ident.type_fiscal})
|
||||
|
||||
# DIAN 1.1.-2021: DSAJ19
|
||||
# DIAN 1.1.-2021: NSAJ19
|
||||
fexml.placeholder_for(
|
||||
'./cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme')
|
||||
|
||||
# DIAN 1.1.-2021: DSAJ20
|
||||
# DIAN 1.1.-2021: NSAJ20
|
||||
fexml.set_element(
|
||||
'./cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cbc:RegistrationName',
|
||||
invoice.invoice_supplier.legal_name)
|
||||
|
||||
# DIAN 1.1.-2021: DSAJ21
|
||||
# DIAN 1.1.-2021: NSAJ21
|
||||
fexml.set_element(
|
||||
'./cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID',
|
||||
invoice.invoice_supplier.ident,
|
||||
# DIAN 1.1.-2021: DSAJ22 DSAJ23 DSAJ24 DSAJ25
|
||||
# DIAN 1.1.-2021: NSAJ22 NSAJ23 NSAJ24 NSAJ25
|
||||
**supplier_company_id_attrs)
|
||||
|
||||
# DIAN 1.1.-2021: DSAJ26
|
||||
# DIAN 1.1.-2021: NSAJ26
|
||||
fexml.set_element(
|
||||
'./cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cbc:TaxLevelCode',
|
||||
invoice.invoice_supplier.responsability_code,
|
||||
listName=invoice.invoice_supplier.responsability_regime_code)
|
||||
|
||||
# DIAN 1.1.-2021: DSAJ39
|
||||
# DIAN 1.1.-2021: NSAJ39
|
||||
fexml.placeholder_for(
|
||||
'./cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cac:TaxScheme')
|
||||
|
||||
# DIAN 1.1.-2021: DSAJ40
|
||||
# DIAN 1.1.-2021: NSAJ40
|
||||
fexml.set_element(
|
||||
'./cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cac:TaxScheme/cbc:ID',
|
||||
invoice.invoice_customer.tax_scheme.code)
|
||||
|
||||
# DIAN 1.1.-2021: DSAJ41
|
||||
# DIAN 1.1.-2021: NSAJ41
|
||||
fexml.set_element(
|
||||
'./cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cac:TaxScheme/cbc:Name',
|
||||
invoice.invoice_customer.tax_scheme.name)
|
||||
|
||||
def set_customer(fexml, invoice):
|
||||
# DIAN 1.1.-2021: DSAK01
|
||||
# DIAN 1.1.-2021: NSAK01
|
||||
fexml.placeholder_for('./cac:AccountingCustomerParty')
|
||||
|
||||
# DIAN 1.1.-2021: DSAK02
|
||||
# DIAN 1.1.-2021: NSAK02
|
||||
fexml.set_element(
|
||||
'./cac:AccountingCustomerParty/cbc:AdditionalAccountID',
|
||||
invoice.invoice_customer.organization_code)
|
||||
|
||||
# DIAN 1.1.-2021: DSAK03
|
||||
# DIAN 1.1.-2021: NSAK03
|
||||
fexml.placeholder_for('./cac:AccountingCustomerParty/cac:Party')
|
||||
|
||||
# DIAN 1.1.-2021: DSAK19
|
||||
# DIAN 1.1.-2021: NSAK19
|
||||
fexml.placeholder_for(
|
||||
'./cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme')
|
||||
|
||||
# DIAN 1.1.-2021: DSAK20
|
||||
# DIAN 1.1.-2021: NSAK20
|
||||
fexml.set_element(
|
||||
'./cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cbc:RegistrationName',
|
||||
invoice.invoice_customer.legal_name)
|
||||
|
||||
customer_company_id_attrs = fe.SCHEME_AGENCY_ATTRS.copy()
|
||||
customer_company_id_attrs.update(
|
||||
{
|
||||
'schemeID': invoice.invoice_customer.ident.dv,
|
||||
'schemeName': invoice.invoice_customer.ident.type_fiscal})
|
||||
|
||||
# DIAN 1.1.-2021: DSAK21
|
||||
# DIAN 1.1.-2021: NSAK21
|
||||
fexml.set_element(
|
||||
'./cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID',
|
||||
invoice.invoice_customer.ident,
|
||||
# DIAN 1.1.-2021: DSAK22 DSAK23 DSAK24 DSAK25
|
||||
# DIAN 1.1.-2021: NSAK22 NSAK23 NSAK24 NSAK25
|
||||
**customer_company_id_attrs)
|
||||
|
||||
# DIAN 1.1.-2021: DSAK26
|
||||
# DIAN 1.1.-2021: NSAK26
|
||||
fexml.set_element(
|
||||
'./cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cbc:TaxLevelCode',
|
||||
invoice.invoice_customer.responsability_code)
|
||||
|
||||
# DIAN 1.1.-2021: DSAK39
|
||||
# DIAN 1.1.-2021: NSAK39
|
||||
fexml.placeholder_for(
|
||||
'./cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cac:TaxScheme')
|
||||
|
||||
# DIAN 1.1.-2021: DSAK40
|
||||
# DIAN 1.1.-2021: NSAK40
|
||||
fexml.set_element(
|
||||
'./cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cac:TaxScheme/cbc:ID',
|
||||
invoice.invoice_customer.tax_scheme.code)
|
||||
|
||||
# DIAN 1.1.-2021: DSAK41
|
||||
# DIAN 1.1.-2021: NSAK41
|
||||
fexml.set_element(
|
||||
'./cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cac:TaxScheme/cbc:Name',
|
||||
invoice.invoice_customer.tax_scheme.name)
|
||||
|
||||
def set_payment_mean(fexml, invoice):
|
||||
payment_mean = invoice.invoice_payment_mean
|
||||
|
||||
# DIAN 1.1.-2021: DSAN01 DSAN02
|
||||
# DIAN 1.1.-2021: NSAN02 NSAN02
|
||||
fexml.set_element('./cac:PaymentMeans/cbc:ID', payment_mean.id)
|
||||
|
||||
# DIAN 1.1.-2021: DSAN03
|
||||
# DIAN 1.1.-2021: NSAN03
|
||||
fexml.set_element(
|
||||
'./cac:PaymentMeans/cbc:PaymentMeansCode',
|
||||
payment_mean.code)
|
||||
|
||||
# DIAN 1.1.-2021: DSAN04
|
||||
# DIAN 1.1.-2021: NSAN04
|
||||
fexml.set_element(
|
||||
'./cac:PaymentMeans/cbc:PaymentDueDate',
|
||||
payment_mean.due_at.strftime('%Y-%m-%d'))
|
||||
|
||||
# DIAN 1.1.-2021: DSAN05
|
||||
# DIAN 1.1.-2021: NSAN05
|
||||
fexml.set_element(
|
||||
'./cac:PaymentMeans/cbc:PaymentID',
|
||||
payment_mean.payment_id)
|
||||
|
||||
def set_element_amount_for(fexml, xml, xpath, amount):
|
||||
if not isinstance(amount, Amount):
|
||||
raise TypeError("amount not is Amount")
|
||||
|
||||
xml.set_element(xpath, amount, currencyID=amount.currency.code)
|
||||
|
||||
def set_element_amount(fexml, xpath, amount):
|
||||
if not isinstance(amount, Amount):
|
||||
raise TypeError("amount not is Amount")
|
||||
|
||||
fexml.set_element(xpath, amount, currencyID=amount.currency.code)
|
||||
|
||||
def set_legal_monetary(fexml, invoice):
|
||||
# DIAN 1.1.-2021: DSAU01 DSAU02 DSAU03
|
||||
# DIAN 1.1.-2021: NSAU01 NSAU02 NSAU03
|
||||
fexml.set_element_amount(
|
||||
'./cac:LegalMonetaryTotal/cbc:LineExtensionAmount',
|
||||
invoice.invoice_legal_monetary_total.line_extension_amount)
|
||||
|
||||
# DIAN 1.1.-2021: DSAU04 DSAU05
|
||||
# DIAN 1.1.-2021: NSAU04 NSAU05
|
||||
fexml.set_element_amount(
|
||||
'./cac:LegalMonetaryTotal/cbc:TaxExclusiveAmount',
|
||||
invoice.invoice_legal_monetary_total.tax_exclusive_amount)
|
||||
|
||||
# DIAN 1.1.-2021: DSAU06 DSAU07
|
||||
# DIAN 1.1.-2021: NSAU06 DSAU07
|
||||
fexml.set_element_amount(
|
||||
'./cac:LegalMonetaryTotal/cbc:TaxInclusiveAmount',
|
||||
invoice.invoice_legal_monetary_total.tax_inclusive_amount)
|
||||
|
||||
# DIAN 1.1.-2021: DSAU10 DSAU11
|
||||
# DIAN 1.1.-2021: NSAU10 DSAU11
|
||||
fexml.set_element_amount(
|
||||
'./cac:LegalMonetaryTotal/cbc:ChargeTotalAmount',
|
||||
invoice.invoice_legal_monetary_total.charge_total_amount)
|
||||
|
||||
# DIAN 1.1.-2021: DSAU14 DSAU15
|
||||
# DIAN 1.1.-2021: NSAU14 DSAU15
|
||||
fexml.set_element_amount(
|
||||
'./cac:LegalMonetaryTotal/cbc:PayableAmount',
|
||||
invoice.invoice_legal_monetary_total.payable_amount)
|
||||
|
||||
def _set_invoice_document_reference(fexml, reference):
|
||||
fexml._do_set_billing_reference(
|
||||
reference, 'cac:InvoiceDocumentReference')
|
||||
|
||||
def _set_credit_note_document_reference(fexml, reference):
|
||||
fexml._do_set_billing_reference(
|
||||
reference, 'cac:CreditNoteDocumentReference')
|
||||
|
||||
def _set_debit_note_document_reference(fexml, reference):
|
||||
fexml._do_set_billing_reference(
|
||||
reference, 'cac:DebitNoteDocumentReference')
|
||||
|
||||
def _do_set_billing_reference(fexml, reference, tag_document):
|
||||
|
||||
if tag_document == 'Invoice':
|
||||
schemeName = 'CUFE-SHA384'
|
||||
else:
|
||||
schemeName = 'CUDS-SHA384'
|
||||
|
||||
fexml.set_element('./cac:BillingReference/%s/cbc:ID' % (tag_document),
|
||||
reference.ident)
|
||||
fexml.set_element(
|
||||
'./cac:BillingReference/cac:InvoiceDocumentReference/cbc:UUID',
|
||||
reference.uuid,
|
||||
schemeName=schemeName)
|
||||
fexml.set_element(
|
||||
'./cac:BillingReference/cac:InvoiceDocumentReference/cbc:IssueDate',
|
||||
reference.date.strftime("%Y-%m-%d"))
|
||||
|
||||
def set_billing_reference(fexml, invoice):
|
||||
reference = invoice.invoice_billing_reference
|
||||
if reference is None:
|
||||
return
|
||||
|
||||
if isinstance(reference, DebitNoteDocumentReference):
|
||||
return fexml._set_debit_note_document_reference(reference)
|
||||
if isinstance(reference, CreditNoteDocumentReference):
|
||||
return fexml._set_credit_note_document_reference(reference)
|
||||
|
||||
if isinstance(reference, InvoiceDocumentReference):
|
||||
return fexml._set_invoice_document_reference(reference)
|
||||
|
||||
def set_discrepancy_response(fexml, invoice):
|
||||
reference = invoice.invoice_discrepancy_response
|
||||
if reference is None:
|
||||
return
|
||||
if isinstance(reference, DebitNoteDocumentReference):
|
||||
return fexml._set_debit_note_document_reference(reference)
|
||||
if isinstance(reference, CreditNoteDocumentReference):
|
||||
return fexml._set_credit_note_document_reference(reference)
|
||||
|
||||
if isinstance(reference, InvoiceDocumentReference):
|
||||
return fexml._set_invoice_document_reference(reference)
|
||||
|
||||
fexml.set_element('./cac:DiscrepancyResponse/cbc:ReferenceID',
|
||||
reference.id)
|
||||
fexml.set_element('./cac:DiscrepancyResponse/cbc:ResponseCode',
|
||||
reference.code)
|
||||
fexml.set_element('./cac:DiscrepancyResponse/cbc:Description',
|
||||
reference.description)
|
||||
|
||||
def set_invoice_totals(fexml, invoice):
|
||||
tax_amount_for = defaultdict(lambda: defaultdict(lambda: Amount(0.0)))
|
||||
percent_for = defaultdict(lambda: None)
|
||||
|
||||
total_tax_amount = Amount(0.0)
|
||||
|
||||
for invoice_line in invoice.invoice_lines:
|
||||
for subtotal in invoice_line.tax.subtotals:
|
||||
if subtotal.scheme is not None:
|
||||
tax_amount_for[
|
||||
subtotal.scheme.code][
|
||||
'tax_amount'] += subtotal.tax_amount
|
||||
tax_amount_for[subtotal.scheme.code][
|
||||
'taxable_amount'] += invoice_line.taxable_amount
|
||||
|
||||
# MACHETE ojo InvoiceLine.tax pasar a Invoice
|
||||
percent_for[subtotal.scheme.code] = subtotal.percent
|
||||
|
||||
total_tax_amount += subtotal.tax_amount
|
||||
|
||||
if total_tax_amount != Amount(0.0):
|
||||
fexml.placeholder_for('./cac:TaxTotal')
|
||||
fexml.set_element_amount('./cac:TaxTotal/cbc:TaxAmount',
|
||||
total_tax_amount)
|
||||
|
||||
for index, item in enumerate(tax_amount_for.items()):
|
||||
cod_impuesto, amount_of = item
|
||||
next_append = index > 0
|
||||
|
||||
# DIAN 1.7.-2020: FAS01
|
||||
line = fexml.fragment('./cac:TaxTotal', append=next_append)
|
||||
# DIAN 1.7.-2020: FAU06
|
||||
tax_amount = amount_of['tax_amount']
|
||||
fexml.set_element_amount_for(line,
|
||||
'/cac:TaxTotal/cbc:TaxAmount',
|
||||
tax_amount)
|
||||
|
||||
# DIAN 1.7.-2020: FAS05
|
||||
fexml.set_element_amount_for(
|
||||
line,
|
||||
'/cac:TaxTotal/cac:TaxSubtotal/cbc:TaxableAmount',
|
||||
amount_of['taxable_amount'])
|
||||
|
||||
# DIAN 1.7.-2020: FAU06
|
||||
fexml.set_element_amount_for(
|
||||
line,
|
||||
'/cac:TaxTotal/cac:TaxSubtotal/cbc:TaxAmount',
|
||||
amount_of['tax_amount'])
|
||||
|
||||
# DIAN 1.7.-2020: FAS07
|
||||
if percent_for[cod_impuesto]:
|
||||
line.set_element('/cac:TaxTotal/cac:TaxSubtotal/cbc:Percent',
|
||||
percent_for[cod_impuesto])
|
||||
|
||||
if percent_for[cod_impuesto]:
|
||||
line.set_element(
|
||||
'/cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cbc:Percent',
|
||||
percent_for[cod_impuesto])
|
||||
|
||||
line.set_element(
|
||||
'/cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cac:TaxScheme/cbc:ID',
|
||||
cod_impuesto)
|
||||
line.set_element(
|
||||
'/cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cac:TaxScheme/cbc:Name', 'IVA')
|
||||
|
||||
# abstract method
|
||||
|
||||
def tag_document(fexml):
|
||||
return 'Invoice'
|
||||
|
||||
# abstract method
|
||||
def tag_document_concilied(fexml):
|
||||
return 'Invoiced'
|
||||
|
||||
def set_invoice_line_withholding(fexml, line, invoice_line):
|
||||
fexml.set_element_amount_for(line,
|
||||
'./cac:WithholdingTaxTotal/cbc:TaxAmount',
|
||||
invoice_line.withholding_amount)
|
||||
# DIAN 1.7.-2020: FAX05
|
||||
fexml.set_element_amount_for(
|
||||
line,
|
||||
'./cac:WithholdingTaxTotal/cac:TaxSubtotal/cbc:TaxableAmount',
|
||||
invoice_line.withholding_taxable_amount)
|
||||
|
||||
for subtotal in invoice_line.withholding.subtotals:
|
||||
line.set_element(
|
||||
'./cac:WithholdingTaxTotal/cac:TaxSubtotal/cbc:TaxAmount',
|
||||
subtotal.tax_amount,
|
||||
currencyID='COP')
|
||||
|
||||
if subtotal.percent is not None:
|
||||
line.set_element(
|
||||
'./cac:WithholdingTaxTotal/cac:TaxSubtotal/cac:TaxCategory/cbc:Percent',
|
||||
'%0.2f' %
|
||||
round(
|
||||
subtotal.percent,
|
||||
2))
|
||||
|
||||
if subtotal.scheme is not None:
|
||||
# DIAN 1.7.-2020: FAX15
|
||||
line.set_element(
|
||||
'./cac:WithholdingTaxTotal/cac:TaxSubtotal/cac:TaxCategory/cac:TaxScheme/cbc:ID',
|
||||
subtotal.scheme.code)
|
||||
line.set_element(
|
||||
'./cac:WithholdingTaxTotal/cac:TaxSubtotal/cac:TaxCategory/cac:TaxScheme/cbc:Name',
|
||||
subtotal.scheme.name)
|
||||
|
||||
def set_invoice_line_tax(fexml, line, invoice_line):
|
||||
fexml.set_element_amount_for(line,
|
||||
'./cac:TaxTotal/cbc:TaxAmount',
|
||||
invoice_line.tax_amount)
|
||||
|
||||
# DIAN 1.7.-2020: FAX05
|
||||
fexml.set_element_amount_for(
|
||||
line,
|
||||
'./cac:TaxTotal/cac:TaxSubtotal/cbc:TaxableAmount',
|
||||
invoice_line.taxable_amount)
|
||||
for subtotal in invoice_line.tax.subtotals:
|
||||
line.set_element(
|
||||
'./cac:TaxTotal/cac:TaxSubtotal/cbc:TaxAmount',
|
||||
subtotal.tax_amount,
|
||||
currencyID='COP')
|
||||
|
||||
if subtotal.percent is not None:
|
||||
line.set_element(
|
||||
'./cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cbc:Percent',
|
||||
'%0.2f' %
|
||||
round(
|
||||
subtotal.percent,
|
||||
2))
|
||||
|
||||
if subtotal.scheme is not None:
|
||||
# DIAN 1.7.-2020: FAX15
|
||||
line.set_element(
|
||||
'./cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cac:TaxScheme/cbc:ID',
|
||||
subtotal.scheme.code)
|
||||
line.set_element(
|
||||
'./cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cac:TaxScheme/cbc:Name',
|
||||
subtotal.scheme.name)
|
||||
|
||||
def set_invoice_lines(fexml, invoice):
|
||||
next_append = False
|
||||
for index, invoice_line in enumerate(invoice.invoice_lines):
|
||||
line = fexml.fragment(
|
||||
'./cac:%sLine' %
|
||||
(fexml.tag_document()),
|
||||
append=next_append)
|
||||
next_append = True
|
||||
|
||||
line.set_element('./cbc:ID', index + 1)
|
||||
line.set_element(
|
||||
'./cbc:%sQuantity' %
|
||||
(fexml.tag_document_concilied()),
|
||||
invoice_line.quantity,
|
||||
unitCode='NAR')
|
||||
fexml.set_element_amount_for(line,
|
||||
'./cbc:LineExtensionAmount',
|
||||
invoice_line.total_amount)
|
||||
|
||||
period = line.fragment('./cac:InvoicePeriod')
|
||||
period.set_element('./cbc:StartDate',
|
||||
datetime.now().strftime('%Y-%m-%d'))
|
||||
period.set_element(
|
||||
'./cbc:DescriptionCode', '1')
|
||||
period.set_element('./cbc:Description',
|
||||
'Por operación')
|
||||
|
||||
if not isinstance(invoice_line.tax, TaxTotalOmit):
|
||||
fexml.set_invoice_line_tax(line, invoice_line)
|
||||
|
||||
if not isinstance(
|
||||
invoice_line.withholding,
|
||||
WithholdingTaxTotalOmit):
|
||||
fexml.set_invoice_line_withholding(line, invoice_line)
|
||||
|
||||
line.set_element(
|
||||
'./cac:Item/cbc:Description',
|
||||
invoice_line.item.description)
|
||||
|
||||
line.set_element(
|
||||
'./cac:Item/cac:StandardItemIdentification/cbc:ID',
|
||||
invoice_line.item.id,
|
||||
schemeID=invoice_line.item.scheme_id,
|
||||
schemeName=invoice_line.item.scheme_name,
|
||||
schemeAgencyID=invoice_line.item.scheme_agency_id)
|
||||
|
||||
line.set_element(
|
||||
'./cac:Price/cbc:PriceAmount',
|
||||
invoice_line.price.amount,
|
||||
currencyID=invoice_line.price.amount.currency.code)
|
||||
# DIAN 1.7.-2020: FBB04
|
||||
line.set_element('./cac:Price/cbc:BaseQuantity',
|
||||
invoice_line.quantity,
|
||||
unitCode=invoice_line.quantity.code)
|
||||
|
||||
for idx, charge in enumerate(invoice_line.allowance_charge):
|
||||
next_append_charge = idx > 0
|
||||
fexml.append_allowance_charge(
|
||||
line, index + 1, charge, append=next_append_charge)
|
||||
|
||||
def set_allowance_charge(fexml, invoice):
|
||||
for idx, charge in enumerate(invoice.invoice_allowance_charge):
|
||||
next_append = idx > 0
|
||||
fexml.append_allowance_charge(
|
||||
fexml, idx + 1, charge, append=next_append)
|
||||
|
||||
def append_allowance_charge(fexml, parent, idx, charge, append=False):
|
||||
line = parent.fragment('./cac:AllowanceCharge', append=append)
|
||||
# DIAN 1.7.-2020: FAQ02
|
||||
line.set_element('./cbc:ID', idx)
|
||||
# DIAN 1.7.-2020: FAQ03
|
||||
line.set_element('./cbc:ChargeIndicator',
|
||||
str(charge.charge_indicator).lower())
|
||||
if charge.reason:
|
||||
line.set_element(
|
||||
'./cbc:AllowanceChargeReasonCode',
|
||||
charge.reason.code)
|
||||
line.set_element(
|
||||
'./cbc:allowanceChargeReason',
|
||||
charge.reason.reason)
|
||||
line.set_element('./cbc:MultiplierFactorNumeric',
|
||||
str(round(charge.multiplier_factor_numeric, 2)))
|
||||
fexml.set_element_amount_for(line, './cbc:Amount', charge.amount)
|
||||
fexml.set_element_amount_for(
|
||||
line, './cbc:BaseAmount', charge.base_amount)
|
||||
|
||||
def attach_invoice(fexml, invoice):
|
||||
"""adiciona etiquetas a FEXML y retorna FEXML
|
||||
en caso de fallar validacion retorna None"""
|
||||
|
||||
fexml.placeholder_for('./ext:UBLExtensions')
|
||||
fexml.set_element('./cbc:UBLVersionID', 'UBL 2.1')
|
||||
fexml.set_element(
|
||||
'./cbc:CustomizationID',
|
||||
invoice.invoice_operation_type)
|
||||
fexml.placeholder_for('./cbc:ProfileID')
|
||||
fexml.placeholder_for('./cbc:ProfileExecutionID')
|
||||
fexml.set_element('./cbc:ID', invoice.invoice_ident)
|
||||
fexml.placeholder_for('./cbc:UUID')
|
||||
fexml.set_element('./cbc:DocumentCurrencyCode', 'COP')
|
||||
fexml.set_element(
|
||||
'./cbc:IssueDate',
|
||||
invoice.invoice_issue.strftime('%Y-%m-%d'))
|
||||
# DIAN 1.7.-2020: FAD10
|
||||
fexml.set_element(
|
||||
'./cbc:IssueTime',
|
||||
invoice.invoice_issue.strftime('%H:%M:%S-05:00'))
|
||||
fexml.set_element(
|
||||
'./cbc:%sTypeCode' %
|
||||
(fexml.tag_document()),
|
||||
invoice.invoice_type_code,
|
||||
listAgencyID='195',
|
||||
listAgencyName='No matching global declaration available for the validation root',
|
||||
listURI='http://www.dian.gov.co')
|
||||
fexml.set_element('./cbc:LineCountNumeric', len(invoice.invoice_lines))
|
||||
fexml.set_element(
|
||||
'./cac:%sPeriod/cbc:StartDate' %
|
||||
(fexml.tag_document()),
|
||||
invoice.invoice_period_start.strftime('%Y-%m-%d'))
|
||||
|
||||
fexml.set_element(
|
||||
'./cac:%sPeriod/cbc:EndDate' %
|
||||
(fexml.tag_document()),
|
||||
invoice.invoice_period_end.strftime('%Y-%m-%d'))
|
||||
|
||||
fexml.customize(invoice)
|
||||
|
||||
fexml.set_supplier(invoice)
|
||||
fexml.set_customer(invoice)
|
||||
fexml.set_legal_monetary(invoice)
|
||||
fexml.set_invoice_totals(invoice)
|
||||
fexml.set_invoice_lines(invoice)
|
||||
fexml.set_payment_mean(invoice)
|
||||
fexml.set_allowance_charge(invoice)
|
||||
fexml.set_discrepancy_response(invoice)
|
||||
fexml.set_billing_reference(invoice)
|
||||
|
||||
return fexml
|
||||
|
||||
def customize(fexml, invoice):
|
||||
"""adiciona etiquetas a FEXML y retorna FEXML
|
||||
en caso de fallar validacion retorna None"""
|
||||
@@ -1,25 +0,0 @@
|
||||
# from .. import fe
|
||||
# from ..form import *
|
||||
from .support_document import DIANSupportDocumentXML
|
||||
|
||||
__all__ = ['DIANSupportDocumentCreditNoteXML']
|
||||
|
||||
|
||||
class DIANSupportDocumentCreditNoteXML(DIANSupportDocumentXML):
|
||||
"""
|
||||
DianInvoiceXML mapea objeto form.Invoice a XML segun
|
||||
lo indicado para la facturacion electronica.
|
||||
"""
|
||||
|
||||
def __init__(self, invoice):
|
||||
super(
|
||||
DIANSupportDocumentCreditNoteXML,
|
||||
self).__init__(
|
||||
invoice,
|
||||
'CreditNote')
|
||||
|
||||
def tag_document(fexml):
|
||||
return 'CreditNote'
|
||||
|
||||
def tag_document_concilied(fexml):
|
||||
return 'Credited'
|
||||
@@ -2,30 +2,18 @@ from .. import fe
|
||||
|
||||
__all__ = ['DIANWrite', 'DIANWriteSigned']
|
||||
|
||||
|
||||
def DIANWrite(xml, filename):
|
||||
document = xml.tostring(xml_declaration=True, encoding='UTF-8')
|
||||
with open(filename, 'w') as f:
|
||||
f.write(document)
|
||||
|
||||
|
||||
def DIANWriteSigned(
|
||||
xml,
|
||||
filename,
|
||||
private_key,
|
||||
passphrase,
|
||||
use_cache_policy=False,
|
||||
dian_signer=None):
|
||||
document = xml.tostring(
|
||||
xml_declaration=True,
|
||||
encoding='UTF-8').encode('utf-8')
|
||||
|
||||
def DIANWriteSigned(xml, filename, private_key, passphrase, use_cache_policy=False, dian_signer=None):
|
||||
document = xml.tostring(xml_declaration=True, encoding='UTF-8').encode('utf-8')
|
||||
if dian_signer is None:
|
||||
dian_signer = fe.DianXMLExtensionSigner
|
||||
|
||||
signer = dian_signer(
|
||||
private_key,
|
||||
passphrase=passphrase,
|
||||
localpolicy=use_cache_policy)
|
||||
signer = dian_signer(private_key, passphrase=passphrase, localpolicy=use_cache_policy)
|
||||
|
||||
with open(filename, 'w') as f:
|
||||
f.write(signer.sign_xml_string(document))
|
||||
|
||||
Reference in New Issue
Block a user