Skip to content

Commit

Permalink
edi: refactor model rules backward compat
Browse files Browse the repository at this point in the history
  • Loading branch information
simahawk committed Aug 12, 2023
1 parent 49ffa65 commit 3d11512
Show file tree
Hide file tree
Showing 5 changed files with 212 additions and 0 deletions.
1 change: 1 addition & 0 deletions edi_oca/migrations/14.0.1.19.0/post-migrate.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ def migrate(cr, version):
kind = "form_btn" if item.pop("form_btn", False) else "custom"
vals = dict(item, name="Default", kind=kind)
model.create(vals)
item.type_id.button_wipe_deprecated_rule_fields()

cr.execute("DROP TABLE exc_type_model_rel_bkp")
_logger.info("edi.exchange.type.rule created")
134 changes: 134 additions & 0 deletions edi_oca/models/edi_exchange_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,28 @@ class EDIExchangeType(models.Model):
inverse_name="type_id",
help="Rules to handle exchanges and UI automatically",
)
# Deprecated fields for rules - begin
# These fields have been deprecated in
# https://github.com/OCA/edi/pull/797
# but are kept for backward compat.
# If you can stop using them now.
# Anyway, annoying warning messages will be logged.
# See inverse methods.
# NOTE: old configurations are migrated automatically on upgrade
# Yet, if you have data files they might be broken
# if we delete these fields.
model_ids = fields.Many2many(
"ir.model", inverse="_inverse_deprecated_rules_model_ids"
)
enable_domain = fields.Char(inverse="_inverse_deprecated_rules_enable_domain")
enable_snippet = fields.Char(inverse="_inverse_deprecated_rules_enable_snippet")
model_manual_btn = fields.Boolean(
inverse="_inverse_deprecated_rules_model_manual_btn"
)
deprecated_rule_fields_still_used = fields.Boolean(
compute="_compute_deprecated_rule_fields_still_used"
)
# Deprecated fields for rules - end
quick_exec = fields.Boolean(
string="Quick execution",
help="When active, records of this type will be processed immediately "
Expand Down Expand Up @@ -226,3 +248,115 @@ def is_partner_enabled(self, partner):
if exc_type.partner_ids:
return partner.id in exc_type.partner_ids.ids
return True

# API to support deprecated model rules fields - begin
def _inverse_deprecated_rules_warning(self):
_fields = ", ".join(
["model_ids", "enable_domain", "enable_snippet", "model_manual_btn"]
)
_logger.warning(
"The fields %s are deprecated, "
"please stop using them in favor of edi.exchange.type.rule",
_fields,
)

def _inverse_deprecated_rules_model_ids(self):
if self.env.context.get("deprecated_rule_fields_bypass_inverse"):
return
self._inverse_deprecated_rules_warning()
for rec in self:
for model in rec.model_ids:
rule = rec._get_rule_by_model(model)
if not rule:
_logger.warning(
"New rule for %s created from deprecated `model_ids`",
model.model,
)
rec.rule_ids += rec._inverse_deprecated_rules_create(model)
rules_to_delete = rec.rule_ids.browse()
for rule in rec.rule_ids:
if rule.model_id not in rec.model_ids:
_logger.warning(
"Rule for %s deleted from deprecated `model_ids`",
rule.model_id.model,
)
rules_to_delete |= rule
rules_to_delete.unlink()

def _inverse_deprecated_rules_enable_domain(self):
if self.env.context.get("deprecated_rule_fields_bypass_inverse"):
return
self._inverse_deprecated_rules_warning()
for rec in self:
for model in rec.model_ids:
rule = rec._get_rule_by_model(model)
if rule:
_logger.warning(
"Rule for %s domain updated from deprecated `enable_domain`",
model.model,
)
rule.enable_domain = rec.enable_domain

def _inverse_deprecated_rules_enable_snippet(self):
if self.env.context.get("deprecated_rule_fields_bypass_inverse"):
return
self._inverse_deprecated_rules_warning()
for rec in self:
for model in rec.model_ids:
rule = rec._get_rule_by_model(model)
if rule:
_logger.warning(
"Rule for %s snippet updated from deprecated `enable_snippet`",
model.model,
)
rule.enable_snippet = rec.enable_snippet

def _inverse_deprecated_rules_model_manual_btn(self):
if self.env.context.get("deprecated_rule_fields_bypass_inverse"):
return
self._inverse_deprecated_rules_warning()
for rec in self:
for model in rec.model_ids:
rule = rec._get_rule_by_model(model)
if rule:
_logger.warning(
"Rule for %s btn updated from deprecated `model_manual_btn`",
model.model,
)
rule.kind = "form_btn" if self.model_manual_btn else "custom"

def _get_rule_by_model(self, model):
return self.rule_ids.filtered(lambda x: x.model_id == model)

def _inverse_deprecated_rules_create(self, model):
kind = "form_btn" if self.model_manual_btn else "custom"
vals = {
"type_id": self.id,
"model_id": model.id,
"kind": kind,
"name": "Default",
"enable_snippet": self.enable_snippet,
"enable_domain": self.enable_domain,
}
return self.rule_ids.create(vals)

@api.depends("model_ids", "enable_domain", "enable_snippet", "model_manual_btn")
def _compute_deprecated_rule_fields_still_used(self):
for rec in self:
rec.deprecated_rule_fields_still_used = (
rec._deprecated_rule_fields_still_used()
)

def _deprecated_rule_fields_still_used(self):
for fname in ("model_ids", "enable_snippet", "enable_domain"):
if self[fname]:
return True

def button_wipe_deprecated_rule_fields(self):
_fields = ["model_ids", "enable_domain", "enable_snippet", "model_manual_btn"]
deprecated_vals = {}.fromkeys(_fields, None)
self.with_context(deprecated_rule_fields_bypass_inverse=True).write(
deprecated_vals
)

# API to support deprecated model rules fields - end
1 change: 1 addition & 0 deletions edi_oca/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@
from . import test_edi_backend_cron
from . import test_security
from . import test_quick_exec
from . import test_exchange_type_deprecated_fields
43 changes: 43 additions & 0 deletions edi_oca/tests/test_exchange_type_deprecated_fields.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Copyright 2023 Camptocamp SA (https://www.camptocamp.com).
# @author: Simone Orsi <simahawk@gmail.com>
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).


from .common import EDIBackendCommonTestCase


class EDIExchangeTypeDeprecatedFieldsTestCase(EDIBackendCommonTestCase):
def test_inverse(self):
typ = self.exchange_type_out
self.assertFalse(typ.rule_ids)
self.assertFalse(typ.deprecated_rule_fields_still_used)
typ.model_ids += self.env["ir.model"]._get("res.partner")
self.assertTrue(typ.deprecated_rule_fields_still_used)
self.assertEqual(typ.rule_ids.mapped("model_id.model"), ["res.partner"])
typ.model_ids += self.env["ir.model"]._get("res.groups")
self.assertEqual(
typ.rule_ids.mapped("model_id.model"), ["res.partner", "res.groups"]
)
typ.enable_domain = "[(1, '=', 1)]"
self.assertRecordValues(
typ.rule_ids, [{"enable_domain": typ.enable_domain, "kind": "custom"}] * 2
)
typ.model_manual_btn = True
self.assertRecordValues(
typ.rule_ids, [{"enable_domain": typ.enable_domain, "kind": "form_btn"}] * 2
)
typ.model_ids -= self.env["ir.model"]._get("res.groups")
self.assertEqual(typ.rule_ids.mapped("model_id.model"), ["res.partner"])
typ.model_ids = False
self.assertFalse(typ.rule_ids)

def test_btn(self):
typ = self.exchange_type_out
typ.model_ids += self.env["ir.model"]._get("res.partner")
typ.enable_domain = "[(1, '=', 1)]"
typ.button_wipe_deprecated_rule_fields()
self.assertFalse(typ.model_ids)
self.assertFalse(typ.enable_domain)
self.assertFalse(typ.enable_snippet)
# Rules are kept
self.assertEqual(typ.rule_ids.mapped("model_id.model"), ["res.partner"])
33 changes: 33 additions & 0 deletions edi_oca/views/edi_exchange_type_views.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
<field name="quick_exec" />
</group>
</group>
<field name="deprecated_rule_fields_still_used" invisible="1" />
<notebook>
<page
name="adv_settings"
Expand Down Expand Up @@ -79,6 +80,38 @@
</tree>
</field>
</page>
<page
name="deprecated_model_rules"
string="DEPRECATED Model rules"
groups="edi_oca.group_edi_advanced_settings_manager"
attrs="{'invisible': [('deprecated_rule_fields_still_used', '=', False)]}"
>
<div class="alert alert-warning" role="alert">
Warning: these fields are deprecated.
If you rely on them for configuring rules via data files,
it's strongly recommended to rework such files
to use `edi.exchange.type.rule` records.
Please note that, due to backward compat,
removing a model from here will cause deletion
of any existing rule for the model.
You can use the button "Wipe" to clean them properly.
</div>
<group>
<field name="model_ids" widget="many2many_tags" />
<field name="enable_domain" />
<field
name="enable_snippet"
widget="ace"
options="{'mode': 'python'}"
/>
<field name="model_manual_btn" />
</group>
<button
type="object"
name="button_wipe_deprecated_rule_fields"
string="Wipe"
/>
</page>
</notebook>
</sheet>
</form>
Expand Down

0 comments on commit 3d11512

Please sign in to comment.