diff --git a/edi_sale_ubl_oca/__manifest__.py b/edi_sale_ubl_oca/__manifest__.py
index 55a3944785..f1c23c0ac9 100644
--- a/edi_sale_ubl_oca/__manifest__.py
+++ b/edi_sale_ubl_oca/__manifest__.py
@@ -31,6 +31,7 @@
],
"demo": [
"demo/edi_exchange_type.xml",
+ "demo/edi_configuration.xml",
"demo/exc_templ_order_response.xml",
],
}
diff --git a/edi_sale_ubl_oca/demo/edi_configuration.xml b/edi_sale_ubl_oca/demo/edi_configuration.xml
new file mode 100644
index 0000000000..614521379a
--- /dev/null
+++ b/edi_sale_ubl_oca/demo/edi_configuration.xml
@@ -0,0 +1,17 @@
+
+
+
+ Demo UBL Sale OrderResponse - order confirmed
+ Show case how you can send out an order response automatically
+ demo_ubl_edi_sale_ordrsp
+
+
+
+ on_edi_sale_order_state_sale
+
+record._edi_send_via_edi(conf.type_id)
+
+
+
diff --git a/edi_sale_ubl_oca/demo/edi_exchange_type.xml b/edi_sale_ubl_oca/demo/edi_exchange_type.xml
index 154bc12b48..a25b1be08a 100644
--- a/edi_sale_ubl_oca/demo/edi_exchange_type.xml
+++ b/edi_sale_ubl_oca/demo/edi_exchange_type.xml
@@ -3,6 +3,7 @@
+
Demo UBL Sale Order Response
demo_UBL_SaleOrderResponse_out
output
@@ -26,33 +27,9 @@ components:
-
-
-
- SO automatic demo
- auto
- [('disable_edi_auto', '=', False)]
-
-actions:
- generate:
- when:
- - write
- trigger_fields:
- - state
- - commitment_date
- tracked_fields:
- - state
- - commitment_date
- if:
- snippet: result = todo.vals.get('state') in ('sale', 'sent', 'cancel') or "commitment_date" in todo.vals
-
-
-
+
Demo UBL Sale Order
demo_UBL_SaleOrder_in
diff --git a/edi_sale_ubl_oca/models/sale_order.py b/edi_sale_ubl_oca/models/sale_order.py
index 117873c74c..5d1b718779 100644
--- a/edi_sale_ubl_oca/models/sale_order.py
+++ b/edi_sale_ubl_oca/models/sale_order.py
@@ -83,17 +83,83 @@ def create(self, vals_list):
.with_context(evt_from_create=None)
)
+ # FIXME: move to core
+ # TODO: test
+ def _edi_send_via_edi(self, exchange_type, force=False, **kw):
+ exchange_record = None
+ # If we are sending an ack, we must check if we can generate it
+ if exchange_type.ack_for_type_ids:
+ if self._edi_can_generate_ack(exchange_type):
+ __, exchange_record = self._edi_get_or_create_ack_record(
+ exchange_type, force=force
+ )
+ else:
+ exchange_record = self._edi_create_exchange_record(exchange_type)
+ if exchange_record:
+ exchange_record.action_exchange_generate_send(**kw)
+
+ def _edi_can_generate_ack(self, exchange_type, force=False):
+ """Have to generate ack for this exchange type?
+
+ :param exchange_type: The exchange type to check.
+
+ It should be generated if:
+ - automation is not disabled and not forced
+ - origin exchange record is set (means it was originated by another record)
+ - origin exchange type is compatible with the configured ack types
+ """
+ if (self.disable_edi_auto and not force) or not self.origin_exchange_record_id:
+ return False
+ return self.origin_exchange_type_id in exchange_type.ack_for_type_ids
+
+ def _edi_get_or_create_ack_record(self, exchange_type, force=False):
+ """
+ Get or create a child record for the given exchange type.
+
+ If the record has not been sent out yet for whatever reason
+ (job delayed, job failed, send failed, etc)
+ we still want to generate a new up to date record to be sent.
+
+ :param exchange_type: The exchange type to create the record for.
+ :param force: If True, will force the creation of the record in case of ack type.
+ """
+ if not self._edi_can_generate_ack(exchange_type, force=force):
+ return False, False
+ parent = self._edi_get_origin()
+ # Filter acks that are not valued yet.
+ exchange_record = self._get_exchange_record(exchange_type).filtered(
+ lambda x: not x.exchange_file
+ )
+ created = False
+ # If the record has not been sent out yet for whatever reason
+ # (job delayed, job failed, send failed, etc)
+ # we still want to generate a new up to date record to be sent.
+ still_pending = exchange_record.edi_exchange_state in (
+ "output_pending",
+ "output_error_on_send",
+ )
+ if not exchange_record or still_pending:
+ vals = exchange_record._exchange_child_record_values()
+ vals["parent_id"] = parent.id
+ # NOTE: to fully automatize this,
+ # is recommended to enable `quick_exec` on the type
+ # otherwise records will have to wait for the cron to pass by.
+ exchange_record = self._edi_create_exchange_record(exchange_type, vals=vals)
+ created = True
+ return created, exchange_record
+
class SaleOrderLine(models.Model):
_name = "sale.order.line"
_inherit = [
"sale.order.line",
- "edi.auto.exchange.consumer.mixin",
"edi.id.mixin",
"edi.state.consumer.mixin",
]
def _edi_determine_lines_state(self, orig_vals):
+ # Make sure lines are up to date
+ self.flush()
# Defaults
for line in self:
if not line.edi_exchange_ready:
diff --git a/edi_sale_ubl_oca/tests/test_order_in.py b/edi_sale_ubl_oca/tests/test_order_in.py
index 0375957308..9c62a81a0a 100644
--- a/edi_sale_ubl_oca/tests/test_order_in.py
+++ b/edi_sale_ubl_oca/tests/test_order_in.py
@@ -49,7 +49,7 @@ def test_existing_order(self):
self.exc_record_in.action_exchange_process()
self.assertEqual(self.exc_record_in.edi_exchange_state, "input_processed_error")
err_msg = "Sales order has already been imported before"
- self.assertEqual(self.exc_record_in.exchange_error, err_msg)
+ self.assertIn(err_msg, self.exc_record_in.exchange_error)
def test_new_order(self):
self.assertEqual(self.exc_record_in.edi_exchange_state, "input_received")
diff --git a/edi_sale_ubl_oca/tests/test_order_in_full_flow.py b/edi_sale_ubl_oca/tests/test_order_in_full_flow.py
index 3fd6470ff1..1adbb47d40 100644
--- a/edi_sale_ubl_oca/tests/test_order_in_full_flow.py
+++ b/edi_sale_ubl_oca/tests/test_order_in_full_flow.py
@@ -2,7 +2,8 @@
# @author: Simone Orsi
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-from odoo import fields
+from unittest import mock
+
from odoo.tests.common import SavepointCase
from odoo.addons.edi_oca.tests.common import EDIBackendTestMixin
@@ -22,15 +23,21 @@ def setUpClass(cls):
cls._setup_env()
cls.backend = cls._get_backend()
cls._setup_inbound_order(cls.backend)
+ cls.edi_conf = cls.env.ref(
+ "edi_sale_ubl_oca.demo_ubl_edi_configuration_confirmed"
+ )
@classmethod
def _get_backend(cls):
return cls.env.ref("edi_ubl_oca.edi_backend_ubl_demo")
- def test_new_order(self):
+ # No need to test sending data
+ @mock.patch("odoo.addons.edi_oca.models.edi_backend.EDIBackend._exchange_send")
+ def test_new_order(self, mock_send):
self.backend._check_input_exchange_sync()
self.assertEqual(self.exc_record_in.edi_exchange_state, "input_processed")
order = self._find_order()
+ order.partner_id.edi_sale_conf_ids = self.edi_conf
self.assertEqual(self.exc_record_in.record, order)
order_msg = order.message_ids[0]
self.assertIn("Exchange processed successfully", order_msg.body)
@@ -59,29 +66,4 @@ def test_new_order(self):
# Test is a valid file
err = handler.validate(file_content)
self.assertEqual(err, None, err)
-
- # TODO: new test
- # Subsequent updates on some fields should trigger new exchanges
- xml_data = handler.parse_xml(file_content)
- old_date = order.commitment_date
- new_date = fields.Date.add(order.commitment_date, days=2)
- self.assertEqual(
- xml_data["cac:Delivery"][0]["cbc:ActualDeliveryDate"],
- fields.Date.to_string(old_date),
- )
- order.write({"commitment_date": new_date})
- ack_exc_record = order.exchange_record_ids.filtered(
- lambda x: x.type_id == self.exc_type_out and x != ack_exc_record
- )
- self.assertEqual(ack_exc_record.parent_id, self.exc_record_in)
- self.assertEqual(ack_exc_record.edi_exchange_state, "output_pending")
- file_content = ack_exc_record._get_file_content()
- self.assertTrue(file_content)
- err = handler.validate(file_content)
- self.assertEqual(err, None, err)
- # Subsequent updates on some fields should trigger new exchanges
- xml_data = handler.parse_xml(file_content)
- self.assertEqual(
- xml_data["cac:Delivery"][0]["cbc:ActualDeliveryDate"],
- fields.Date.to_string(new_date),
- )
+ # TODO: test data
diff --git a/edi_sale_ubl_oca/tests/test_order_response_out.py b/edi_sale_ubl_oca/tests/test_order_response_out.py
index 7767af094a..ba7f164493 100644
--- a/edi_sale_ubl_oca/tests/test_order_response_out.py
+++ b/edi_sale_ubl_oca/tests/test_order_response_out.py
@@ -76,4 +76,4 @@ def test_xml(self):
self.assertEqual(err, None, err)
data = handler.parse_xml(file_content)
# TODO: test all main data
- self.assertEqual(data["cbc:OrderResponseCode"], "AP")
+ self.assertEqual(data["cbc:OrderResponseCode"], "CA")
diff --git a/setup/edi_sale_ubl_oca/odoo/addons/edi_sale_ubl_oca b/setup/edi_sale_ubl_oca/odoo/addons/edi_sale_ubl_oca
new file mode 120000
index 0000000000..8bed21b906
--- /dev/null
+++ b/setup/edi_sale_ubl_oca/odoo/addons/edi_sale_ubl_oca
@@ -0,0 +1 @@
+../../../../edi_sale_ubl_oca
\ No newline at end of file
diff --git a/setup/edi_sale_ubl_oca/setup.py b/setup/edi_sale_ubl_oca/setup.py
new file mode 100644
index 0000000000..28c57bb640
--- /dev/null
+++ b/setup/edi_sale_ubl_oca/setup.py
@@ -0,0 +1,6 @@
+import setuptools
+
+setuptools.setup(
+ setup_requires=['setuptools-odoo'],
+ odoo_addon=True,
+)