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

Reply via email to