[IMP] {l10n_}account_edi_ubl_cii{_tests},l10n_{ro,sa}_edi: add standard fields on UBL 2.0
The aim of this commit is mainly to add optional standard node directly
on UBL 2.0.
This will allow national customization of ubl to be easier to implement.
List of modification:
- Add the following nodes:
- AddressFormatCode
- BuildingNumber
- PlotIdentification
- CitySubdivisionName
- Name under TaxScheme
- DocumentTypeCode
- reduce zatca customization
- add attrs to several place to ease customization of attributes
- add a hook from which customization can override all decimal places to
enforce a maximum
- add a hook to ease the modification of the `legal_monetary_total_vals`
sub dict
- add method to allow customization to provide attributes for
DocumentTypeCode node.
Notes:
Regarding PlotIdentification and CitySubdivisionName, I decided to not
populate some of those field for now because I didn't think of a
reliable way to get their value while zatca benefits from fields created
in l10n_sa_edi.
Task-id: 3326977
Part-of: odoo/odoo#136072
This commit is contained in:
@@ -5,7 +5,11 @@
|
||||
<t xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
|
||||
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
|
||||
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
|
||||
<cbc:AddressFormatCode t-att="vals.get('address_format_code_attrs', {})" t-out="vals.get('address_format_code')"/>
|
||||
<cbc:StreetName t-out="vals.get('street_name')"/>
|
||||
<cbc:BuildingNumber t-out="vals.get('building_number')"/>
|
||||
<cbc:PlotIdentification t-out="vals.get('plot_identification')"/>
|
||||
<cbc:CitySubdivisionName t-out="vals.get('city_subdivision_name ')"/>
|
||||
<cbc:AdditionalStreetName t-out="vals.get('additional_street_name')"/>
|
||||
<cbc:CityName t-out="vals.get('city_name')"/>
|
||||
<cbc:PostalZone t-out="vals.get('postal_zone')"/>
|
||||
@@ -58,7 +62,10 @@
|
||||
</t>
|
||||
</cac:RegistrationAddress>
|
||||
<cac:TaxScheme>
|
||||
<cbc:ID t-out="foreach_vals.get('tax_scheme_id')"/>
|
||||
<cbc:ID
|
||||
t-att="foreach_vals.get('tax_scheme_id_attrs', {})"
|
||||
t-out="foreach_vals.get('tax_scheme_id')"/>
|
||||
<cbc:Name t-out="foreach_vals.get('tax_name')"/>
|
||||
</cac:TaxScheme>
|
||||
</cac:PartyTaxScheme>
|
||||
</t>
|
||||
@@ -67,8 +74,8 @@
|
||||
<cac:PartyLegalEntity>
|
||||
<cbc:RegistrationName t-out="foreach_vals.get('registration_name')"/>
|
||||
<cbc:CompanyID
|
||||
t-att="foreach_vals.get('company_id_attrs', {})"
|
||||
t-out="foreach_vals.get('company_id')"/>
|
||||
t-att="foreach_vals.get('company_id_attrs', {})"
|
||||
t-out="foreach_vals.get('company_id')"/>
|
||||
<cac:RegistrationAddress>
|
||||
<t t-call="{{AddressType_template}}">
|
||||
<t t-set="vals" t-value="foreach_vals.get('registration_address_vals', {})"/>
|
||||
@@ -139,7 +146,11 @@
|
||||
<cbc:TaxExemptionReason
|
||||
t-out="vals.get('tax_exemption_reason')"/>
|
||||
<cac:TaxScheme>
|
||||
<cbc:ID t-translation="off" t-out="vals.get('tax_scheme_id')"/>
|
||||
<cbc:ID
|
||||
t-translation="off"
|
||||
t-att="vals.get('tax_scheme_id_attrs')"
|
||||
t-out="vals.get('tax_scheme_id')"/>
|
||||
<cbc:Name t-translation="off" t-out="vals.get('tax_scheme_name')"/>
|
||||
</cac:TaxScheme>
|
||||
</t>
|
||||
</template>
|
||||
@@ -263,7 +274,9 @@
|
||||
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
|
||||
<cbc:UBLVersionID t-out="vals.get('ubl_version_id')"/>
|
||||
<cbc:CustomizationID t-out="vals.get('customization_id')"/>
|
||||
<cbc:ProfileID t-out="vals.get('profile_id')"/>
|
||||
<cbc:ProfileID
|
||||
t-att="vals.get('profile_id_attrs', {})"
|
||||
t-out="vals.get('profile_id')"/>
|
||||
<cbc:ID t-out="vals.get('id')"/>
|
||||
<cbc:IssueDate t-out="vals.get('issue_date')"/>
|
||||
<cbc:InvoiceTypeCode
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from odoo import _, models, Command
|
||||
from odoo.tools import float_repr
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
@@ -104,6 +102,10 @@ class AccountEdiCommon(models.AbstractModel):
|
||||
return None
|
||||
return float_repr(float_round(amount, precision_digits), precision_digits)
|
||||
|
||||
def _get_currency_decimal_places(self, currency_id):
|
||||
# Allows other documents to easily override in case there is a flat max precision number
|
||||
return currency_id.decimal_places
|
||||
|
||||
def _get_uom_unece_code(self, line):
|
||||
"""
|
||||
list of codes: https://docs.peppol.eu/poacc/billing/3.0/codelist/UNECERec20/
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from lxml import etree
|
||||
|
||||
from odoo import models, _
|
||||
from odoo.osv import expression
|
||||
from odoo.tools import html2plaintext, cleanup_xml_node, find_xml_value
|
||||
from lxml import etree
|
||||
|
||||
|
||||
class AccountEdiXmlUBL20(models.AbstractModel):
|
||||
@@ -169,7 +169,7 @@ class AccountEdiXmlUBL20(models.AbstractModel):
|
||||
def _get_invoice_tax_totals_vals_list(self, invoice, taxes_vals):
|
||||
tax_totals_vals = {
|
||||
'currency': invoice.currency_id,
|
||||
'currency_dp': invoice.currency_id.decimal_places,
|
||||
'currency_dp': self._get_currency_decimal_places(invoice.currency_id),
|
||||
'tax_amount': taxes_vals['tax_amount_currency'],
|
||||
'tax_subtotal_vals': [],
|
||||
}
|
||||
@@ -177,7 +177,7 @@ class AccountEdiXmlUBL20(models.AbstractModel):
|
||||
if grouping_key['tax_amount_type'] != 'fixed':
|
||||
tax_totals_vals['tax_subtotal_vals'].append({
|
||||
'currency': invoice.currency_id,
|
||||
'currency_dp': invoice.currency_id.decimal_places,
|
||||
'currency_dp': self._get_currency_decimal_places(invoice.currency_id),
|
||||
'taxable_amount': vals['base_amount_currency'],
|
||||
'tax_amount': vals['tax_amount_currency'],
|
||||
'percent': vals['_tax_category_vals_']['percent'],
|
||||
@@ -235,7 +235,7 @@ class AccountEdiXmlUBL20(models.AbstractModel):
|
||||
if grouping_key['tax_amount_type'] == 'fixed':
|
||||
fixed_tax_charge_vals_list.append({
|
||||
'currency_name': line.currency_id.name,
|
||||
'currency_dp': line.currency_id.decimal_places,
|
||||
'currency_dp': self._get_currency_decimal_places(line.currency_id),
|
||||
'charge_indicator': 'true',
|
||||
'allowance_charge_reason_code': 'AEO',
|
||||
'allowance_charge_reason': tax_details['tax_name'],
|
||||
@@ -255,7 +255,7 @@ class AccountEdiXmlUBL20(models.AbstractModel):
|
||||
|
||||
allowance_vals = {
|
||||
'currency_name': line.currency_id.name,
|
||||
'currency_dp': line.currency_id.decimal_places,
|
||||
'currency_dp': self._get_currency_decimal_places(line.currency_id),
|
||||
|
||||
# Must be 'false' since this method is for allowances.
|
||||
'charge_indicator': 'false',
|
||||
@@ -292,7 +292,7 @@ class AccountEdiXmlUBL20(models.AbstractModel):
|
||||
|
||||
return {
|
||||
'currency': line.currency_id,
|
||||
'currency_dp': line.currency_id.decimal_places,
|
||||
'currency_dp': self._get_currency_decimal_places(line.currency_id),
|
||||
|
||||
# The price of an item, exclusive of VAT, after subtracting item price discount.
|
||||
'price_amount': gross_price_unit,
|
||||
@@ -321,7 +321,7 @@ class AccountEdiXmlUBL20(models.AbstractModel):
|
||||
)
|
||||
return {
|
||||
'currency': line.currency_id,
|
||||
'currency_dp': line.currency_id.decimal_places,
|
||||
'currency_dp': self._get_currency_decimal_places(line.currency_id),
|
||||
'id': line_id + 1,
|
||||
'invoiced_quantity': line.quantity,
|
||||
'invoiced_quantity_attrs': {'unitCode': uom},
|
||||
@@ -332,13 +332,25 @@ class AccountEdiXmlUBL20(models.AbstractModel):
|
||||
'price_vals': self._get_invoice_line_price_vals(line),
|
||||
}
|
||||
|
||||
def _get_invoice_legal_monetary_total_vals(self, invoice, taxes_vals, line_extension_amount, allowance_total_amount):
|
||||
""" Method used to fill the cac:LegalMonetaryTotal node"""
|
||||
return {
|
||||
'currency': invoice.currency_id,
|
||||
'currency_dp': self._get_currency_decimal_places(invoice.currency_id),
|
||||
'line_extension_amount': line_extension_amount,
|
||||
'tax_exclusive_amount': taxes_vals['base_amount_currency'],
|
||||
'tax_inclusive_amount': invoice.amount_total,
|
||||
'allowance_total_amount': allowance_total_amount or None,
|
||||
'prepaid_amount': invoice.amount_total - invoice.amount_residual,
|
||||
'payable_amount': invoice.amount_residual,
|
||||
}
|
||||
|
||||
def _apply_invoice_tax_filter(self, base_line, tax_values):
|
||||
"""
|
||||
To be overridden to apply a specific tax filter
|
||||
"""
|
||||
return True
|
||||
|
||||
|
||||
def _apply_invoice_line_filter(self, invoice_line):
|
||||
"""
|
||||
To be overridden to apply a specific invoice line filter
|
||||
@@ -451,18 +463,9 @@ class AccountEdiXmlUBL20(models.AbstractModel):
|
||||
# allowances at the document level, the allowances on invoices (eg. discount) are on invoice_line_vals
|
||||
'allowance_charge_vals': document_allowance_charge_vals_list,
|
||||
'tax_total_vals': self._get_invoice_tax_totals_vals_list(invoice, taxes_vals),
|
||||
'legal_monetary_total_vals': {
|
||||
'currency': invoice.currency_id,
|
||||
'currency_dp': invoice.currency_id.decimal_places,
|
||||
'line_extension_amount': line_extension_amount,
|
||||
'tax_exclusive_amount': taxes_vals['base_amount_currency'],
|
||||
'tax_inclusive_amount': invoice.amount_total,
|
||||
'allowance_total_amount': allowance_total_amount or None,
|
||||
'prepaid_amount': invoice.amount_total - invoice.amount_residual,
|
||||
'payable_amount': invoice.amount_residual,
|
||||
},
|
||||
'legal_monetary_total_vals': self._get_invoice_legal_monetary_total_vals(invoice, taxes_vals, line_extension_amount, allowance_total_amount),
|
||||
'invoice_line_vals': invoice_line_vals_list,
|
||||
'currency_dp': invoice.currency_id.decimal_places, # currency decimal places
|
||||
'currency_dp': self._get_currency_decimal_places(invoice.currency_id), # currency decimal places
|
||||
},
|
||||
}
|
||||
|
||||
@@ -474,6 +477,7 @@ class AccountEdiXmlUBL20(models.AbstractModel):
|
||||
vals['vals']['credit_note_type_code'] = 381
|
||||
|
||||
return vals
|
||||
|
||||
def _export_invoice_constraints(self, invoice, vals):
|
||||
constraints = self._invoice_constraints_common(invoice)
|
||||
constraints.update({
|
||||
@@ -491,6 +495,13 @@ class AccountEdiXmlUBL20(models.AbstractModel):
|
||||
xml_content = self.env['ir.qweb']._render(vals['main_template'], vals)
|
||||
return etree.tostring(cleanup_xml_node(xml_content), xml_declaration=True, encoding='UTF-8'), set(errors)
|
||||
|
||||
def _get_document_type_code_vals(self, invoice, invoice_data):
|
||||
"""Returns the values used for the `DocumentTypeCode` node"""
|
||||
# To be overriden by custom format if required
|
||||
# http://www.datypic.com/sc/ubl20/e-cbc_DocumentTypeCode.html
|
||||
document_type_code = 380 if invoice.move_type == 'out_invoice' else 381
|
||||
return {'attrs': {}, 'value': document_type_code}
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# IMPORT
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
@@ -56,3 +56,10 @@ class AccountMove(models.Model):
|
||||
def _get_edi_doc_attachments_to_export(self):
|
||||
# EXTENDS 'account'
|
||||
return super()._get_edi_doc_attachments_to_export() + self.ubl_cii_xml_id
|
||||
|
||||
def _need_ubl_cii_xml(self):
|
||||
self.ensure_one()
|
||||
return not self.invoice_pdf_report_id \
|
||||
and not self.ubl_cii_xml_id \
|
||||
and self.is_sale_document() \
|
||||
and bool(self.partner_id.ubl_cii_format)
|
||||
|
||||
@@ -17,16 +17,9 @@ class AccountMoveSend(models.Model):
|
||||
_inherit = 'account.move.send'
|
||||
|
||||
enable_ubl_cii_xml = fields.Boolean(compute='_compute_send_mail_extra_fields')
|
||||
checkbox_ubl_cii_label = fields.Char(compute='_compute_checkbox_ubl_cii_label') # label for the checkbox_ubl_cii_xml field
|
||||
checkbox_ubl_cii_label = fields.Char(compute='_compute_checkbox_ubl_cii_label')
|
||||
checkbox_ubl_cii_xml = fields.Boolean(compute='_compute_checkbox_ubl_cii_xml', store=True, readonly=False)
|
||||
|
||||
@api.model
|
||||
def _get_default_enable_ubl_cii_xml(self, move):
|
||||
return not move.invoice_pdf_report_id \
|
||||
and not move.ubl_cii_xml_id \
|
||||
and move.is_sale_document() \
|
||||
and bool(move.partner_id.ubl_cii_format)
|
||||
|
||||
def _get_available_field_values_in_multi(self, move):
|
||||
# EXTENDS 'account'
|
||||
values = super()._get_available_field_values_in_multi(move)
|
||||
@@ -51,7 +44,7 @@ class AccountMoveSend(models.Model):
|
||||
# EXTENDS 'account'
|
||||
super()._compute_send_mail_extra_fields()
|
||||
for wizard in self:
|
||||
wizard.enable_ubl_cii_xml = any(wizard._get_default_enable_ubl_cii_xml(m) for m in wizard.move_ids)
|
||||
wizard.enable_ubl_cii_xml = any(m._need_ubl_cii_xml() for m in wizard.move_ids)
|
||||
|
||||
@api.depends('checkbox_ubl_cii_xml')
|
||||
def _compute_mail_attachments_widget(self):
|
||||
@@ -99,9 +92,8 @@ class AccountMoveSend(models.Model):
|
||||
# EXTENDS 'account'
|
||||
super()._hook_invoice_document_before_pdf_report_render(invoice, invoice_data)
|
||||
|
||||
if self.mode == 'invoice_single' and self.checkbox_ubl_cii_xml and self._get_default_enable_ubl_cii_xml(invoice):
|
||||
if self.mode == 'invoice_single' and self.checkbox_ubl_cii_xml and invoice._need_ubl_cii_xml():
|
||||
builder = invoice.partner_id._get_edi_builder()
|
||||
|
||||
xml_content, errors = builder._export_invoice(invoice)
|
||||
filename = builder._export_invoice_filename(invoice)
|
||||
|
||||
@@ -136,8 +128,8 @@ class AccountMoveSend(models.Model):
|
||||
if 'ubl_cii_xml_options' in invoice_data and invoice_data['ubl_cii_xml_options']['ubl_cii_format'] != 'facturx':
|
||||
self._postprocess_invoice_ubl_xml(invoice, invoice_data)
|
||||
|
||||
# Always silently generate a Factur-X and embed it inside the PDF (inter-portability)
|
||||
if 'ubl_cii_xml_options' in invoice_data and invoice_data['ubl_cii_xml_options']['ubl_cii_format'] == 'facturx':
|
||||
# Always silently generate a Factur-X and embed it inside the PDF for inter-portability
|
||||
if invoice_data.get('ubl_cii_xml_options', {}).get('ubl_cii_format') == 'facturx':
|
||||
xml_facturx = invoice_data['ubl_cii_xml_attachment_values']['raw']
|
||||
else:
|
||||
xml_facturx = self.env['account.edi.xml.cii']._export_invoice(invoice)[0]
|
||||
@@ -163,8 +155,7 @@ class AccountMoveSend(models.Model):
|
||||
writer.addAttachment('factur-x.xml', xml_facturx, subtype='text/xml')
|
||||
|
||||
# PDF-A.
|
||||
if 'ubl_cii_xml_options' in invoice_data \
|
||||
and invoice_data['ubl_cii_xml_options']['ubl_cii_format'] == 'facturx' \
|
||||
if invoice_data.get('ubl_cii_xml_options', {}).get('ubl_cii_format') == 'facturx' \
|
||||
and not writer.is_pdfa:
|
||||
try:
|
||||
writer.convert_to_pdfa()
|
||||
@@ -189,7 +180,7 @@ class AccountMoveSend(models.Model):
|
||||
writer_buffer.close()
|
||||
|
||||
def _postprocess_invoice_ubl_xml(self, invoice, invoice_data):
|
||||
# Add PDF to XML
|
||||
# Adding the PDF to the XML
|
||||
tree = etree.fromstring(invoice_data['ubl_cii_xml_attachment_values']['raw'])
|
||||
anchor_elements = tree.xpath("//*[local-name()='AccountingSupplierParty']")
|
||||
if not anchor_elements:
|
||||
@@ -197,12 +188,19 @@ class AccountMoveSend(models.Model):
|
||||
|
||||
filename = invoice_data['pdf_attachment_values']['name']
|
||||
content = invoice_data['pdf_attachment_values']['raw']
|
||||
|
||||
edi_model = invoice_data["ubl_cii_xml_options"]["builder"]
|
||||
doc_type_code_vals = edi_model._get_document_type_code_vals(invoice, invoice_data)
|
||||
document_type_code_attributes = " ".join(f'{name}="{value}"' for name, value in doc_type_code_vals['attrs'].items())
|
||||
document_type_code_value = doc_type_code_vals.get('value', '')
|
||||
|
||||
to_inject = f'''
|
||||
<cac:AdditionalDocumentReference
|
||||
xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
|
||||
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
|
||||
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2">
|
||||
<cbc:ID>{escape(filename)}</cbc:ID>
|
||||
<cbc:DocumentTypeCode {document_type_code_attributes}>{document_type_code_value}</cbc:DocumentTypeCode>
|
||||
<cac:Attachment>
|
||||
<cbc:EmbeddedDocumentBinaryObject
|
||||
mimeCode="application/pdf"
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
</cac:OrderReference>
|
||||
<cac:AdditionalDocumentReference>
|
||||
<cbc:ID>___ignore___</cbc:ID>
|
||||
<cbc:DocumentTypeCode>380</cbc:DocumentTypeCode>
|
||||
<cbc:Attachment>
|
||||
<cbc:EmbeddedDocumentBinaryObject>___ignore___</cbc:EmbeddedDocumentBinaryObject>
|
||||
</cbc:Attachment>
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
</cac:OrderReference>
|
||||
<cac:AdditionalDocumentReference>
|
||||
<cbc:ID>___ignore___</cbc:ID>
|
||||
<cbc:DocumentTypeCode>381</cbc:DocumentTypeCode>
|
||||
<cbc:Attachment>
|
||||
<cbc:EmbeddedDocumentBinaryObject>___ignore___</cbc:EmbeddedDocumentBinaryObject>
|
||||
</cbc:Attachment>
|
||||
|
||||
+1
@@ -17,6 +17,7 @@
|
||||
</cac:OrderReference>
|
||||
<cac:AdditionalDocumentReference>
|
||||
<cbc:ID>___ignore___</cbc:ID>
|
||||
<cbc:DocumentTypeCode>380</cbc:DocumentTypeCode>
|
||||
<cbc:Attachment>
|
||||
<cbc:EmbeddedDocumentBinaryObject mimeCode="___ignore___" filename="___ignore___">___ignore___</cbc:EmbeddedDocumentBinaryObject>
|
||||
</cbc:Attachment>
|
||||
|
||||
+1
@@ -17,6 +17,7 @@
|
||||
</cac:OrderReference>
|
||||
<cac:AdditionalDocumentReference>
|
||||
<cbc:ID>___ignore___</cbc:ID>
|
||||
<cbc:DocumentTypeCode>380</cbc:DocumentTypeCode>
|
||||
<cbc:Attachment>
|
||||
<cbc:EmbeddedDocumentBinaryObject mimeCode="___ignore___" filename="___ignore___">___ignore___</cbc:EmbeddedDocumentBinaryObject>
|
||||
</cbc:Attachment>
|
||||
|
||||
+1
@@ -17,6 +17,7 @@
|
||||
</cac:OrderReference>
|
||||
<cac:AdditionalDocumentReference>
|
||||
<cbc:ID>___ignore___</cbc:ID>
|
||||
<cbc:DocumentTypeCode>380</cbc:DocumentTypeCode>
|
||||
<cbc:Attachment>
|
||||
<cbc:EmbeddedDocumentBinaryObject mimeCode="___ignore___" filename="___ignore___">___ignore___</cbc:EmbeddedDocumentBinaryObject>
|
||||
</cbc:Attachment>
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
</cac:OrderReference>
|
||||
<cac:AdditionalDocumentReference>
|
||||
<cbc:ID>___ignore___</cbc:ID>
|
||||
<cbc:DocumentTypeCode>380</cbc:DocumentTypeCode>
|
||||
<cbc:Attachment>
|
||||
<cbc:EmbeddedDocumentBinaryObject>___ignore___</cbc:EmbeddedDocumentBinaryObject>
|
||||
</cbc:Attachment>
|
||||
|
||||
+1
@@ -14,6 +14,7 @@
|
||||
</cac:OrderReference>
|
||||
<cac:AdditionalDocumentReference>
|
||||
<cbc:ID>___ignore___</cbc:ID>
|
||||
<cbc:DocumentTypeCode>380</cbc:DocumentTypeCode>
|
||||
<cbc:Attachment>
|
||||
<cbc:EmbeddedDocumentBinaryObject>___ignore___</cbc:EmbeddedDocumentBinaryObject>
|
||||
</cbc:Attachment>
|
||||
|
||||
+1
@@ -17,6 +17,7 @@
|
||||
</cac:OrderReference>
|
||||
<cac:AdditionalDocumentReference>
|
||||
<cbc:ID>___ignore___</cbc:ID>
|
||||
<cbc:DocumentTypeCode>380</cbc:DocumentTypeCode>
|
||||
<cbc:Attachment>
|
||||
<cbc:EmbeddedDocumentBinaryObject mimeCode="___ignore___" filename="___ignore___">
|
||||
___ignore___
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
</cac:OrderReference>
|
||||
<cac:AdditionalDocumentReference>
|
||||
<cbc:ID>___ignore___</cbc:ID>
|
||||
<cbc:DocumentTypeCode>381</cbc:DocumentTypeCode>
|
||||
<cbc:Attachment>
|
||||
<cbc:EmbeddedDocumentBinaryObject>___ignore___</cbc:EmbeddedDocumentBinaryObject>
|
||||
</cbc:Attachment>
|
||||
|
||||
+1
@@ -14,6 +14,7 @@
|
||||
</cac:OrderReference>
|
||||
<cac:AdditionalDocumentReference>
|
||||
<cbc:ID>___ignore___</cbc:ID>
|
||||
<cbc:DocumentTypeCode>380</cbc:DocumentTypeCode>
|
||||
<cbc:Attachment>
|
||||
<cbc:EmbeddedDocumentBinaryObject>___ignore___</cbc:EmbeddedDocumentBinaryObject>
|
||||
</cbc:Attachment>
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
</cac:BillingReference>
|
||||
<cac:AdditionalDocumentReference>
|
||||
<cbc:ID>___ignore___</cbc:ID>
|
||||
<cbc:DocumentTypeCode>381</cbc:DocumentTypeCode>
|
||||
<cbc:Attachment>
|
||||
<cbc:EmbeddedDocumentBinaryObject>___ignore___</cbc:EmbeddedDocumentBinaryObject>
|
||||
</cbc:Attachment>
|
||||
|
||||
+1
@@ -14,6 +14,7 @@
|
||||
</cac:OrderReference>
|
||||
<cac:AdditionalDocumentReference>
|
||||
<cbc:ID>___ignore___</cbc:ID>
|
||||
<cbc:DocumentTypeCode>380</cbc:DocumentTypeCode>
|
||||
<cbc:Attachment>
|
||||
<cbc:EmbeddedDocumentBinaryObject>___ignore___</cbc:EmbeddedDocumentBinaryObject>
|
||||
</cbc:Attachment>
|
||||
|
||||
+1
@@ -13,6 +13,7 @@
|
||||
</cac:OrderReference>
|
||||
<cac:AdditionalDocumentReference>
|
||||
<cbc:ID>___ignore___</cbc:ID>
|
||||
<cbc:DocumentTypeCode>381</cbc:DocumentTypeCode>
|
||||
<cbc:Attachment>
|
||||
<cbc:EmbeddedDocumentBinaryObject>___ignore___</cbc:EmbeddedDocumentBinaryObject>
|
||||
</cbc:Attachment>
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
</cac:OrderReference>
|
||||
<cac:AdditionalDocumentReference>
|
||||
<cbc:ID>INV_2017_00001.pdf</cbc:ID>
|
||||
<cbc:DocumentTypeCode>380</cbc:DocumentTypeCode>
|
||||
<cac:Attachment>
|
||||
<cbc:EmbeddedDocumentBinaryObject mimeCode="application/pdf" filename="INV_2017_00001.pdf">___ignore___</cbc:EmbeddedDocumentBinaryObject>
|
||||
</cac:Attachment>
|
||||
|
||||
+1
@@ -15,6 +15,7 @@
|
||||
</cac:OrderReference>
|
||||
<cac:AdditionalDocumentReference>
|
||||
<cbc:ID>INV_2017_00001.pdf</cbc:ID>
|
||||
<cbc:DocumentTypeCode>380</cbc:DocumentTypeCode>
|
||||
<cac:Attachment>
|
||||
<cbc:EmbeddedDocumentBinaryObject mimeCode="application/pdf" filename="INV_2017_00001.pdf">___ignore___</cbc:EmbeddedDocumentBinaryObject>
|
||||
</cac:Attachment>
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
</cac:OrderReference>
|
||||
<cac:AdditionalDocumentReference xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
|
||||
<cbc:ID>RINV_2017_00001.pdf</cbc:ID>
|
||||
<cbc:DocumentTypeCode>381</cbc:DocumentTypeCode>
|
||||
<cac:Attachment>
|
||||
<cbc:EmbeddedDocumentBinaryObject mimeCode="application/pdf" filename="RINV_2017_00001.pdf">___ignore___</cbc:EmbeddedDocumentBinaryObject>
|
||||
</cac:Attachment>
|
||||
|
||||
@@ -176,18 +176,6 @@
|
||||
<template id="ubl_21_AddressType_zatca" inherit_id="account_edi_ubl_cii.ubl_20_AddressType" primary="True">
|
||||
<!-- AdditionalStreetName causes the Validation SDK to crash, so it has to be removed -->
|
||||
<xpath expr="//*[local-name()='AdditionalStreetName']" position="replace"/>
|
||||
<xpath expr="//*[local-name()='StreetName']" position="after">
|
||||
<t xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
|
||||
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
|
||||
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
|
||||
<!-- Add Building number in compliance with rules KSA-17 (seller)/ KSA-18 (customer) -->
|
||||
<cbc:BuildingNumber t-out="vals.get('building_number')"/>
|
||||
<!-- Add Plot identification in compliance with rules KSA-23 (seller)/ KSA-19 (customer) -->
|
||||
<cbc:PlotIdentification t-out="vals.get('plot_identification')"/>
|
||||
<!-- Add Neighborhood in compliance with rules KSA-3 (seller)/ KSA-4 (customer) -->
|
||||
<cbc:CitySubdivisionName t-out="vals.get('neighborhood')"/>
|
||||
</t>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="ubl_21_InvoiceType_zatca" inherit_id="account_edi_ubl_cii.ubl_21_InvoiceType" primary="True">
|
||||
|
||||
@@ -118,7 +118,7 @@ class AccountEdiXmlUBL21Zatca(models.AbstractModel):
|
||||
return {
|
||||
**super()._get_partner_address_vals(partner),
|
||||
'building_number': partner.l10n_sa_edi_building_number,
|
||||
'neighborhood': partner.street2,
|
||||
'city_subdivision_name ': partner.street2,
|
||||
'plot_identification': partner.l10n_sa_edi_plot_identification,
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user