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()