[WIP] Followers rewrite: in create/write, the purpose is to add the field in the...
authorThibault Delavallée <tde@openerp.com>
Tue, 14 Aug 2012 17:06:12 +0000 (19:06 +0200)
committerThibault Delavallée <tde@openerp.com>
Tue, 14 Aug 2012 17:06:12 +0000 (19:06 +0200)
bzr revid: tde@openerp.com-20120814170612-ax8xhcmmttrcphnl

addons/crm/crm_lead.py
addons/hr_holidays/hr_holidays.py
addons/hr_recruitment/hr_recruitment.py
addons/mail/mail_group.py
addons/mail/mail_thread.py
addons/mrp/mrp.py
addons/project/project.py
addons/project_issue/project_issue.py

index 6e1d3a7..6b29dbb 100644 (file)
@@ -859,13 +859,10 @@ class crm_lead(base_stage, osv.osv):
     # OpenChatter methods and notifications
     # ----------------------------------------
 
-    def message_get_subscribers(self, cr, uid, ids, context=None):
-        """ Override to add the salesman. """
-        user_ids = super(crm_lead, self).message_get_subscribers(cr, uid, ids, context=context)
-        for obj in self.browse(cr, uid, ids, context=context):
-            if obj.user_id and not obj.user_id.id in user_ids:
-                user_ids.append(obj.user_id.id)
-        return user_ids
+    def message_get_follower_fields(self, cr, uid, ids, context=None):
+        """ Override to add 'user_id' field to automatic subscription. """
+        res = super(crm_lead, self).message_get_follower_fields(cr, uid, ids, context=context)
+        return res.append('user_id')
 
     def stage_set_send_note(self, cr, uid, ids, stage_id, context=None):
         """ Override of the (void) default notification method. """
index 7eedfa5..1788c85 100644 (file)
@@ -366,15 +366,10 @@ class hr_holidays(osv.osv):
                     result[obj.id] = hr_manager_group['users']
         return result
 
-    def message_get_subscribers(self, cr, uid, ids, context=None):
-        """ Override to add employee and its manager. """
-        user_ids = super(hr_holidays, self).message_get_subscribers(cr, uid, ids, context=context)
-        for obj in self.browse(cr, uid, ids, context=context):
-            if obj.user_id and not obj.user_id.id in user_ids:
-                user_ids.append(obj.user_id.id)
-            if obj.employee_id.parent_id and not obj.employee_id.parent_id.user_id.id in user_ids:
-                user_ids.append(obj.employee_id.parent_id.user_id.id)
-        return user_ids
+    def message_get_follower_fields(self, cr, uid, ids, context=None):
+        """ Override to add 'user_id' field to automatic subscription. """
+        res = super(hr_holidays, self).message_get_follower_fields(cr, uid, ids, context=context)
+        return res + ['user_id', 'employee_id.parent_id.user_id']
         
     def create_notificate(self, cr, uid, ids, context=None):
         for obj in self.browse(cr, uid, ids, context=context):
index 1db7917..cdd3252 100644 (file)
@@ -461,13 +461,10 @@ class hr_applicant(base_stage, osv.Model):
     # OpenChatter methods and notifications
     # -------------------------------------------------------
 
-    def message_get_subscribers(self, cr, uid, ids, context=None):
-        """ Override to add responsible user. """
-        user_ids = super(hr_applicant, self).message_get_subscribers(cr, uid, ids, context=context)
-        for obj in self.browse(cr, uid, ids, context=context):
-            if obj.user_id and not obj.user_id.id in user_ids:
-                user_ids.append(obj.user_id.id)
-        return user_ids
+    def message_get_follower_fields(self, cr, uid, ids, context=None):
+        """ Override to add 'user_id' field to automatic subscription. """
+        res = super(hr_applicant, self).message_get_follower_fields(cr, uid, ids, context=context)
+        return res.append('user_id')
 
     def stage_set_send_note(self, cr, uid, ids, stage_id, context=None):
         """ Override of the (void) default notification method. """
index 8400854..306a758 100644 (file)
@@ -184,3 +184,12 @@ class mail_group(osv.Model):
 
     def action_group_leave(self, cr, uid, ids, context=None):
         return self.message_unsubscribe(cr, uid, ids, context=context)
+
+    # ----------------------------------------
+    # OpenChatter methods and notifications
+    # ----------------------------------------
+
+    def message_get_monitored_follower_fields(self, cr, uid, ids, context=None):
+        """ Add 'responsible_id' to the monitored fields """
+        res = super(mail_group, self).message_get_monitored_follower_fields(cr, uid, ids, context=context)
+        return res + ['responsible_id']
index efba082..473dffe 100644 (file)
@@ -35,6 +35,10 @@ import xmlrpclib
 _logger = logging.getLogger(__name__)
 
 class many2many_reference(fields.many2many):
+    """ many2many_reference is an override of fields.many2many. It manages
+        many2many-like table where one id is given by two fields, res_model
+        and res_id.
+    """
     
     def _get_query_and_where_params(self, cr, model, ids, values, where_params):
         """ Add in where:
@@ -54,6 +58,7 @@ class many2many_reference(fields.many2many):
         return query, where_params
 
     def set(self, cr, model, id, name, values, user=None, context=None):
+        """ Override to add the res_model field in queries. """
         if not values: return
         rel, id1, id2 = self._sql_names(model)
         obj = model.pool.get(self._obj)
@@ -64,7 +69,7 @@ class many2many_reference(fields.many2many):
                 idnew = obj.create(cr, user, act[2], context=context)
                 cr.execute('INSERT INTO '+rel+' ('+id1+','+id2+',res_model) VALUES (%s,%s,%s)', (id, idnew, model._name))
             elif act[0] == 3:
-                cr.execute('DELETE FROM "'+rel+'" WHERE '+id1+'=%s AND '+id2+'=%s AND res_model=%s', (id, act[1], model._name))
+                cr.execute('DELETE FROM '+rel+' WHERE '+id1+'=%s AND '+id2+'=%s AND res_model=%s', (id, act[1], model._name))
             elif act[0] == 4:
                 # following queries are in the same transaction - so should be relatively safe
                 cr.execute('SELECT 1 FROM '+rel+' WHERE '+id1+'=%s AND '+id2+'=%s AND res_model=%s', (id, act[1], model._name))
@@ -80,7 +85,6 @@ class many2many_reference(fields.many2many):
                 for act_nbr in act[2]:
                     cr.execute('INSERT INTO '+rel+' ('+id1+','+id2+',res_model) VALUES (%s,%s,%s)', (id, act_nbr, model._name))
             else:
-                print act
                 return super(many2many_reference, self).set(cr, model, id, name, values, user, context)
 
 class mail_thread(osv.Model):
@@ -160,18 +164,36 @@ class mail_thread(osv.Model):
     #------------------------------------------------------
 
     def create(self, cr, uid, vals, context=None):
-        """ Automatically subscribe the creator """
+        """ Override of create to subscribe :
+            - the writer
+            - followers given by the monitored fields
+        """
         thread_id = super(mail_thread, self).create(cr, uid, vals, context=context)
+        fields = self.message_get_follower_fields(cr, uid, [thread_id], context=context)
+        print fields
         if thread_id:
             self.message_subscribe(cr, uid, [thread_id], [uid], context=context)
         return thread_id
 
     def write(self, cr, uid, ids, vals, context=None):
-        """ Override of write to subscribe the writer, except if he has changed
-            the followers (to avoid unfollow-->follow). """
+        """ Override of write to subscribe :
+            - the writer
+            - followers given by the monitored fields
+        """
         if isinstance(ids, (int, long)):
             ids = [ids]
+        command = self.message_get_automatic_followers(cr, uid, ids, vals, context=context)
+        print command
+        if vals.get('message_follower_ids'):
+            vals['message_follower_ids'] += command
+        else:
+            vals['message_follower_ids'] = command
+        print vals
         write_res = super(mail_thread, self).write(cr, uid, ids, vals, context=context)
+        
+        
+        
+
         if write_res and not vals.get('message_follower_ids'):
             self.message_subscribe(cr, uid, ids, [uid], context=context)
         return write_res;
@@ -188,6 +210,39 @@ class mail_thread(osv.Model):
         msg_obj.unlink(cr, uid, msg_to_del_ids, context=context)
         return super(mail_thread, self).unlink(cr, uid, ids, context=context)
 
+    def message_get_automatic_followers(self, cr, uid, ids, record_vals, add_uid=True, fetch_missing=False, context=None):
+        """
+
+            :param record_vals: values given to the create method of the new
+                record, or values updated in a write.
+            :param monitored_fields: a list of fields that are monitored. Those
+                fields must be many2one fields to the res.users model.
+            :param fetch_missing: is set to True, the method will read the
+                record to find values that are not present in record_vals.
+
+            #TODO : UPDATE WHEN MERGING TO PARTNERS
+        """
+        # get monitored fields
+        monitored_fields = self.message_get_monitored_follower_fields(cr, uid, ids, context=context)
+        print monitored_fields
+        # for each monitored field: if in record_vals, it has been modified
+        fields = [field for field in monitored_fields if field in record_vals.iterkeys()]
+        print fields
+
+        follower_ids = []
+        for field in fields:
+            value = record_vals.get(field)
+            if value:
+                follower_ids.append(value)
+            elif fetch_missing:
+                pass
+
+        print follower_ids
+        if add_uid and uid not in follower_ids:
+            follower_ids.append(uid)
+
+        return self.message_subscribe_get_command(cr, uid, follower_ids, context=context)
+
     #------------------------------------------------------
     # mail.message wrappers and tools
     #------------------------------------------------------
@@ -931,6 +986,12 @@ class mail_thread(osv.Model):
     # Subscription mechanism
     #------------------------------------------------------
 
+    def message_get_monitored_follower_fields(self, cr, uid, ids, context=None):
+        """ Returns a list of fields containing a res.user.id. Those fields
+            will be checked to automatically subscribe those users.
+        """
+        return []
+
     def message_get_subscribers(self, cr, uid, ids, context=None):
         """ Returns the current document followers. Basically this method
             checks in mail.followers for entries with matching res_model,
@@ -953,6 +1014,10 @@ class mail_thread(osv.Model):
         write_res = self.write(cr, uid, ids, {'message_follower_ids': [(4, id) for id in to_subscribe_uids]}, context=context)
         return [follower.id for thread in self.browse(cr, uid, ids, context=context) for follower in thread.message_follower_ids]
 
+    def message_subscribe_get_command(self, cr, uid, follower_ids, context=None):
+        """ Generate the many2many command to add followers. """
+        return [(4, id) for id in follower_ids]
+
     def message_unsubscribe(self, cr, uid, ids, user_ids = None, context=None):
         """ Unsubscribe the user (or user_ids) from the current document.
             
@@ -963,6 +1028,10 @@ class mail_thread(osv.Model):
         write_res = self.write(cr, uid, ids, {'message_follower_ids': [(3, id) for id in to_unsubscribe_uids]}, context=context)
         return [follower.id for thread in self.browse(cr, uid, ids, context=context) for follower in thread.message_follower_ids]
 
+    def message_unsubscribe_get_command(self, cr, uid, follower_ids, context=None):
+        """ Generate the many2many command to remove followers. """
+        return [(3, id) for id in follower_ids]
+
     #------------------------------------------------------
     # Notification API
     #------------------------------------------------------
index 749d95c..a41e4db 100644 (file)
@@ -1046,13 +1046,10 @@ class mrp_production(osv.osv):
     # OpenChatter methods and notifications
     # ---------------------------------------------------
 
-    def message_get_subscribers(self, cr, uid, ids, context=None):
-        """ Override to add responsible user. """
-        user_ids = super(mrp_production, self).message_get_subscribers(cr, uid, ids, context=context)
-        for obj in self.browse(cr, uid, ids, context=context):
-            if obj.user_id and not obj.user_id.id in user_ids:
-                user_ids.append(obj.user_id.id)
-        return user_ids
+    def message_get_follower_fields(self, cr, uid, ids, context=None):
+        """ Override to add 'user_id' field to automatic subscription. """
+        res = super(mrp_production, self).message_get_follower_fields(cr, uid, ids, context=context)
+        return res.append('user_id')
 
     def create_send_note(self, cr, uid, ids, context=None):
         self.message_append_note(cr, uid, ids, body=_("Manufacturing order has been <b>created</b>."), context=context)
index 6f3b23f..b1db7fd 100644 (file)
@@ -513,13 +513,10 @@ def Project():
     # OpenChatter methods and notifications
     # ------------------------------------------------
 
-    def message_get_subscribers(self, cr, uid, ids, context=None):
-        """ Override to add responsible user. """
-        user_ids = super(project, self).message_get_subscribers(cr, uid, ids, context=context)
-        for obj in self.browse(cr, uid, ids, context=context):
-            if obj.user_id and not obj.user_id.id in user_ids:
-                user_ids.append(obj.user_id.id)
-        return user_ids
+    def message_get_follower_fields(self, cr, uid, ids, context=None):
+        """ Override to add 'user_id' field to automatic subscription. """
+        res = super(project, self).message_get_follower_fields(cr, uid, ids, context=context)
+        return res.append('user_id')
 
     def create(self, cr, uid, vals, context=None):
         if context is None: context = {}
@@ -1201,15 +1198,10 @@ class task(base_stage, osv.osv):
                 result[obj.id].append(obj.user_id.id)
         return result
 
-    def message_get_subscribers(self, cr, uid, ids, context=None):
-        """ Override to add responsible user and project manager. """
-        user_ids = super(task, self).message_get_subscribers(cr, uid, ids, context=context)
-        for obj in self.browse(cr, uid, ids, context=context):
-            if obj.user_id and not obj.user_id.id in user_ids:
-                user_ids.append(obj.user_id.id)
-            if obj.manager_id and not obj.manager_id.id in user_ids:
-                user_ids.append(obj.manager_id.id)
-        return user_ids
+    def message_get_follower_fields(self, cr, uid, ids, context=None):
+        """ Override to add 'user_id' field to automatic subscription. """
+        res = super(task, self).message_get_follower_fields(cr, uid, ids, context=context)
+        return res + ['user_id', 'manager_id']
 
     def stage_set_send_note(self, cr, uid, ids, stage_id, context=None):
         """ Override of the (void) default notification method. """
index 7b2afbe..5aa34c1 100644 (file)
@@ -502,13 +502,10 @@ class project_issue(base_stage, osv.osv):
     # OpenChatter methods and notifications
     # -------------------------------------------------------
 
-    def message_get_subscribers(self, cr, uid, ids, context=None):
-        """ Override to add responsible user. """
-        user_ids = super(project_issue, self).message_get_subscribers(cr, uid, ids, context=context)
-        for obj in self.browse(cr, uid, ids, context=context):
-            if obj.user_id and not obj.user_id.id in user_ids:
-                user_ids.append(obj.user_id.id)
-        return user_ids
+    def message_get_follower_fields(self, cr, uid, ids, context=None):
+        """ Override to add 'user_id' field to automatic subscription. """
+        res = super(project_issue, self).message_get_follower_fields(cr, uid, ids, context=context)
+        return res.append('user_id')
 
     def stage_set_send_note(self, cr, uid, ids, stage_id, context=None):
         """ Override of the (void) default notification method. """