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