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 @@