summaryrefslogtreecommitdiff
path: root/odoo
diff options
context:
space:
mode:
authorXavier Morel <xmo@odoo.com>2019-03-22 08:02:15 +0000
committerXavier Morel <xmo@odoo.com>2019-04-01 10:34:47 +0000
commit7e0b29cbcdaa324e342d6877dd220749b8211771 (patch)
tree683abee4280fe2e92f2bcc6b038c00b77feb5719 /odoo
parent295690ce70f972386be1170dabb7cab5a16e7c05 (diff)
[FIX] core: backport changes in 12.1/master to 12.0
PRs #28645 and #31494 were not applied to 12.0, but there's no reason not to, they should only fix things (make behaviours more in-line with the regular client), and since o2m is an area where more fixes are needed and it would be nice to have them in 12.0...
Diffstat (limited to 'odoo')
-rw-r--r--odoo/addons/test_testing_utilities/models.py2
-rw-r--r--odoo/tests/common.py82
2 files changed, 43 insertions, 41 deletions
diff --git a/odoo/addons/test_testing_utilities/models.py b/odoo/addons/test_testing_utilities/models.py
index dee6dff08fb..fbdec47a7cf 100644
--- a/odoo/addons/test_testing_utilities/models.py
+++ b/odoo/addons/test_testing_utilities/models.py
@@ -71,7 +71,7 @@ class M2Onchange(models.Model):
def _on_change_f2(self):
self.f = self.env['test_testing_utilities.m2o'].search([
('name', 'ilike', self.f2),
- ], limit=1)
+ ], limit=1) if self.f2 else False
class M2MChange(models.Model):
_name = 'test_testing_utilities.e'
diff --git a/odoo/tests/common.py b/odoo/tests/common.py
index dd808aaec30..ac31b08ee81 100644
--- a/odoo/tests/common.py
+++ b/odoo/tests/common.py
@@ -1101,44 +1101,6 @@ class Form(object):
fvg['tree'] = etree.fromstring(fvg['arch'])
object.__setattr__(self, '_view', fvg)
- # TODO: make this less crappy?
- # look up edition view for the O2M
- for f, descr in fvg['fields'].items():
- if descr['type'] != 'one2many':
- continue
-
- node = self._get_node(f)
- default_view = next(
- (m for m in node.get('mode', 'tree').split(',') if m != 'form'),
- 'tree'
- )
-
- refs = {
- m.group('view_type'): m.group('view_id')
- for m in ref_re.finditer(node.get('context', ''))
- }
- # always fetch for simplicity, ensure we always have a tree and
- # a form view
- submodel = env[descr['relation']]
- views = submodel.with_context(**refs) \
- .load_views([(False, 'tree'), (False, 'form')])['fields_views']
- # embedded views should take the priority on externals
- views.update(descr['views'])
- # re-set all resolved views on the descriptor
- descr['views'] = views
-
- # if the default view is a kanban or a non-editable list, the
- # "edition controller" is the form view
- edition = views['form']
- edition['tree'] = etree.fromstring(edition['arch'])
- if default_view == 'tree':
- subarch = etree.fromstring(views['tree']['arch'])
- if subarch.get('editable'):
- edition = views['tree']
- edition['tree'] = subarch
-
- self._process_fvg(submodel, edition)
- descr['views']['edition'] = edition
self._process_fvg(recordp, fvg)
@@ -1155,6 +1117,37 @@ class Form(object):
else:
self._init_from_defaults(self._model)
+ def _o2m_set_edition_view(self, descr, node):
+ default_view = next(
+ (m for m in node.get('mode', 'tree').split(',') if m != 'form'),
+ 'tree'
+ )
+ refs = {
+ m.group('view_type'): m.group('view_id')
+ for m in ref_re.finditer(node.get('context', ''))
+ }
+ # always fetch for simplicity, ensure we always have a tree and
+ # a form view
+ submodel = self._env[descr['relation']]
+ views = submodel.with_context(**refs) \
+ .load_views([(False, 'tree'), (False, 'form')])['fields_views']
+ # embedded views should take the priority on externals
+ views.update(descr['views'])
+ # re-set all resolved views on the descriptor
+ descr['views'] = views
+ # if the default view is a kanban or a non-editable list, the
+ # "edition controller" is the form view
+ edition = views['form']
+ edition['tree'] = etree.fromstring(edition['arch'])
+ if default_view == 'tree':
+ subarch = etree.fromstring(views['tree']['arch'])
+ if subarch.get('editable'):
+ edition = views['tree']
+ edition['tree'] = subarch
+
+ self._process_fvg(submodel, edition)
+ descr['views']['edition'] = edition
+
def _get_node(self, f):
""" Find etree node for the field ``f`` in the current arch
"""
@@ -1181,8 +1174,11 @@ class Form(object):
# pre-resolve modifiers & bind to arch toplevel
modifiers = fvg['modifiers'] = {}
contexts = fvg['contexts'] = {}
- for f in fvg['tree'].iter('field'):
+ order = fvg['fields_ordered'] = []
+ for f in fvg['tree'].xpath('//field[not(ancestor::field)]'):
fname = f.get('name')
+ order.append(fname)
+
modifiers[fname] = {
modifier: domain if isinstance(domain, bool) else normalize_domain(domain)
for modifier, domain in json.loads(f.get('modifiers', '{}')).items()
@@ -1190,6 +1186,11 @@ class Form(object):
ctx = f.get('context')
if ctx:
contexts[fname] = ctx
+
+ descr = fvg['fields'].get(fname) or {'type': None}
+ if descr['type'] == 'one2many':
+ self._o2m_set_edition_view(descr, f)
+
fvg['modifiers']['id'] = {'required': False, 'readonly': True}
fvg['onchange'] = model._onchange_spec(fvg)
@@ -1225,7 +1226,8 @@ class Form(object):
# on creation, every field is considered changed by the client
# apparently
- self._perform_onchange(list(vals.keys() - {'id'}))
+ # and fields should be sent in view order, not whatever fields_view_get['fields'].keys() is
+ self._perform_onchange(self._view['fields_ordered'])
def _init_from_values(self, values):
self._values.update(