summaryrefslogtreecommitdiff
path: root/odoo/addons
diff options
context:
space:
mode:
authorChristophe Simonis <chs@odoo.com>2016-10-19 18:16:14 +0200
committerChristophe Simonis <chs@odoo.com>2016-10-19 18:16:14 +0200
commit938ffb92da1ea898f661aec04745f7630e2f378c (patch)
tree7faeed8433101836cd0239cf6c23629ef1f1289d /odoo/addons
parent1f9e92dfef325b6727e1bee3de55bff095ec6cf2 (diff)
parent6466aa499fc37bba5f4feeeecac99448ef88e62e (diff)
[MERGE] forward port branch 10.0 up to 6466aa4
Diffstat (limited to 'odoo/addons')
-rw-r--r--odoo/addons/base/ir/ir_model.py14
-rw-r--r--odoo/addons/base/ir/ir_ui_view.py17
-rw-r--r--odoo/addons/base/tests/test_views.py8
-rw-r--r--odoo/addons/test_impex/tests/test_export.py4
-rw-r--r--odoo/addons/test_new_api/tests/__init__.py1
-rw-r--r--odoo/addons/test_new_api/tests/test_onchange.py2
-rw-r--r--odoo/addons/test_new_api/tests/test_one2many.py65
-rw-r--r--odoo/addons/test_pylint/tests/test_pylint.py1
8 files changed, 100 insertions, 12 deletions
diff --git a/odoo/addons/base/ir/ir_model.py b/odoo/addons/base/ir/ir_model.py
index b4376c99467..1e23c311da2 100644
--- a/odoo/addons/base/ir/ir_model.py
+++ b/odoo/addons/base/ir/ir_model.py
@@ -1208,6 +1208,7 @@ class IrModelData(models.Model):
datas = self.search([('module', 'in', modules_to_remove)])
wkf_todo = []
to_unlink = tools.OrderedSet()
+ undeletable = self.browse([])
for data in datas.sorted(key='id', reverse=True):
model = data.model
@@ -1232,6 +1233,7 @@ class IrModelData(models.Model):
_logger.info('Unable to force processing of workflow for item %s@%s in order to leave activity to be deleted', res_id, model, exc_info=True)
def unlink_if_refcount(to_unlink):
+ undeletable = self.browse()
for model, res_id in to_unlink:
external_ids = self.search([('model', '=', model), ('res_id', '=', res_id)])
if external_ids - datas:
@@ -1255,28 +1257,30 @@ class IrModelData(models.Model):
self.env[model].browse(res_id).unlink()
except Exception:
_logger.info('Unable to delete %s@%s', res_id, model, exc_info=True)
+ undeletable += external_ids
self._cr.execute('ROLLBACK TO SAVEPOINT record_unlink_save')
else:
self._cr.execute('RELEASE SAVEPOINT record_unlink_save')
+ return undeletable
# Remove non-model records first, then model fields, and finish with models
- unlink_if_refcount(item for item in to_unlink if item[0] not in ('ir.model', 'ir.model.fields', 'ir.model.constraint'))
- unlink_if_refcount(item for item in to_unlink if item[0] == 'ir.model.constraint')
+ undeletable += unlink_if_refcount(item for item in to_unlink if item[0] not in ('ir.model', 'ir.model.fields', 'ir.model.constraint'))
+ undeletable += unlink_if_refcount(item for item in to_unlink if item[0] == 'ir.model.constraint')
modules = self.env['ir.module.module'].search([('name', 'in', modules_to_remove)])
constraints = self.env['ir.model.constraint'].search([('module', 'in', modules.ids)])
constraints._module_data_uninstall()
- unlink_if_refcount(item for item in to_unlink if item[0] == 'ir.model.fields')
+ undeletable += unlink_if_refcount(item for item in to_unlink if item[0] == 'ir.model.fields')
relations = self.env['ir.model.relation'].search([('module', 'in', modules.ids)])
relations._module_data_uninstall()
- unlink_if_refcount(item for item in to_unlink if item[0] == 'ir.model')
+ undeletable += unlink_if_refcount(item for item in to_unlink if item[0] == 'ir.model')
self._cr.commit()
- datas.unlink()
+ (datas - undeletable).unlink()
@api.model
def _process_end(self, modules):
diff --git a/odoo/addons/base/ir/ir_ui_view.py b/odoo/addons/base/ir/ir_ui_view.py
index 67c755581d3..10bf7c627b4 100644
--- a/odoo/addons/base/ir/ir_ui_view.py
+++ b/odoo/addons/base/ir/ir_ui_view.py
@@ -229,10 +229,11 @@ actual arch.
for view, view_wo_lang in zip(self, self.with_context(lang=None)):
view_wo_lang.arch = view.arch_base
+ @api.depends('write_date')
def _compute_model_data_id(self):
- # get the last ir_model_data record corresponding to self
+ # get the first ir_model_data record corresponding to self
domain = [('model', '=', 'ir.ui.view'), ('res_id', 'in', self.ids)]
- for data in self.env['ir.model.data'].search_read(domain, ['res_id']):
+ for data in self.env['ir.model.data'].search_read(domain, ['res_id'], order='id desc'):
view = self.browse(data['res_id'])
view.model_data_id = data['id']
@@ -343,7 +344,15 @@ actual arch.
values['name'] = "%s %s" % (values.get('model'), values['type'])
self.clear_caches()
- return super(View, self).create(self._compute_defaults(values))
+
+ if 'install_mode_data' in self._context:
+ # the view is created from a data file by installing a module; delay
+ # the recomputation of field 'model_data_id' until its xmlid record
+ # is created
+ with self.env.norecompute():
+ return super(View, self).create(self._compute_defaults(values))
+ else:
+ return super(View, self).create(self._compute_defaults(values))
@api.multi
def write(self, vals):
@@ -1168,4 +1177,4 @@ actual arch.
try:
self.browse(vid)._check_xml()
except Exception as e:
- self.raise_view_error("Can't validate view: %s" % e.message, vid)
+ self.raise_view_error("Can't validate view:\n%s" % (e.message or repr(e)), vid)
diff --git a/odoo/addons/base/tests/test_views.py b/odoo/addons/base/tests/test_views.py
index 38f30308fab..adbabdc48ad 100644
--- a/odoo/addons/base/tests/test_views.py
+++ b/odoo/addons/base/tests/test_views.py
@@ -12,6 +12,14 @@ from odoo.tests import common
from odoo.tools import mute_logger
+class ViewXMLID(common.TransactionCase):
+ def test_model_data_id(self):
+ """ Check whether views know their xmlid record. """
+ view = self.env.ref('base.view_company_form')
+ self.assertTrue(view)
+ self.assertTrue(view.model_data_id)
+ self.assertEqual(view.model_data_id.complete_name, 'base.view_company_form')
+
class ViewCase(common.TransactionCase):
def setUp(self):
super(ViewCase, self).setUp()
diff --git a/odoo/addons/test_impex/tests/test_export.py b/odoo/addons/test_impex/tests/test_export.py
index e80f6df0866..226ba9943f6 100644
--- a/odoo/addons/test_impex/tests/test_export.py
+++ b/odoo/addons/test_impex/tests/test_export.py
@@ -23,7 +23,7 @@ class CreatorCase(common.TransactionCase):
def export(self, value, fields=('value',), context=None):
record = self.make(value)
record.invalidate_cache()
- return record._BaseModel__export_rows([f.split('/') for f in fields])
+ return record._export_rows([f.split('/') for f in fields])
class test_boolean_field(CreatorCase):
@@ -449,7 +449,7 @@ class test_o2m_multiple(CreatorCase):
def export(self, value=None, fields=('child1', 'child2',), context=None, **values):
record = self.make(value, **values)
- return record._BaseModel__export_rows([f.split('/') for f in fields])
+ return record._export_rows([f.split('/') for f in fields])
def test_empty(self):
self.assertEqual(
diff --git a/odoo/addons/test_new_api/tests/__init__.py b/odoo/addons/test_new_api/tests/__init__.py
index 2bbcfe40990..b90ccc96825 100644
--- a/odoo/addons/test_new_api/tests/__init__.py
+++ b/odoo/addons/test_new_api/tests/__init__.py
@@ -3,5 +3,6 @@
from . import test_new_fields
from . import test_onchange
from . import test_attributes
+from . import test_one2many
from . import test_ui
from . import test_domain
diff --git a/odoo/addons/test_new_api/tests/test_onchange.py b/odoo/addons/test_new_api/tests/test_onchange.py
index 87fc8229b7c..a6e2bff1b35 100644
--- a/odoo/addons/test_new_api/tests/test_onchange.py
+++ b/odoo/addons/test_new_api/tests/test_onchange.py
@@ -176,7 +176,7 @@ class TestOnChange(common.TransactionCase):
self.assertEqual(values, {
'name': partner.name,
'partner': partner.id,
- 'lines': [(5,), (4, line.id)],
+ 'lines': [(6, 0, [line.id])],
})
# modify 'partner'
diff --git a/odoo/addons/test_new_api/tests/test_one2many.py b/odoo/addons/test_new_api/tests/test_one2many.py
new file mode 100644
index 00000000000..38dee13ab54
--- /dev/null
+++ b/odoo/addons/test_new_api/tests/test_one2many.py
@@ -0,0 +1,65 @@
+# -*- coding: utf-8 -*-
+from openerp.tests.common import TransactionCase
+
+
+class One2manyCase(TransactionCase):
+ def setUp(self):
+ super(One2manyCase, self).setUp()
+ self.Line = self.env["test_new_api.multi.line"]
+ self.multi = self.env["test_new_api.multi"].create({
+ "name": "What is up?"
+ })
+
+ def operations(self):
+ """Run operations on o2m fields to check all works fine."""
+ # Check the lines first
+ self.assertItemsEqual(
+ self.multi.lines.mapped('name'),
+ map(str, range(10)))
+ # Modify the first line and drop the last one
+ self.multi.lines[0].name = "hello"
+ self.multi.lines = self.multi.lines[:-1]
+ self.assertEqual(len(self.multi.lines), 9)
+ self.assertIn("hello", self.multi.lines.mapped('name'))
+ # Invalidate the cache and check again; this crashes if the value
+ # of self.multi.lines in cache contains new records
+ self.multi.invalidate_cache()
+ self.assertEqual(len(self.multi.lines), 9)
+ self.assertIn("hello", self.multi.lines.mapped('name'))
+
+ def test_new_one_by_one(self):
+ """Check lines created with ``new()`` and appended one by one."""
+ for name in range(10):
+ self.multi.lines |= self.Line.new({"name": str(name)})
+ self.operations()
+
+ def test_new_single(self):
+ """Check lines created with ``new()`` and added in one step."""
+ self.multi.lines = self.Line.browse(
+ [self.Line.new({"name": str(name)}).id for name in range(10)]
+ )
+ self.operations()
+
+ def test_create_one_by_one(self):
+ """Check lines created with ``create()`` and appended one by one."""
+ for name in range(10):
+ self.multi.lines |= self.Line.create({"name": str(name)})
+ self.operations()
+
+ def test_create_single(self):
+ """Check lines created with ``create()`` and added in one step."""
+ self.multi.lines = self.Line.browse(
+ [self.Line.create({"name": str(name)}).id for name in range(10)]
+ )
+ self.operations()
+
+ def test_rpcstyle_one_by_one(self):
+ """Check lines created with RPC style and appended one by one."""
+ for name in range(10):
+ self.multi.lines = [(0, 0, {"name": str(name)})]
+ self.operations()
+
+ def test_rpcstyle_single(self):
+ """Check lines created with RPC style and added in one step"""
+ self.multi.lines = [(0, 0, {'name': str(name)}) for name in range(10)]
+ self.operations()
diff --git a/odoo/addons/test_pylint/tests/test_pylint.py b/odoo/addons/test_pylint/tests/test_pylint.py
index 251db1f6eba..38fa4c3d51a 100644
--- a/odoo/addons/test_pylint/tests/test_pylint.py
+++ b/odoo/addons/test_pylint/tests/test_pylint.py
@@ -22,6 +22,7 @@ _logger = logging.getLogger(__name__)
class TestPyLint(TransactionCase):
ENABLED_CODES = [
+ 'E0601', # using variable before assignment
'W0123', # eval used
'W0101', # unreachable code
]