diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py
index fbe8592348d..71b6008c08d 100644
--- a/addons/mail/mail_thread.py
+++ b/addons/mail/mail_thread.py
@@ -343,10 +343,11 @@ class mail_thread(osv.AbstractModel):
track_ctx = dict(context)
if 'lang' not in track_ctx:
track_ctx['lang'] = self.pool.get('res.users').browse(cr, uid, uid, context=context).lang
- tracked_fields = self._get_tracked_fields(cr, uid, values.keys(), context=track_ctx)
- if tracked_fields:
- initial_values = {thread_id: dict((item, False) for item in tracked_fields)}
- self.message_track(cr, uid, [thread_id], tracked_fields, initial_values, context=track_ctx)
+ if not context.get('mail_notrack'):
+ tracked_fields = self._get_tracked_fields(cr, uid, values.keys(), context=track_ctx)
+ if tracked_fields:
+ initial_values = {thread_id: dict((item, False) for item in tracked_fields)}
+ self.message_track(cr, uid, [thread_id], tracked_fields, initial_values, context=track_ctx)
return thread_id
def write(self, cr, uid, ids, values, context=None):
@@ -367,7 +368,11 @@ class mail_thread(osv.AbstractModel):
result = super(mail_thread, self).write(cr, uid, ids, values, context=context)
self.message_auto_subscribe(cr, uid, ids, values.keys(), context=context, values=values)
- # Perform the tracking
+ if not context.get('mail_notrack'):
+ # Perform the tracking
+ tracked_fields = self._get_tracked_fields(cr, uid, values.keys(), context=context)
+ else:
+ tracked_fields = None
if tracked_fields:
self.message_track(cr, uid, ids, tracked_fields, initial_values, context=track_ctx)
return result
@@ -388,6 +393,9 @@ class mail_thread(osv.AbstractModel):
return res
def copy(self, cr, uid, id, default=None, context=None):
+ # avoid tracking multiple temporary changes during copy
+ context = dict(context or {}, mail_notrack=True)
+
default = default or {}
default['message_ids'] = []
default['message_follower_ids'] = []
@@ -1500,6 +1508,9 @@ class mail_thread(osv.AbstractModel):
""" Add partners to the records followers. """
if context is None:
context = {}
+ # not necessary for computation, but saves an access right check
+ if not partner_ids:
+ return True
mail_followers_obj = self.pool.get('mail.followers')
subtype_obj = self.pool.get('mail.message.subtype')
@@ -1558,6 +1569,9 @@ class mail_thread(osv.AbstractModel):
def message_unsubscribe(self, cr, uid, ids, partner_ids, context=None):
""" Remove partners from the records followers. """
+ # not necessary for computation, but saves an access right check
+ if not partner_ids:
+ return True
user_pid = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=context)['partner_id'][0]
if set(partner_ids) == set([user_pid]):
self.check_access_rights(cr, uid, 'read')
diff --git a/addons/project/project.py b/addons/project/project.py
index 053aded1d4e..273fb4fcf3e 100644
--- a/addons/project/project.py
+++ b/addons/project/project.py
@@ -364,6 +364,11 @@ class project(osv.osv):
default['state'] = 'open'
default['line_ids'] = []
default['tasks'] = []
+
+ # Don't prepare (expensive) data to copy children (analytic accounts),
+ # they are discarded in analytic.copy(), and handled in duplicate_template()
+ default['child_ids'] = []
+
proj = self.browse(cr, uid, id, context=context)
if not default.get('name', False):
default.update(name=_("%s (copy)") % (proj.name))
@@ -696,23 +701,13 @@ class task(osv.osv):
return {'value': vals}
def duplicate_task(self, cr, uid, map_ids, context=None):
- for new in map_ids.values():
- task = self.browse(cr, uid, new, context)
- child_ids = [ ch.id for ch in task.child_ids]
- if task.child_ids:
- for child in task.child_ids:
- if child.id in map_ids.keys():
- child_ids.remove(child.id)
- child_ids.append(map_ids[child.id])
-
- parent_ids = [ ch.id for ch in task.parent_ids]
- if task.parent_ids:
- for parent in task.parent_ids:
- if parent.id in map_ids.keys():
- parent_ids.remove(parent.id)
- parent_ids.append(map_ids[parent.id])
- #FIXME why there is already the copy and the old one
- self.write(cr, uid, new, {'parent_ids':[(6,0,set(parent_ids))], 'child_ids':[(6,0, set(child_ids))]})
+ mapper = lambda t: map_ids.get(t.id, t.id)
+ for task in self.browse(cr, uid, map_ids.values(), context):
+ new_child_ids = set(map(mapper, task.child_ids))
+ new_parent_ids = set(map(mapper, task.parent_ids))
+ if new_child_ids or new_parent_ids:
+ task.write({'parent_ids': [(6,0,list(new_parent_ids))],
+ 'child_ids': [(6,0,list(new_child_ids))]})
def copy_data(self, cr, uid, id, default=None, context=None):
if default is None:
diff --git a/addons/sale/sale_view.xml b/addons/sale/sale_view.xml
index e04e022797f..28ef6b03990 100644
--- a/addons/sale/sale_view.xml
+++ b/addons/sale/sale_view.xml
@@ -77,9 +77,9 @@
-
+
-
+
-
+
diff --git a/addons/sale_stock/sale_stock_view.xml b/addons/sale_stock/sale_stock_view.xml
index 81f16c5eb40..6d0214fba67 100644
--- a/addons/sale_stock/sale_stock_view.xml
+++ b/addons/sale_stock/sale_stock_view.xml
@@ -20,8 +20,8 @@
-
-
+
+ {"shipping_except":"red","invoice_except":"red","waiting_date":"blue"}