From 003ac3c0535949190c7d264e87d5c101b47c63b5 Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Mon, 30 Jul 2012 12:24:35 +0530 Subject: [PATCH 01/16] [ADD] Add mail.message.subtype model in mail bzr revid: fka@tinyerp.com-20120730065435-u586t9y9gtfmx5tl --- addons/mail/__init__.py | 1 + addons/mail/__openerp__.py | 1 + 2 files changed, 2 insertions(+) diff --git a/addons/mail/__init__.py b/addons/mail/__init__.py index 805c27386f3..bac92a833ff 100644 --- a/addons/mail/__init__.py +++ b/addons/mail/__init__.py @@ -19,6 +19,7 @@ # ############################################################################## +import mail_message_subtype import mail_message import mail_thread import mail_group diff --git a/addons/mail/__openerp__.py b/addons/mail/__openerp__.py index ee22b0c153f..b8b359b8922 100644 --- a/addons/mail/__openerp__.py +++ b/addons/mail/__openerp__.py @@ -62,6 +62,7 @@ The main features of the module are: 'depends': ['base', 'base_tools'], 'data': [ 'wizard/mail_compose_message_view.xml', + 'mail_message_subtype.xml', 'mail_message_view.xml', 'mail_subscription_view.xml', 'mail_thread_view.xml', From cb473c4ffccfbf680d5bcbb6b64753315beeeac4 Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Mon, 30 Jul 2012 12:33:29 +0530 Subject: [PATCH 02/16] [ADD] mail_message_subtype files added in mail bzr revid: fka@tinyerp.com-20120730070329-0iyb0r1908a8y86r --- addons/mail/mail_message_subtype.py | 41 ++++++++++++++++++++ addons/mail/mail_message_subtype.xml | 56 ++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 addons/mail/mail_message_subtype.py create mode 100644 addons/mail/mail_message_subtype.xml diff --git a/addons/mail/mail_message_subtype.py b/addons/mail/mail_message_subtype.py new file mode 100644 index 00000000000..0a167a0f1d9 --- /dev/null +++ b/addons/mail/mail_message_subtype.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2009-today OpenERP SA () +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see +# +############################################################################## + +from osv import osv +from osv import fields + +class mail_message_subtype(osv.osv): + + _name = 'mail.message.subtype' + _description = 'mail_message_subtype' + _columns = { + 'name': fields.char(' Message Subtype ', size = 128, + required = True, select = 1, + help = 'Subtype Of Message'), + 'model_ids': fields.many2many('ir.model', + 'mail_message_subtyp_message_rel', + 'message_subtype_id', 'model_id', 'Model', + help = "link some subtypes to several models, for projet/task"), + 'default': fields.boolean('Default', help = "When subscribing to the document, users will receive by default messages related to this subtype unless they uncheck this subtype"), + } + _defaults = { + 'default': True, + } diff --git a/addons/mail/mail_message_subtype.xml b/addons/mail/mail_message_subtype.xml new file mode 100644 index 00000000000..8de3224470f --- /dev/null +++ b/addons/mail/mail_message_subtype.xml @@ -0,0 +1,56 @@ + + + + + + + + mail.message.subtype.tree + mail.message.subtype + tree + 10 + + + + + + + + + + + mail.message.subtype.form + mail.message.subtype + form + +
+ + + + + + + + + + + + +
+
+
+ + + Subtypes + mail.message.subtype + form + tree,form + + + + +
+
From b5c3a5327fcceb6d6c8843cd148e2f72d728ca08 Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Mon, 30 Jul 2012 14:38:04 +0530 Subject: [PATCH 03/16] [ADD] Add many2many subtype_id field in mail.subscription bzr revid: fka@tinyerp.com-20120730090804-x3lpju3fq11hg703 --- addons/mail/mail_subscription.py | 4 ++++ addons/mail/mail_subscription_view.xml | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/addons/mail/mail_subscription.py b/addons/mail/mail_subscription.py index fc82af879a9..a3baa024ef0 100644 --- a/addons/mail/mail_subscription.py +++ b/addons/mail/mail_subscription.py @@ -42,6 +42,10 @@ class mail_subscription(osv.osv): help='Id of the followed resource'), 'user_id': fields.many2one('res.users', string='Related User', ondelete='cascade', required=True, select=1), + 'subtype_ids': fields.many2many('mail.message.subtype', + 'mail_message_subtyp_rel', + 'subscription_id', 'subtype_id', 'Subtype', + help = "linking some subscription to several subtype for projet/task"), } class mail_notification(osv.osv): diff --git a/addons/mail/mail_subscription_view.xml b/addons/mail/mail_subscription_view.xml index c3d79d48308..b88b8c25258 100644 --- a/addons/mail/mail_subscription_view.xml +++ b/addons/mail/mail_subscription_view.xml @@ -20,6 +20,27 @@ + + mail.subscription.form + mail.subscription + form + +
+ + + + + + + + + + + + +
+
+
From c494b78f7776f64bde8d4cdefa82f7cdda867548 Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Mon, 30 Jul 2012 15:05:50 +0530 Subject: [PATCH 04/16] [ADD] Add many2one subtype_id field in mail.message bzr revid: fka@tinyerp.com-20120730093550-h9xnithn5h3eq5nk --- addons/mail/mail_message.py | 1 + addons/mail/mail_message_view.xml | 1 + 2 files changed, 2 insertions(+) diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index b96b6e3791e..14de51b39ab 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -230,6 +230,7 @@ class mail_message(osv.Model): select=True, ondelete='set null', help="Parent message, used for displaying as threads with hierarchy"), 'child_ids': fields.one2many('mail.message', 'parent_id', 'Child Messages'), + 'subtype_id': fields.many2one('mail.message.subtype', 'Subtype', select = True), } _defaults = { diff --git a/addons/mail/mail_message_view.xml b/addons/mail/mail_message_view.xml index 986bb4bef38..374b97624b1 100644 --- a/addons/mail/mail_message_view.xml +++ b/addons/mail/mail_message_view.xml @@ -152,6 +152,7 @@ + From 24264e759d42ab47f0b4b7f11a1341a3108c08b8 Mon Sep 17 00:00:00 2001 From: "Randhir Mayatra (OpenERP)" Date: Mon, 6 Aug 2012 16:10:15 +0530 Subject: [PATCH 05/16] [IMP] make changes into thread file bzr revid: rma@tinyerp.com-20120806104015-et9znlwd5lrqggfn --- addons/mail/mail_message.py | 3 ++- addons/mail/mail_thread.py | 15 ++++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index 14de51b39ab..8b88647b108 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -275,6 +275,7 @@ class mail_message(osv.Model): def create(self, cr, uid, values, context=None): self.check(cr, uid, [], mode='create', context=context, values=values) return super(mail_message, self).create(cr, uid, values, context) + def read(self, cr, uid, ids, fields_to_read=None, context=None, load='_classic_read'): self.check(cr, uid, ids, 'read', context=context) @@ -392,7 +393,7 @@ class mail_message(osv.Model): def cancel(self, cr, uid, ids, context=None): return self.write(cr, uid, ids, {'state':'cancel'}, context=context) - + def process_email_queue(self, cr, uid, ids=None, context=None): """Send immediately queued messages, committing after each message is sent - this is not transactional and should diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 1655ab98afb..0afddc747d6 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -176,7 +176,7 @@ class mail_thread(osv.Model): email_id = self.message_create_notify_by_email(cr, uid, vals, user_to_push_ids, context=context) return msg_id - + #TODO :in message creation: in push method: push only if user is subscriber (current case) and if user is sucscribed to the subtype (to add) def message_get_user_ids_to_notify(self, cr, uid, thread_ids, new_msg_vals, context=None): subscription_obj = self.pool.get('mail.subscription') # get body @@ -327,7 +327,7 @@ class mail_thread(osv.Model): if partner_ids is None: partner_ids = [] mail_partner_ids = [(6, 0, partner_ids)] - + data = { 'subject': subject, 'body_text': body_text or (hasattr(thread, 'description') and thread.description or ''), @@ -363,7 +363,6 @@ class mail_thread(osv.Model): new_msg_ids.append(self.message_create(cr, uid, thread.id, data, context=context)) return new_msg_ids - def message_append_dict(self, cr, uid, ids, msg_dict, context=None): """Creates a new mail.message attached to the given threads (``ids``), with the contents of ``msg_dict``, by calling ``message_append`` @@ -874,6 +873,10 @@ class mail_thread(osv.Model): :param user_ids: a list of user_ids; if not set, subscribe uid instead """ + # TODO:Update Massage Subscribe and add paramenter subtype_ids + # if subtype_ids is False: add default ones (res_model = self._name, default = True) + # in method: if user_id already subscriber, update its subscription with subtype_ids + subscription_obj = self.pool.get('mail.subscription') to_subscribe_uids = [uid] if user_ids is None else user_ids create_ids = [] @@ -883,7 +886,8 @@ class mail_thread(osv.Model): if user_id in already_subscribed_user_ids: continue create_ids.append(subscription_obj.create(cr, uid, {'res_model': self._name, 'res_id': id, 'user_id': user_id}, context=context)) return create_ids - + #TODO : Add method : add message_subscribe_udpate_subtypes(..., user_id, subtype_ids): + def message_unsubscribe(self, cr, uid, ids, user_ids = None, context=None): """ Unsubscribe the user (or user_ids) from the current document. @@ -900,7 +904,8 @@ class mail_thread(osv.Model): if not to_delete_sub_ids: return False return subscription_obj.unlink(cr, uid, to_delete_sub_ids, context=context) - + #TODO : Add Method : add message_subscribeption_remove_subtype(..., user_id, subtype_id): + #TODO : Add method : add message_subscription_remove_subtype_name(.., user_id, subtype_name) #------------------------------------------------------ # Notification API #------------------------------------------------------ From d00b0a9d0e9f81f89fb5a222add0b55884fa917f Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Wed, 8 Aug 2012 17:58:12 +0530 Subject: [PATCH 06/16] [IMP] improve mail_thread bzr revid: fka@tinyerp.com-20120808122812-v0hw80phlnb9es75 --- addons/mail/mail_thread.py | 315 ++++++++++++++++++++----------------- 1 file changed, 171 insertions(+), 144 deletions(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 0afddc747d6..3e5bfabe350 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -62,33 +62,33 @@ class mail_thread(osv.Model): _name = 'mail.thread' _description = 'Email Thread' - def _get_message_ids(self, cr, uid, ids, name, args, context=None): + def _get_message_ids(self, cr, uid, ids, name, args, context = None): res = {} for id in ids: - message_ids = self.message_search(cr, uid, [id], context=context) - subscriber_ids = self.message_get_subscribers(cr, uid, [id], context=context) + message_ids = self.message_search(cr, uid, [id], context = context) + subscriber_ids = self.message_get_subscribers(cr, uid, [id], context = context) res[id] = { 'message_ids': message_ids, 'message_summary': "9 %d + %d" % (len(message_ids), len(subscriber_ids)), } return res - def _search_message_ids(self, cr, uid, obj, name, args, context=None): + def _search_message_ids(self, cr, uid, obj, name, args, context = None): msg_obj = self.pool.get('mail.message') - msg_ids = msg_obj.search(cr, uid, ['&', ('res_id', 'in', args[0][2]), ('model', '=', self._name)], context=context) + msg_ids = msg_obj.search(cr, uid, ['&', ('res_id', 'in', args[0][2]), ('model', '=', self._name)], context = context) return [('id', 'in', msg_ids)] _columns = { - 'message_ids': fields.function(_get_message_ids, method=True, - fnct_search=_search_message_ids, - type='one2many', obj='mail.message', _fields_id = 'res_id', - string='Temp messages', multi="_get_message_ids", - help="Functional field holding messages related to the current document."), + 'message_ids': fields.function(_get_message_ids, method = True, + fnct_search = _search_message_ids, + type = 'one2many', obj = 'mail.message', _fields_id = 'res_id', + string = 'Temp messages', multi = "_get_message_ids", + help = "Functional field holding messages related to the current document."), 'message_state': fields.boolean('Read', - help="When checked, new messages require your attention."), - 'message_summary': fields.function(_get_message_ids, method=True, - type='text', string='Summary', multi="_get_message_ids", - help="Holds the Chatter summary (number of messages, ...). "\ + help = "When checked, new messages require your attention."), + 'message_summary': fields.function(_get_message_ids, method = True, + type = 'text', string = 'Summary', multi = "_get_message_ids", + help = "Holds the Chatter summary (number of messages, ...). "\ "This summary is directly in html format in order to "\ "be inserted in kanban views."), } @@ -101,23 +101,23 @@ class mail_thread(osv.Model): # Automatic subscription when creating/reading #------------------------------------------------------ - def create(self, cr, uid, vals, context=None): + def create(self, cr, uid, vals, context = None): """Automatically subscribe the creator """ - thread_id = super(mail_thread, self).create(cr, uid, vals, context=context) + 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) + self.message_subscribe(cr, uid, [thread_id], [uid], context = context) return thread_id - def write(self, cr, uid, ids, vals, context=None): + def write(self, cr, uid, ids, vals, context = None): """Automatically subscribe the writer""" if isinstance(ids, (int, long)): ids = [ids] - write_res = super(mail_thread, self).write(cr, uid, ids, vals, context=context); + write_res = super(mail_thread, self).write(cr, uid, ids, vals, context = context); if write_res: - self.message_subscribe(cr, uid, ids, [uid], context=context) + self.message_subscribe(cr, uid, ids, [uid], context = context) return write_res; - def unlink(self, cr, uid, ids, context=None): + def unlink(self, cr, uid, ids, context = None): """Override unlink, to automatically delete - subscriptions - messages @@ -128,19 +128,19 @@ class mail_thread(osv.Model): subscr_obj = self.pool.get('mail.subscription') msg_obj = self.pool.get('mail.message') # delete subscriptions - subscr_to_del_ids = subscr_obj.search(cr, uid, [('res_model', '=', self._name), ('res_id', 'in', ids)], context=context) - subscr_obj.unlink(cr, uid, subscr_to_del_ids, context=context) + subscr_to_del_ids = subscr_obj.search(cr, uid, [('res_model', '=', self._name), ('res_id', 'in', ids)], context = context) + subscr_obj.unlink(cr, uid, subscr_to_del_ids, context = context) # delete messages and notifications - msg_to_del_ids = msg_obj.search(cr, uid, [('model', '=', self._name), ('res_id', 'in', ids)], context=context) - msg_obj.unlink(cr, uid, msg_to_del_ids, context=context) + msg_to_del_ids = msg_obj.search(cr, uid, [('model', '=', self._name), ('res_id', 'in', ids)], context = context) + msg_obj.unlink(cr, uid, msg_to_del_ids, context = context) - return super(mail_thread, self).unlink(cr, uid, ids, context=context) + return super(mail_thread, self).unlink(cr, uid, ids, context = context) #------------------------------------------------------ # mail.message wrappers and tools #------------------------------------------------------ - def message_create(self, cr, uid, thread_id, vals, context=None): + def message_create(self, cr, uid, thread_id, vals, context = None): """ OpenChatter: wrapper of mail.message create method - creates the mail.message - automatically subscribe the message writer @@ -155,57 +155,58 @@ class mail_thread(osv.Model): # automatically subscribe the writer of the message if vals['user_id']: - self.message_subscribe(cr, uid, [thread_id], [vals['user_id']], context=context) + self.message_subscribe(cr, uid, [thread_id], [vals['user_id']], context = context) # create message - msg_id = message_obj.create(cr, uid, vals, context=context) + msg_id = message_obj.create(cr, uid, vals, context = context) # Set as unread if writer is not the document responsible - self.message_create_set_unread(cr, uid, [thread_id], context=context) + self.message_create_set_unread(cr, uid, [thread_id], context = context) # special: if install mode, do not push demo data if context.get('install_mode', False): return msg_id # get users that will get a notification pushed - user_to_push_ids = self.message_get_user_ids_to_notify(cr, uid, [thread_id], vals, context=context) + user_to_push_ids = self.message_get_user_ids_to_notify(cr, uid, [thread_id], vals, context = context) for id in user_to_push_ids: - notification_obj.create(cr, uid, {'user_id': id, 'message_id': msg_id}, context=context) + notification_obj.create(cr, uid, {'user_id': id, 'message_id': msg_id}, context = context) # create the email to send - email_id = self.message_create_notify_by_email(cr, uid, vals, user_to_push_ids, context=context) + email_id = self.message_create_notify_by_email(cr, uid, vals, user_to_push_ids, context = context) return msg_id + #TODO :in message creation: in push method: push only if user is subscriber (current case) and if user is sucscribed to the subtype (to add) - def message_get_user_ids_to_notify(self, cr, uid, thread_ids, new_msg_vals, context=None): + def message_get_user_ids_to_notify(self, cr, uid, thread_ids, new_msg_vals, context = None): subscription_obj = self.pool.get('mail.subscription') # get body body = new_msg_vals.get('body_html', '') if new_msg_vals.get('content_subtype') == 'html' else new_msg_vals.get('body_text', '') # get subscribers - notif_user_ids = self.message_get_subscribers(cr, uid, thread_ids, context=context) + notif_user_ids = self.message_get_subscribers(cr, uid, thread_ids, context = context) # add users requested via parsing message (@login) - notif_user_ids += self.message_parse_users(cr, uid, body, context=context) + notif_user_ids += self.message_parse_users(cr, uid, body, context = context) # add users requested to perform an action (need_action mechanism) if hasattr(self, 'get_needaction_user_ids'): - user_ids_dict = self.get_needaction_user_ids(cr, uid, thread_ids, context=context) + user_ids_dict = self.get_needaction_user_ids(cr, uid, thread_ids, context = context) for id, user_ids in user_ids_dict.iteritems(): notif_user_ids += user_ids # add users notified of the parent messages (because: if parent message contains @login, login must receive the replies) if new_msg_vals.get('parent_id'): notif_obj = self.pool.get('mail.notification') - parent_notif_ids = notif_obj.search(cr, uid, [('message_id', '=', new_msg_vals.get('parent_id'))], context=context) - parent_notifs = notif_obj.read(cr, uid, parent_notif_ids, context=context) + parent_notif_ids = notif_obj.search(cr, uid, [('message_id', '=', new_msg_vals.get('parent_id'))], context = context) + parent_notifs = notif_obj.read(cr, uid, parent_notif_ids, context = context) notif_user_ids += [parent_notif['user_id'][0] for parent_notif in parent_notifs] # remove duplicate entries notif_user_ids = list(set(notif_user_ids)) return notif_user_ids - def message_parse_users(self, cr, uid, string, context=None): + def message_parse_users(self, cr, uid, string, context = None): """Parse message content - if find @login -(^|\s)@((\w|@|\.)*)-: returns the related ids this supports login that are emails (such as @raoul@grobedon.net) @@ -213,14 +214,14 @@ class mail_thread(osv.Model): regex = re.compile('(^|\s)@((\w|@|\.)*)') login_lst = [item[1] for item in regex.findall(string)] if not login_lst: return [] - user_ids = self.pool.get('res.users').search(cr, uid, [('login', 'in', login_lst)], context=context) + user_ids = self.pool.get('res.users').search(cr, uid, [('login', 'in', login_lst)], context = context) return user_ids #------------------------------------------------------ # Generic message api #------------------------------------------------------ - def message_capable_models(self, cr, uid, context=None): + def message_capable_models(self, cr, uid, context = None): ret_dict = {} for model_name in self.pool.obj_list(): model = self.pool.get(model_name) @@ -228,13 +229,13 @@ class mail_thread(osv.Model): ret_dict[model_name] = model._description return ret_dict - def message_append(self, cr, uid, threads, subject, body_text=None, body_html=None, - type='email', email_date=None, parent_id=False, - content_subtype='plain', state=None, - partner_ids=None, email_from=False, email_to=False, - email_cc=None, email_bcc=None, reply_to=None, - headers=None, message_id=False, references=None, - attachments=None, original=None, context=None): + def message_append(self, cr, uid, threads, subject, body_text = None, body_html = None, + type = 'email', subtype_id = False, email_date = None, parent_id = False, + content_subtype = 'plain', state = None, + partner_ids = None, email_from = False, email_to = False, + email_cc = None, email_bcc = None, reply_to = None, + headers = None, message_id = False, references = None, + attachments = None, original = None, context = None): """ Creates a new mail.message through message_create. The new message is attached to the current mail.thread, containing all the details passed as parameters. All attachments will be attached to the @@ -298,7 +299,7 @@ class mail_thread(osv.Model): if all(isinstance(thread_id, (int, long)) for thread_id in threads): model = context.get('thread_model') or self._name model_pool = self.pool.get(model) - threads = model_pool.browse(cr, uid, threads, context=context) + threads = model_pool.browse(cr, uid, threads, context = context) ir_attachment = self.pool.get('ir.attachment') mail_message = self.pool.get('mail.message') @@ -318,7 +319,7 @@ class mail_thread(osv.Model): 'res_model': thread._name, 'res_id': thread.id, } - to_attach.append(ir_attachment.create(cr, uid, data_attach, context=context)) + to_attach.append(ir_attachment.create(cr, uid, data_attach, context = context)) # find related partner: partner_id column in thread object, or self is res.partner model partner_id = ('partner_id' in thread._columns.keys()) and (thread.partner_id and thread.partner_id.id or False) or False if not partner_id and thread._name == 'res.partner': @@ -361,9 +362,10 @@ class mail_thread(osv.Model): 'reply_to': reply_to, 'original': original, }) - new_msg_ids.append(self.message_create(cr, uid, thread.id, data, context=context)) + new_msg_ids.append(self.message_create(cr, uid, thread.id, data, context = context)) return new_msg_ids - def message_append_dict(self, cr, uid, ids, msg_dict, context=None): + + def message_append_dict(self, cr, uid, ids, msg_dict, context = None): """Creates a new mail.message attached to the given threads (``ids``), with the contents of ``msg_dict``, by calling ``message_append`` with the mail details. All attachments in msg_dict will be @@ -382,9 +384,10 @@ class mail_thread(osv.Model): return self.message_append(cr, uid, ids, subject = msg_dict.get('subject'), body_text = msg_dict.get('body_text'), - body_html= msg_dict.get('body_html'), + body_html = msg_dict.get('body_html'), parent_id = msg_dict.get('parent_id', False), type = msg_dict.get('type', 'email'), + subtype_id = msg_dict.get('subtype_id', False), content_subtype = msg_dict.get('content_subtype'), state = msg_dict.get('state'), partner_ids = msg_dict.get('partner_ids'), @@ -406,7 +409,7 @@ class mail_thread(osv.Model): # Message loading #------------------------------------------------------ - def _message_search_ancestor_ids(self, cr, uid, ids, child_ids, ancestor_ids, context=None): + def _message_search_ancestor_ids(self, cr, uid, ids, child_ids, ancestor_ids, context = None): """ Given message child_ids ids, find their ancestors until ancestor_ids using their parent_id relationship. @@ -425,13 +428,13 @@ class mail_thread(osv.Model): ] message_obj = self.pool.get('mail.message') - messages_temp = message_obj.read(cr, uid, child_ids, ['id', 'parent_id'], context=context) + messages_temp = message_obj.read(cr, uid, child_ids, ['id', 'parent_id'], context = context) parent_ids = _get_parent_ids(messages_temp, ancestor_ids, child_ids) child_ids += parent_ids cur_iter = 0; max_iter = 100; # avoid infinite loop while (parent_ids and (cur_iter < max_iter)): cur_iter += 1 - messages_temp = message_obj.read(cr, uid, parent_ids, ['id', 'parent_id'], context=context) + messages_temp = message_obj.read(cr, uid, parent_ids, ['id', 'parent_id'], context = context) parent_ids = _get_parent_ids(messages_temp, ancestor_ids, child_ids) child_ids += parent_ids if (cur_iter > max_iter): @@ -440,7 +443,7 @@ class mail_thread(osv.Model): "message graph, leading to a curious error. Have fun.") return child_ids - def message_search_get_domain(self, cr, uid, ids, context=None): + def message_search_get_domain(self, cr, uid, ids, context = None): """ OpenChatter feature: get the domain to search the messages related to a document. mail.thread defines the default behavior as being messages with model = self._name, id in ids. @@ -449,8 +452,8 @@ class mail_thread(osv.Model): """ return ['&', ('res_id', 'in', ids), ('model', '=', self._name)] - def message_search(self, cr, uid, ids, fetch_ancestors=False, ancestor_ids=None, - limit=100, offset=0, domain=None, count=False, context=None): + def message_search(self, cr, uid, ids, fetch_ancestors = False, ancestor_ids = None, + limit = 100, offset = 0, domain = None, count = False, context = None): """ OpenChatter feature: return thread messages ids according to the search domain given by ``message_search_get_domain``. @@ -477,17 +480,17 @@ class mail_thread(osv.Model): default domain. :param limit, offset, count, context: as usual """ - search_domain = self.message_search_get_domain(cr, uid, ids, context=context) + search_domain = self.message_search_get_domain(cr, uid, ids, context = context) if domain: search_domain += domain message_obj = self.pool.get('mail.message') - message_res = message_obj.search(cr, uid, search_domain, limit=limit, offset=offset, count=count, context=context) + message_res = message_obj.search(cr, uid, search_domain, limit = limit, offset = offset, count = count, context = context) if not count and fetch_ancestors: - message_res += self._message_search_ancestor_ids(cr, uid, ids, message_res, ancestor_ids, context=context) + message_res += self._message_search_ancestor_ids(cr, uid, ids, message_res, ancestor_ids, context = context) return message_res - def message_read(self, cr, uid, ids, fetch_ancestors=False, ancestor_ids=None, - limit=100, offset=0, domain=None, context=None): + def message_read(self, cr, uid, ids, fetch_ancestors = False, ancestor_ids = None, + limit = 100, offset = 0, domain = None, context = None): """ OpenChatter feature: read the messages related to some threads. This method is used mainly the Chatter widget, to directly have read result instead of searching then reading. @@ -495,8 +498,8 @@ class mail_thread(osv.Model): Please see message_search for more information about the parameters. """ message_ids = self.message_search(cr, uid, ids, fetch_ancestors, ancestor_ids, - limit, offset, domain, context=context) - messages = self.pool.get('mail.message').read(cr, uid, message_ids, context=context) + limit, offset, domain, context = context) + messages = self.pool.get('mail.message').read(cr, uid, message_ids, context = context) """ Retrieve all attachments names """ map_id_to_name = dict((attachment_id, '') for message in messages for attachment_id in message['attachment_ids']) @@ -506,7 +509,7 @@ class mail_thread(osv.Model): map_id_to_name[attach_id] = '' # use empty string as a placeholder ids = map_id_to_name.keys() - names = self.pool.get('ir.attachment').name_get(cr, uid, ids, context=context) + names = self.pool.get('ir.attachment').name_get(cr, uid, ids, context = context) # convert the list of tuples into a dictionnary for name in names: @@ -520,13 +523,13 @@ class mail_thread(osv.Model): msg["attachments"].append({'id': attach_id, 'name': map_id_to_name[attach_id]}) # Set the threads as read - self.message_check_and_set_read(cr, uid, ids, context=context) + self.message_check_and_set_read(cr, uid, ids, context = context) # Sort and return the messages - messages = sorted(messages, key=lambda d: (-d['id'])) + messages = sorted(messages, key = lambda d: (-d['id'])) return messages - def message_get_pushed_messages(self, cr, uid, ids, fetch_ancestors=False, ancestor_ids=None, - limit=100, offset=0, msg_search_domain=[], context=None): + def message_get_pushed_messages(self, cr, uid, ids, fetch_ancestors = False, ancestor_ids = None, + limit = 100, offset = 0, msg_search_domain = [], context = None): """ OpenChatter: wall: get the pushed notifications and used them to fetch messages to display on the wall. @@ -550,13 +553,13 @@ class mail_thread(osv.Model): # compose final domain domain = [('user_id', '=', uid)] + msg_search_domain # get notifications - notification_ids = notification_obj.search(cr, uid, domain, limit=limit, offset=offset, context=context) - notifications = notification_obj.browse(cr, uid, notification_ids, context=context) + notification_ids = notification_obj.search(cr, uid, domain, limit = limit, offset = offset, context = context) + notifications = notification_obj.browse(cr, uid, notification_ids, context = context) msg_ids = [notification.message_id.id for notification in notifications] # get messages - msg_ids = msg_obj.search(cr, uid, [('id', 'in', msg_ids)], context=context) - if (fetch_ancestors): msg_ids = self._message_search_ancestor_ids(cr, uid, ids, msg_ids, ancestor_ids, context=context) - msgs = msg_obj.read(cr, uid, msg_ids, context=context) + msg_ids = msg_obj.search(cr, uid, [('id', 'in', msg_ids)], context = context) + if (fetch_ancestors): msg_ids = self._message_search_ancestor_ids(cr, uid, ids, msg_ids, ancestor_ids, context = context) + msgs = msg_obj.read(cr, uid, msg_ids, context = context) return msgs #------------------------------------------------------ @@ -564,9 +567,9 @@ class mail_thread(osv.Model): #------------------------------------------------------ # message_process will call either message_new or message_update. - def message_process(self, cr, uid, model, message, custom_values=None, - save_original=False, strip_attachments=False, - context=None): + def message_process(self, cr, uid, model, message, custom_values = None, + save_original = False, strip_attachments = False, + context = None): """Process an incoming RFC2822 email message related to the given thread model, relying on ``mail.message.parse()`` for the parsing operation, and then calling ``message_new`` @@ -606,7 +609,7 @@ class mail_thread(osv.Model): if isinstance(message, unicode): message = message.encode('utf-8') msg_txt = email.message_from_string(message) - msg = mail_message.parse_message(msg_txt, save_original=save_original, context=context) + msg = mail_message.parse_message(msg_txt, save_original = save_original, context = context) # update state msg['state'] = 'received' @@ -619,7 +622,7 @@ class mail_thread(osv.Model): if hasattr(model_pool, 'message_new'): return model_pool.message_new(cr, uid, msg, custom_values, - context=context) + context = context) res_id = False if msg.get('references') or msg.get('in-reply-to'): references = msg.get('references') or msg.get('in-reply-to') @@ -640,19 +643,19 @@ class mail_thread(osv.Model): res_id = res_id if model_pool.exists(cr, uid, res_id): if hasattr(model_pool, 'message_update'): - model_pool.message_update(cr, uid, [res_id], msg, {}, context=context) + model_pool.message_update(cr, uid, [res_id], msg, {}, context = context) else: # referenced thread was not found, we'll have to create a new one res_id = False if not res_id: res_id = create_record(msg) # To forward the email to other followers - self.message_forward(cr, uid, model, [res_id], msg_txt, context=context) + self.message_forward(cr, uid, model, [res_id], msg_txt, context = context) # Set as Unread - model_pool.message_mark_as_unread(cr, uid, [res_id], context=context) + model_pool.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): + def message_new(self, cr, uid, msg_dict, custom_values = None, context = None): """Called by ``message_process`` when a new message is received for a given thread model, if the message did not belong to an existing thread. @@ -681,17 +684,17 @@ class mail_thread(osv.Model): context = {} model = context.get('thread_model') or self._name model_pool = self.pool.get(model) - fields = model_pool.fields_get(cr, uid, context=context) - data = model_pool.default_get(cr, uid, fields, context=context) + 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', '') 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) + 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, update_vals=None, context=None): + 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 @@ -711,10 +714,10 @@ class mail_thread(osv.Model): 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) + 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): + def message_thread_followers(self, cr, uid, ids, context = None): """ Returns a list of email addresses of the people following this thread, including the sender of each mail, and the people who were in CC of the messages, if any. @@ -722,7 +725,7 @@ class mail_thread(osv.Model): res = {} if isinstance(ids, (str, int, long)): ids = [long(ids)] - for thread in self.browse(cr, uid, ids, context=context): + for thread in self.browse(cr, uid, ids, context = context): l = set() for message in thread.message_ids: l.add((message.user_id and message.user_id.user_email) or '') @@ -731,7 +734,7 @@ class mail_thread(osv.Model): res[thread.id] = filter(None, l) return res - def message_forward(self, cr, uid, model, thread_ids, msg, email_error=False, context=None): + def message_forward(self, cr, uid, model, thread_ids, msg, email_error = False, context = None): """Sends an email to all people following the given threads. The emails are forwarded immediately, not queued for sending, and not archived. @@ -746,7 +749,7 @@ class mail_thread(osv.Model): model_pool = self.pool.get(model) smtp_server_obj = self.pool.get('ir.mail_server') mail_message = self.pool.get('mail.message') - for res in model_pool.browse(cr, uid, thread_ids, context=context): + for res in model_pool.browse(cr, uid, thread_ids, context = context): if hasattr(model_pool, 'message_thread_followers'): followers = model_pool.message_thread_followers(cr, uid, [res.id])[res.id] else: @@ -765,7 +768,7 @@ class mail_thread(osv.Model): smtp_from, = to_email(msg['from']) msg['from'] = smtp_from - msg['to'] = ", ".join(forward_to) + msg['to'] = ", ".join(forward_to) msg['message-id'] = tools.generate_tracking_message_id(res.id) if not smtp_server_obj.send_email(cr, uid, msg) and email_error: subj = msg['subject'] @@ -775,7 +778,7 @@ class mail_thread(osv.Model): smtp_server_obj.send_email(cr, uid, msg) return True - def message_partner_by_email(self, cr, uid, email, context=None): + def message_partner_by_email(self, cr, uid, email, context = None): """Attempts to return the id of a partner address matching the given ``email``, and the corresponding partner id. Can be used by classes using the ``mail.thread`` mixin @@ -811,16 +814,16 @@ class mail_thread(osv.Model): # Note specific #------------------------------------------------------ - def log(self, cr, uid, id, message, secondary=False, context=None): + def log(self, cr, uid, id, message, secondary = False, context = None): _logger.warning("log() is deprecated. As this module inherit from \ mail.thread, the message will be managed by this \ module instead of by the res.log mechanism. Please \ use the mail.thread OpenChatter API instead of the \ now deprecated res.log.") - self.message_append_note(cr, uid, [id], 'res.log', message, context=context) + self.message_append_note(cr, uid, [id], 'res.log', message, context = context) - def message_append_note(self, cr, uid, ids, subject=None, body=None, parent_id=False, - type='notification', content_subtype='html', context=None): + def message_append_note(self, cr, uid, ids, subject = None, body = None, parent_id = False, + type = 'notification', subtype_id = False, content_subtype = 'html', context = None): if content_subtype == 'html': body_html = body body_text = body @@ -828,14 +831,14 @@ class mail_thread(osv.Model): body_html = body body_text = body return self.message_append(cr, uid, ids, subject, body_html, body_text, - type, parent_id=parent_id, - content_subtype=content_subtype, context=context) + type, subtype_id = subtype_id, parent_id = parent_id, + content_subtype = content_subtype, context = context) #------------------------------------------------------ # Subscription mechanism #------------------------------------------------------ - def message_get_subscribers(self, cr, uid, ids, context=None): + def message_get_subscribers(self, cr, uid, ids, context = None): """ Returns the current document followers. Basically this method checks in mail.subscription for entries with matching res_model, res_id. @@ -844,18 +847,18 @@ class mail_thread(osv.Model): ids returned by this method. """ subscr_obj = self.pool.get('mail.subscription') - subscr_ids = subscr_obj.search(cr, uid, ['&', ('res_model', '=', self._name), ('res_id', 'in', ids)], context=context) - return [sub['user_id'][0] for sub in subscr_obj.read(cr, uid, subscr_ids, ['user_id'], context=context)] + subscr_ids = subscr_obj.search(cr, uid, ['&', ('res_model', '=', self._name), ('res_id', 'in', ids)], context = context) + return [sub['user_id'][0] for sub in subscr_obj.read(cr, uid, subscr_ids, ['user_id'], context = context)] - def message_read_subscribers(self, cr, uid, ids, fields=['id', 'name', 'avatar'], context=None): + def message_read_subscribers(self, cr, uid, ids, fields = ['id', 'name', 'avatar'], context = None): """ Returns the current document followers as a read result. Used mainly for Chatter having only one method to call to have details about users. """ - user_ids = self.message_get_subscribers(cr, uid, ids, context=context) - return self.pool.get('res.users').read(cr, uid, user_ids, fields=fields, context=context) + user_ids = self.message_get_subscribers(cr, uid, ids, context = context) + return self.pool.get('res.users').read(cr, uid, user_ids, fields = fields, context = context) - def message_is_subscriber(self, cr, uid, ids, user_id = None, context=None): + def message_is_subscriber(self, cr, uid, ids, user_id = None, context = None): """ Check if uid or user_id (if set) is a subscriber to the current document. @@ -863,16 +866,17 @@ class mail_thread(osv.Model): check is done on uid """ sub_user_id = uid if user_id is None else user_id - if sub_user_id in self.message_get_subscribers(cr, uid, ids, context=context): + if sub_user_id in self.message_get_subscribers(cr, uid, ids, context = context): return True return False - def message_subscribe(self, cr, uid, ids, user_ids = None, context=None): + def message_subscribe(self, cr, uid, ids, user_ids = None, subtype_ids = None, context = None): """ Subscribe the user (or user_ids) to the current document. :param user_ids: a list of user_ids; if not set, subscribe uid instead """ + # TODO:Update Massage Subscribe and add paramenter subtype_ids # if subtype_ids is False: add default ones (res_model = self._name, default = True) # in method: if user_id already subscriber, update its subscription with subtype_ids @@ -881,14 +885,20 @@ class mail_thread(osv.Model): to_subscribe_uids = [uid] if user_ids is None else user_ids create_ids = [] for id in ids: - already_subscribed_user_ids = self.message_get_subscribers(cr, uid, [id], context=context) + already_subscribed_user_ids = self.message_get_subscribers(cr, uid, [id], context = context) for user_id in to_subscribe_uids: - if user_id in already_subscribed_user_ids: continue - create_ids.append(subscription_obj.create(cr, uid, {'res_model': self._name, 'res_id': id, 'user_id': user_id}, context=context)) + res = {'res_model': self._name, 'res_id': id, 'user_id': user_id} + res['subtype_ids'] = [0, 0, {'res_model': self._name, 'default': True}] + if user_id in already_subscribed_user_ids: + if subtype_ids: + res['subtype_ids'] = [(6, 0, subtype_ids)] + else: continue + create_ids.append(subscription_obj.create(cr, uid, res, context = context)) return create_ids + #TODO : Add method : add message_subscribe_udpate_subtypes(..., user_id, subtype_ids): - def message_unsubscribe(self, cr, uid, ids, user_ids = None, context=None): + def message_unsubscribe(self, cr, uid, ids, user_ids = None, context = None): """ Unsubscribe the user (or user_ids) from the current document. :param user_ids: a list of user_ids; if not set, subscribe @@ -900,17 +910,19 @@ class mail_thread(osv.Model): to_unsubscribe_uids = [uid] if user_ids is None else user_ids subscription_obj = self.pool.get('mail.subscription') to_delete_sub_ids = subscription_obj.search(cr, uid, - ['&', '&', ('res_model', '=', self._name), ('res_id', 'in', ids), ('user_id', 'in', to_unsubscribe_uids)], context=context) + ['&', '&', ('res_model', '=', self._name), ('res_id', 'in', ids), ('user_id', 'in', to_unsubscribe_uids)], context = context) if not to_delete_sub_ids: return False - return subscription_obj.unlink(cr, uid, to_delete_sub_ids, context=context) + + return subscription_obj.unlink(cr, uid, to_delete_sub_ids, context = context) #TODO : Add Method : add message_subscribeption_remove_subtype(..., user_id, subtype_id): #TODO : Add method : add message_subscription_remove_subtype_name(.., user_id, subtype_name) + #------------------------------------------------------ # Notification API #------------------------------------------------------ - def message_create_notify_by_email(self, cr, uid, new_msg_values, user_to_notify_ids, context=None): + def message_create_notify_by_email(self, cr, uid, new_msg_values, user_to_notify_ids, context = None): """ When creating a new message and pushing notifications, emails must be send if users have chosen to receive notifications by email via the notification_email_pref field. @@ -937,11 +949,11 @@ class mail_thread(osv.Model): user_to_notify_ids.remove(new_msg_values.get('user_id')) # get user_ids directly asked - user_to_push_from_parse_ids = self.message_parse_users(cr, uid, body, context=context) + user_to_push_from_parse_ids = self.message_parse_users(cr, uid, body, context = context) # try to find an email_to email_to = '' - for user in res_users_obj.browse(cr, uid, user_to_notify_ids, context=context): + for user in res_users_obj.browse(cr, uid, user_to_notify_ids, context = context): if not user.notification_email_pref == 'all' and \ not (user.notification_email_pref == 'to_me' and user.id in user_to_push_from_parse_ids): continue @@ -955,17 +967,17 @@ class mail_thread(osv.Model): return # try to find an email_from - current_user = res_users_obj.browse(cr, uid, [uid], context=context)[0] + current_user = res_users_obj.browse(cr, uid, [uid], context = context)[0] email_from = new_msg_values.get('email_from') if not email_from: email_from = current_user.user_email # get email content, create it (with mail_message.create) email_values = self.message_create_notify_get_email_dict(cr, uid, new_msg_values, email_from, email_to, context) - email_id = message_obj.create(cr, uid, email_values, context=context) + email_id = message_obj.create(cr, uid, email_values, context = context) return email_id - def message_create_notify_get_email_dict(self, cr, uid, new_msg_values, email_from, email_to, context=None): + def message_create_notify_get_email_dict(self, cr, uid, new_msg_values, email_from, email_to, context = None): values = dict(new_msg_values) body_html = new_msg_values.get('body_html', '') @@ -989,47 +1001,62 @@ class mail_thread(osv.Model): }) return values - def message_remove_pushed_notifications(self, cr, uid, ids, msg_ids, remove_childs=True, context=None): + def message_remove_pushed_notifications(self, cr, uid, ids, msg_ids, remove_childs = True, context = None): notif_obj = self.pool.get('mail.notification') msg_obj = self.pool.get('mail.message') if remove_childs: - notif_msg_ids = msg_obj.search(cr, uid, [('id', 'child_of', msg_ids)], context=context) + notif_msg_ids = msg_obj.search(cr, uid, [('id', 'child_of', msg_ids)], context = context) else: notif_msg_ids = msg_ids - 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) + 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_create_set_unread(self, cr, uid, ids, context=None): + def message_create_set_unread(self, cr, uid, ids, context = None): """ When creating a new message, set as unread if uid is not the object responsible. """ - for obj in self.browse(cr, uid, ids, context=context): + for obj in self.browse(cr, uid, ids, context = context): if obj.message_state and hasattr(obj, 'user_id') and (not obj.user_id or obj.user_id.id != uid): - self.message_mark_as_unread(cr, uid, [obj.id], context=context) + self.message_mark_as_unread(cr, uid, [obj.id], context = context) - def message_check_and_set_unread(self, cr, uid, ids, context=None): + def message_check_and_set_unread(self, cr, uid, ids, context = None): """ Set unread if uid is the object responsible or if the object has no responsible. """ - for obj in self.browse(cr, uid, ids, context=context): + for obj in self.browse(cr, uid, ids, context = context): if obj.message_state and hasattr(obj, 'user_id') and (not obj.user_id or obj.user_id.id == uid): - self.message_mark_as_unread(cr, uid, [obj.id], context=context) + self.message_mark_as_unread(cr, uid, [obj.id], context = context) - def message_mark_as_unread(self, cr, uid, ids, context=None): + def message_mark_as_unread(self, cr, uid, ids, context = None): """ Set as unread. """ - return self.write(cr, uid, ids, {'message_state': False}, context=context) + return self.write(cr, uid, ids, {'message_state': False}, context = context) - def message_check_and_set_read(self, cr, uid, ids, context=None): + def message_check_and_set_read(self, cr, uid, ids, context = None): """ Set read if uid is the object responsible. """ - for obj in self.browse(cr, uid, ids, context=context): + for obj in self.browse(cr, uid, ids, context = context): if not obj.message_state and hasattr(obj, 'user_id') and obj.user_id and obj.user_id.id == uid: - self.message_mark_as_read(cr, uid, [obj.id], context=context) + self.message_mark_as_read(cr, uid, [obj.id], context = context) - def message_mark_as_read(self, cr, uid, ids, context=None): + def message_mark_as_read(self, cr, uid, ids, context = None): """ Set as read. """ - return self.write(cr, uid, ids, {'message_state': True}, context=context) - + return self.write(cr, uid, ids, {'message_state': True}, context = context) + def message_subscribe_udpate_subtypes(self, cr, uid, ids, user_id, subtype_ids): + subscription_obj = self.pool.get('mail.subscription') + subscription_ids = subscription_obj.search(cr, uid, [('res_model', '=', self._name), ('res_id', 'in', ids)]) + return subscription_obj.write(cr, uid, subscription_ids, {'subtype_ids': [6, 0 , subtype_ids]}, context = context) #overright or add new one + + def message_subscription_remove_subtype(self, cr, uid, ids, user_id, subtype_id): + subscription_obj = self.pool.get('mail.subscription') + subscription_ids = subscription_obj.search(cr, uid, [('res_model', '=', self._name), ('res_id', 'in', ids)]) + return subscription_obj.write(cr, uid, subscription_ids, {'subtype_ids': [3, subtype_id]}, context = context) # remove linl or record ? + + def message_subscription_remove_subtype_name(self, cr, uid, ids, user_id, subtype_name): + subtype_obj = self.pool.get('mail.message.subtype') + subtype_ids = subtype_obj.search(cr, uid, [('name', '=', subtype_name), ('model_ids', '=', self._name)]) + if not subtype_ids: + return False + self.message_subscription_remove_subtype(cr, uid, ids, user_id, subtype_ids) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From b942c562240d999c2f20ea154547ac46dde179a8 Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Thu, 9 Aug 2012 14:52:56 +0530 Subject: [PATCH 07/16] [ADD] Add demo data in crm lead bzr revid: fka@tinyerp.com-20120809092256-r27t6y9nvndwnole --- addons/crm/crm_lead.py | 17 ++++++++++------- addons/crm/crm_lead_demo.xml | 32 ++++++++++++++++++++++++++++++++ addons/mail/mail_thread.py | 2 +- 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index d5ec1309baa..675f41c94f4 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -275,6 +275,9 @@ class crm_lead(base_stage, osv.osv): def create(self, cr, uid, vals, context=None): obj_id = super(crm_lead, self).create(cr, uid, vals, context) + obj = self.browse(cr, uid, obj_id, context) + if obj.user_id: + self.message_subscribe(cr, uid, ids, obj.user_id.id, context = context) self.create_send_note(cr, uid, [obj_id], context=context) return obj_id @@ -849,13 +852,13 @@ 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_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 stage_set_send_note(self, cr, uid, ids, stage_id, context=None): """ Override of the (void) default notification method. """ diff --git a/addons/crm/crm_lead_demo.xml b/addons/crm/crm_lead_demo.xml index 7ed3bc2a86b..b064a9adfb1 100644 --- a/addons/crm/crm_lead_demo.xml +++ b/addons/crm/crm_lead_demo.xml @@ -540,5 +540,37 @@ ref('crm_case_ericdubois4'), ref('crm_case_abcfuelcounits0')], {}" /> + + new + + + + + won + + + + lost + + + + stage change + + + + + other + + + + + email + + + + comment + + + diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 3e5bfabe350..21d123ec024 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -1051,7 +1051,7 @@ class mail_thread(osv.Model): def message_subscription_remove_subtype(self, cr, uid, ids, user_id, subtype_id): subscription_obj = self.pool.get('mail.subscription') subscription_ids = subscription_obj.search(cr, uid, [('res_model', '=', self._name), ('res_id', 'in', ids)]) - return subscription_obj.write(cr, uid, subscription_ids, {'subtype_ids': [3, subtype_id]}, context = context) # remove linl or record ? + return subscription_obj.write(cr, uid, subscription_ids, {'subtype_ids': [3, subtype_id]}, context = context) # remove link def message_subscription_remove_subtype_name(self, cr, uid, ids, user_id, subtype_name): subtype_obj = self.pool.get('mail.message.subtype') From dae19bc174b3962088bf4b9fd0701f80ab8f8e5e Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Thu, 9 Aug 2012 16:48:06 +0530 Subject: [PATCH 08/16] [IMP] improve crm_lead bzr revid: fka@tinyerp.com-20120809111806-k79sserip4oyzo1r --- addons/crm/crm_lead.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index 675f41c94f4..a3fccffb011 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -277,7 +277,7 @@ class crm_lead(base_stage, osv.osv): obj_id = super(crm_lead, self).create(cr, uid, vals, context) obj = self.browse(cr, uid, obj_id, context) if obj.user_id: - self.message_subscribe(cr, uid, ids, obj.user_id.id, context = context) + self.message_subscribe(cr, uid, [obj_id], [obj.user_id.id], context = context) self.create_send_note(cr, uid, [obj_id], context=context) return obj_id From 0e916d159242e46d3f4b2c914c0d8dc49e88ee03 Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Mon, 13 Aug 2012 18:40:40 +0530 Subject: [PATCH 09/16] [IMP] improve mail_thread bzr revid: fka@tinyerp.com-20120813131040-32v2tcz3eltkx4fn --- addons/crm/crm_lead.py | 28 +++++++++++++++++++++------- addons/mail/mail_thread.py | 3 ++- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index da845cc8e5f..b02369cce9f 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -865,7 +865,9 @@ class crm_lead(base_stage, osv.osv): def stage_set_send_note(self, cr, uid, ids, stage_id, context=None): """ Override of the (void) default notification method. """ stage_name = self.pool.get('crm.case.stage').name_get(cr, uid, [stage_id], context=context)[0][1] - return self.message_append_note(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), context=context) + res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm', 'mail_subtype_lead_stage_change') + res_id = res[1] + return self.message_append_note(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), subtype_id=res_id,context=context) def case_get_note_msg_prefix(self, cr, uid, lead, context=None): if isinstance(lead, (int, long)): @@ -875,33 +877,45 @@ class crm_lead(base_stage, osv.osv): def create_send_note(self, cr, uid, ids, context=None): for id in ids: message = _("%s has been created.")% (self.case_get_note_msg_prefix(cr, uid, id, context=context)) - self.message_append_note(cr, uid, [id], body=message, context=context) + res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm', 'mail_subtype_lead_new') + res_id = res[1] + self.message_append_note(cr, uid, [id], body=message, subtype_id=res_id, context=context) return True def case_mark_lost_send_note(self, cr, uid, ids, context=None): message = _("Opportunity has been lost.") - return self.message_append_note(cr, uid, ids, body=message, context=context) + res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm', 'mail_subtype_lead_lost') + res_id = res[1] + return self.message_append_note(cr, uid, ids, body=message,subtype_id=res_id, context=context) def case_mark_won_send_note(self, cr, uid, ids, context=None): message = _("Opportunity has been won.") - return self.message_append_note(cr, uid, ids, body=message, context=context) + res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm', 'mail_subtype_lead_won') + res_id = res[1] + return self.message_append_note(cr, uid, ids, body=message, subtype_id=res_id, context=context) def schedule_phonecall_send_note(self, cr, uid, ids, phonecall_id, action, context=None): phonecall = self.pool.get('crm.phonecall').browse(cr, uid, [phonecall_id], context=context)[0] if action == 'log': prefix = 'Logged' else: prefix = 'Scheduled' message = _("%s a call for the %s.") % (prefix, phonecall.date) - return self.message_append_note(cr, uid, ids, body=message, context=context) + res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm', 'mail_subtype_lead_other') + res_id = res[1] + return self.message_append_note(cr, uid, ids, body=message, subtype_id=res_id, context=context) def _lead_set_partner_send_note(self, cr, uid, ids, context=None): for lead in self.browse(cr, uid, ids, context=context): message = _("%s partner is now set to %s." % (self.case_get_note_msg_prefix(cr, uid, lead, context=context), lead.partner_id.name)) - lead.message_append_note(body=message) + res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm', 'mail_subtype_lead_other') + res_id = res[1] + lead.message_append_note(body=message, subtype_id=res_id) return True def convert_opportunity_send_note(self, cr, uid, lead, context=None): message = _("Lead has been converted to an opportunity.") - lead.message_append_note(body=message) + res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm', 'mail_subtype_lead_other') + res_id = res[1] + lead.message_append_note(body=message, subtype_id=res_id) return True crm_lead() diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 79b734379d0..14e9138be55 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -335,6 +335,7 @@ class mail_thread(osv.Model): 'parent_id': parent_id, 'date': email_date or fields.datetime.now(), 'type': type, + 'subtype_id' : subtype_id, 'content_subtype': content_subtype, 'state': state, 'message_id': message_id, @@ -866,7 +867,7 @@ class mail_thread(osv.Model): now deprecated res.log.") self.message_append_note(cr, uid, [id], 'res.log', message, context=context) - def message_append_note(self, cr, uid, ids, subject=None, subtype_id=None, body=None, parent_id=False, + def message_append_note(self, cr, uid, ids, subject=None, subtype_id=False, body=None, parent_id=False, type='notification', content_subtype='html', context=None): if content_subtype == 'html': body_html = body From 9fac5651d55d44e4b6eb8d16fe0b802bc1df349d Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Tue, 14 Aug 2012 12:21:49 +0530 Subject: [PATCH 10/16] [IMP] improve as per suggetion bzr revid: fka@tinyerp.com-20120814065149-h1xf3we6t37bsyk3 --- addons/crm/crm_data.xml | 2 +- addons/crm/crm_lead.py | 28 +++++++--------------------- addons/mail/data/mail_group_data.xml | 2 +- addons/mail/mail_thread.py | 13 ++++++------- 4 files changed, 15 insertions(+), 30 deletions(-) diff --git a/addons/crm/crm_data.xml b/addons/crm/crm_data.xml index 5e5f408673a..dfe2e4653c3 100644 --- a/addons/crm/crm_data.xml +++ b/addons/crm/crm_data.xml @@ -63,7 +63,7 @@ - + Module CRM has been installed From the top menu Sales, you can: trace leads and opportunities, get accurate forecast on your sales pipeline, plan meetings and phonecalls, get realtime statistics and efficiently organize the communication with your prospects. diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index b02369cce9f..976eb333ddd 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -865,9 +865,7 @@ class crm_lead(base_stage, osv.osv): def stage_set_send_note(self, cr, uid, ids, stage_id, context=None): """ Override of the (void) default notification method. """ stage_name = self.pool.get('crm.case.stage').name_get(cr, uid, [stage_id], context=context)[0][1] - res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm', 'mail_subtype_lead_stage_change') - res_id = res[1] - return self.message_append_note(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), subtype_id=res_id,context=context) + return self.message_append_note(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), subtype_id="stage change",context=context) def case_get_note_msg_prefix(self, cr, uid, lead, context=None): if isinstance(lead, (int, long)): @@ -877,45 +875,33 @@ class crm_lead(base_stage, osv.osv): def create_send_note(self, cr, uid, ids, context=None): for id in ids: message = _("%s has been created.")% (self.case_get_note_msg_prefix(cr, uid, id, context=context)) - res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm', 'mail_subtype_lead_new') - res_id = res[1] - self.message_append_note(cr, uid, [id], body=message, subtype_id=res_id, context=context) + self.message_append_note(cr, uid, [id], body=message, subtype_id="new", context=context) return True def case_mark_lost_send_note(self, cr, uid, ids, context=None): message = _("Opportunity has been lost.") - res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm', 'mail_subtype_lead_lost') - res_id = res[1] - return self.message_append_note(cr, uid, ids, body=message,subtype_id=res_id, context=context) + return self.message_append_note(cr, uid, ids, body=message,subtype_id="lost", context=context) def case_mark_won_send_note(self, cr, uid, ids, context=None): message = _("Opportunity has been won.") - res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm', 'mail_subtype_lead_won') - res_id = res[1] - return self.message_append_note(cr, uid, ids, body=message, subtype_id=res_id, context=context) + return self.message_append_note(cr, uid, ids, body=message, subtype_id="won", context=context) def schedule_phonecall_send_note(self, cr, uid, ids, phonecall_id, action, context=None): phonecall = self.pool.get('crm.phonecall').browse(cr, uid, [phonecall_id], context=context)[0] if action == 'log': prefix = 'Logged' else: prefix = 'Scheduled' message = _("%s a call for the %s.") % (prefix, phonecall.date) - res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm', 'mail_subtype_lead_other') - res_id = res[1] - return self.message_append_note(cr, uid, ids, body=message, subtype_id=res_id, context=context) + return self.message_append_note(cr, uid, ids, body=message, context=context) def _lead_set_partner_send_note(self, cr, uid, ids, context=None): for lead in self.browse(cr, uid, ids, context=context): message = _("%s partner is now set to %s." % (self.case_get_note_msg_prefix(cr, uid, lead, context=context), lead.partner_id.name)) - res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm', 'mail_subtype_lead_other') - res_id = res[1] - lead.message_append_note(body=message, subtype_id=res_id) + lead.message_append_note(body=message) return True def convert_opportunity_send_note(self, cr, uid, lead, context=None): message = _("Lead has been converted to an opportunity.") - res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm', 'mail_subtype_lead_other') - res_id = res[1] - lead.message_append_note(body=message, subtype_id=res_id) + lead.message_append_note(body=message) return True crm_lead() diff --git a/addons/mail/data/mail_group_data.xml b/addons/mail/data/mail_group_data.xml index 09a6ca29a2d..3a2ad01fab8 100644 --- a/addons/mail/data/mail_group_data.xml +++ b/addons/mail/data/mail_group_data.xml @@ -16,7 +16,7 @@ - + Welcome to OpenERP! Your homepage is a summary of messages you received and key information about documents you follow. diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 14e9138be55..8d1259ea4ff 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -228,8 +228,8 @@ class mail_thread(osv.Model): ret_dict[model_name] = model._description return ret_dict - def message_append(self, cr, uid, threads, subject, body_text=None, body_html=None, - type = 'email', subtype_id = False, email_date = None, parent_id = False, + def message_append(self, cr, uid, threads, subject,subtype_id = "other", body_text=None, body_html=None, + type = 'email', email_date = None, parent_id = False, content_subtype='plain', state=None, partner_ids=None, email_from=False, email_to=False, email_cc=None, email_bcc=None, reply_to=None, @@ -335,7 +335,6 @@ class mail_thread(osv.Model): 'parent_id': parent_id, 'date': email_date or fields.datetime.now(), 'type': type, - 'subtype_id' : subtype_id, 'content_subtype': content_subtype, 'state': state, 'message_id': message_id, @@ -383,11 +382,11 @@ class mail_thread(osv.Model): """ return self.message_append(cr, uid, ids, subject = msg_dict.get('subject'), + subtype_id = msg_dict.get('subtype_id','other'), body_text = msg_dict.get('body_text'), body_html= msg_dict.get('body_html'), parent_id = msg_dict.get('parent_id', False), type = msg_dict.get('type', 'email'), - subtype_id = msg_dict.get('subtype_id', False), content_subtype = msg_dict.get('content_subtype'), state = msg_dict.get('state'), partner_ids = msg_dict.get('partner_ids'), @@ -867,7 +866,7 @@ class mail_thread(osv.Model): now deprecated res.log.") self.message_append_note(cr, uid, [id], 'res.log', message, context=context) - def message_append_note(self, cr, uid, ids, subject=None, subtype_id=False, body=None, parent_id=False, + def message_append_note(self, cr, uid, ids, subject=None, subtype_id='other', body=None, parent_id=False, type='notification', content_subtype='html', context=None): if content_subtype == 'html': body_html = body @@ -875,8 +874,8 @@ class mail_thread(osv.Model): else: body_html = body body_text = body - return self.message_append(cr, uid, ids, subject, body_html, body_text, - type, subtype_id = subtype_id, parent_id = parent_id, + return self.message_append(cr, uid, ids, subject,subtype_id, body_html, body_text, + type, parent_id = parent_id, content_subtype=content_subtype, context=context) #------------------------------------------------------ From 86768264f4e0027d62ac300410a8ef691e95d862 Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Tue, 14 Aug 2012 12:49:19 +0530 Subject: [PATCH 11/16] [IMP] Add constraints in message subtype model bzr revid: fka@tinyerp.com-20120814071919-pk9wkepp7v1geswa --- addons/mail/mail_message_subtype.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/addons/mail/mail_message_subtype.py b/addons/mail/mail_message_subtype.py index 0a167a0f1d9..0c4f5e7baa6 100644 --- a/addons/mail/mail_message_subtype.py +++ b/addons/mail/mail_message_subtype.py @@ -39,3 +39,6 @@ class mail_message_subtype(osv.osv): _defaults = { 'default': True, } + _sql_constraints = [ + ('name_uniq', 'unique (name)', 'The name of the message subtype must be unique !') + ] From 0ae13ed393ed42b1d6d3ef600556d526e7840a9d Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Tue, 14 Aug 2012 17:42:50 +0530 Subject: [PATCH 12/16] [IMP] improve message_create() in mail_thread bzr revid: fka@tinyerp.com-20120814121250-32fb4key3nt9lcaq --- addons/crm/crm_lead.py | 8 +++--- addons/mail/mail_thread.py | 55 ++++++++++++++++++++++---------------- 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index 976eb333ddd..0ec901698df 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -865,7 +865,7 @@ class crm_lead(base_stage, osv.osv): def stage_set_send_note(self, cr, uid, ids, stage_id, context=None): """ Override of the (void) default notification method. """ stage_name = self.pool.get('crm.case.stage').name_get(cr, uid, [stage_id], context=context)[0][1] - return self.message_append_note(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), subtype_id="stage change",context=context) + return self.message_append_note(cr, uid, ids, body= _("Stage changed to %s.") % (stage_name), subtype="stage change",context=context) def case_get_note_msg_prefix(self, cr, uid, lead, context=None): if isinstance(lead, (int, long)): @@ -875,16 +875,16 @@ class crm_lead(base_stage, osv.osv): def create_send_note(self, cr, uid, ids, context=None): for id in ids: message = _("%s has been created.")% (self.case_get_note_msg_prefix(cr, uid, id, context=context)) - self.message_append_note(cr, uid, [id], body=message, subtype_id="new", context=context) + self.message_append_note(cr, uid, [id], body=message, subtype="new", context=context) return True def case_mark_lost_send_note(self, cr, uid, ids, context=None): message = _("Opportunity has been lost.") - return self.message_append_note(cr, uid, ids, body=message,subtype_id="lost", context=context) + return self.message_append_note(cr, uid, ids, body=message,subtype="lost", context=context) def case_mark_won_send_note(self, cr, uid, ids, context=None): message = _("Opportunity has been won.") - return self.message_append_note(cr, uid, ids, body=message, subtype_id="won", context=context) + return self.message_append_note(cr, uid, ids, body=message, subtype="won", context=context) def schedule_phonecall_send_note(self, cr, uid, ids, phonecall_id, action, context=None): phonecall = self.pool.get('crm.phonecall').browse(cr, uid, [phonecall_id], context=context)[0] diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 8d1259ea4ff..4ffdac80116 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -153,29 +153,37 @@ class mail_thread(osv.Model): notification_obj = self.pool.get('mail.notification') body = vals.get('body_html', '') if vals.get('content_subtype') == 'html' else vals.get('body_text', '') + subtype_obj=self.pool.get('mail.message.subtype') + subtype_id=subtype_obj.search(cr, uid, [('name', '=', vals.get('subtype')), ('model_ids', '=', self._name)]) + vals['subtype_id'] = subtype_id[0] + user_subscribe=self.message_is_subscriber(cr, uid, [thread_id], vals['user_id'], context) # automatically subscribe the writer of the message if vals['user_id']: self.message_subscribe(cr, uid, [thread_id], [vals['user_id']], context=context) - # create message - msg_id = message_obj.create(cr, uid, vals, context=context) - - # Set as unread if writer is not the document responsible - self.message_create_set_unread(cr, uid, [thread_id], context=context) - - # special: if install mode, do not push demo data - if context.get('install_mode', False): - return msg_id - - # get users that will get a notification pushed - user_to_push_ids = self.message_get_user_ids_to_notify(cr, uid, [thread_id], vals, context=context) - for id in user_to_push_ids: - notification_obj.create(cr, uid, {'user_id': id, 'message_id': msg_id}, context=context) - - # create the email to send - email_id = self.message_create_notify_by_email(cr, uid, vals, user_to_push_ids, context=context) - - return msg_id + for subtype_obj in subtype_obj.browse(cr,uid,subtype_id,context): + if subtype_obj.default and user_subscribe: + # create message + msg_id = message_obj.create(cr, uid, vals, context=context) + + # Set as unread if writer is not the document responsible + self.message_create_set_unread(cr, uid, [thread_id], context=context) + + # special: if install mode, do not push demo data + if context.get('install_mode', False): + return msg_id + + # get users that will get a notification pushed + user_to_push_ids = self.message_get_user_ids_to_notify(cr, uid, [thread_id], vals, context=context) + for id in user_to_push_ids: + notification_obj.create(cr, uid, {'user_id': id, 'message_id': msg_id}, context=context) + + # create the email to send + email_id = self.message_create_notify_by_email(cr, uid, vals, user_to_push_ids, context=context) + + return msg_id + else: + return False def message_get_user_ids_to_notify(self, cr, uid, thread_ids, new_msg_vals, context=None): subscription_obj = self.pool.get('mail.subscription') @@ -228,7 +236,7 @@ class mail_thread(osv.Model): ret_dict[model_name] = model._description return ret_dict - def message_append(self, cr, uid, threads, subject,subtype_id = "other", body_text=None, body_html=None, + def message_append(self, cr, uid, threads, subject,subtype = "other", body_text=None, body_html=None, type = 'email', email_date = None, parent_id = False, content_subtype='plain', state=None, partner_ids=None, email_from=False, email_to=False, @@ -330,6 +338,7 @@ class mail_thread(osv.Model): data = { 'subject': subject, + 'subtype': subtype, 'body_text': body_text or (hasattr(thread, 'description') and thread.description or ''), 'body_html': body_html or '', 'parent_id': parent_id, @@ -382,7 +391,7 @@ class mail_thread(osv.Model): """ return self.message_append(cr, uid, ids, subject = msg_dict.get('subject'), - subtype_id = msg_dict.get('subtype_id','other'), + subtype = msg_dict.get('subtype','other'), body_text = msg_dict.get('body_text'), body_html= msg_dict.get('body_html'), parent_id = msg_dict.get('parent_id', False), @@ -866,7 +875,7 @@ class mail_thread(osv.Model): now deprecated res.log.") self.message_append_note(cr, uid, [id], 'res.log', message, context=context) - def message_append_note(self, cr, uid, ids, subject=None, subtype_id='other', body=None, parent_id=False, + def message_append_note(self, cr, uid, ids, subject=None, subtype='other', body=None, parent_id=False, type='notification', content_subtype='html', context=None): if content_subtype == 'html': body_html = body @@ -874,7 +883,7 @@ class mail_thread(osv.Model): else: body_html = body body_text = body - return self.message_append(cr, uid, ids, subject,subtype_id, body_html, body_text, + return self.message_append(cr, uid, ids, subject,subtype, body_html, body_text, type, parent_id = parent_id, content_subtype=content_subtype, context=context) From 40768f8fd838635737dc7a376a7282a49620d43e Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Tue, 14 Aug 2012 19:13:14 +0530 Subject: [PATCH 13/16] [IMP] improve mail_thread bzr revid: fka@tinyerp.com-20120814134314-lyen3a13a76db9sv --- addons/mail/mail_thread.py | 74 +++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 04cb5bc6bc6..5b2efb98fcc 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -140,7 +140,7 @@ class mail_thread(osv.Model): # mail.message wrappers and tools #------------------------------------------------------ - def message_create(self, cr, uid, thread_id, vals, context=None): + def message_create(self, cr, uid, thread_id, vals, context = None): """ OpenChatter: wrapper of mail.message create method - creates the mail.message - automatically subscribe the message writer @@ -151,40 +151,40 @@ class mail_thread(osv.Model): message_obj = self.pool.get('mail.message') notification_obj = self.pool.get('mail.notification') + subscription_obj = self.pool.get('mail.subscription') body = vals.get('body_html', '') if vals.get('content_subtype') == 'html' else vals.get('body_text', '') - subtype_obj=self.pool.get('mail.message.subtype') - subtype_id=subtype_obj.search(cr, uid, [('name', '=', vals.get('subtype')), ('model_ids', '=', self._name)]) - if subtype_id: - vals['subtype_id'] = subtype_id[0] - user_subscribe=self.message_is_subscriber(cr, uid, [thread_id], vals['user_id'], context) # automatically subscribe the writer of the message if vals['user_id']: - self.message_subscribe(cr, uid, [thread_id], [vals['user_id']], context=context) + self.message_subscribe(cr, uid, [thread_id], [vals['user_id']], context = context) - for subtype_obj in subtype_obj.browse(cr,uid,subtype_id,context): - if subtype_obj.default and user_subscribe: - # create message - msg_id = message_obj.create(cr, uid, vals, context=context) - - # Set as unread if writer is not the document responsible - self.message_create_set_unread(cr, uid, [thread_id], context=context) - - # special: if install mode, do not push demo data - if context.get('install_mode', False): - return msg_id - - # get users that will get a notification pushed - user_to_push_ids = self.message_get_user_ids_to_notify(cr, uid, [thread_id], vals, context=context) - for id in user_to_push_ids: - notification_obj.create(cr, uid, {'user_id': id, 'message_id': msg_id}, context=context) - - # create the email to send - email_id = self.message_create_notify_by_email(cr, uid, vals, user_to_push_ids, context=context) - - return msg_id - else: - return False + # create message + msg_id = message_obj.create(cr, uid, vals, context = context) + + # Set as unread if writer is not the document responsible + self.message_create_set_unread(cr, uid, [thread_id], context = context) + + # special: if install mode, do not push demo data + if context.get('install_mode', False): + return msg_id + + # get users that will get a notification pushed + user_to_push_ids = self.message_get_user_ids_to_notify(cr, uid, [thread_id], vals, context = context) + subtype_id = vals.get('subtype', False) + subtype_ids = self.pool.get('mail.message.subtype').name_search(cr, uid, subtype_id) + subtype_id = len(subtype_ids) and subtype_ids[0][0] or False + for user_id in user_to_push_ids: + if subtype_id: + #TOCHECK: domain to find subscrition details of subtype + subscription_ids = subscription_obj.search(cr, uid, [('res_model','=',vals['model']),('res_id','=',vals['res_id']),('subtype_ids','in',subtype_id),('user_id','=',user_id)]) + if not subscription_ids: + continue + notification_obj.create(cr, uid, {'user_id': user_id, 'message_id': msg_id}, context = context) + + # create the email to send + email_id = self.message_create_notify_by_email(cr, uid, vals, user_to_push_ids, context = context) + + return msg_id def message_get_user_ids_to_notify(self, cr, uid, thread_ids, new_msg_vals, context=None): subscription_obj = self.pool.get('mail.subscription') @@ -237,13 +237,13 @@ class mail_thread(osv.Model): ret_dict[model_name] = model._description return ret_dict - def message_append(self, cr, uid, threads, subject,subtype = "other", body_text=None, body_html=None, + def message_append(self, cr, uid, threads, subject, body_text=None, body_html=None, type = 'email', email_date = None, parent_id = False, content_subtype='plain', state=None, partner_ids=None, email_from=False, email_to=False, email_cc=None, email_bcc=None, reply_to=None, headers=None, message_id=False, references=None, - attachments=None, original=None, context=None): + attachments=None, original=None, subtype = "other", context=None): """ Creates a new mail.message through message_create. The new message is attached to the current mail.thread, containing all the details passed as parameters. All attachments will be attached to the @@ -392,7 +392,6 @@ class mail_thread(osv.Model): """ return self.message_append(cr, uid, ids, subject = msg_dict.get('subject'), - subtype = msg_dict.get('subtype','other'), body_text = msg_dict.get('body_text'), body_html= msg_dict.get('body_html'), parent_id = msg_dict.get('parent_id', False), @@ -412,6 +411,7 @@ class mail_thread(osv.Model): attachments = msg_dict.get('attachments'), headers = msg_dict.get('headers'), original = msg_dict.get('original'), + subtype = msg_dict.get('subtype','other'), context = context) #------------------------------------------------------ @@ -876,17 +876,17 @@ class mail_thread(osv.Model): now deprecated res.log.") self.message_append_note(cr, uid, [id], 'res.log', message, context=context) - def message_append_note(self, cr, uid, ids, subject=None, subtype='other', body=None, parent_id=False, - type='notification', content_subtype='html', context=None): + def message_append_note(self, cr, uid, ids, subject=None, body=None, parent_id=False, + type='notification', content_subtype='html', subtype='other', context=None): if content_subtype == 'html': body_html = body body_text = body else: body_html = body body_text = body - return self.message_append(cr, uid, ids, subject,subtype, body_html, body_text, + return self.message_append(cr, uid, ids, subject, body_text, body_html, type, parent_id = parent_id, - content_subtype=content_subtype, context=context) + content_subtype=content_subtype, subtype=subtype, context=context) #------------------------------------------------------ # Subscription mechanism From a929752e463204cd1b9c3c214edc25d6d6897d09 Mon Sep 17 00:00:00 2001 From: "Foram Katharotiya (OpenERP)" Date: Thu, 16 Aug 2012 16:33:06 +0530 Subject: [PATCH 14/16] [IMP]remove selectin subtype field & change name of obj bzr revid: fka@tinyerp.com-20120816110306-q0mrqa2tp8128nmv --- addons/crm/crm_lead.py | 6 +++--- addons/mail/mail_message.py | 2 +- addons/mail/mail_thread.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index 2e6a3b5514d..0ecc7d9bee2 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -278,9 +278,9 @@ class crm_lead(base_stage, osv.osv): def create(self, cr, uid, vals, context=None): obj_id = super(crm_lead, self).create(cr, uid, vals, context) - obj = self.browse(cr, uid, obj_id, context) - if obj.user_id: - self.message_subscribe(cr, uid, [obj_id], [obj.user_id.id], context = context) + record = self.browse(cr, uid, obj_id, context) + if record.user_id: + self.message_subscribe(cr, uid, [obj_id], [record.user_id.id], context = context) self.create_send_note(cr, uid, [obj_id], context=context) return obj_id diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index 3d0ea943d3a..a50d091f7ff 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -234,7 +234,7 @@ class mail_message(osv.Model): select=True, ondelete='set null', help="Parent message, used for displaying as threads with hierarchy"), 'child_ids': fields.one2many('mail.message', 'parent_id', 'Child Messages'), - 'subtype_id': fields.many2one('mail.message.subtype', 'Subtype', select = True), + 'subtype_id': fields.many2one('mail.message.subtype', 'Subtype'), } _defaults = { diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 840cfbaaa37..ddace0cf9b9 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -273,7 +273,7 @@ class mail_thread(osv.Model): followers_obj = self.pool.get('mail.followers') subtype_obj = self.pool.get('mail.message.subtype') subtype_name = vals.get('subtype') - sutype = False + subtype = False body = vals.get('body_html', '') if vals.get('content_subtype') == 'html' else vals.get('body_text', '') if subtype_name: subtypes = subtype_obj.name_search(cr, uid, subtype_name) From 1b2f6c7551ffeda6c17c7d9492aae08d85efe6e3 Mon Sep 17 00:00:00 2001 From: "Randhir Mayatra (OpenERP)" Date: Mon, 20 Aug 2012 10:42:22 +0530 Subject: [PATCH 15/16] [IMP]add message_subtype.yml bzr revid: rma@tinyerp.com-20120820051222-9dk4p47uz53j5nzo --- addons/crm/__openerp__.py | 3 +- .../crm/test/process/crm_message_subtype.yml | 54 +++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 addons/crm/test/process/crm_message_subtype.yml diff --git a/addons/crm/__openerp__.py b/addons/crm/__openerp__.py index 643908c1098..f0f181c47da 100644 --- a/addons/crm/__openerp__.py +++ b/addons/crm/__openerp__.py @@ -129,7 +129,8 @@ Creates a dashboard for CRM that includes: 'test/process/segmentation.yml', 'test/ui/crm_demo.yml', 'test/ui/duplicate_lead.yml', - 'test/ui/delete_lead.yml' + 'test/ui/delete_lead.yml', + 'test/process/crm_message_subtype.yml', ], 'installable': True, 'application': True, diff --git a/addons/crm/test/process/crm_message_subtype.yml b/addons/crm/test/process/crm_message_subtype.yml new file mode 100644 index 00000000000..a83c729ecd4 --- /dev/null +++ b/addons/crm/test/process/crm_message_subtype.yml @@ -0,0 +1,54 @@ +- + I have add the sub_type name other with default false +- + !record {model: mail.message.subtype, id: mail_subtype_lead_won }: + name: won + model_ids: + - crm.model_crm_lead + default: False +- + I have add the sub_type name email with default true +- + !record {model: mail.message.subtype, id: mail_subtype_lead_email }: + name: email + model_ids: + - crm.model_crm_lead + default: True +- + I have add the sub_type name comment with default true +- + !record {model: mail.message.subtype, id: mail_subtype_lead_comment }: + name: comment + model_ids: + - crm.model_crm_lead + default: True + +- + I have search and write its subtype in followers +- + !python {model: mail.followers}: | + ids = self.search(cr, uid, [('res_model', '=', 'crm.lead'),('res_id', '=', ref('crm_case_1'))]) + self.write(cr, uid, ids, {'subtype_ids': [(6,0,[ref('mail_subtype_lead_won')])]}) +- + I have change the lead into mark won +- + !python {model: crm.lead}: | + self.convert_opportunity(cr, uid ,[ref("crm_case_1")], ref("base.res_partner_4")) + self.case_mark_won(cr, uid,[ref("crm_case_1")] ) +- + I have check the lead into mark won +- + !assert {model: crm.lead, id: crm_case_1 ,string: 'The record is not in won state'}: + - state == 'done' +- + I have check to if subtype is won then display notification. +- + !python {model: mail.message}: | + ids = self.search(cr, uid, [('model', '=','crm.lead'),('res_id', '=', ref('crm_case_1'))]) + browse = self.browse(cr,uid,ids) + + assert ids, 'lead is in won' + + + + From aef5236ba71e9150b56c6b74f4518d7362e6010b Mon Sep 17 00:00:00 2001 From: "Randhir Mayatra (OpenERP)" Date: Mon, 20 Aug 2012 12:48:10 +0530 Subject: [PATCH 16/16] [FIX]make changes into crm_message_subtype.yml file bzr revid: rma@tinyerp.com-20120820071810-fn1wdg36syq1epd5 --- .../crm/test/process/crm_message_subtype.yml | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/addons/crm/test/process/crm_message_subtype.yml b/addons/crm/test/process/crm_message_subtype.yml index a83c729ecd4..705d3cc2fc4 100644 --- a/addons/crm/test/process/crm_message_subtype.yml +++ b/addons/crm/test/process/crm_message_subtype.yml @@ -22,9 +22,8 @@ model_ids: - crm.model_crm_lead default: True - - - I have search and write its subtype in followers + I have add the subtypes as won in feeds - !python {model: mail.followers}: | ids = self.search(cr, uid, [('res_model', '=', 'crm.lead'),('res_id', '=', ref('crm_case_1'))]) @@ -41,14 +40,9 @@ !assert {model: crm.lead, id: crm_case_1 ,string: 'The record is not in won state'}: - state == 'done' - - I have check to if subtype is won then display notification. + I have check the subtype as won in feeds - - !python {model: mail.message}: | - ids = self.search(cr, uid, [('model', '=','crm.lead'),('res_id', '=', ref('crm_case_1'))]) - browse = self.browse(cr,uid,ids) - - assert ids, 'lead is in won' - - - - + !python {model: mail.followers}: | + followers_ids =self.search(cr, uid, [('res_model', '=','crm.lead'),('res_id', '=', ref('crm_case_1')),('subtype_ids', 'in',[ref('mail_subtype_lead_won')])]) + if len(followers_ids): + assert followers_ids, 'lead is in won'