changeset 0775630fb492 in trytond:default
details: https://hg.tryton.org/trytond?cmd=changeset;node=0775630fb492
description:
Manage deletable and writable state from ir.rule
issue9357
review290101002
diffstat:
CHANGELOG | 1 +
trytond/model/modelsql.py | 24 ++++-
trytond/tests/rule.py | 8 +
trytond/tests/test_rule.py | 244 +++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 275 insertions(+), 2 deletions(-)
diffs (331 lines):
diff -r 311b990db2e3 -r 0775630fb492 CHANGELOG
--- a/CHANGELOG Tue Sep 22 10:16:52 2020 +0200
+++ b/CHANGELOG Wed Sep 23 10:04:19 2020 +0200
@@ -1,3 +1,4 @@
+* Add deletable and writable state from ir.rule to read
* Add language attribute to data tag
* Add e-mail template
* Send e-mail on behalf of user
diff -r 311b990db2e3 -r 0775630fb492 trytond/model/modelsql.py
--- a/trytond/model/modelsql.py Tue Sep 22 10:16:52 2020 +0200
+++ b/trytond/model/modelsql.py Wed Sep 23 10:04:19 2020 +0200
@@ -696,7 +696,7 @@
if 'write_date' not in fields_names:
extra_fields.add('write_date')
for field_name in fields_names:
- if field_name == '_timestamp':
+ if field_name in {'_timestamp', '_write', '_delete'}:
continue
if '.' in field_name:
field_name, field_related = field_name.split('.', 1)
@@ -732,6 +732,26 @@
field = cls._fields.get(f)
if field and field.sql_type():
columns.append(field.sql_column(table).as_(f))
+ elif f in {'_write', '_delete'}:
+ if not callable(cls.table_query):
+ rule_domain = Rule.domain_get(
+ cls.__name__, mode=f.lstrip('_'))
+ if rule_domain:
+ rule_tables = {None: (table, None)}
+ rule_tables, rule_expression = cls.search_domain(
+ rule_domain, tables=rule_tables)
+ if len(rule_tables) > 1:
+ # The expression uses another table
+ rule_tables, rule_expression = cls.search_domain(
+ rule_domain)
+ rule_from = convert_from(None, rule_tables)
+ rule_table, _ = rule_tables[None]
+ rule_where = rule_table.id == table.id
+ rule_expression = rule_from.select(
+ rule_expression, where=rule_where)
+ columns.append(rule_expression.as_(f))
+ else:
+ columns.append(Literal(True).as_(f))
elif f == '_timestamp' and not callable(cls.table_query):
sql_type = fields.Char('timestamp').sql_type().base
columns.append(Extract('EPOCH',
@@ -774,7 +794,7 @@
for column in columns:
# Split the output name to remove SQLite type detection
fname = column.output_name.split()[0]
- if fname == '_timestamp':
+ if fname.startswith('_'):
continue
field = cls._fields[fname]
if not hasattr(field, 'get'):
diff -r 311b990db2e3 -r 0775630fb492 trytond/tests/rule.py
--- a/trytond/tests/rule.py Tue Sep 22 10:16:52 2020 +0200
+++ b/trytond/tests/rule.py Wed Sep 23 10:04:19 2020 +0200
@@ -8,9 +8,17 @@
"Test Rule"
__name__ = 'test.rule'
field = fields.Char("Field")
+ relation = fields.Many2One('test.rule.relation', "Relation")
+
+
+class TestRuleRelation(ModelSQL):
+ "Test Rule Relation"
+ __name__ = 'test.rule.relation'
+ field = fields.Char("Field")
def register(module):
Pool.register(
TestRule,
+ TestRuleRelation,
module=module, type_='model')
diff -r 311b990db2e3 -r 0775630fb492 trytond/tests/test_rule.py
--- a/trytond/tests/test_rule.py Tue Sep 22 10:16:52 2020 +0200
+++ b/trytond/tests/test_rule.py Wed Sep 23 10:04:19 2020 +0200
@@ -379,6 +379,250 @@
self.assertListEqual(TestRule.search([]), [])
+ @with_transaction()
+ def test_write_field_no_rule(self):
+ "Test _write field when there's no rule"
+ pool = Pool()
+ TestRule = pool.get('test.rule')
+ writable, = TestRule.create([{'field': 'foo'}])
+
+ value, = TestRule.read([writable.id], ['_write'])
+ self.assertEqual(value['_write'], True)
+
+ @with_transaction()
+ def test_write_field_rule_True(self):
+ "Test _write field when there's a rule - True"
+ pool = Pool()
+ TestRule = pool.get('test.rule')
+ RuleGroup = pool.get('ir.rule.group')
+ Model = pool.get('ir.model')
+
+ model, = Model.search([('model', '=', 'test.rule')])
+ rule_group, = RuleGroup.create([{
+ 'name': "Field different from foo",
+ 'model': model.id,
+ 'global_p': True,
+ 'perm_read': False,
+ 'perm_create': False,
+ 'perm_write': True,
+ 'perm_delete': False,
+ 'rules': [('create', [{
+ 'domain': json.dumps(
+ [('field', '!=', 'foo')]),
+ }])],
+ }])
+ writable, = TestRule.create([{'field': 'bar'}])
+
+ value, = TestRule.read([writable.id], ['_write'])
+ self.assertEqual(value['_write'], True)
+
+ @with_transaction()
+ def test_write_field_rule_False(self):
+ "Test _write field when there's a rule - False"
+ pool = Pool()
+ TestRule = pool.get('test.rule')
+ RuleGroup = pool.get('ir.rule.group')
+ Model = pool.get('ir.model')
+
+ model, = Model.search([('model', '=', 'test.rule')])
+ rule_group, = RuleGroup.create([{
+ 'name': "Field different from foo",
+ 'model': model.id,
+ 'global_p': True,
+ 'perm_read': False,
+ 'perm_create': False,
+ 'perm_write': True,
+ 'perm_delete': False,
+ 'rules': [('create', [{
+ 'domain': json.dumps(
+ [('field', '!=', 'foo')]),
+ }])],
+ }])
+ non_writable, = TestRule.create([{'field': 'foo'}])
+
+ value, = TestRule.read([non_writable.id], ['_write'])
+ self.assertEqual(value['_write'], False)
+
+ @with_transaction()
+ def test_write_field_relation_rule_True(self):
+ "Test _write field when there's a rule with a relation - True"
+ pool = Pool()
+ TestRule = pool.get('test.rule')
+ TestRuleRelation = pool.get('test.rule.relation')
+ RuleGroup = pool.get('ir.rule.group')
+ Model = pool.get('ir.model')
+
+ model, = Model.search([('model', '=', 'test.rule')])
+ rule_group, = RuleGroup.create([{
+ 'name': "Field different from foo",
+ 'model': model.id,
+ 'global_p': True,
+ 'perm_read': False,
+ 'perm_create': False,
+ 'perm_write': True,
+ 'perm_delete': False,
+ 'rules': [('create', [{
+ 'domain': json.dumps(
+ [('relation.field', '!=', 'foo')]),
+ }])],
+ }])
+ relation, = TestRuleRelation.create([{'field': 'bar'}])
+ writable, = TestRule.create([{'relation': relation}])
+
+ value, = TestRule.read([writable.id], ['_write'])
+ self.assertEqual(value['_write'], True)
+
+ @with_transaction()
+ def test_write_field_relation_rule_False(self):
+ "Test _write field when there's a rule with a relation - False"
+ pool = Pool()
+ TestRule = pool.get('test.rule')
+ TestRuleRelation = pool.get('test.rule.relation')
+ RuleGroup = pool.get('ir.rule.group')
+ Model = pool.get('ir.model')
+
+ model, = Model.search([('model', '=', 'test.rule')])
+ rule_group, = RuleGroup.create([{
+ 'name': "Field different from foo",
+ 'model': model.id,
+ 'global_p': True,
+ 'perm_read': False,
+ 'perm_create': False,
+ 'perm_write': True,
+ 'perm_delete': False,
+ 'rules': [('create', [{
+ 'domain': json.dumps(
+ [('relation.field', '!=', 'foo')]),
+ }])],
+ }])
+ relation, = TestRuleRelation.create([{'field': 'foo'}])
+ non_writable, = TestRule.create([{'relation': relation}])
+
+ value, = TestRule.read([non_writable.id], ['_write'])
+ self.assertEqual(value['_write'], False)
+
+ @with_transaction()
+ def test_delete_field_no_rule(self):
+ "Test _delete field when there's no rule"
+ pool = Pool()
+ TestRule = pool.get('test.rule')
+ deletable, = TestRule.create([{'field': 'foo'}])
+
+ value, = TestRule.read([deletable.id], ['_delete'])
+ self.assertEqual(value['_delete'], True)
+
+ @with_transaction()
+ def test_delete_field_rule_True(self):
+ "Test _delete field when there's a rule - True"
+ pool = Pool()
+ TestRule = pool.get('test.rule')
+ RuleGroup = pool.get('ir.rule.group')
+ Model = pool.get('ir.model')
+
+ model, = Model.search([('model', '=', 'test.rule')])
+ rule_group, = RuleGroup.create([{
+ 'name': "Field different from foo",
+ 'model': model.id,
+ 'global_p': True,
+ 'perm_read': False,
+ 'perm_create': False,
+ 'perm_write': False,
+ 'perm_delete': True,
+ 'rules': [('create', [{
+ 'domain': json.dumps(
+ [('field', '!=', 'foo')]),
+ }])],
+ }])
+ deletable, = TestRule.create([{'field': 'bar'}])
+
+ value, = TestRule.read([deletable.id], ['_delete'])
+ self.assertEqual(value['_delete'], True)
+
+ @with_transaction()
+ def test_delete_field_rule_False(self):
+ "Test _delete field when there's a rule - False"
+ pool = Pool()
+ TestRule = pool.get('test.rule')
+ RuleGroup = pool.get('ir.rule.group')
+ Model = pool.get('ir.model')
+
+ model, = Model.search([('model', '=', 'test.rule')])
+ rule_group, = RuleGroup.create([{
+ 'name': "Field different from foo",
+ 'model': model.id,
+ 'global_p': True,
+ 'perm_read': False,
+ 'perm_create': False,
+ 'perm_write': False,
+ 'perm_delete': True,
+ 'rules': [('create', [{
+ 'domain': json.dumps(
+ [('field', '!=', 'foo')]),
+ }])],
+ }])
+ non_deletable, = TestRule.create([{'field': 'foo'}])
+
+ value, = TestRule.read([non_deletable.id], ['_delete'])
+ self.assertEqual(value['_delete'], False)
+
+ @with_transaction()
+ def test_delete_field_relation_rule_True(self):
+ "Test _delete field when there's a rule with a relation - True"
+ pool = Pool()
+ TestRule = pool.get('test.rule')
+ TestRuleRelation = pool.get('test.rule.relation')
+ RuleGroup = pool.get('ir.rule.group')
+ Model = pool.get('ir.model')
+
+ model, = Model.search([('model', '=', 'test.rule')])
+ rule_group, = RuleGroup.create([{
+ 'name': "Field different from foo",
+ 'model': model.id,
+ 'global_p': True,
+ 'perm_read': False,
+ 'perm_create': False,
+ 'perm_write': False,
+ 'perm_delete': True,
+ 'rules': [('create', [{
+ 'domain': json.dumps(
+ [('relation.field', '!=', 'foo')]),
+ }])],
+ }])
+ relation, = TestRuleRelation.create([{'field': 'bar'}])
+ deletable, = TestRule.create([{'relation': relation}])
+
+ value, = TestRule.read([deletable.id], ['_delete'])
+ self.assertEqual(value['_delete'], True)
+
+ @with_transaction()
+ def test_delete_field_relation_rule_False(self):
+ "Test _delete field when there's a rule with a relation - False"
+ pool = Pool()
+ TestRule = pool.get('test.rule')
+ TestRuleRelation = pool.get('test.rule.relation')
+ RuleGroup = pool.get('ir.rule.group')
+ Model = pool.get('ir.model')
+
+ model, = Model.search([('model', '=', 'test.rule')])
+ rule_group, = RuleGroup.create([{
+ 'name': "Field different from foo",
+ 'model': model.id,
+ 'global_p': True,
+ 'perm_read': False,
+ 'perm_create': False,
+ 'perm_write': False,
+ 'perm_delete': True,
+ 'rules': [('create', [{
+ 'domain': json.dumps(
+ [('relation.field', '!=', 'foo')]),
+ }])],
+ }])
+ relation, = TestRuleRelation.create([{'field': 'foo'}])
+ non_deletable, = TestRule.create([{'relation': relation}])
+
+ value, = TestRule.read([non_deletable.id], ['_delete'])
+ self.assertEqual(value['_delete'], False)
+
def suite():
suite_ = unittest.TestSuite()