Browse Source

Differentiate rules according to their origin

pull/208/head
Guewen Baconnier 9 years ago
parent
commit
9b8393167e
  1. 67
      partner_changeset/models/changeset_field_rule.py
  2. 5
      partner_changeset/models/res_partner_changeset.py
  3. 36
      partner_changeset/tests/test_changeset_field_rule.py
  4. 7
      partner_changeset/views/changeset_field_rule_views.xml

67
partner_changeset/models/changeset_field_rule.py

@ -19,6 +19,8 @@
#
#
from itertools import chain
from openerp import models, fields, api
from openerp.tools.cache import ormcache
@ -42,13 +44,41 @@ class ChangesetFieldRule(models.Model):
"Validate: manually applied by an administrator.\n"
"Never: change never applied.",
)
source_model_id = fields.Many2one(
comodel_name='ir.model',
string='Source Model',
ondelete='cascade',
domain=lambda self: [('id', 'in', self._domain_source_models().ids)],
help="If a source model is defined, the rule will be applied only "
"when the change is made from this origin. "
"Rules without source model are global and applies to all "
"backends.\n"
"Rules with a source model have precedence over global rules, "
"but if a field has no rule with a source model, the global rule "
"is used."
)
_sql_constraints = [
('model_field_uniq',
'unique (model_id, field_id)',
'A rule already exists for this field.')
'unique (model_id, source_model_id, field_id)',
'A rule already exists for this field.'),
]
@api.model
def _domain_source_models(self):
""" Returns the models for which we can define rules.
Example for submodules (replace by the xmlid of the model):
::
models = super(ChangesetFieldRule, self)._domain_source_models()
return models | self.env.ref('base.model_res_users')
Rules without model are global and apply for all models.
"""
return self.env['ir.model'].browse()
@api.model
def _default_model_id(self):
return self.env.ref('base.model_res_partner').id
@ -62,9 +92,36 @@ class ChangesetFieldRule(models.Model):
@ormcache()
@api.model
def get_rules(self, model_name):
rules = self.search([('model_id', '=', model_name)])
return {rule.field_id.name: rule for rule in rules}
def get_rules(self, model_name, source_model_name):
""" Return the rules for a model
If the key ``__changeset_rules_source_model`` is provided in the
context with the name of a model, rules for this specific model
will be searched for, if no rule is found, a generic rule
(without source_model_id) will be searched.
The source model is the model which ask for a change, it will be
for instance ``res.users``, ``lefac.backend`` or ``magellan.backend``.
The second argument (``source_model_name``) is optional but
cannot be an optional keyword argument otherwise it would not be
in the key for the cache. The callers have to pass ``None`` if
they want only global rules.
"""
if source_model_name:
model_rules = self.search(
[('model_id', '=', model_name),
('source_model_id.model', '=', source_model_name)],
)
else:
model_rules = self.browse()
rules = self.search([('model_id', '=', model_name),
('source_model_id', '=', False)])
# model's rules have precedence over global ones so we take the
# global rules first, then we update them with the source
# model's rules
return {rule.field_id.name: rule for rule in chain(rules, model_rules)}
@api.model
def create(self, vals):

5
partner_changeset/models/res_partner_changeset.py

@ -132,7 +132,10 @@ class ResPartnerChangeset(models.Model):
change_model = self.env['res.partner.changeset.change']
write_values = values.copy()
changes = []
rules = self.env['changeset.field.rule'].get_rules(record._model._name)
rules = self.env['changeset.field.rule'].get_rules(
record._model._name,
source_model_name=source_model,
)
for field in values:
rule = rules.get(field)
if not rule:

36
partner_changeset/tests/test_changeset_field_rule.py

@ -27,6 +27,7 @@ class TestChangesetFieldRule(common.TransactionCase):
def setUp(self):
super(TestChangesetFieldRule, self).setUp()
self.partner_model_id = self.env.ref('base.model_res_partner').id
self.company_model_id = self.env.ref('base.model_res_company').id
self.field_name = self.env.ref('base.field_res_partner_name')
self.field_street = self.env.ref('base.field_res_partner_street')
@ -43,9 +44,34 @@ class TestChangesetFieldRule(common.TransactionCase):
'field_id': self.field_street.id,
'action': 'never',
})
get_rules = ChangesetFieldRule.get_rules('res.partner')
get_rules = ChangesetFieldRule.get_rules('res.partner', None)
self.assertEqual(get_rules, {'name': rule1, 'street': rule2})
def test_get_rules_source(self):
ChangesetFieldRule = self.env['changeset.field.rule']
ChangesetFieldRule.search([]).unlink()
rule1 = ChangesetFieldRule.create({
'model_id': self.partner_model_id,
'field_id': self.field_name.id,
'action': 'validate',
})
rule2 = ChangesetFieldRule.create({
'model_id': self.partner_model_id,
'field_id': self.field_street.id,
'action': 'never',
})
rule3 = ChangesetFieldRule.create({
'model_id': self.partner_model_id,
'source_model_id': self.company_model_id,
'field_id': self.field_street.id,
'action': 'never',
})
model = ChangesetFieldRule
rules = model.get_rules('res.partner', None)
self.assertEqual(rules, {'name': rule1, 'street': rule2})
rules = model.get_rules('res.partner', 'res.company')
self.assertEqual(rules, {'name': rule1, 'street': rule3})
def test_get_rules_cache(self):
ChangesetFieldRule = self.env['changeset.field.rule']
ChangesetFieldRule.search([]).unlink()
@ -55,7 +81,7 @@ class TestChangesetFieldRule(common.TransactionCase):
'action': 'validate',
})
self.assertEqual(
ChangesetFieldRule.get_rules('res.partner')['name'].action,
ChangesetFieldRule.get_rules('res.partner', None)['name'].action,
'validate',
)
# Write on cursor to bypass the cache invalidation for the
@ -64,13 +90,13 @@ class TestChangesetFieldRule(common.TransactionCase):
"SET action = 'never' "
"WHERE id = %s", (rule.id,))
self.assertEqual(
ChangesetFieldRule.get_rules('res.partner')['name'].action,
ChangesetFieldRule.get_rules('res.partner', None)['name'].action,
'validate',
)
rule.action = 'auto'
self.assertEqual(
ChangesetFieldRule.get_rules('res.partner')['name'].action,
ChangesetFieldRule.get_rules('res.partner', None)['name'].action,
'auto',
)
rule.unlink()
self.assertFalse(ChangesetFieldRule.get_rules('res.partner'))
self.assertFalse(ChangesetFieldRule.get_rules('res.partner', None))

7
partner_changeset/views/changeset_field_rule_views.xml

@ -6,8 +6,8 @@
<field name="model">changeset.field.rule</field>
<field name="arch" type="xml">
<tree string="Changeset Fields Rules">
<field name="model_id"/>
<field name="field_id"/>
<field name="source_model_id"/>
<field name="action"/>
</tree>
</field>
@ -22,9 +22,12 @@
<group>
<field name="model_id" invisible="1"/>
<field name="field_id"
options="{'no_create_edit': True, 'no_open': True}"
domain="[('model_id', '=', model_id),
('ttype', 'in', ('char', 'selection', 'date', 'datetime', 'float', 'integer', 'text', 'boolean', 'many2one')),
('readonly', '=', False)]"/>
<field name="source_model_id"
options="{'no_create_edit': True, 'no_open': True}"/>
<field name="action"/>
</group>
</sheet>
@ -37,8 +40,8 @@
<field name="model">changeset.field.rule</field>
<field name="arch" type="xml">
<search string="Changeset Fields Rules">
<field name="model_id"/>
<field name="field_id"/>
<field name="source_model_id"/>
<field name="action"/>
</search>
</field>

Loading…
Cancel
Save