summaryrefslogtreecommitdiff
path: root/odoo/tests
diff options
context:
space:
mode:
authorXavier Morel <xmo@odoo.com>2019-09-24 13:22:25 +0000
committerfw-bot <otis@odoo.com>2019-09-25 16:37:19 +0000
commit77099c54b602eb1a71c2a176eeebcceefaf7aec6 (patch)
tree285eed8e714dab9e5dae740f74b24eba656b7742 /odoo/tests
parent98b7129e20979a4dbbeb72ea1109112744f813d5 (diff)
[FIX] core: o2m modifiers in the SSF
Because the sub-record values would not necessarily get fetched ever (whether default or stored), the computation of modifiers might blow up if it relied on one of the un-fetched un-specified fields. One such situation is trying to create a partner with child partners if base_address_city is installed: the module adds a readonly attr predicated upon the parent_id, without explicitly providing such the field would be missing from the O2M record's values. Closes #37176 closes odoo/odoo#37452 X-original-commit: 184d1b69eac2b78c72228c81c5c6cf8cc4a56eb4 Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
Diffstat (limited to 'odoo/tests')
-rw-r--r--odoo/tests/common.py40
1 files changed, 36 insertions, 4 deletions
diff --git a/odoo/tests/common.py b/odoo/tests/common.py
index 59c4cd334b5..9350ff49327 100644
--- a/odoo/tests/common.py
+++ b/odoo/tests/common.py
@@ -1537,8 +1537,9 @@ class Form(object):
values = {}
fields = self._view['fields']
for f in fields:
+ descr = fields[f]
v = self._values[f]
- if self._get_modifier(f, 'required') and not fields[f]['type'] == 'boolean':
+ if self._get_modifier(f, 'required') and not descr['type'] == 'boolean':
assert v is not False, "{} is a required field".format(f)
# skip unmodified fields
@@ -1550,8 +1551,8 @@ class Form(object):
if not node.get('force_save'):
continue
- if fields[f]['type'] == 'one2many':
- view = fields[f]['views']['edition']
+ if descr['type'] == 'one2many':
+ view = descr['views']['edition']
modifiers = view['modifiers']
oldvals = v
v = []
@@ -1565,7 +1566,21 @@ class Form(object):
for (c, rid, vs) in oldvals:
if c in (0, 1):
items = list(getattr(vs, 'changed_items', vs.items)())
- # FIXME: should be more extensive processing of o2m defaults
+ fields_ = view['fields']
+ missing = fields_.keys() - vs.keys()
+ if missing:
+ Model = self._env[descr['relation']]
+ if c == 0:
+ vs.update(dict.fromkeys(missing, False))
+ vs.update(
+ (k, _cleanup_from_default(fields_[k], v))
+ for k, v in Model.default_get(list(missing)).items()
+ )
+ else:
+ vs.update(record_to_values(
+ {k: v for k, v in fields_.items() if k not in vs},
+ Model.browse(rid)
+ ))
vs.setdefault('id', False)
vs['•parent•'] = self._values
vs = {
@@ -1971,6 +1986,23 @@ def record_to_values(fields, record):
r[f] = v
return r
+def _cleanup_from_default(type_, value):
+ if not value:
+ if type_ == 'many2many':
+ return [(6, False, [])]
+ elif type_ == 'one2many':
+ return []
+ elif type_ in ('integer', 'float'):
+ return 0
+ return value
+
+ if type_ == 'one2many':
+ return [c for c in value if c[0] != 6]
+ elif type_ == 'datetime' and isinstance(value, datetime):
+ return odoo.fields.Datetime.to_string(value)
+ elif type_ == 'date' and isinstance(value, date):
+ return odoo.fields.Date.to_string(value)
+
def _get_node(view, f, *arg):
""" Find etree node for the field ``f`` in the view's arch
"""