From 01532c2216a556bb2abbb626d3fc03ac55a8506f Mon Sep 17 00:00:00 2001 From: "Andrea Grazioso (agr-odoo)" Date: Tue, 30 Jan 2024 16:59:18 +0100 Subject: [PATCH] [FIX] l10n_ke_edi_tremol: send proforma when missing legal info With Kenya localization installed Create an invoice Send&Print Issue: The sytem will issue the final pdf before the invoice has been send to the fiscal device, so the legal information is actually missing Solution: 1. If the allow_fallback_pdf is True (in case of transaction from the e-commerce for example) we generate a proforma pdf invoice. 2. Else we raise an error to prevent the user to send invalid invoice. Also added a warning to let the user know that a proforma will be generated because the invoice was not sent to the Fiscal Device. opw-3599869 closes odoo/odoo#151751 Signed-off-by: Laurent Smet (las) Signed-off-by: Andrea Grazioso (agr) Co-authored-by: Claire Bretton (clbr) --- addons/l10n_ke_edi_tremol/__init__.py | 1 + addons/l10n_ke_edi_tremol/__manifest__.py | 1 + .../i18n/l10n_ke_edi_tremol.pot | 18 +++++++ .../l10n_ke_edi_tremol/models/account_move.py | 10 ++++ addons/l10n_ke_edi_tremol/tests/__init__.py | 3 +- .../tests/test_account_move_send.py | 49 +++++++++++++++++++ addons/l10n_ke_edi_tremol/wizard/__init__.py | 1 + .../wizard/account_move_send.py | 36 ++++++++++++++ .../wizard/account_move_send_views.xml | 19 +++++++ 9 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 addons/l10n_ke_edi_tremol/tests/test_account_move_send.py create mode 100644 addons/l10n_ke_edi_tremol/wizard/__init__.py create mode 100644 addons/l10n_ke_edi_tremol/wizard/account_move_send.py create mode 100644 addons/l10n_ke_edi_tremol/wizard/account_move_send_views.xml diff --git a/addons/l10n_ke_edi_tremol/__init__.py b/addons/l10n_ke_edi_tremol/__init__.py index 516b13b639e..e48b94ed9e1 100644 --- a/addons/l10n_ke_edi_tremol/__init__.py +++ b/addons/l10n_ke_edi_tremol/__init__.py @@ -2,3 +2,4 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. # from . import models +from . import wizard diff --git a/addons/l10n_ke_edi_tremol/__manifest__.py b/addons/l10n_ke_edi_tremol/__manifest__.py index 02cb3bc789e..6795c34957a 100644 --- a/addons/l10n_ke_edi_tremol/__manifest__.py +++ b/addons/l10n_ke_edi_tremol/__manifest__.py @@ -16,6 +16,7 @@ This module integrates with the Kenyan G03 Tremol control unit device to the KRA 'views/report_invoice.xml', 'views/res_config_settings_view.xml', 'views/res_partner_views.xml', + 'wizard/account_move_send_views.xml', ], 'assets': { 'web.assets_backend': [ diff --git a/addons/l10n_ke_edi_tremol/i18n/l10n_ke_edi_tremol.pot b/addons/l10n_ke_edi_tremol/i18n/l10n_ke_edi_tremol.pot index c1301ae598b..87a82c188f8 100644 --- a/addons/l10n_ke_edi_tremol/i18n/l10n_ke_edi_tremol.pot +++ b/addons/l10n_ke_edi_tremol/i18n/l10n_ke_edi_tremol.pot @@ -258,6 +258,14 @@ msgid "" "The exemption number of the partner. Provided by the Kenyan government." msgstr "" +#. module: l10n_ke_edi_tremol +#. odoo-python +#: code:addons/l10n_ke_edi_tremol/wizard/account_move_send.py:0 +#, python-format +msgid "" +"The following documents have no details related to the fiscal device." +msgstr "" + #. module: l10n_ke_edi_tremol #: model_terms:ir.ui.view,arch_db:l10n_ke_edi_tremol.res_config_settings_view_form msgid "" @@ -274,6 +282,16 @@ msgid "" msgstr "" #. module: l10n_ke_edi_tremol +#. odoo-python +#: code:addons/l10n_ke_edi_tremol/wizard/account_move_send.py:0 +#, python-format +msgid "" +"This document does not have details related to the fiscal device, a proforma" +" invoice will be used." +msgstr "" + +#. module: l10n_ke_edi_tremol +#. odoo-python #: code:addons/l10n_ke_edi_tremol/models/account_move.py:0 #, python-format msgid "" diff --git a/addons/l10n_ke_edi_tremol/models/account_move.py b/addons/l10n_ke_edi_tremol/models/account_move.py index a6037ac97a7..f57aec21601 100644 --- a/addons/l10n_ke_edi_tremol/models/account_move.py +++ b/addons/l10n_ke_edi_tremol/models/account_move.py @@ -80,6 +80,16 @@ class AccountMove(models.Model): return errors + def _l10n_ke_fiscal_device_details_filled(self): + self.ensure_one() + return all([ + self.country_code == 'KE', + self.l10n_ke_cu_invoice_number, + self.l10n_ke_cu_serial_number, + self.l10n_ke_cu_qrcode, + self.l10n_ke_cu_datetime, + ]) + # ------------------------------------------------------------------------- # SERIALISERS # ------------------------------------------------------------------------- diff --git a/addons/l10n_ke_edi_tremol/tests/__init__.py b/addons/l10n_ke_edi_tremol/tests/__init__.py index d3af06e024d..ea508560c70 100644 --- a/addons/l10n_ke_edi_tremol/tests/__init__.py +++ b/addons/l10n_ke_edi_tremol/tests/__init__.py @@ -1,3 +1,4 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from .import test_move_export +from . import test_account_move_send +from . import test_move_export diff --git a/addons/l10n_ke_edi_tremol/tests/test_account_move_send.py b/addons/l10n_ke_edi_tremol/tests/test_account_move_send.py new file mode 100644 index 00000000000..0b4dbca216a --- /dev/null +++ b/addons/l10n_ke_edi_tremol/tests/test_account_move_send.py @@ -0,0 +1,49 @@ +from datetime import timedelta + +from odoo import fields +from odoo.exceptions import UserError +from odoo.tests import tagged +from odoo.addons.account.tests.test_account_move_send import TestAccountMoveSendCommon + + +@tagged('post_install_l10n', 'post_install', '-at_install') +class TestKEAccountMoveSend(TestAccountMoveSendCommon): + + @classmethod + def setUpClass(cls, chart_template_ref='ke'): + super().setUpClass(chart_template_ref=chart_template_ref) + + def test_sent_to_fiscal_device(self): + invoice = self.init_invoice("out_invoice", amounts=[1000], post=True, partner=self.partner_a) + # Write data as if the invoice was successfully sent to fiscal device + invoice.write({ + 'l10n_ke_cu_invoice_number': 'test_ke_invoice_number', + 'l10n_ke_cu_serial_number': 'test_ke_serial_number', + 'l10n_ke_cu_qrcode': 'test_ke_qrcode', + 'l10n_ke_cu_datetime': fields.Datetime.now() - timedelta(days=1), + }) + + wizard = self.create_send_and_print(invoice) + self.assertFalse(wizard.l10n_ke_edi_warning_message) + wizard.action_send_and_print() + + self.assertTrue(invoice.invoice_pdf_report_id) + + def test_not_sent_to_fiscal_device_but_allow_fallback(self): + invoice = self.init_invoice("out_invoice", amounts=[1000], post=True, partner=self.partner_a) + wizard = self.create_send_and_print(invoice) + self.assertTrue(wizard.l10n_ke_edi_warning_message) + wizard.action_send_and_print(allow_fallback_pdf=True) + + # The PDF is not generated but a proforma. + self.assertFalse(invoice.invoice_pdf_report_id) + self.assertTrue(self.env['ir.attachment'].search([ + ('name', '=', invoice._get_invoice_proforma_pdf_report_filename()), + ])) + + def test_not_sent_to_fiscal_device_raises(self): + invoice = self.init_invoice("out_invoice", amounts=[1000], post=True, partner=self.partner_a) + wizard = self.create_send_and_print(invoice) + self.assertTrue(wizard.l10n_ke_edi_warning_message) + with self.assertRaisesRegex(UserError, wizard.l10n_ke_edi_warning_message): + wizard.action_send_and_print() diff --git a/addons/l10n_ke_edi_tremol/wizard/__init__.py b/addons/l10n_ke_edi_tremol/wizard/__init__.py new file mode 100644 index 00000000000..cf39f38e70a --- /dev/null +++ b/addons/l10n_ke_edi_tremol/wizard/__init__.py @@ -0,0 +1 @@ +from . import account_move_send diff --git a/addons/l10n_ke_edi_tremol/wizard/account_move_send.py b/addons/l10n_ke_edi_tremol/wizard/account_move_send.py new file mode 100644 index 00000000000..042b51c86af --- /dev/null +++ b/addons/l10n_ke_edi_tremol/wizard/account_move_send.py @@ -0,0 +1,36 @@ +from odoo import _, models, fields, api +from odoo.exceptions import UserError + + +class AccountMoveSend(models.TransientModel): + _inherit = 'account.move.send' + + l10n_ke_edi_warning_message = fields.Text(compute='_compute_l10n_ke_edi_warning_message') + + @api.depends('move_ids') + def _compute_l10n_ke_edi_warning_message(self): + for wizard in self: + warning_moves = wizard.move_ids.filtered(lambda m: m.country_code == 'KE' and not m._l10n_ke_fiscal_device_details_filled()) + if warning_moves: + wizard.l10n_ke_edi_warning_message = '\n'.join([ + _("The following documents have no details related to the fiscal device."), + *(warning_moves.mapped('name')) + ]) + else: + wizard.l10n_ke_edi_warning_message = False + + def _hook_invoice_document_before_pdf_report_render(self, invoice, invoice_data): + # EXTENDS account + super()._hook_invoice_document_before_pdf_report_render(invoice, invoice_data) + if invoice.country_code == 'KE' and not invoice._l10n_ke_fiscal_device_details_filled(): + invoice_data['error'] = _( + "This document does not have details related to the fiscal device, a proforma invoice will be used." + ) + + def action_send_and_print(self, force_synchronous=False, allow_fallback_pdf=False, **kwargs): + # EXTENDS account - prevent Send & Print if KE invoices aren't validated and no fallback is allowed. + self.ensure_one() + if not allow_fallback_pdf \ + and any(move.country_code == 'KE' and not move._l10n_ke_fiscal_device_details_filled() for move in self.move_ids): + raise UserError(self.l10n_ke_edi_warning_message) + return super().action_send_and_print(force_synchronous=force_synchronous, allow_fallback_pdf=allow_fallback_pdf, **kwargs) diff --git a/addons/l10n_ke_edi_tremol/wizard/account_move_send_views.xml b/addons/l10n_ke_edi_tremol/wizard/account_move_send_views.xml new file mode 100644 index 00000000000..ecb78887b55 --- /dev/null +++ b/addons/l10n_ke_edi_tremol/wizard/account_move_send_views.xml @@ -0,0 +1,19 @@ + + + + + account.move.send.form.inherit.l10n_ke_edi_tremol + account.move.send + + + + + + + + +