Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[14.0] edi_sale_oca: use edi.configuration #1067

Open
wants to merge 2 commits into
base: 14.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions edi_sale_oca/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
],
}
1 change: 1 addition & 0 deletions edi_sale_oca/components/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import listeners
27 changes: 27 additions & 0 deletions edi_sale_oca/components/listeners.py
Original file line number Diff line number Diff line change
@@ -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)
13 changes: 13 additions & 0 deletions edi_sale_oca/data/edi_configuration.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<!-- Generic state change -->
<record
id="edi_conf_trigger_sale_order_state_change"
model="edi.configuration.trigger"
>
<field name="name">On SO state change</field>
<field name="code">on_edi_sale_order_state_change</field>
<field name="description">Trigger when a sale order state changes</field>
<field name="model_id" ref="sale.model_sale_order" />
</record>
</odoo>
38 changes: 38 additions & 0 deletions edi_sale_oca/demo/edi_configuration.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="demo_edi_configuration_confirmed" model="edi.configuration">
<field name="name">Demo Sale OrderResponse - order confirmed</field>
<field
name="description"
>Show case how you can send out an order response automatically</field>
<field name="type_id" ref="demo_edi_exc_type_order_out" />
<field name="backend_id" ref="demo_edi_backend" />
<field name="model_id" ref="sale.model_sale_order" />
<field name="trigger_id" ref="edi_conf_trigger_sale_order_state_change" />
<field name="snippet_do">
# 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)
</field>
</record>
<record id="demo_edi_configuration_done" model="edi.configuration">
<field name="name">Demo Sale OrderResponse - order done</field>
<field
name="description"
>Show case how you can send out an order response automatically</field>
<field name="type_id" ref="demo_edi_exc_type_order_out" />
<field name="backend_id" ref="demo_edi_backend" />
<field name="model_id" ref="sale.model_sale_order" />
<field name="trigger_id" ref="edi_conf_trigger_sale_order_state_change" />
<field name="snippet_do">
if record.state == 'done':
record._edi_send_via_edi(conf.type_id)
</field>
</record>

</odoo>
27 changes: 14 additions & 13 deletions edi_sale_oca/demo/edi_exchange_type.xml
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!-- TODO: add demo and tests for fake input/output exchanges. -->
<!-- <record id="demo_edi_exc_type_order_in" model="edi.exchange.type">

<record id="demo_edi_exc_type_order_out" model="edi.exchange.type">
<field name="backend_type_id" ref="demo_edi_backend_type_sale" />
<field name="backend_id" ref="demo_edi_backend" />
<field name="name">Demo Sale Order Response</field>
<field name="code">demo_SaleOrder_out</field>
<field name="direction">output</field>
<field name="exchange_filename_pattern">{record_name}-{type.code}-{dt}</field>
<field name="exchange_file_ext">xml</field>
</record>

<record id="demo_edi_exc_type_order_in" model="edi.exchange.type">
<field name="backend_type_id" ref="demo_edi_backend_type_sale" />
<field name="backend_id" ref="demo_edi_backend" />
<field name="ack_type_id" ref="demo_edi_exc_type_order_response_out" />
<!-- <field name="ack_type_id" ref="demo_edi_exc_type_order_out" /> -->
<field name="name">Demo Sale Order</field>
<field name="code">demo_SaleOrder_in</field>
<field name="direction">input</field>
<field name="exchange_file_ext">xml</field>
<field name="advanced_settings_edit">
components:
process:
usage: input.process.sale.order
env_ctx:
default_price_source: 'pricelist'
default_import_type: 'xml'
random_key: custom
</field>
</record> -->
</record>

</odoo>
1 change: 1 addition & 0 deletions edi_sale_oca/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
from . import sale_order
from . import res_partner
19 changes: 19 additions & 0 deletions edi_sale_oca/models/res_partner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Copyright 2024 Camptocamp SA
# @author: Simone Orsi <[email protected]>
# 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")],
)
1 change: 1 addition & 0 deletions edi_sale_oca/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
from . import test_order
from . import test_generate
6 changes: 5 additions & 1 deletion edi_sale_oca/tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
108 changes: 108 additions & 0 deletions edi_sale_oca/tests/test_generate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# Copyright 2024 Camptocamp SA
# @author: Simone Orsi <[email protected]>
# 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")
22 changes: 12 additions & 10 deletions edi_sale_oca/views/res_partner.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,18 @@
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form" />
<field name="arch" type="xml">
<xpath expr="//page[last()]" position="after">
<page name="edi" string="EDI">
<!--
TODO: IMO this page must be provided by edi_oca
and all the modules should hook here instead of adding their own blocks
here and there (see edi_account_oca, edi_stock_oca, etc)
-->
<group name="edi_main" />
</page>
</xpath>
<group name="edi_main" position="after">
<group name="sale" string="Sale">
<field name="edi_sale_conf_ids" nolabel="1">
<tree>
<field name="name" />
<field name="trigger_id" />
<field name="type_id" />
<field name="model_id" />
</tree>
</field>
</group>
</group>
</field>
</record>
</odoo>
3 changes: 3 additions & 0 deletions test-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ PyYAML
xmlunittest
# tests use python 3.6 and pypdf dropped support for python 3.6-3.7 in 5.0
pypdf==4.3.1

# [14.0][IMP] edi_oca: Add new model edi.configuration #1035
odoo14-addon-edi_oca @ git+https://github.com/OCA/edi@refs/pull/1035/head#subdirectory=setup/edi_oca
Loading