[FIX] core: handle multi level o2m in SSF

Technically it does 3 different things:

* switch from 1 level of o2m to 2 levels of o2m when recursing
* handles `parent.<xxx>` readonly modifiers on o2m subfields
* handles `id` readonly modifiers on o2m subfields (already worked in the
  normal case but not for o2m records from default_get)

The last two especially are temporary quickfixes, that will need proper fixes.

closes odoo/odoo#32428

Signed-off-by: Christophe Simonis <chs@odoo.com>
This commit is contained in:
Xavier Morel
2019-04-04 14:20:51 +00:00
committed by Christophe Simonis
parent 95c9227cb3
commit 7e4b0350c3
+15 -11
View File
@@ -1117,7 +1117,7 @@ class Form(object):
else:
self._init_from_defaults(self._model)
def _o2m_set_edition_view(self, descr, node):
def _o2m_set_edition_view(self, descr, node, level):
default_view = next(
(m for m in node.get('mode', 'tree').split(',') if m != 'form'),
'tree'
@@ -1146,7 +1146,7 @@ class Form(object):
edition['tree'] = subarch
# don't recursively process o2ms in o2ms
self._process_fvg(submodel, edition, o2m=False)
self._process_fvg(submodel, edition, level=level-1)
descr['views']['edition'] = edition
def __str__(self):
@@ -1156,16 +1156,16 @@ class Form(object):
self._values.get('id', False),
)
def _process_fvg(self, model, fvg, o2m=True):
def _process_fvg(self, model, fvg, level=2):
""" Post-processes to augment the fields_view_get with:
* an id field (may not be present if not in the view but needed)
* pre-processed modifiers (map of modifier name to json-loaded domain)
* pre-processed onchanges list
"""
fvg['fields']['id'] = {'type': 'id'}
fvg['fields'].setdefault('id', {'type': 'id'})
# pre-resolve modifiers & bind to arch toplevel
modifiers = fvg['modifiers'] = {}
modifiers = fvg['modifiers'] = {'id': {'required': False, 'readonly': True}}
contexts = fvg['contexts'] = {}
order = fvg['fields_ordered'] = []
for f in fvg['tree'].xpath('//field[not(ancestor::field)]'):
@@ -1181,10 +1181,9 @@ class Form(object):
contexts[fname] = ctx
descr = fvg['fields'].get(fname) or {'type': None}
if o2m and descr['type'] == 'one2many':
self._o2m_set_edition_view(descr, f)
if level and descr['type'] == 'one2many':
self._o2m_set_edition_view(descr, f, level)
fvg['modifiers']['id'] = {'required': False, 'readonly': True}
fvg['onchange'] = model._onchange_spec(fvg)
def _init_from_defaults(self, model):
@@ -1263,7 +1262,9 @@ class Form(object):
stack.append(e1 or e2)
elif isinstance(it, list):
f, op, val = it
field_val = vals[f]
# hack-ish handling of parent.<field> modifiers
f, n = re.subn(r'^parent\.', '', f, 1)
field_val = (vals['•parent•'] if n else vals)[f]
stack.append(self._OPS[op](field_val, val))
else:
raise ValueError("Unknown domain element %s" % it)
@@ -1391,9 +1392,12 @@ class Form(object):
for (c, rid, vs) in oldvals:
if c in (0, 1):
items = getattr(vs, 'changed_items', vs.items)
items = list(getattr(vs, 'changed_items', vs.items)())
# FIXME: should be more extensive processing of o2m defaults
vs.setdefault('id', False)
vs['•parent•'] = self._values
vs = {
k: v for k, v in items()
k: v for k, v in items
if nodes[k].get('force_save') or not self._get_modifier(k, 'readonly', modmap=modifiers, vals=vs)
}
v.append((c, rid, vs))