diff --git a/edi_core_oca/models/edi_exchange_type.py b/edi_core_oca/models/edi_exchange_type.py index 5850cf356..3346e487f 100644 --- a/edi_core_oca/models/edi_exchange_type.py +++ b/edi_core_oca/models/edi_exchange_type.py @@ -147,6 +147,14 @@ class EDIExchangeType(models.Model): """, ) advanced_settings = Serialized(default={}, compute="_compute_advanced_settings") + exchange_record_ids = fields.One2many( + comodel_name="edi.exchange.record", + inverse_name="type_id", + ) + exchange_record_count = fields.Integer( + string="# Exchange Records", + compute="_compute_exchange_record_count", + ) rule_ids = fields.One2many( comodel_name="edi.exchange.type.rule", inverse_name="type_id", @@ -240,6 +248,17 @@ def _compute_ack_for_type_ids(self): for rec in self: rec.ack_for_type_ids = [x.id for x in by_type_id.get(rec.id, [])] + @api.depends("exchange_record_ids") + def _compute_exchange_record_count(self): + data = self.env["edi.exchange.record"]._read_group( + [("type_id", "in", self.ids)], + groupby=["type_id"], + aggregates=["__count"], + ) + mapped_data = {type_.id: count for type_, count in data} + for rec in self: + rec.exchange_record_count = mapped_data.get(rec.id, 0) + def get_settings(self): return self.advanced_settings @@ -331,3 +350,16 @@ def copy_data(self, default=None): default = dict(default or {}) default.setdefault("code", f"{self.code}/COPY_FIXME") return super().copy_data(default=default) + + def action_view_exchange_records(self): + self.ensure_one() + action = self.env["ir.actions.act_window"]._for_xml_id( + "edi_core_oca.act_open_edi_exchange_record_view" + ) + action["domain"] = [("type_id", "=", self.id)] + action["context"] = { + "default_type_id": self.id, + "default_backend_id": self.backend_id.id, + "search_default_type_id": self.id, + } + return action diff --git a/edi_core_oca/tests/test_exchange_type.py b/edi_core_oca/tests/test_exchange_type.py index 6edfd79c6..5d3ae33bb 100644 --- a/edi_core_oca/tests/test_exchange_type.py +++ b/edi_core_oca/tests/test_exchange_type.py @@ -167,3 +167,40 @@ def test_archive_rules(self): rule2.invalidate_recordset() self.assertFalse(rule1.active) self.assertFalse(rule2.active) + + def _create_exchange_record(self, exc_type): + return self.backend.create_record( + exc_type.code, + {"model": self.partner._name, "res_id": self.partner.id}, + ) + + def test_exchange_record_count(self): + exc_type = self.exchange_type_out + self.assertEqual(exc_type.exchange_record_count, 0) + rec1 = self._create_exchange_record(exc_type) + rec2 = self._create_exchange_record(exc_type) + # Record on a different type must not be counted + self._create_exchange_record(self.exchange_type_in) + self.assertEqual(exc_type.exchange_record_count, 2) + self.assertEqual(set(exc_type.exchange_record_ids.ids), {rec1.id, rec2.id}) + + def test_action_view_exchange_records(self): + exc_type = self.exchange_type_out + rec = self._create_exchange_record(exc_type) + action = exc_type.action_view_exchange_records() + self.assertEqual(action["type"], "ir.actions.act_window") + self.assertEqual(action["res_model"], "edi.exchange.record") + self.assertIn(("type_id", "=", exc_type.id), action["domain"]) + ctx = action["context"] + self.assertEqual(ctx.get("default_type_id"), exc_type.id) + self.assertEqual(ctx.get("default_backend_id"), exc_type.backend_id.id) + self.assertEqual(ctx.get("search_default_type_id"), exc_type.id) + # The action's domain must actually match the created exchange record + records = self.env[action["res_model"]].search(action["domain"]) + self.assertIn(rec, records) + + def test_action_view_exchange_records_requires_singleton(self): + with self.assertRaises(ValueError): + ( + self.exchange_type_out | self.exchange_type_in + ).action_view_exchange_records() diff --git a/edi_core_oca/views/edi_exchange_type_views.xml b/edi_core_oca/views/edi_exchange_type_views.xml index 244019da9..cddc4a36b 100644 --- a/edi_core_oca/views/edi_exchange_type_views.xml +++ b/edi_core_oca/views/edi_exchange_type_views.xml @@ -26,6 +26,20 @@ bg_color="bg-danger" invisible="active" /> +
+ +