diff options
| author | Xavier Morel <xmo@odoo.com> | 2019-09-24 13:22:25 +0000 |
|---|---|---|
| committer | fw-bot <otis@odoo.com> | 2019-09-25 16:37:19 +0000 |
| commit | 77099c54b602eb1a71c2a176eeebcceefaf7aec6 (patch) | |
| tree | 285eed8e714dab9e5dae740f74b24eba656b7742 /odoo/tests | |
| parent | 98b7129e20979a4dbbeb72ea1109112744f813d5 (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.py | 40 |
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 """ |
