summaryrefslogtreecommitdiff
path: root/odoo
diff options
context:
space:
mode:
authorqdp-odoo <qdp@odoo.com>2016-12-30 17:20:36 +0100
committerqdp-odoo <qdp@odoo.com>2016-12-30 17:21:25 +0100
commit4f29b77e3d1677ffc88336cc99fb7f09d49d7dd1 (patch)
tree0642a57228cc2e0e3ab04d5afbfb5adf882b689c /odoo
parent33a413eb2944db4a35d035f42161159ae53dd830 (diff)
[MERGE] foward port of 10.0 up to revision 84a650e33aadb29661121410813e3de37a5ad3e9
Diffstat (limited to 'odoo')
-rw-r--r--odoo/addons/base/ir/ir_actions.py2
-rw-r--r--odoo/addons/base/ir/ir_attachment.py13
-rw-r--r--odoo/addons/base/ir/ir_model.py12
-rw-r--r--odoo/fields.py12
-rw-r--r--odoo/models.py11
-rw-r--r--odoo/tests/addons/test_translation_import/tests.yml4
-rw-r--r--odoo/tests/addons/test_translation_import/tests/test_term_count.py2
-rw-r--r--odoo/tests/addons/test_translation_import/view.xml2
8 files changed, 49 insertions, 9 deletions
diff --git a/odoo/addons/base/ir/ir_actions.py b/odoo/addons/base/ir/ir_actions.py
index 55da335d7e2..e164c5fdb13 100644
--- a/odoo/addons/base/ir/ir_actions.py
+++ b/odoo/addons/base/ir/ir_actions.py
@@ -211,7 +211,7 @@ class IrActionsReportXml(models.Model):
for report in self:
if report.ir_values_id:
try:
- self.report.ir_values_id.sudo().unlink()
+ report.ir_values_id.sudo().unlink()
except Exception:
raise UserError(_('Deletion of the action record failed.'))
return True
diff --git a/odoo/addons/base/ir/ir_attachment.py b/odoo/addons/base/ir/ir_attachment.py
index d84a18d7f69..528df926e5d 100644
--- a/odoo/addons/base/ir/ir_attachment.py
+++ b/odoo/addons/base/ir/ir_attachment.py
@@ -138,8 +138,17 @@ class IrAttachment(models.Model):
if self._storage() != 'file':
return
- # prevent all concurrent updates on ir_attachment while collecting!
+ # Continue in a new transaction. The LOCK statement below must be the
+ # first one in the current transaction, otherwise the database snapshot
+ # used by it may not contain the most recent changes made to the table
+ # ir_attachment! Indeed, if concurrent transactions create attachments,
+ # the LOCK statement will wait until those concurrent transactions end.
+ # But this transaction will not see the new attachements if it has done
+ # other requests before the LOCK (like the method _storage() above).
cr = self._cr
+ cr.commit()
+
+ # prevent all concurrent updates on ir_attachment while collecting!
cr.execute("LOCK ir_attachment IN SHARE MODE")
# retrieve the file names from the checklist
@@ -168,6 +177,8 @@ class IrAttachment(models.Model):
with tools.ignore(OSError):
os.unlink(filepath)
+ # commit to release the lock
+ cr.commit()
_logger.info("filestore gc %d checked, %d removed", len(checklist), removed)
@api.depends('store_fname', 'db_datas')
diff --git a/odoo/addons/base/ir/ir_model.py b/odoo/addons/base/ir/ir_model.py
index 7259c0bbc1d..868eba9b8bb 100644
--- a/odoo/addons/base/ir/ir_model.py
+++ b/odoo/addons/base/ir/ir_model.py
@@ -435,6 +435,12 @@ class IrModelFields(models.Model):
model = self.env[record.model]
field = model._fields[record.name]
if field.type == 'many2one' and model._field_inverses.get(field):
+ if self._context.get(MODULE_UNINSTALL_FLAG):
+ # automatically unlink the corresponding one2many field(s)
+ inverses = self.search([('relation', '=', field.model_name),
+ ('relation_field', '=', field.name)])
+ inverses.unlink()
+ continue
msg = _("The field '%s' cannot be removed because the field '%s' depends on it.")
raise UserError(msg % (field, model._field_inverses[field][0]))
@@ -714,6 +720,12 @@ class IrModelConstraint(models.Model):
self.unlink()
+ @api.multi
+ def copy(self, default=None):
+ default = dict(default or {})
+ default['name'] = self.name + '_copy'
+ return super(IrModelConstraint, self).copy(default)
+
class IrModelRelation(models.Model):
"""
diff --git a/odoo/fields.py b/odoo/fields.py
index 90f4b2f943c..3240b83d801 100644
--- a/odoo/fields.py
+++ b/odoo/fields.py
@@ -1578,6 +1578,7 @@ class Datetime(Field):
class Binary(Field):
type = 'binary'
_slots = {
+ 'prefetch': False, # not prefetched by default
'attachment': False, # whether value is stored in attachment
}
@@ -1747,6 +1748,14 @@ class Selection(Field):
return item[1]
return False
+ def convert_to_column(self, value, record):
+ """ Convert ``value`` from the ``write`` format to the SQL format. """
+ if value is None or value is False:
+ return None
+ if isinstance(value, unicode):
+ return value.encode('utf8')
+ return str(value)
+
class Reference(Selection):
type = 'reference'
@@ -2398,6 +2407,9 @@ class Many2many(_RelationalMulti):
class Serialized(Field):
""" Serialized fields provide the storage for sparse fields. """
type = 'serialized'
+ _slots = {
+ 'prefetch': False, # not prefetched by default
+ }
column_type = ('text', 'text')
def convert_to_column(self, value, record):
diff --git a/odoo/models.py b/odoo/models.py
index 29aca32a50f..06aab521071 100644
--- a/odoo/models.py
+++ b/odoo/models.py
@@ -665,10 +665,11 @@ class BaseModel(object):
methods = []
for attr, func in getmembers(cls, is_constraint):
for name in func._constrains:
- if name not in cls._fields:
+ field = cls._fields.get(name)
+ if not field:
_logger.warning("method %s.%s: @constrains parameter %r is not a field name", cls._name, attr, name)
- if not cls._fields[name].store:
- _logger.warning("method %s.%s: @constrains parameter %r is not stored", cls._name, attr, name)
+ if not (field.store or field.inverse):
+ _logger.warning("method %s.%s: @constrains parameter %r is not writeable", cls._name, attr, name)
methods.append(func)
# optimization: memoize result on cls, it will not be recomputed
@@ -3514,6 +3515,8 @@ class BaseModel(object):
record._cache.update(record._convert_to_cache(new_vals, update=True))
for key in new_vals:
self._fields[key].determine_inverse(self)
+ # check Python constraints for inversed fields
+ self._validate_fields(set(new_vals) - set(old_vals))
return True
@@ -3772,6 +3775,8 @@ class BaseModel(object):
with self.env.protecting(protected_fields, record):
for key in new_vals:
self._fields[key].determine_inverse(record)
+ # check Python constraints for inversed fields
+ record._validate_fields(set(new_vals) - set(old_vals))
return record
diff --git a/odoo/tests/addons/test_translation_import/tests.yml b/odoo/tests/addons/test_translation_import/tests.yml
index 9138fb7cd27..e129baec516 100644
--- a/odoo/tests/addons/test_translation_import/tests.yml
+++ b/odoo/tests/addons/test_translation_import/tests.yml
@@ -8,6 +8,6 @@
Assert we have loaded the correct number of entries for the given source string.
-
!python {model: ir.translation }: |
- ids = self.search(cr, uid,
+ translations = self.search(
[('src', '=', '1XBUO5PUYH2RYZSA1FTLRYS8SPCNU1UYXMEYMM25ASV7JC2KTJZQESZYRV9L8CGB')])
- assert len(ids) == 2, "2 entries are expected, got %s instead." % len(ids)
+ assert len(translations) == 2, "2 entries are expected, got %s instead." % len(translations)
diff --git a/odoo/tests/addons/test_translation_import/tests/test_term_count.py b/odoo/tests/addons/test_translation_import/tests/test_term_count.py
index 9d2be3ba82c..d63f2b01baa 100644
--- a/odoo/tests/addons/test_translation_import/tests/test_term_count.py
+++ b/odoo/tests/addons/test_translation_import/tests/test_term_count.py
@@ -10,6 +10,6 @@ class TestTermCount(common.TransactionCase):
Just make sure we have as many translation entries as we wanted.
"""
odoo.tools.trans_load(self.cr, 'test_translation_import/i18n/fr.po', 'fr_FR', verbose=False)
- ids = self.registry('ir.translation').search(self.cr, self.uid,
+ ids = self.env['ir.translation'].search(
[('src', '=', '1XBUO5PUYH2RYZSA1FTLRYS8SPCNU1UYXMEYMM25ASV7JC2KTJZQESZYRV9L8CGB')])
self.assertEqual(len(ids), 2)
diff --git a/odoo/tests/addons/test_translation_import/view.xml b/odoo/tests/addons/test_translation_import/view.xml
index 52847b74eac..7dd417707e3 100644
--- a/odoo/tests/addons/test_translation_import/view.xml
+++ b/odoo/tests/addons/test_translation_import/view.xml
@@ -11,7 +11,7 @@
<field name="target">current</field>
</record>
- <menuitem id="menu_test_translation" parent="menu_tests" name="Test translation"/>
+ <menuitem id="menu_test_translation" name="Test translation"/>
<menuitem id="menu_test_translation_import"
name="Test translation import"