Skip to content

Commit 77e61e5

Browse files
yankinmaxsimahawk
authored andcommitted
[IMP] edi_purchase_oca: get rid of components
Co-author: Simone Orsi <simahawk@gmail.com>
1 parent 6a55562 commit 77e61e5

9 files changed

Lines changed: 195 additions & 86 deletions

File tree

edi_purchase_oca/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
11
from . import models
2-
from . import components

edi_purchase_oca/__manifest__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@
99
"license": "LGPL-3",
1010
"author": "ForgeFlow, Camptocamp, Odoo Community Association (OCA)",
1111
"website": "https://github.com/OCA/edi-framework",
12-
"depends": ["purchase", "edi_oca", "component_event"],
12+
"depends": [
13+
"purchase",
14+
"edi_core_oca",
15+
],
1316
"data": [
1417
"views/purchase_order_views.xml",
1518
"views/edi_exchange_record_views.xml",

edi_purchase_oca/components/__init__.py

Lines changed: 0 additions & 1 deletion
This file was deleted.

edi_purchase_oca/components/listeners.py

Lines changed: 0 additions & 27 deletions
This file was deleted.

edi_purchase_oca/models/purchase_order.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,6 @@ class PurchaseOrder(models.Model):
1010
"purchase.order",
1111
"edi.exchange.consumer.mixin",
1212
]
13+
14+
def _edi_config_field_relation(self):
15+
return self.partner_id.edi_purchase_conf_ids

edi_purchase_oca/tests/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
from . import test_edi_conf
1+
from . import test_generate

edi_purchase_oca/tests/common.py

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# Copyright 2026 Camptocamp SA
2+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
3+
4+
from odoo import fields
5+
from odoo.fields import Command
6+
7+
from odoo.addons.edi_core_oca.tests.common import EDIBackendTestMixin
8+
9+
10+
class PurchaseEDIBackendTestMixin(EDIBackendTestMixin):
11+
@classmethod
12+
def _get_backend_type(cls):
13+
backend_type = cls.env["edi.backend.type"].search(
14+
[("code", "=", "purchase_demo")], limit=1
15+
)
16+
if backend_type:
17+
return backend_type
18+
return cls.env["edi.backend.type"].create(
19+
{
20+
"name": "Purchase DEMO",
21+
"code": "purchase_demo",
22+
}
23+
)
24+
25+
@classmethod
26+
def _get_backend(cls):
27+
backend_type = cls._get_backend_type()
28+
backend = cls.env["edi.backend"].search(
29+
[("backend_type_id", "=", backend_type.id)], limit=1
30+
)
31+
if backend:
32+
return backend
33+
return cls.env["edi.backend"].create(
34+
{
35+
"name": "purchase DEMO",
36+
"backend_type_id": backend_type.id,
37+
}
38+
)
39+
40+
@classmethod
41+
def _create_exchange_type(cls, **kw):
42+
model = cls.env["edi.exchange.type"]
43+
code = kw.get("code")
44+
if code:
45+
exchange_type = model.search(
46+
[("code", "=", code), ("backend_id", "=", cls.backend.id)], limit=1
47+
)
48+
if exchange_type:
49+
return exchange_type
50+
return super()._create_exchange_type(**kw)
51+
52+
53+
class OrderMixin:
54+
@classmethod
55+
def _create_purchase_order(cls, **kw):
56+
model = cls.env["purchase.order"]
57+
vals = {
58+
"partner_id": cls.vendor.id,
59+
"user_id": cls.env.ref("base.user_admin").id,
60+
"date_planned": fields.Datetime.now(),
61+
}
62+
vals.update(kw)
63+
if hasattr(model, "play_onchanges"):
64+
po_vals = model.play_onchanges(vals, [])
65+
else:
66+
po_vals = vals.copy()
67+
if "order_line" in vals:
68+
po_vals["order_line"] = [Command.create(x) for x in vals["order_line"]]
69+
return model.create(po_vals)
70+
71+
@classmethod
72+
def _setup_order(cls):
73+
cls.vendor = cls.env["res.partner"].create(
74+
{"name": "Azure Interior", "country_id": cls.env.company.country_id.id}
75+
)
76+
cls.product = cls.env["product.product"].create(
77+
{
78+
"name": "Product 1",
79+
"default_code": "1234567",
80+
"purchase_ok": True,
81+
}
82+
)
83+
return {
84+
"order_line": [
85+
{
86+
"product_id": cls.product.id,
87+
"product_qty": 10,
88+
"price_unit": 100.0,
89+
}
90+
],
91+
}

edi_purchase_oca/tests/test_edi_conf.py

Lines changed: 0 additions & 55 deletions
This file was deleted.
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# Copyright 2026 Camptocamp SA
2+
# @author Simone Orsi <simone.orsi@camptocamp.com>
3+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
4+
5+
from odoo.tests.common import TransactionCase
6+
7+
from .common import OrderMixin, PurchaseEDIBackendTestMixin
8+
9+
10+
class TestGenerateViaConf(TransactionCase, PurchaseEDIBackendTestMixin, OrderMixin):
11+
"""Verify that purchase EDI generation is driven by ``edi.configuration``.
12+
13+
No component / no fake handler: we simply assert that the snippets bound
14+
to the partner via ``partner_id.edi_purchase_conf_ids`` are executed by
15+
the state-change event dispatched by ``edi.exchange.consumer.mixin``.
16+
17+
Each snippet writes a marker on ``conf.description`` so we can verify
18+
which configurations actually ran.
19+
"""
20+
21+
# Snippet writes the order's state on the conf description if it matches
22+
# the expected target state.
23+
_snippet_tpl = (
24+
"if record.state == '{state}':\n"
25+
" conf.write({{'description': "
26+
"(conf.description or '') + '|' + record.state}})"
27+
)
28+
29+
@classmethod
30+
def setUpClass(cls):
31+
super().setUpClass()
32+
cls._setup_env()
33+
cls._setup_records()
34+
35+
cls.exc_type = cls._create_exchange_type(
36+
name="Demo Purchase Order out",
37+
code="demo_PurchaseOrder_out",
38+
direction="output",
39+
exchange_filename_pattern="{record_name}-{type.code}-{dt}",
40+
exchange_file_ext="xml",
41+
)
42+
cls.state_change_trigger = cls.env.ref(
43+
"edi_purchase_oca.edi_conf_trigger_purchase_order_state_change"
44+
)
45+
purchase_model_id = cls.env["ir.model"]._get_id("purchase.order")
46+
cls.edi_conf_confirmed = cls.env["edi.configuration"].create(
47+
{
48+
"name": "Demo Purchase Order - order confirmed",
49+
"type_id": cls.exc_type.id,
50+
"backend_id": cls.backend.id,
51+
"model_id": purchase_model_id,
52+
"trigger_id": cls.state_change_trigger.id,
53+
"snippet_do": cls._snippet_tpl.format(state="purchase"),
54+
}
55+
)
56+
cls.edi_conf_cancelled = cls.env["edi.configuration"].create(
57+
{
58+
"name": "Demo Purchase Order - order cancelled",
59+
"type_id": cls.exc_type.id,
60+
"backend_id": cls.backend.id,
61+
"model_id": purchase_model_id,
62+
"trigger_id": cls.state_change_trigger.id,
63+
"snippet_do": cls._snippet_tpl.format(state="cancel"),
64+
}
65+
)
66+
cls._setup_order()
67+
68+
def test_new_order_no_conf_no_output(self):
69+
# No conf linked to the vendor -> no snippet executed.
70+
order = self._create_purchase_order()
71+
order.button_confirm()
72+
self.assertFalse(self.edi_conf_confirmed.description)
73+
self.assertFalse(self.edi_conf_cancelled.description)
74+
75+
def test_new_order_1conf_output(self):
76+
self.vendor.edi_purchase_conf_ids = self.edi_conf_confirmed
77+
order = self._create_purchase_order()
78+
self.assertFalse(self.edi_conf_confirmed.description)
79+
order.button_confirm()
80+
self.assertEqual(self.edi_conf_confirmed.description, "|purchase")
81+
# The cancelled conf is not even attached to the vendor.
82+
self.assertFalse(self.edi_conf_cancelled.description)
83+
84+
def test_new_order_2conf_output(self):
85+
self.vendor.edi_purchase_conf_ids = (
86+
self.edi_conf_confirmed | self.edi_conf_cancelled
87+
)
88+
order = self._create_purchase_order()
89+
# Confirm -> only the "confirmed" snippet matches
90+
order.button_confirm()
91+
self.assertEqual(self.edi_conf_confirmed.description, "|purchase")
92+
self.assertFalse(self.edi_conf_cancelled.description)
93+
# Cancel -> the "cancelled" snippet matches
94+
order.button_cancel()
95+
self.assertEqual(self.edi_conf_confirmed.description, "|purchase")
96+
self.assertEqual(self.edi_conf_cancelled.description, "|cancel")

0 commit comments

Comments
 (0)