From c9ff7eb26697368d14056685e62af77b9d101843 Mon Sep 17 00:00:00 2001 From: Simone Orsi Date: Fri, 29 Nov 2024 11:28:14 +0100 Subject: [PATCH 1/2] edi_sale_oca: use edi.configuration --- edi_sale_oca/__manifest__.py | 3 + edi_sale_oca/components/__init__.py | 1 + edi_sale_oca/components/listeners.py | 27 ++++++ edi_sale_oca/data/edi_configuration.xml | 13 +++ edi_sale_oca/demo/edi_configuration.xml | 38 +++++++++ edi_sale_oca/demo/edi_exchange_type.xml | 27 +++--- edi_sale_oca/models/__init__.py | 1 + edi_sale_oca/models/res_partner.py | 19 +++++ edi_sale_oca/tests/__init__.py | 1 + edi_sale_oca/tests/common.py | 6 +- edi_sale_oca/tests/test_generate.py | 108 ++++++++++++++++++++++++ edi_sale_oca/views/res_partner.xml | 22 ++--- 12 files changed, 242 insertions(+), 24 deletions(-) create mode 100644 edi_sale_oca/components/listeners.py create mode 100644 edi_sale_oca/data/edi_configuration.xml create mode 100644 edi_sale_oca/demo/edi_configuration.xml create mode 100644 edi_sale_oca/models/res_partner.py create mode 100644 edi_sale_oca/tests/test_generate.py diff --git a/edi_sale_oca/__manifest__.py b/edi_sale_oca/__manifest__.py index 1a5c93ac3a..a371e6a50d 100644 --- a/edi_sale_oca/__manifest__.py +++ b/edi_sale_oca/__manifest__.py @@ -18,12 +18,15 @@ "sale", ], "data": [ + "data/edi_configuration.xml", "views/res_partner.xml", "views/sale_order.xml", + "views/res_partner.xml", "views/edi_exchange_record.xml", ], "demo": [ "demo/edi_backend.xml", "demo/edi_exchange_type.xml", + "demo/edi_configuration.xml", ], } diff --git a/edi_sale_oca/components/__init__.py b/edi_sale_oca/components/__init__.py index e69de29bb2..a441d8bd1f 100644 --- a/edi_sale_oca/components/__init__.py +++ b/edi_sale_oca/components/__init__.py @@ -0,0 +1 @@ +from . import listeners diff --git a/edi_sale_oca/components/listeners.py b/edi_sale_oca/components/listeners.py new file mode 100644 index 0000000000..c213d646a2 --- /dev/null +++ b/edi_sale_oca/components/listeners.py @@ -0,0 +1,27 @@ +# Copyright 2024 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo.addons.component.core import Component + + +class EDIConfigSOListener(Component): + _name = "edi.listener.config.sale.order" + _inherit = "base.event.listener" + _apply_on = ["sale.order"] + + def on_record_create(self, record, fields=None): + trigger = "on_record_create" + return self._exec_conf(record, trigger) + + def on_record_write(self, record, fields=None): + trigger = "on_record_write" + return self._exec_conf(record, trigger) + + def on_edi_sale_order_state_change(self, record, state=None): + trigger = "on_edi_sale_order_state_change" + return self._exec_conf(record, trigger) + + def _exec_conf(self, record, trigger, conf_field="edi_sale_conf_ids"): + confs = record.partner_id[conf_field].edi_get_conf(trigger) + for conf in confs: + conf.edi_exec_snippet_do(record) diff --git a/edi_sale_oca/data/edi_configuration.xml b/edi_sale_oca/data/edi_configuration.xml new file mode 100644 index 0000000000..3ddd6d7bd1 --- /dev/null +++ b/edi_sale_oca/data/edi_configuration.xml @@ -0,0 +1,13 @@ + + + + + On SO state change + on_edi_sale_order_state_change + Trigger when a sale order state changes + + + diff --git a/edi_sale_oca/demo/edi_configuration.xml b/edi_sale_oca/demo/edi_configuration.xml new file mode 100644 index 0000000000..514cc2c49d --- /dev/null +++ b/edi_sale_oca/demo/edi_configuration.xml @@ -0,0 +1,38 @@ + + + + Demo Sale OrderResponse - order confirmed + Show case how you can send out an order response automatically + + + + + +# STATES +# ('draft', 'Quotation'), +# ('sent', 'Quotation Sent'), +# ('sale', 'Sales Order'), +# ('done', 'Locked'), +# ('cancel', 'Cancelled'), +if record.state == 'sale': + record._edi_send_via_edi(conf.type_id) + + + + Demo Sale OrderResponse - order done + Show case how you can send out an order response automatically + + + + + +if record.state == 'done': + record._edi_send_via_edi(conf.type_id) + + + + diff --git a/edi_sale_oca/demo/edi_exchange_type.xml b/edi_sale_oca/demo/edi_exchange_type.xml index 49d9d08083..a1a6f3b47f 100644 --- a/edi_sale_oca/demo/edi_exchange_type.xml +++ b/edi_sale_oca/demo/edi_exchange_type.xml @@ -1,23 +1,24 @@ - - Demo Sale Order demo_SaleOrder_in input xml - -components: - process: - usage: input.process.sale.order - env_ctx: - default_price_source: 'pricelist' - default_import_type: 'xml' - random_key: custom - - --> + diff --git a/edi_sale_oca/models/__init__.py b/edi_sale_oca/models/__init__.py index 6aacb75313..c0ee851195 100644 --- a/edi_sale_oca/models/__init__.py +++ b/edi_sale_oca/models/__init__.py @@ -1 +1,2 @@ from . import sale_order +from . import res_partner diff --git a/edi_sale_oca/models/res_partner.py b/edi_sale_oca/models/res_partner.py new file mode 100644 index 0000000000..ea2a15c227 --- /dev/null +++ b/edi_sale_oca/models/res_partner.py @@ -0,0 +1,19 @@ +# Copyright 2024 Camptocamp SA +# @author: Simone Orsi +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + + +from odoo import fields, models + + +class ResPartner(models.Model): + _inherit = "res.partner" + + edi_sale_conf_ids = fields.Many2many( + string="EDI sale configuration", + comodel_name="edi.configuration", + relation="res_partner_edi_sale_configuration_rel", + column1="partner_id", + column2="conf_id", + domain=[("model_name", "=", "sale.order")], + ) diff --git a/edi_sale_oca/tests/__init__.py b/edi_sale_oca/tests/__init__.py index e6fb64b6b6..975f7f7956 100644 --- a/edi_sale_oca/tests/__init__.py +++ b/edi_sale_oca/tests/__init__.py @@ -1 +1,2 @@ from . import test_order +from . import test_generate diff --git a/edi_sale_oca/tests/common.py b/edi_sale_oca/tests/common.py index 523642abb6..3ffd7c1e81 100644 --- a/edi_sale_oca/tests/common.py +++ b/edi_sale_oca/tests/common.py @@ -15,7 +15,11 @@ def _create_sale_order(cls, **kw): model = cls.env["sale.order"] vals = dict(commitment_date=fields.Date.today()) vals.update(kw) - so_vals = model.play_onchanges(vals, []) + # Loose dependency on onchange_helper + if hasattr(model, "play_onchanges"): + so_vals = model.play_onchanges(vals, []) + else: + so_vals = vals.copy() if "order_line" in so_vals: so_vals["order_line"] = [(0, 0, x) for x in vals["order_line"]] return model.create(so_vals) diff --git a/edi_sale_oca/tests/test_generate.py b/edi_sale_oca/tests/test_generate.py new file mode 100644 index 0000000000..a9ef71208e --- /dev/null +++ b/edi_sale_oca/tests/test_generate.py @@ -0,0 +1,108 @@ +# Copyright 2024 Camptocamp SA +# @author: Simone Orsi +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + + +from odoo.addons.component.tests.common import SavepointComponentRegistryCase +from odoo.addons.edi_oca.tests.common import EDIBackendTestMixin +from odoo.addons.edi_oca.tests.fake_components import ( + FakeOutputGenerator, + FakeOutputSender, +) + + +class Generator(FakeOutputGenerator): + _backend_type = "sale_demo" + _exchange_type = "demo_SaleOrder_out" + + +class Sender(FakeOutputSender): + _backend_type = "sale_demo" + _exchange_type = "demo_SaleOrder_out" + + +class TestProcessComponent(SavepointComponentRegistryCase, EDIBackendTestMixin): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls._setup_env() + cls.backend = cls._get_backend() + cls.exc_type = cls.env.ref("edi_sale_oca.demo_edi_exc_type_order_out") + cls.edi_conf_confirmed = cls.env.ref( + "edi_sale_oca.demo_edi_configuration_confirmed" + ) + cls.edi_conf_done = cls.env.ref("edi_sale_oca.demo_edi_configuration_done") + cls.partner = cls.env.ref("base.res_partner_2").copy({"name": "John Doe"}) + cls._load_module_components(cls, "edi_oca") + cls._load_module_components(cls, "edi_sale_oca") + cls._build_components( + cls, + Generator, + Sender, + ) + + def setUp(self): + super().setUp() + Generator.reset_faked() + Sender.reset_faked() + + @classmethod + def _get_backend(cls): + return cls.env.ref("edi_sale_oca.demo_edi_backend") + + def test_lookup(self): + # Just ensuring test setup is done properly + record = self.backend.create_record(self.exc_type.code, {}) + comp = self.backend._get_component(record, "generate") + self.assertEqual(comp._name, Generator._name) + comp = self.backend._get_component(record, "send") + self.assertEqual(comp._name, Sender._name) + + def test_new_order_no_conf_no_output(self): + order = self.env["sale.order"].create( + { + "partner_id": self.partner.id, + } + ) + order.action_confirm() + self.assertFalse(order.exchange_record_ids) + + def test_new_order_1conf_output(self): + self.partner.edi_sale_conf_ids = self.edi_conf_confirmed + order = self.env["sale.order"].create( + { + "partner_id": self.partner.id, + } + ) + self.assertFalse(order.exchange_record_ids) + order.with_context(fake_output="ORDER CONFIRM").action_confirm() + self.assertEqual(len(order.exchange_record_ids), 1) + record = order.exchange_record_ids[0] + self.assertEqual(record._get_file_content(), "ORDER CONFIRM") + self.assertEqual(record.type_id, self.exc_type) + # When done, nothing changes + order.action_done() + self.assertEqual(len(order.exchange_record_ids), 1) + record = order.exchange_record_ids[0] + self.assertEqual(record.type_id, self.exc_type) + + def test_new_order_2conf_output(self): + self.partner.edi_sale_conf_ids = self.edi_conf_confirmed | self.edi_conf_done + order = self.env["sale.order"].create( + { + "partner_id": self.partner.id, + } + ) + self.assertFalse(order.exchange_record_ids) + order.with_context(fake_output="ORDER CONFIRM").action_confirm() + self.assertEqual(len(order.exchange_record_ids), 1) + record = order.exchange_record_ids[0] + self.assertEqual(record._get_file_content(), "ORDER CONFIRM") + self.assertEqual(record.type_id, self.exc_type) + # When done, nothing changes + order.with_context(fake_output="ORDER DONE").action_done() + record1, record2 = order.exchange_record_ids + self.assertEqual(record1.type_id, self.exc_type) + self.assertEqual(record1._get_file_content(), "ORDER CONFIRM") + self.assertEqual(record2.type_id, self.exc_type) + self.assertEqual(record2._get_file_content(), "ORDER DONE") diff --git a/edi_sale_oca/views/res_partner.xml b/edi_sale_oca/views/res_partner.xml index c0afc4a76a..c327efb238 100644 --- a/edi_sale_oca/views/res_partner.xml +++ b/edi_sale_oca/views/res_partner.xml @@ -7,16 +7,18 @@ res.partner - - - - - - + + + + + + + + + + + + From 5c6b114fcaee5e66fcf06b3fa8eb63bcfd04563b Mon Sep 17 00:00:00 2001 From: Simone Orsi Date: Mon, 2 Dec 2024 15:57:05 +0100 Subject: [PATCH 2/2] edi_sale_input_oca: avoid demo data clash --- edi_sale_input_oca/demo/edi_exchange_type.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/edi_sale_input_oca/demo/edi_exchange_type.xml b/edi_sale_input_oca/demo/edi_exchange_type.xml index bec19fddc4..ae1e05f744 100644 --- a/edi_sale_input_oca/demo/edi_exchange_type.xml +++ b/edi_sale_input_oca/demo/edi_exchange_type.xml @@ -5,7 +5,7 @@ Demo Sale Order - demo_SaleOrder_in + demo_edi_sale_input_so_in input xml