Thibault Delavallée (OpenERP) has proposed merging 
lp:~openerp-dev/openobject-addons/trunk-mail-state-tde into 
lp:openobject-addons.

Requested reviews:
  OpenERP Core Team (openerp)

For more details, see:
https://code.launchpad.net/~openerp-dev/openobject-addons/trunk-mail-state-tde/+merge/108573
-- 
https://code.launchpad.net/~openerp-dev/openobject-addons/trunk-mail-state-tde/+merge/108573
Your team OpenERP R&D Team is subscribed to branch 
lp:~openerp-dev/openobject-addons/trunk-mail-state-tde.
=== modified file 'crm/crm_lead.py'
--- crm/crm_lead.py	2012-06-04 08:26:46 +0000
+++ crm/crm_lead.py	2012-06-04 14:16:32 +0000
@@ -262,11 +262,10 @@
     def get_needaction_user_ids(self, cr, uid, ids, context=None):
         result = dict.fromkeys(ids, [])
         for obj in self.browse(cr, uid, ids, context=context):
-            # salesman must perform an action when in draft mode
-            if obj.state == 'draft' and obj.user_id:
+            if obj.thread_is_read == False and hasattr(obj, 'user_id') and obj.user_id:
                 result[obj.id] = [obj.user_id.id]
         return result
-    
+
     def create(self, cr, uid, vals, context=None):
         obj_id = super(crm_lead, self).create(cr, uid, vals, context)
         self.create_send_note(cr, uid, [obj_id], context=context)
@@ -756,64 +755,6 @@
                 'type': 'ir.actions.act_window',
         }
 
-
-    def message_new(self, cr, uid, msg, custom_values=None, context=None):
-        """Automatically calls when new email message arrives"""
-        res_id = super(crm_lead, self).message_new(cr, uid, msg, custom_values=custom_values, context=context)
-        subject = msg.get('subject')  or _("No Subject")
-        body = msg.get('body_text')
-
-        msg_from = msg.get('from')
-        priority = msg.get('priority')
-        vals = {
-            'name': subject,
-            'email_from': msg_from,
-            'email_cc': msg.get('cc'),
-            'description': body,
-            'user_id': False,
-        }
-        if priority:
-            vals['priority'] = priority
-        vals.update(self.message_partner_by_email(cr, uid, msg.get('from', False)))
-        self.write(cr, uid, [res_id], vals, context)
-        return res_id
-
-    def message_update(self, cr, uid, ids, msg, vals=None, default_act='pending', context=None):
-        if isinstance(ids, (str, int, long)):
-            ids = [ids]
-        if vals == None:
-            vals = {}
-        super(crm_lead, self).message_update(cr, uid, ids, msg, context=context)
-
-        if msg.get('priority') in dict(crm.AVAILABLE_PRIORITIES):
-            vals['priority'] = msg.get('priority')
-        maps = {
-            'cost':'planned_cost',
-            'revenue': 'planned_revenue',
-            'probability':'probability'
-        }
-        vls = {}
-        for line in msg['body_text'].split('\n'):
-            line = line.strip()
-            res = tools.misc.command_re.match(line)
-            if res and maps.get(res.group(1).lower()):
-                key = maps.get(res.group(1).lower())
-                vls[key] = res.group(2).lower()
-        vals.update(vls)
-
-        # Unfortunately the API is based on lists
-        # but we want to update the state based on the
-        # previous state, so we have to loop:
-        for case in self.browse(cr, uid, ids, context=context):
-            values = dict(vals)
-            if case.state in CRM_LEAD_PENDING_STATES:
-                #re-open
-                values.update(state=crm.AVAILABLE_STATES[1][0])
-                if not case.date_open:
-                    values['date_open'] = time.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)
-            res = self.write(cr, uid, [case.id], values, context=context)
-        return res
-
     def action_makeMeeting(self, cr, uid, ids, context=None):
         """
         This opens Meeting's calendar view to schedule meeting on current Opportunity
@@ -868,7 +809,54 @@
             if stage.on_change:
                 vals['probability'] = stage.probability
         return super(crm_lead,self).write(cr, uid, ids, vals, context)
-    
+
+    # ----------------------------------------
+    # Mail Gateway
+    # ----------------------------------------
+
+    def message_new(self, cr, uid, msg, custom_values=None, context=None):
+        """ Overrides mail_thread message_new that is called by the mailgateway
+            through message_process.
+            This override updates the document according to the email.
+        """
+        if custom_values is None: custom_values = {}
+        custom_values.update({
+            'name':  msg.get('subject') or _("No Subject"),
+            'description': msg.get('body_text'),
+            'email_from': msg.get('from'),
+            'email_cc': msg.get('cc'),
+            'user_id': False,
+        })
+        if msg.get('priority') in dict(crm.AVAILABLE_PRIORITIES):
+            custom_values['priority'] = msg.get('priority')
+        custom_values.update(self.message_partner_by_email(cr, uid, msg.get('from', False), context=context))
+        return super(crm_lead, self).message_new(cr, uid, msg, custom_values=custom_values, context=context)
+
+    def message_update(self, cr, uid, ids, msg, update_vals=None, context=None):
+        """ Overrides mail_thread message_update that is called by the mailgateway
+            through message_process.
+            This method updates the document according to the email.
+        """
+        if isinstance(ids, (str, int, long)):
+            ids = [ids]
+        if update_vals is None: update_vals = {}
+
+        if msg.get('priority') in dict(crm.AVAILABLE_PRIORITIES):
+            vals['priority'] = msg.get('priority')
+        maps = {
+            'cost':'planned_cost',
+            'revenue': 'planned_revenue',
+            'probability':'probability',
+        }
+        for line in msg.get('body_text', '').split('\n'):
+            line = line.strip()
+            res = tools.misc.command_re.match(line)
+            if res and maps.get(res.group(1).lower()):
+                key = maps.get(res.group(1).lower())
+                vals[key] = res.group(2).lower()
+
+        return super(crm_lead, self).message_update(cr, uid, ids, msg, update_vals=update_vals, context=context)
+
     # ----------------------------------------
     # OpenChatter methods and notifications
     # ----------------------------------------

=== modified file 'crm/crm_lead_view.xml'
--- crm/crm_lead_view.xml	2012-06-04 12:20:53 +0000
+++ crm/crm_lead_view.xml	2012-06-04 14:16:32 +0000
@@ -70,12 +70,27 @@
                             states="cancel"/>
                     <button name="case_cancel" string="Cancel" type="object"
                             states="draft,open,pending"/>
+<<<<<<< TREE
                     <field name="stage_id" widget="statusbar"
+=======
+                    <button name="message_mark_as_unread" string="Mark Unread" type="object"
+                            attrs="{'invisible':[('thread_is_read', '==', False)]}"/>
+                    <button name="message_mark_as_read" string="Mark Read" type="object"
+                            attrs="{'invisible':[('thread_is_read', '==', True)]}"/>
+                    <div class="oe_right">
+                        <field name="stage_id" nolabel="1" widget="statusbar"
+>>>>>>> MERGE-SOURCE
                             on_change="onchange_stage_id(stage_id)"/>
                 </header>
                 <sheet layout="auto">
                 <group colspan="4" col="7">
+<<<<<<< TREE
                     <field name="name"/>
+=======
+                    <field name="thread_is_read"/>
+                    <newline/>
+                    <field name="name" required="1" string="Subject"/>
+>>>>>>> MERGE-SOURCE
                     <field name="priority"/>
                     <field name="categ_id"
                         widget="selection"

=== modified file 'crm_claim/crm_claim.py'
--- crm_claim/crm_claim.py	2012-06-01 14:40:59 +0000
+++ crm_claim/crm_claim.py	2012-06-04 14:16:32 +0000
@@ -183,59 +183,53 @@
                    }
         address = self.pool.get('res.partner').browse(cr, uid, part)
         return {'value': {'email_from': address.email, 'partner_phone': address.phone}}
-    
+
+    # -------------------------------------------------------
+    # Mail gateway
+    # -------------------------------------------------------
+
     def message_new(self, cr, uid, msg, custom_values=None, context=None):
-        """Automatically called when new email message arrives"""
-        res_id = super(crm_claim,self).message_new(cr, uid, msg, custom_values=custom_values, context=context)
-        subject = msg.get('subject')
-        body = msg.get('body_text')
-        msg_from = msg.get('from')
-        priority = msg.get('priority')
-        vals = {
-            'name': subject,
-            'email_from': msg_from,
+        """ Overrides mail_thread message_new that is called by the mailgateway
+            through message_process.
+            This override updates the document according to the email.
+        """
+        if custom_values is None: custom_values = {}
+        custom_values.update({
+            'name': msg.get('subject') or _("No Subject"),
+            'description': msg.get('body_text'),
+            'email_from': msg.get('from'),
             'email_cc': msg.get('cc'),
-            'description': body,
-            'user_id': False,
-        }
-        if priority:
-            vals['priority'] = priority
-        vals.update(self.message_partner_by_email(cr, uid, msg.get('from', False)))
-        self.write(cr, uid, [res_id], vals, context=context)
-        return res_id
+        })
+        if msg.get('priority'):
+            custom_values['priority'] = msg.get('priority')
+        custom_values.update(self.message_partner_by_email(cr, uid, msg.get('from'), context=context))
+        return super(crm_claim,self).message_new(cr, uid, msg, custom_values=custom_values, context=context)
 
-    def message_update(self, cr, uid, ids, msg, vals={}, default_act='pending', context=None):
+    def message_update(self, cr, uid, ids, msg, update_vals=None, context=None):
+        """ Overrides mail_thread message_update that is called by the mailgateway
+            through message_process.
+            This method updates the document according to the email.
+        """
         if isinstance(ids, (str, int, long)):
             ids = [ids]
-
-        res_id = super(crm_claim,self).message_update(cr, uid, ids, msg, context=context)
+        if update_vals is None: update_vals = {}
 
         if msg.get('priority') in dict(crm.AVAILABLE_PRIORITIES):
-            vals['priority'] = msg.get('priority')
+            update_vals['priority'] = msg.get('priority')
 
         maps = {
             'cost':'planned_cost',
             'revenue': 'planned_revenue',
             'probability':'probability'
         }
-        vls = {}
         for line in msg['body_text'].split('\n'):
             line = line.strip()
             res = tools.misc.command_re.match(line)
             if res and maps.get(res.group(1).lower()):
                 key = maps.get(res.group(1).lower())
-                vls[key] = res.group(2).lower()
-        vals.update(vls)
+                update_vals[key] = res.group(2).lower()
 
-        # Unfortunately the API is based on lists
-        # but we want to update the state based on the
-        # previous state, so we have to loop:
-        for case in self.browse(cr, uid, ids, context=context):
-            values = dict(vals)
-            if case.state in CRM_CLAIM_PENDING_STATES:
-                values.update(state=crm.AVAILABLE_STATES[1][0]) #re-open
-            res = self.write(cr, uid, [case.id], values, context=context)
-        return res
+        return  super(crm_claim,self).message_update(cr, uid, ids, msg, update_vals=update_vals, context=context)
 
     # ---------------------------------------------------
     # OpenChatter methods and notifications

=== modified file 'crm_fundraising/crm_fundraising.py'
--- crm_fundraising/crm_fundraising.py	2012-06-01 14:40:59 +0000
+++ crm_fundraising/crm_fundraising.py	2012-06-04 14:16:32 +0000
@@ -127,21 +127,26 @@
         self.create_send_note(cr, uid, [obj_id], context=context)
         return obj_id
 
+    # -------------------------------------------------------
+    # Mail gateway
+    # -------------------------------------------------------
+
     def message_new(self, cr, uid, msg, custom_values=None, context=None):
-        """Automatically called when new email message arrives"""
-        res_id = super(crm_fundraising,self).message_new(cr, uid, msg, custom_values=custom_values, context=context)
-        vals = {
-            'name': msg.get('subject'),
+        """ Overrides mail_thread message_new that is called by the mailgateway
+            through message_process.
+            This override also updates the document according to the email.
+        """
+        if custom_values is None: custom_values = {}
+        custom_values.update({
+            'name': msg.get('subject') or _("No Subject"),
+            'description': msg.get('body_text'),
             'email_from': msg.get('from'),
             'email_cc': msg.get('cc'),
-            'description': msg.get('body_text'),
-        }
-        priority = msg.get('priority')
-        if priority:
-            vals['priority'] = priority
-        vals.update(self.message_partner_by_email(cr, uid, msg.get('from')))
-        self.write(cr, uid, [res_id], vals, context=context)
-        return res_id
+        })
+        if msg.get('priority'):
+            custom_values['priority'] = priority
+        custom_values.update(self.message_partner_by_email(cr, uid, msg.get('from'), context=context))
+        return super(crm_fundraising,self).message_new(cr, uid, msg, custom_values=custom_values, context=context)
 
     # ---------------------------------------------------
     # OpenChatter methods and notifications

=== modified file 'crm_helpdesk/crm_helpdesk.py'
--- crm_helpdesk/crm_helpdesk.py	2012-06-01 14:40:59 +0000
+++ crm_helpdesk/crm_helpdesk.py	2012-06-04 14:16:32 +0000
@@ -95,55 +95,52 @@
         self.create_send_note(cr, uid, [obj_id], context=context)
         return obj_id
 
-    def message_new(self, cr, uid, msg_dict, custom_values=None, context=None):
-        """Automatically called when new email message arrives"""
-        res_id = super(crm_helpdesk,self).message_new(cr, uid, msg_dict, custom_values=custom_values, context=context)
-        subject = msg_dict.get('subject')  or _("No Subject")
-        body = msg_dict.get('body_text')
-        msg_from = msg_dict.get('from')
-        vals = {
-            'name': subject,
-            'email_from': msg_from,
-            'email_cc': msg_dict.get('cc'),
-            'description': body,
+    # -------------------------------------------------------
+    # Mail gateway
+    # -------------------------------------------------------
+
+    def message_new(self, cr, uid, msg, custom_values=None, context=None):
+        """ Overrides mail_thread message_new that is called by the mailgateway
+            through message_process.
+            This override updates the document according to the email.
+        """
+        if custom_values is None: custom_values = {}
+        custom_values.update({
+            'name': msg.get('subject') or _("No Subject"),
+            'description': msg.get('body_text'),
+            'email_from': msg.get('from'),
+            'email_cc': msg.get('cc'),
             'user_id': False,
-        }
-        vals.update(self.message_partner_by_email(cr, uid, msg_from))
+        })
+        custom_values.update(self.message_partner_by_email(cr, uid, msg.get('from'), context=context))
         self.write(cr, uid, [res_id], vals, context)
-        return res_id
+        return super(crm_helpdesk,self).message_new(cr, uid, msg_dict, custom_values=custom_values, context=context)
 
-    def message_update(self, cr, uid, ids, msg, vals={}, default_act='pending', context=None):
+    def message_update(self, cr, uid, ids, msg, update_vals=None, context=None):
+        """ Overrides mail_thread message_update that is called by the mailgateway
+            through message_process.
+            This method updates the document according to the email.
+        """
         if isinstance(ids, (str, int, long)):
             ids = [ids]
-
-        super(crm_helpdesk,self).message_update(cr, uid, ids, msg, context=context)
+        if update_vals is None: update_vals = {}
 
         if msg.get('priority') in dict(crm.AVAILABLE_PRIORITIES):
-            vals['priority'] = msg.get('priority')
+            update_vals['priority'] = msg.get('priority')
 
         maps = {
             'cost':'planned_cost',
             'revenue': 'planned_revenue',
             'probability':'probability'
         }
-        vls = {}
         for line in msg['body_text'].split('\n'):
             line = line.strip()
             res = tools.misc.command_re.match(line)
             if res and maps.get(res.group(1).lower()):
                 key = maps.get(res.group(1).lower())
-                vls[key] = res.group(2).lower()
-        vals.update(vls)
+                update_vals[key] = res.group(2).lower()
 
-        # Unfortunately the API is based on lists
-        # but we want to update the state based on the
-        # previous state, so we have to loop:
-        for case in self.browse(cr, uid, ids, context=context):
-            values = dict(vals)
-            if case.state in CRM_HELPDESK_STATES:
-                values.update(state=crm.AVAILABLE_STATES[1][0]) #re-open
-            res = self.write(cr, uid, [case.id], values, context=context)
-        return res
+        return super(crm_helpdesk,self).message_update(cr, uid, ids, msg, update_vals=update_vals, context=context)
 
     # ******************************
     # OpenChatter

=== modified file 'hr_recruitment/hr_recruitment.py'
--- hr_recruitment/hr_recruitment.py	2012-06-01 11:36:25 +0000
+++ hr_recruitment/hr_recruitment.py	2012-06-04 14:16:32 +0000
@@ -362,54 +362,53 @@
         return value
 
     def message_new(self, cr, uid, msg, custom_values=None, context=None):
-        """Automatically called when new email message arrives"""
-        res_id = super(hr_applicant,self).message_new(cr, uid, msg, custom_values=custom_values, context=context)
-        subject = msg.get('subject') or _("No Subject")
-        body = msg.get('body_text')
-        msg_from = msg.get('from')
-        priority = msg.get('priority')
-        vals = {
-            'name': subject,
-            'email_from': msg_from,
+        """ Overrides mail_thread message_new that is called by the mailgateway
+            through message_process.
+            This override updates the document according to the email.
+        """
+        if custom_values is None: custom_values = {}
+        custom_values.update({
+            'name':  msg.get('subject') or _("No Subject"),
+            'description': msg.get('body_text'),
+            'email_from': msg.get('from'),
             'email_cc': msg.get('cc'),
-            'description': body,
             'user_id': False,
-        }
-        if priority:
-            vals['priority'] = priority
-        vals.update(self.message_partner_by_email(cr, uid, msg.get('from', False)))
-        self.write(cr, uid, [res_id], vals, context)
-        return res_id
+        })
+        if msg.get('priority'):
+            custom_values['priority'] = msg.get('priority')
+        custom_values.update(self.message_partner_by_email(cr, uid, msg.get('from', False), context=context))
+        return super(hr_applicant,self).message_new(cr, uid, msg, custom_values=custom_values, context=context)
 
-    def message_update(self, cr, uid, ids, msg, vals=None, default_act='pending', context=None):
+    def message_update(self, cr, uid, ids, msg, update_vals=None, context=None):
+        """ Override mail_thread message_update that is called by the mailgateway
+            through message_process.
+            This method updates the document according to the email.
+        """
         if isinstance(ids, (str, int, long)):
             ids = [ids]
-        if vals is None:
-            vals = {}
-        msg_from = msg['from']
-        vals.update({
-            'description': msg['body_text']
+        if update_vals is None: vals = {}
+        
+        update_vals.update({
+            'description': msg.get('body'),
+            'email_from': msg.get('from'),
+            'email_cc': msg.get('cc'),
         })
-        if msg.get('priority', False):
-            vals['priority'] = msg.get('priority')
+        if msg.get('priority'):
+            update_vals['priority'] = msg.get('priority')
 
         maps = {
-            'cost':'planned_cost',
+            'cost': 'planned_cost',
             'revenue': 'planned_revenue',
-            'probability':'probability'
+            'probability': 'probability',
         }
-        vls = { }
-        for line in msg['body_text'].split('\n'):
+        for line in msg.get('body_text', '').split('\n'):
             line = line.strip()
             res = tools.misc.command_re.match(line)
             if res and maps.get(res.group(1).lower(), False):
                 key = maps.get(res.group(1).lower())
-                vls[key] = res.group(2).lower()
+                update_vals[key] = res.group(2).lower()
 
-        vals.update(vls)
-        res = self.write(cr, uid, ids, vals, context=context)
-        self.message_append_dict(cr, uid, ids, msg, context=context)
-        return res
+        return super(hr_applicant, self).message_update(cr, uids, ids, update_vals=update_vals, context=context)
 
     def create(self, cr, uid, vals, context=None):
         obj_id = super(hr_applicant, self).create(cr, uid, vals, context=context)

=== modified file 'mail/mail_thread.py'
--- mail/mail_thread.py	2012-06-01 13:26:44 +0000
+++ mail/mail_thread.py	2012-06-04 14:16:32 +0000
@@ -71,7 +71,10 @@
     # OpenChatter: message_ids is a dummy field that should not be used
     _columns = {
         'message_ids': fields.function(_get_message_ids, method=True,
-                        type='one2many', obj='mail.message', string='Temp messages', _fields_id = 'res_id'),
+                        type='one2many', obj='mail.message', string='Temp messages', _fields_id = 'res_id',
+                        help="Functional field holding messages related to the current document."),
+        'thread_is_read': fields.boolean('Read',
+                        help="When checked, new messages require your attention."),
     }
 
     #------------------------------------------------------
@@ -79,10 +82,11 @@
     #------------------------------------------------------
 
     def create(self, cr, uid, vals, context=None):
-        """Automatically subscribe the creator"""
-        thread_id = super(mail_thread, self).create(cr, uid, vals, context=context);
-        self.message_subscribe(cr, uid, [thread_id], [uid], context=context)
-        return thread_id;
+        """Automatically subscribe the creator """
+        thread_id = super(mail_thread, self).create(cr, uid, vals, context=context)
+        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):
         """Automatically subscribe the writer"""
@@ -101,8 +105,6 @@
            a foreign key with a 'cascade' ondelete attribute.
            Notifications will be deleted with messages
         """
-        if context is None:
-            context = {}
         subscr_obj = self.pool.get('mail.subscription')
         msg_obj = self.pool.get('mail.message')
         # delete subscriptions
@@ -119,13 +121,14 @@
     #------------------------------------------------------
 
     def message_create(self, cr, uid, thread_id, vals, context=None):
-        """OpenSocial: wrapper of mail.message create method
+        """ OpenChatter: wrapper of mail.message create method
            - creates the mail.message
            - automatically subscribe the message writer
            - push the message to subscribed users
         """
         if context is None:
             context = {}
+        
         message_obj = self.pool.get('mail.message')
         subscription_obj = self.pool.get('mail.subscription')
         notification_obj = self.pool.get('mail.notification')
@@ -532,6 +535,8 @@
             res_id = create_record(msg)
         #To forward the email to other followers
         self.message_forward(cr, uid, model, [res_id], msg_txt, context=context)
+        # Set as Unread
+        self.message_mark_as_unread(cr, uid, [res_id], context=context)
         return res_id
 
     def message_new(self, cr, uid, msg_dict, custom_values=None, context=None):
@@ -566,29 +571,34 @@
         fields = model_pool.fields_get(cr, uid, context=context)
         data = model_pool.default_get(cr, uid, fields, context=context)
         if 'name' in fields and not data.get('name'):
-            data['name'] = msg_dict.get('from','')
+            data['name'] = msg_dict.get('from', '')
         if custom_values and isinstance(custom_values, dict):
             data.update(custom_values)
         res_id = model_pool.create(cr, uid, data, context=context)
         self.message_append_dict(cr, uid, [res_id], msg_dict, context=context)
         return res_id
 
-    def message_update(self, cr, uid, ids, msg_dict, vals={}, default_act=None, context=None):
-        """Called by ``message_process`` when a new message is received
-           for an existing thread. The default behavior is to create a
-           new mail.message in the given thread (by calling
-           ``message_append_dict``)
-           Additional behavior may be implemented by overriding this
-           method.
+    def message_update(self, cr, uid, ids, msg_dict, update_vals=None, context=None):
+        """ Called by ``message_process`` when a new message is received
+            for an existing thread. The default behavior is to create a
+            new mail.message in the given thread (by calling
+            ``message_append_dict``)
+            Additional behavior may be implemented by overriding this
+            method.
 
-           :param dict msg_dict: a map containing the email details and
+            :param dict msg_dict: a map containing the email details and
                                 attachments. See ``message_process`` and
                                 ``mail.message.parse()`` for details.
-           :param dict context: if a ``thread_model`` value is present
+            :param dict vals: a dict containing values to update records
+                              given their ids; if the dict is None or is
+                              void, no write operation is performed.
+            :param dict context: if a ``thread_model`` value is present
                                 in the context, its value will be used
                                 to determine the model of the thread to
                                 update (instead of the current model).
         """
+        if update_vals:
+            self.write(cr, uid, ids, update_vals, context=context)
         return self.message_append_dict(cr, uid, ids, msg_dict, context=context)
 
     def message_thread_followers(self, cr, uid, ids, context=None):
@@ -791,4 +801,23 @@
         to_del_notif_ids = notif_obj.search(cr, uid, ['&', ('user_id', '=', uid), ('message_id', 'in', notif_msg_ids)], context=context)
         return notif_obj.unlink(cr, uid, to_del_notif_ids, context=context)
 
+    #------------------------------------------------------
+    # Thread_state
+    #------------------------------------------------------
+    
+    def message_mark_as_read(self, cr, uid, ids, context=None):
+        return self.write(cr, uid, ids, {'thread_is_read': True}, context=context)
+    
+    def message_mark_as_unread(self, cr, uid, ids, context=None):
+        return self.write(cr, uid, ids, {'thread_is_read': False}, context=context)
+
+    def get_needaction_user_ids(self, cr, uid, ids, context=None):
+        result = dict.fromkeys(ids, [])
+        for obj in self.browse(cr, uid, ids, context=context):
+            if obj.thread_is_read == False and hasattr(obj, 'user_id') and obj.user_id:
+                result[obj.id] = [obj.user_id.id]
+        print 'needaction: %s' % (str(result))
+        return result
+
+
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

=== modified file 'project_issue/project_issue.py'
--- project_issue/project_issue.py	2012-06-01 11:36:25 +0000
+++ project_issue/project_issue.py	2012-06-04 14:16:32 +0000
@@ -467,69 +467,56 @@
     # -------------------------------------------------------
     
     def message_new(self, cr, uid, msg, custom_values=None, context=None):
-        """Automatically called when new email message arrives"""
-        if context is None:
-            context = {}
-        subject = msg.get('subject') or _('No Title')
-        body = msg.get('body_text')
-        msg_from = msg.get('from')
-        priority = msg.get('priority')
-        vals = {
-            'name': subject,
-            'email_from': msg_from,
+        """ Overrides mail_thread message_new that is called by the mailgateway
+            through message_process.
+            This override updates the document according to the email.
+        """
+        if custom_values is None: custom_values = {}
+        if context is None: context = {}
+        context['state_to'] = 'draft'
+
+        custom_values.update({
+            'name':  msg.get('subject') or _("No Subject"),
+            'description': msg.get('body_text'),
+            'email_from': msg.get('from'),
             'email_cc': msg.get('cc'),
-            'description': body,
             'user_id': False,
-        }
-        if priority:
-            vals['priority'] = priority
-        vals.update(self.message_partner_by_email(cr, uid, msg_from))
-        context.update({'state_to' : 'draft'})
-
-        if custom_values and isinstance(custom_values, dict):
-            vals.update(custom_values)
-
-        res_id = self.create(cr, uid, vals, context)
-        self.message_append_dict(cr, uid, [res_id], msg, context=context)
+        })
+        if  msg.get('priority'):
+            custom_values['priority'] =  msg.get('priority')
+        custom_values.update(self.message_partner_by_email(cr, uid, msg.get('from'), context=context))
+
+        res_id = super(project_issue, self).message_new(cr, uid, msg, custom_values=custom_values, context=context)
         self.convert_to_bug(cr, uid, [res_id], context=context)
         return res_id
 
-    def message_update(self, cr, uid, ids, msg, vals=None, default_act='pending', context=None):
-        if vals is None:
-            vals = {}
-
+    def message_update(self, cr, uid, ids, msg, update_vals=None, context=None):
+        """ Overrides mail_thread message_update that is called by the mailgateway
+            through message_process.
+            This method updates the document according to the email.
+        """
         if isinstance(ids, (str, int, long)):
             ids = [ids]
-
-        vals.update({
-            'description': msg['body_text']
-        })
-        if msg.get('priority', False):
-            vals['priority'] = msg.get('priority')
-
+        if update_vals is None: update_vals = {}
+
+        # Update doc values according to the message
+        update_vals['description'] = msg.get('body_text', '')
+        if msg.get('priority'):
+            update_vals['priority'] = msg.get('priority')
+        # Parse 'body_text' to find values to update
         maps = {
             'cost': 'planned_cost',
             'revenue': 'planned_revenue',
-            'probability': 'probability'
+            'probability': 'probability',
         }
-
-        # Reassign the 'open' state to the case if this one is in pending or done
-        for record in self.browse(cr, uid, ids, context=context):
-            if record.state in ('pending', 'done'):
-                self.case_set(cr, uid, ids, 'open', {}, context=context)
-
-        vls = { }
-        for line in msg['body_text'].split('\n'):
+        for line in msg.get('body_text', '').split('\n'):
             line = line.strip()
             res = tools.misc.command_re.match(line)
             if res and maps.get(res.group(1).lower(), False):
                 key = maps.get(res.group(1).lower())
-                vls[key] = res.group(2).lower()
+                update_vals[key] = res.group(2).lower()
 
-        vals.update(vls)
-        res = self.write(cr, uid, ids, vals)
-        self.message_append_dict(cr, uid, ids, msg, context=context)
-        return res
+        return super(project_issue, self).message_update(cr, uid, ids, update_vals=update_vals, context=context)
     
     # -------------------------------------------------------
     # OpenChatter methods and notifications

=== modified file 'project_mailgate/project_mailgate.py'
--- project_mailgate/project_mailgate.py	2012-06-01 13:22:33 +0000
+++ project_mailgate/project_mailgate.py	2012-06-04 14:16:32 +0000
@@ -19,30 +19,35 @@
 #
 ##############################################################################
 
+import binascii
 from osv import fields, osv
 from tools.translate import _
 import tools
-import binascii
-
 
 class project_tasks(osv.osv):
     _inherit = 'project.task'
 
     def message_new(self, cr, uid, msg, custom_values=None, context=None):
-        res_id = super(project_tasks,self).message_new(cr, uid, msg, custom_values=custom_values, context=context)
-        subject = msg.get('subject')
-        msg_from = msg.get('from')
-        data = {
+        """ Overrides mail_thread message_new that is called by the mailgateway
+            through message_process.
+            This override updates the document according to the email.
+        """
+        if custom_values is None: custom_values = {}
+        custom_values.update({
             'name': subject,
             'planned_hours': 0.0,
-        }
-        data.update(self.message_partner_by_email(cr, uid, msg_from))
-        self.write(cr, uid, [res_id], data, context)
-        return res_id
-
-    def message_update(self, cr, uid, ids, msg, data={}, default_act='pending'):
-        act = 'do_'+default_act
-
+            'subject': msg.get('subject'),
+        })
+        custom_values.update(self.message_partner_by_email(cr, uid, msg.get('from', False), context=context))
+        return super(project_tasks,self).message_new(cr, uid, msg, custom_values=custom_values, context=context)
+
+    def message_update(self, cr, uid, ids, msg, update_vals=None, context=None):
+        """ Overrides mail_thread message_update that is called by the mailgateway
+            through message_process.
+            This method updates the task according to the email.
+        """
+        if update_vals is None: update_vals = {}
+        act = False
         maps = {
             'cost':'planned_hours',
         }
@@ -54,17 +59,15 @@
                 field = maps.get(match)
                 if field:
                     try:
-                        data[field] = float(res.group(2).lower())
+                        update_vals[field] = float(res.group(2).lower())
                     except (ValueError, TypeError):
                         pass
                 elif match.lower() == 'state' \
                         and res.group(2).lower() in ['cancel','close','draft','open','pending']:
                     act = 'do_%s' % res.group(2).lower()
-
-        self.write(cr, uid, ids, data, context=context)
-        getattr(self,act)(cr, uid, ids, context=context)
-        self.message_append_note(cr, uid, [res_id], body=msg, context=context)
-        return True
+        if act:
+            getattr(self,act)(cr, uid, ids, context=context)
+        return super(project_tasks,self).message_update(cr, uid, msg, update_vals=update_vals, context=context)
 
     def message_thread_followers(self, cr, uid, ids, context=None):
         followers = super(project_tasks,self).message_thread_followers(cr, uid, ids, context=context)
@@ -74,5 +77,5 @@
             followers[task.id] = filter(None, task_followers)
         return followers
 
-project_tasks()
+
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

_______________________________________________
Mailing list: https://launchpad.net/~openerp-dev-gtk
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~openerp-dev-gtk
More help   : https://help.launchpad.net/ListHelp

Reply via email to