From 2263f6e1fee021ac5b2cd2faddd8c793a314e23b Mon Sep 17 00:00:00 2001 From: Stana Natanaela Date: Fri, 2 Feb 2024 10:24:43 +0200 Subject: [PATCH 1/5] [14.0] adaugare import factura si modificare export_cius_ro --- .../models/account_edi_format.py | 66 ++++++++-------- .../models/account_edi_xml_cius_ro.py | 77 ++++++++++++++++++- 2 files changed, 110 insertions(+), 33 deletions(-) diff --git a/l10n_ro_account_edi_ubl/models/account_edi_format.py b/l10n_ro_account_edi_ubl/models/account_edi_format.py index b22429052..74715602d 100644 --- a/l10n_ro_account_edi_ubl/models/account_edi_format.py +++ b/l10n_ro_account_edi_ubl/models/account_edi_format.py @@ -18,39 +18,41 @@ class AccountEdiXmlCIUSRO(models.Model): def _export_cius_ro(self, invoice): self.ensure_one() # Create file content. - builder = self._get_xml_builder(invoice.company_id) - xml_content, errors = builder._export_invoice(invoice) - if errors: - raise UserError( - _("The following errors occurred while generating the " "XML file:\n%s") - % "\n".join(errors) + res = self.env["ir.attachment"] + if not invoice.l10n_ro_edi_transaction: + edi_document = invoice.edi_document_ids.filtered( + lambda l: l.edi_format_id.code == "cius_ro" ) - xml_content = xml_content.decode() - xml_content = xml_content.encode() - xml_name = builder._export_invoice_filename(invoice) - old_attachment = self.env["ir.attachment"].search( - [ - ("res_model", "=", "account.move"), - ("res_id", "=", invoice.id), - ("name", "=", xml_name), - ] - ) - edi_document = invoice.edi_document_ids.filtered( - lambda x: x.attachment_id in old_attachment.ids - ) - if edi_document: - edi_document.attachment_id = False - - old_attachment.unlink() - return self.env["ir.attachment"].create( - { - "name": xml_name, - "raw": xml_content, - "mimetype": "application/xml", - "res_model": "account.move", - "res_id": invoice.id, - } - ) + if edi_document: + builder = self._get_xml_builder(invoice.company_id) + xml_content, errors = builder._export_invoice(invoice) + if errors: + raise UserError( + _( + "The following errors occurred while generating the " + "XML file:\n%s" + ) + % "\n".join(errors) + ) + xml_content = xml_content.decode() + xml_content = xml_content.encode() + xml_name = builder._export_invoice_filename(invoice) + old_attachment = edi_document.attachment_id + if old_attachment: + edi_document.attachment_id = False + old_attachment.unlink() + res = self.env["ir.attachment"].create( + { + "name": xml_name, + "raw": xml_content, + "mimetype": "application/xml", + "res_model": "account.move", + "res_id": invoice.id, + } + ) + else: + res = invoice._get_edi_attachment(self) + return res def _export_invoice_filename(self, invoice): return f"{invoice.name.replace('/', '_')}_cius_ro.xml" diff --git a/l10n_ro_account_edi_ubl/models/account_edi_xml_cius_ro.py b/l10n_ro_account_edi_ubl/models/account_edi_xml_cius_ro.py index 497634e04..75a34740a 100644 --- a/l10n_ro_account_edi_ubl/models/account_edi_xml_cius_ro.py +++ b/l10n_ro_account_edi_ubl/models/account_edi_xml_cius_ro.py @@ -2,6 +2,9 @@ # Copyright (C) 2022 NextERP Romania # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from base64 import b64decode, b64encode + +import requests from odoo import _, models @@ -49,7 +52,10 @@ def _get_tax_category_list(self, invoice, taxes): # for vals in vals_list: # vals.pop('tax_exemption_reason', None) for vals in vals_list: - if "Invers" in taxes.name: + word_to_check = "Invers" + if any( + word_to_check.lower() in word.lower() for word in taxes.mapped("name") + ): vals["id"] = "AE" vals["tax_category_code"] = "AE" vals["tax_exemption_reason_code"] = "VATEX-EU-AE" @@ -219,3 +225,72 @@ def _import_fill_invoice_line_taxes( return super()._import_fill_invoice_line_taxes( journal, tax_nodes, invoice_line_form, inv_line_vals, logs ) + + def _import_invoice(self, journal, filename, tree, existing_invoice=None): + invoice = super(AccountEdiXmlCIUSRO, self)._import_invoice( + journal, filename, tree, existing_invoice=existing_invoice + ) + additional_docs = tree.findall("./{*}AdditionalDocumentReference") + if len(additional_docs) == 0: + res = self.l10n_ro_renderAnafPdf(invoice) + if not res: + pdf = ( + self.env["ir.actions.report"] + .sudo() + ._render_qweb_pdf( + "account.account_invoices_without_payment", [invoice.id] + ) + ) + b64_pdf = b64encode(pdf[0]) + self.l10n_ro_addPDF_from_att(invoice, b64_pdf) + return invoice + + def l10n_ro_renderAnafPdf(self, invoice): + attachement = invoice.attachment_ids.filtered( + lambda x: f"{invoice.l10n_ro_edi_transaction}.xml" in x.name + ) + if not attachement: + return False + headers = {"Content-Type": "text/plain"} + xml = b64decode(attachement.datas) + val1 = "refund" in invoice.move_type and "FCN" or "FACT1" + val2 = "DA" + try: + res = requests.post( + f"https://webservicesp.anaf.ro/prod/FCTEL/rest/transformare/{val1}/{val2}", + data=xml, + headers=headers, + timeout=10, + ) + if "The requested URL was rejected" in res.text: + xml = xml.replace( + b'xsi:schemaLocation="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2 ../../UBL-2.1(1)/xsd/maindoc/UBLInvoice-2.1.xsd"', # noqa: B950 + "", + ) + res = requests.post( + f"https://webservicesp.anaf.ro/prod/FCTEL/rest/transformare/{val1}/{val2}", + data=xml, + headers=headers, + timeout=10, + ) + except Exception: + return False + else: + return self.l10n_ro_addPDF_from_att(invoice, b64encode(res.content)) + + def l10n_ro_addPDF_from_att(self, invoice, pdf): + attachments = self.env["ir.attachment"].create( + { + "name": invoice.ref, + "res_id": invoice.id, + "res_model": "account.move", + "datas": pdf + b"=" * (len(pdf) % 3), # Fix incorrect padding + "type": "binary", + "mimetype": "application/pdf", + } + ) + if attachments: + invoice.with_context(no_new_invoice=True).message_post( + attachment_ids=attachments.ids + ) + return True From b5c06f1b8635bc28cc2d4669c70963a9882eb367 Mon Sep 17 00:00:00 2001 From: Stana Natanaela Date: Fri, 2 Feb 2024 14:11:31 +0200 Subject: [PATCH 2/5] update l10n_ro_renderAnafPdf --- .../models/account_edi_xml_cius_ro.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/l10n_ro_account_edi_ubl/models/account_edi_xml_cius_ro.py b/l10n_ro_account_edi_ubl/models/account_edi_xml_cius_ro.py index 75a34740a..668d2025a 100644 --- a/l10n_ro_account_edi_ubl/models/account_edi_xml_cius_ro.py +++ b/l10n_ro_account_edi_ubl/models/account_edi_xml_cius_ro.py @@ -246,13 +246,19 @@ def _import_invoice(self, journal, filename, tree, existing_invoice=None): return invoice def l10n_ro_renderAnafPdf(self, invoice): - attachement = invoice.attachment_ids.filtered( + inv_attachments = self.env["ir.attachment"].search( + [ + ("res_model", "=", "account.move"), + ("res_id", "=", invoice.id), + ] + ) + attachment = inv_attachments.filtered( lambda x: f"{invoice.l10n_ro_edi_transaction}.xml" in x.name ) - if not attachement: + if not attachment: return False headers = {"Content-Type": "text/plain"} - xml = b64decode(attachement.datas) + xml = b64decode(attachment.datas) val1 = "refund" in invoice.move_type and "FCN" or "FACT1" val2 = "DA" try: From dcd2e329f6aec4d9e1e522047a009bb55fd95e41 Mon Sep 17 00:00:00 2001 From: Fekete Mihai Date: Sat, 3 Feb 2024 14:13:02 +0200 Subject: [PATCH 3/5] Update __manifest__.py --- l10n_ro_account_edi_ubl/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/l10n_ro_account_edi_ubl/__manifest__.py b/l10n_ro_account_edi_ubl/__manifest__.py index bc819f1f2..2b9e50d04 100644 --- a/l10n_ro_account_edi_ubl/__manifest__.py +++ b/l10n_ro_account_edi_ubl/__manifest__.py @@ -21,7 +21,7 @@ "views/cius_template.xml", ], "license": "AGPL-3", - "version": "14.0.1.26.1", + "version": "14.0.1.26.2", "author": "Terrabit," "NextERP Romania," "Odoo Community Association (OCA)", "website": "https://github.com/OCA/l10n-romania", "installable": True, From fb843a2dab9bf21b2bd46b45f047c3fa97555333 Mon Sep 17 00:00:00 2001 From: Stana Natanaela Date: Sat, 3 Feb 2024 14:16:33 +0200 Subject: [PATCH 4/5] update _get_invoice_line_item_vals --- .../models/account_edi_xml_cius_ro.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/l10n_ro_account_edi_ubl/models/account_edi_xml_cius_ro.py b/l10n_ro_account_edi_ubl/models/account_edi_xml_cius_ro.py index 668d2025a..64abd9793 100644 --- a/l10n_ro_account_edi_ubl/models/account_edi_xml_cius_ro.py +++ b/l10n_ro_account_edi_ubl/models/account_edi_xml_cius_ro.py @@ -93,9 +93,12 @@ def _get_invoice_line_item_vals(self, line, taxes_vals): vals = super()._get_invoice_line_item_vals(line, taxes_vals) vals["description"] = vals["description"][:200] vals["name"] = vals["name"][:100] - if vals["classified_tax_category_vals"][0]["tax_category_code"] == "AE": - vals["classified_tax_category_vals"][0]["tax_exemption_reason_code"] = "" - vals["classified_tax_category_vals"][0]["tax_exemption_reason"] = "" + if vals["classified_tax_category_vals"]: + if vals["classified_tax_category_vals"][0]["tax_category_code"] == "AE": + vals["classified_tax_category_vals"][0][ + "tax_exemption_reason_code" + ] = "" + vals["classified_tax_category_vals"][0]["tax_exemption_reason"] = "" return vals def _get_invoice_line_price_vals(self, line): From daeae3fa4366803e929ebe884547328a7720e9ad Mon Sep 17 00:00:00 2001 From: Stana Natanaela Date: Wed, 7 Feb 2024 11:10:37 +0200 Subject: [PATCH 5/5] update _import_invoice --- l10n_ro_account_edi_ubl/README.rst | 2 +- l10n_ro_account_edi_ubl/models/account_edi_xml_cius_ro.py | 6 ++---- l10n_ro_account_edi_ubl/static/description/index.html | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/l10n_ro_account_edi_ubl/README.rst b/l10n_ro_account_edi_ubl/README.rst index 4f874aa79..97be9f114 100644 --- a/l10n_ro_account_edi_ubl/README.rst +++ b/l10n_ro_account_edi_ubl/README.rst @@ -7,7 +7,7 @@ Romania - eFactura Account EDI UBL !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:f0742680032ecf2d84a81327307c618d7b00e80c530e4ea063f68dbea1db3002 + !! source digest: sha256:135a7168588c1a063969fa7e09e27650225a9ee3e08a25bed1bbe074c279aad1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Mature-brightgreen.png diff --git a/l10n_ro_account_edi_ubl/models/account_edi_xml_cius_ro.py b/l10n_ro_account_edi_ubl/models/account_edi_xml_cius_ro.py index 64abd9793..f72c307de 100644 --- a/l10n_ro_account_edi_ubl/models/account_edi_xml_cius_ro.py +++ b/l10n_ro_account_edi_ubl/models/account_edi_xml_cius_ro.py @@ -238,11 +238,9 @@ def _import_invoice(self, journal, filename, tree, existing_invoice=None): res = self.l10n_ro_renderAnafPdf(invoice) if not res: pdf = ( - self.env["ir.actions.report"] + self.env.ref("account.account_invoices_without_payment") .sudo() - ._render_qweb_pdf( - "account.account_invoices_without_payment", [invoice.id] - ) + ._render_qweb_pdf([invoice.id]) ) b64_pdf = b64encode(pdf[0]) self.l10n_ro_addPDF_from_att(invoice, b64_pdf) diff --git a/l10n_ro_account_edi_ubl/static/description/index.html b/l10n_ro_account_edi_ubl/static/description/index.html index 97a6cf08c..3aa372ca6 100644 --- a/l10n_ro_account_edi_ubl/static/description/index.html +++ b/l10n_ro_account_edi_ubl/static/description/index.html @@ -367,7 +367,7 @@

Romania - eFactura Account EDI UBL

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:f0742680032ecf2d84a81327307c618d7b00e80c530e4ea063f68dbea1db3002 +!! source digest: sha256:135a7168588c1a063969fa7e09e27650225a9ee3e08a25bed1bbe074c279aad1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Mature License: AGPL-3 OCA/l10n-romania Translate me on Weblate Try me on Runboat

The module will generate E-Invoice XML files according to ANAF E-Invoicing service.