[FIX] testing utilities: o2m should not strip readonly fields

In the normal course of saving-action, readonly fields are stripped
out when sending data to the server. The SSF would reuse the same code
when "saving" O2M lines to the parent record however that is not
correct and would lead to misbehaving views as readonly (non-stored)
fields used as "transients" (storing data within the extent of a
record's edition session) would not behave properly.

Fix by overriding the O2M Form's save so that readonly fields are
kept and stored in the parent record.

Closes #23620
This commit is contained in:
Laurent Smet
2018-04-03 15:46:04 +02:00
committed by xmo-odoo
parent f5b1d4945c
commit 34c7fe2e77
5 changed files with 76 additions and 1 deletions
@@ -12,3 +12,5 @@ access_test_testing_utilities_parent,access_test_testing_utilities_parent,model_
access_test_testing_utilities_sub,access_test_testing_utilities_sub,model_test_testing_utilities_sub,,1,0,0,0
access_test_testing_utilities_sub2,access_test_testing_utilities_sub2,model_test_testing_utilities_sub2,,1,0,0,0
access_test_testing_utilities_sub3,access_test_testing_utilities_sub3,model_test_testing_utilities_sub3,,1,0,0,0
access_test_testing_utilities_onchange_parent,access_test_testing_utilities_onchange_parent,model_test_testing_utilities_onchange_parent,,1,0,0,0
access_test_testing_utilities_onchange_line,access_test_testing_utilities_onchange_line,model_test_testing_utilities_onchange_line,,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
12 access_test_testing_utilities_sub access_test_testing_utilities_sub model_test_testing_utilities_sub 1 0 0 0
13 access_test_testing_utilities_sub2 access_test_testing_utilities_sub2 model_test_testing_utilities_sub2 1 0 0 0
14 access_test_testing_utilities_sub3 access_test_testing_utilities_sub3 model_test_testing_utilities_sub3 1 0 0 0
15 access_test_testing_utilities_onchange_parent access_test_testing_utilities_onchange_parent model_test_testing_utilities_onchange_parent 1 0 0 0
16 access_test_testing_utilities_onchange_line access_test_testing_utilities_onchange_line model_test_testing_utilities_onchange_line 1 0 0 0
@@ -104,4 +104,25 @@
</form>
</field>
</record>
<record id="m2o_onchange_view" model="ir.ui.view">
<field name="name">Dynamic Onchange Test View</field>
<field name="model">test_testing_utilities.onchange_parent</field>
<field name="arch" type="xml">
<form>
<sheet>
<notebook>
<page>
<field name="line_ids" widget="one2many_list" context="{'line_ids': line_ids}">
<tree editable="bottom">
<field name="dummy"/>
<field name="flag" invisible="1" readonly="1"/>
</tree>
</field>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
</odoo>
@@ -169,3 +169,26 @@ class O2MSub3(models.Model):
def _compute_name(self):
for r in self:
r.name = str(r.v)
class O2MOnchangeParent(models.Model):
_name = 'test_testing_utilities.onchange_parent'
line_ids = fields.One2many('test_testing_utilities.onchange_line', 'parent')
@api.onchange('line_ids')
def _onchange_line_ids(self):
for line in self.line_ids.filtered(lambda l: l.flag):
self.env['test_testing_utilities.onchange_line'].new({'parent': self.id})
class M2OOnchangeLine(models.Model):
_name = 'test_testing_utilities.onchange_line'
parent = fields.Many2one('test_testing_utilities.onchange_parent')
dummy = fields.Float()
flag = fields.Boolean(store=False)
@api.onchange('dummy')
def _onchange_flag(self):
self.flag = True
@@ -393,6 +393,17 @@ class TestO2M(TransactionCase):
with self.assertRaises(AssertionError):
f.subs.remove(index=0)
def test_o2m_dyn_onchange(self):
f = Form(self.env['test_testing_utilities.onchange_parent'], view='test_testing_utilities.m2o_onchange_view')
with f.line_ids.new() as new_line:
new_line.dummy = 42
self.assertTrue(new_line.flag)
with f.line_ids.edit(index=0) as new_line:
self.assertTrue(new_line.flag)
class TestEdition(TransactionCase):
""" These use the context manager form as we don't need the record
post-save (we already have it) and it's easier to see what bits act on
+19 -1
View File
@@ -955,7 +955,6 @@ class Form(object):
# marks any onchange source as changed (default_get or explicit set)
self._changed.update(fields)
result = self._model.onchange(
self._onchange_values(),
fields,
@@ -1071,6 +1070,25 @@ class O2MForm(Form):
# FIXME: should be called when performing on change => value needs to be serialised into parent every time?
proxy._parent._perform_onchange([proxy._field])
def _values_to_save(self):
""" Validates values and returns only fields modified since
load/save
"""
values = {}
for f in self._view['fields']:
v = self._values[f]
if self._get_modifier(f, 'required'):
assert v is not False, "{} is a required field".format(f)
# skip unmodified fields
if f not in self._changed:
continue
# if self._get_modifier(f, 'readonly'):
# continue
# TODO: filter out (1, _, {}) from o2m values
values[f] = v
return values
class X2MProxy(object):
_parent = None
_field = None