summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaphael Collet <rco@openerp.com>2016-12-09 09:20:43 +0100
committerRaphael Collet <rco@openerp.com>2016-12-09 09:40:31 +0100
commita3f2b8937ad24b2cc5bc22c1cccef16e54572a28 (patch)
tree6e5158c2588a04b107130b7e6917e55b9bd97aa9
parentf4ad09b30eb3f42e1d0b62fa0c9cb8dc9c633b56 (diff)
[FIX] fields: computed fields with some erroneous records
When computing a field on a recordset with erroneous records in the middle, the field is invalidated for some records of the recordset. OPW 697059
-rw-r--r--openerp/addons/test_new_api/tests/test_new_fields.py20
-rw-r--r--openerp/fields.py12
2 files changed, 27 insertions, 5 deletions
diff --git a/openerp/addons/test_new_api/tests/test_new_fields.py b/openerp/addons/test_new_api/tests/test_new_fields.py
index 7ca55c4eabd..323c2c2c31d 100644
--- a/openerp/addons/test_new_api/tests/test_new_fields.py
+++ b/openerp/addons/test_new_api/tests/test_new_fields.py
@@ -131,6 +131,26 @@ class TestNewFields(common.TransactionCase):
})
check_stored(discussion3)
+ def test_11_computed_access(self):
+ """ test computed fields with access right errors """
+ User = self.env['res.users']
+ user1 = User.create({'name': 'Aaaah', 'login': 'a'})
+ user2 = User.create({'name': 'Boooh', 'login': 'b'})
+ user3 = User.create({'name': 'Crrrr', 'login': 'c'})
+ # add a rule to not give access to user2
+ self.env['ir.rule'].create({
+ 'model_id': self.env['ir.model'].search([('model', '=', 'res.users')]).id,
+ 'domain_force': "[('id', '!=', %d)]" % user2.id,
+ })
+ # group users as a recordset, and read them as user demo
+ users = (user1 + user2 + user3).sudo(self.env.ref('base.user_demo'))
+ user1, user2, user3 = users
+ # regression test: a bug invalidated the field's value from cache
+ user1.company_type
+ with self.assertRaises(AccessError):
+ user2.company_type
+ user3.company_type
+
def test_12_recursive(self):
""" test recursively dependent fields """
Category = self.env['test_new_api.category']
diff --git a/openerp/fields.py b/openerp/fields.py
index ed536c82ff6..60f5d7fa69a 100644
--- a/openerp/fields.py
+++ b/openerp/fields.py
@@ -884,21 +884,21 @@ class Field(object):
def _compute_value(self, records):
""" Invoke the compute method on ``records``. """
# initialize the fields to their corresponding null value in cache
- computed = records._field_computed[self]
- for field in computed:
+ for field in records._field_computed[self]:
for record in records:
record._cache[field] = field.convert_to_cache(False, record, validate=False)
- records.env.computed[field].update(records._ids)
if isinstance(self.compute, basestring):
getattr(records, self.compute)()
else:
self.compute(records)
- for field in computed:
- records.env.computed[field].difference_update(records._ids)
def compute_value(self, records):
""" Invoke the compute method on ``records``; the results are in cache. """
with records.env.do_in_draft():
+ saved = {}
+ for field in records._field_computed[self]:
+ ids = saved[field] = records.env.computed[field]
+ records.env.computed[field] = ids.union(records._ids)
try:
self._compute_value(records)
except (AccessError, MissingError):
@@ -908,6 +908,8 @@ class Field(object):
self._compute_value(record)
except Exception as exc:
record._cache[self.name] = FailedValue(exc)
+ finally:
+ records.env.computed.update(saved)
def determine_value(self, record):
""" Determine the value of ``self`` for ``record``. """