From 47214c9d2d3d1b236e9a8ccba95dd4dbccab8445 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 13 Mar 2012 14:59:49 +0100 Subject: [PATCH 01/11] [IMP] mail.message: cleaned code bzr revid: tde@openerp.com-20120313135949-l4wmzcg1kpqidzgh --- addons/mail/mail_message.py | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index 58926079575..bd32da93374 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -2,7 +2,7 @@ ############################################################################## # # OpenERP, Open Source Management Solution -# Copyright (C) 2010-2011 OpenERP SA () +# Copyright (C) 2010-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 @@ -72,10 +72,10 @@ class mail_message_common(osv.osv_memory): _rec_name = 'subject' _columns = { 'subject': fields.char('Subject', size=512, required=True), - 'model': fields.char('Related Document model', size=128, select=1), # was readonly - 'res_id': fields.integer('Related Document ID', select=1), # was readonly + 'model': fields.char('Related Document model', size=128, select=1), + 'res_id': fields.integer('Related Document ID', select=1), 'date': fields.datetime('Date'), - 'email_from': fields.char('From', size=128, help='Message sender, taken from user preferences. If empty, this is not a mail but a message.'), + 'email_from': fields.char('From', size=128, help='Message sender, taken from user preferences.'), 'email_to': fields.char('To', size=256, help='Message recipients'), 'email_cc': fields.char('Cc', size=256, help='Carbon copy message recipients'), 'email_bcc': fields.char('Bcc', size=256, help='Blind carbon copy message recipients'), @@ -89,16 +89,19 @@ class mail_message_common(osv.osv_memory): "select plaintext or rich text contents accordingly", readonly=1), 'body_text': fields.text('Text contents', help="Plain-text version of the message"), 'body_html': fields.text('Rich-text contents', help="Rich-text/HTML version of the message"), + 'parent_id': fields.many2one('mail.message', 'Parent message', help="Parent message, used for displaying as threads with hierarchy"), } _defaults = { 'subtype': 'plain', - 'date': (lambda *a: datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')), + 'date': (lambda *a: fields.datetime.now()), } class mail_message(osv.osv): - '''Model holding RFC2822 email messages, and providing facilities - to parse, queue and send new messages + '''Model holding messages: system notification (replacing res.log + notifications), comments (for OpenSocial feature) and + RFC2822 email messages. This model also provides facilities to + parse, queue and send new email messages. Messages that do not have a value for the email_from column are simple log messages (e.g. document state changes), while @@ -178,31 +181,18 @@ class mail_message(osv.osv): ], 'State', readonly=True), 'auto_delete': fields.boolean('Auto Delete', help="Permanently delete this email after sending it, to save space"), 'original': fields.binary('Original', help="Original version of the message, as it was sent on the network", readonly=1), - # note feature: add type (email, comment, notification) and need_action 'type': fields.selection([ ('email', 'e-mail'), ('comment', 'Comment'), ('notification', 'System notification'), ], 'Type', help="Message type: e-mail for e-mail message, notification for system message, comment for other messages such as user replies"), - 'parent_id': fields.many2one('mail.message', 'Parent message', help="Parent message if message belongs to a thread"), + } _defaults = { 'state': 'received', 'type': 'comment', } - - #------------------------------------------------------ - # Generic api - #------------------------------------------------------ - - def create(self, cr, uid, vals, context=None): - # temporary log directly created messages (to debug OpenSocial) - if not 'mail.thread' in context: - _logger.warning('Creating message without using mail.thread API') - _logger.warning('Message details: %s', str(vals)) - msg_id = super(mail_message, self).create(cr, uid, vals, context) - return msg_id #------------------------------------------------------ # E-Mail api From ac644cfd4f6f12e9b9b7d2a3570f54cb2ad83bb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 13 Mar 2012 16:06:35 +0100 Subject: [PATCH 02/11] [IMP] mail.thread: cleaned code; added unlink management (subscriptions and messages are deleted, notifications are automatically deleted when messages are deleted because of foreign key); improved code and comments bzr revid: tde@openerp.com-20120313150635-wwbvs30s0w7ru8qk --- addons/mail/mail_thread.py | 119 +++++++++++++++++++------------------ 1 file changed, 62 insertions(+), 57 deletions(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 6ea9d806c7b..80091b5a4cb 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -2,7 +2,7 @@ ############################################################################## # # OpenERP, Open Source Management Solution -# Copyright (C) 2009-Today OpenERP SA () +# 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 @@ -41,16 +41,23 @@ class mail_thread(osv.osv): name collisions with methods of the models that will inherit from this mixin. - ``mail.thread`` adds a one2many of mail.messages, acting as the - thread's history, and a few methods that may be overridden to - implement model-specific behavior upon arrival of new messages. + ``mail.thread`` is designed to work without adding any field + to the extended models. All functionalities and expected behavior + are managed by mail.thread, using model name and record ids. + A widget has been designed for the 6.1 and following version of OpenERP + web-client. However, due to technical limitations, ``mail.thread`` + adds a simulated one2many field, to display the web widget by + overriding the default field displayed. Using this field + is not recommanded has it will disappeear in future version + of OpenERP, leading to a pure mixin class. Inheriting classes are not required to implement any method, as the default implementation will work for any model. However it is common to override at least the ``message_new`` and ``message_update`` methods (calling ``super``) to add model-specific behavior at - creation and update of a thread. - + creation and update of a thread; and ``message_get_subscribers`` + to manage more precisely the social aspect of the thread through + the followers. ''' _name = 'mail.thread' _description = 'Email Thread' @@ -63,12 +70,10 @@ class mail_thread(osv.osv): res[thread.id] = [obj['id'] for obj in records] return res - # OpenSocial: removed message_ids and copy method, this will be replaced by message_load + # OpenSocial: message_ids_social is a dummy field that should not be used _columns = { 'message_ids_social': fields.function(_get_message_ids, method=True, - type='one2many', obj='mail.message', string='Temp messages', - ), - #widget='mail.ThreadView'), + type='one2many', obj='mail.message', string='Temp messages'), } #------------------------------------------------------ @@ -86,6 +91,28 @@ class mail_thread(osv.osv): self.message_subscribe(cr, uid, ids, [uid], context=context) return write_res; + def unlink(self, cr, uid, ids, context=None): + """Override unlink, to automatically delete + - subscriptions + - messages + that are linked with res_model and res_id, not through + 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') + + 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) + + 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) + + super(mail_thread, self).unlink(cr, uid, ids, context=context) + #------------------------------------------------------ # Generic message api #------------------------------------------------------ @@ -98,34 +125,30 @@ class mail_thread(osv.osv): if context is None: context = {} + need_action_pushed = False + user_to_push_ids = [] subscription_obj = self.pool.get('mail.subscription') notification_obj = self.pool.get('mail.notification') - need_action_pushed = False - # create message msg_id = self.pool.get('mail.message').create(cr, uid, vals, context=context) - obj = self.browse(cr, uid, [thread_id], context=context)[0] + thread_obj = self.browse(cr, uid, [thread_id], context=context)[0] # automatically subscribe the writer of the message if not subscribed - if vals['user_id']: - if not self.message_is_subscriber(cr, uid, [thread_id], context=context): - self.message_subscribe(cr, uid, [thread_id], context=context) + if vals['user_id'] and not self.message_is_subscriber(cr, vals['user_id'], [thread_id], context=context): + self.message_subscribe(cr, uid, [thread_id], [vals['user_id']], context=context) # push the message to suscribed users users = self.message_get_subscribers(cr, uid, [thread_id], context=context) - for user in users: - notification_obj.create(cr, uid, {'user_id': user['id'], 'message_id': msg_id}, context=context) - # push to need_action_user_id - if obj.need_action_user_id == user['id']: need_action_pushed = True - # push to need_action_user_id if user does not follow the object - if obj.need_action_user_id and not need_action_pushed: - notification_obj.create(cr, uid, {'user_id': obj.need_action_user_id.id, 'message_id': msg_id}, context=context) - + user_to_push_ids += [user['id'] for user in users] # parse message to get requested users - user_ids = self.message_parse_users(cr, uid, [msg_id], vals['body_text'], context=context) - for user_id in user_ids: - notification_obj.create(cr, uid, {'user_id': user_id, 'message_id': msg_id}, context=context) + user_to_push_ids += self.message_parse_users(cr, uid, [msg_id], vals['body_text'], context=context) + # push to need_action_user_id if set + if thread_obj.need_action_user_id and thread_obj.need_action_user_id.id not in user_to_push_ids: + user_to_push_ids.append(thread_obj.need_action_user_id.id) + + # effectively subscribe users + self.message_subscribe(cr, uid, [thread_id], user_to_push_ids, context=context) return msg_id @@ -261,8 +284,6 @@ class mail_thread(osv.osv): 'reply_to': reply_to, 'original': original, } - #mail_message.create(cr, uid, data, context=context) - context['mail.thread'] = True self.message_create(cr, uid, thread.id, data, context=context) return True @@ -282,7 +303,7 @@ class mail_thread(osv.osv): to determine the model of the thread to update (instead of the current model). """ - # 6.2 OpenSocial feature: add default email type for old API + # OpenSocial: add default email type for old API if not 'type' in msg_dict: msg_dict['type'] = 'email' return self.message_append(cr, uid, ids, subject = msg_dict.get('subject'), @@ -307,7 +328,8 @@ class mail_thread(osv.osv): # Message loading def _message_get_parent_ids(self, cr, uid, ids, child_ids, root_ids, context=None): - if context is None: context = {} + if context is None: + context = {} msg_obj = self.pool.get('mail.message') msgs_tmp = msg_obj.read(cr, uid, child_ids, context=context) parent_ids = [msg['parent_id'][0] for msg in msgs_tmp if msg['parent_id'] not in root_ids and msg['parent_id'][0] not in child_ids] @@ -325,7 +347,8 @@ class mail_thread(osv.osv): loading messages: search in mail.messages where res_id = ids, (res_)model = current model see get_pushed_messages for parameters explanation """ - if context is None: context = {} + if context is None: + context = {} msg_obj = self.pool.get('mail.message') msg_ids = msg_obj.search(cr, uid, ['&', ('res_id', 'in', ids), ('model', '=', self._name)] + domain, limit=limit, offset=offset, context=context) @@ -365,17 +388,13 @@ class mail_thread(osv.osv): # Message tools def message_get_discussions_nbr(self, cr, uid, ids, context=None): - count = 0 message_obj = self.pool.get('mail.message') - for id in ids: - count += message_obj.search(cr, uid, [('model', '=', self._name), ('res_id', '=', id)], count=True) # TODO: add parent_id when merging branch + count = message_obj.search(cr, uid, [('model', '=', self._name), ('res_id', '=', ids), ('parent_id', '=', False)], count=True) return count def message_get_messages_nbr(self, cr, uid, ids, context=None): - count = 0 message_obj = self.pool.get('mail.message') - for id in ids: - count += message_obj.search(cr, uid, [('model', '=', self._name), ('res_id', '=', id)], count=True) + count = message_obj.search(cr, uid, [('model', '=', self._name), ('res_id', 'in', ids)], count=True) return count #------------------------------------------------------ @@ -627,33 +646,19 @@ class mail_thread(osv.osv): def message_append_note(self, cr, uid, ids, subject, body, parent_id=False, type='notification', context=None): return self.message_append(cr, uid, ids, subject, body_text=body, parent_id=parent_id, type=type, context=context) - - # old log overrided method: now calls message_append_note - def log(self, cr, uid, id, message, secondary=False, context=None): - """ OpenSocial add: new res_log implementation - A res.log is now a mail.message, as all messages in OpenERP - It has a notification type. - It can have a need_action flag attached if an user - has to perform a given action. - See mail.message, mail.subscription and mail.notification for more details. - """ - if context and context.get('disable_log'): - #return True # old behavior - print 'Log diabled, but we do not care currently about that. We want you to have our logs !' - #return self.message_append_note(cr, uid, [id], 'System notification', message, context=context) #------------------------------------------------------ # Subscription mechanism #------------------------------------------------------ - def _message_get_subscribers_ids(self, cr, uid, ids, context=None): - subscription_obj = self.pool.get('mail.subscription') - sub_ids = subscription_obj.search(cr, uid, ['&', ('res_model', '=', self._name), ('res_id', 'in', ids)], context=context) - subs = subscription_obj.read(cr, uid, sub_ids, context=context) + def message_get_subscribers_ids(self, cr, uid, ids, context=None): + subscr_obj = self.pool.get('mail.subscription') + subscr_ids = subscr_obj.search(cr, uid, ['&', ('res_model', '=', self._name), ('res_id', 'in', ids)], context=context) + subs = subscr_obj.read(cr, uid, subscr_ids, context=context) return [sub['user_id'][0] for sub in subs] def message_get_subscribers(self, cr, uid, ids, context=None): - user_ids = self._message_get_subscribers_ids(cr, uid, ids, context=context) + user_ids = self.message_get_subscribers_ids(cr, uid, ids, context=context) users = self.pool.get('res.users').read(cr, uid, user_ids, fields=['id', 'name', 'avatar_mini'], context=context) return users From 0bc2d60303842dd204174228e310a83249f5ff35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 13 Mar 2012 16:24:15 +0100 Subject: [PATCH 03/11] [FIX] mail.message: views: fixed priorities (was sequence) bzr revid: tde@openerp.com-20120313152415-qi5jznlvx5mibami --- addons/mail/mail_message_view.xml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/addons/mail/mail_message_view.xml b/addons/mail/mail_message_view.xml index dad4946268a..e58c2d1c818 100644 --- a/addons/mail/mail_message_view.xml +++ b/addons/mail/mail_message_view.xml @@ -6,7 +6,7 @@ mail.message.tree.short mail.message tree - 15 + 20 @@ -23,7 +23,7 @@ mail.message.form.short mail.message form - 15 + 20
@@ -47,6 +47,7 @@ mail.message.search.short mail.message search + 20 @@ -210,7 +211,7 @@ action="action_view_mail_message" /> - (w)All Feeds + All Feeds mail.all_feeds @@ -218,7 +219,7 @@ My Feeds mail.all_feeds - + From a6fbb12aaf427362582481d763fe4e0dbaffb327 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 13 Mar 2012 16:24:52 +0100 Subject: [PATCH 04/11] [IMP] mail.subscrpition: cleaned code and views bzr revid: tde@openerp.com-20120313152452-8fmd3swgaiml9d1l --- addons/mail/mail_subscription.py | 21 ++++++++------------- addons/mail/mail_subscription_view.xml | 4 ++-- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/addons/mail/mail_subscription.py b/addons/mail/mail_subscription.py index eaf53bc1c17..aa5662190f6 100644 --- a/addons/mail/mail_subscription.py +++ b/addons/mail/mail_subscription.py @@ -2,7 +2,7 @@ ############################################################################## # # OpenERP, Open Source Management Solution -# Copyright (C) 2010-2011 OpenERP SA () +# 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 @@ -19,49 +19,44 @@ # ############################################################################## -import tools from osv import osv from osv import fields -from tools.translate import _ class mail_subscription(osv.osv): """ mail_subscription holds the data related to the follow mechanism inside OpenERP. - A subscription can be of following: + A subscription is characterized by: - res_model: model of the followed objects - - res_id: ID of resource OR - - res_domain: a domain filtering followed objects - currently removed + - res_id: ID of resource (may be 0 for every objects) """ _name = 'mail.subscription' _rec_name = 'id' + _order = 'res_model asc' _columns = { 'res_model': fields.char('Related Document Model', size=128, select=1, required=True), 'res_id': fields.integer('Related Document ID', select=1), - #'res_domain': fields.char('res_domain', size=256), 'user_id': fields.many2one('res.users', string='Related User ID', ondelete='cascade', required=True, select=1), } - _defaults = { - } -mail_subscription() class mail_notification(osv.osv): """ - TODO + mail_notification is a relational table modeling messages pushed to users. + - read: todo """ _name = 'mail.notification' _rec_name = 'id' _log_access = False + _order = 'message_id desc' _columns = { 'user_id': fields.many2one('res.users', string='User', ondelete='cascade', required=True, select=1), 'message_id': fields.many2one('mail.message', string='Message', - ondelete='cascade', required=True), + ondelete='cascade', required=True, select=1), 'read': fields.boolean('Read'), # TODO: add a timestamp ? or use message date ? } _defaults = { 'read': False, } -mail_notification() diff --git a/addons/mail/mail_subscription_view.xml b/addons/mail/mail_subscription_view.xml index 56ffad1bcfc..4fde0938ad4 100644 --- a/addons/mail/mail_subscription_view.xml +++ b/addons/mail/mail_subscription_view.xml @@ -13,9 +13,9 @@ 10 - + @@ -53,4 +53,4 @@ - \ No newline at end of file + From 979e5d07149bc2072e9778d1535f727a8aed7a58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 13 Mar 2012 16:25:23 +0100 Subject: [PATCH 05/11] [IMP] mail.thread views: cleaned code bzr revid: tde@openerp.com-20120313152523-kjxvn5xgbv4f65em --- addons/mail/mail_thread_view.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/addons/mail/mail_thread_view.xml b/addons/mail/mail_thread_view.xml index e6bc4c672aa..def47fc73da 100644 --- a/addons/mail/mail_thread_view.xml +++ b/addons/mail/mail_thread_view.xml @@ -10,16 +10,16 @@ - - My Feeds + + All Feeds - + - - (w)All Feeds - - + + My Feeds + + From e2fe93c646d520acd9e23cf250618398dec45128 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 13 Mar 2012 17:01:39 +0100 Subject: [PATCH 06/11] [FIX] hr_holidays: fixed function name change bzr revid: tde@openerp.com-20120313160139-28cei2grildmbo9y --- addons/hr_holidays/hr_holidays.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/hr_holidays/hr_holidays.py b/addons/hr_holidays/hr_holidays.py index b9453ae908f..8d34509dd02 100644 --- a/addons/hr_holidays/hr_holidays.py +++ b/addons/hr_holidays/hr_holidays.py @@ -367,7 +367,7 @@ class hr_holidays(osv.osv): return result def message_get_subscribers(self, cr, uid, ids, context=None): - sub_ids = self._message_get_subscribers_ids(cr, uid, ids, context=context); + sub_ids = self.message_get_subscribers_ids(cr, uid, ids, context=context); # add the employee and its manager if specified to the subscribed users for obj in self.browse(cr, uid, ids, context=context): if obj.employee_id.parent_id: From 69904e2036bcb30730f19ae871841a5e08004f26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 13 Mar 2012 17:19:02 +0100 Subject: [PATCH 07/11] [IMP] mail.group: cleaned code; added user as default responsible when creating a group. bzr revid: tde@openerp.com-20120313161902-dwxzjy68bcuj39kk --- addons/mail/mail_group.py | 44 +++++++++++++++++++-------------- addons/mail/mail_group_view.xml | 2 +- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/addons/mail/mail_group.py b/addons/mail/mail_group.py index 649701ff702..a213a6249d9 100644 --- a/addons/mail/mail_group.py +++ b/addons/mail/mail_group.py @@ -2,7 +2,7 @@ ############################################################################## # # OpenERP, Open Source Management Solution -# Copyright (C) 2010-2011 OpenERP SA () +# Copyright (C) 2010-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 @@ -29,9 +29,9 @@ from PIL import Image class mail_group(osv.osv): """ - A mail_group is a collection of users sharing messages in a discussion group. - Mail groups are different from user groups because they don't have a specific field holding users. - Group users are users that follow the mail group, using the subscription/follow mechanism of OpenChatter. + A mail_group is a collection of users sharing messages in a discussion + group. Group users are users that follow the mail group, using the + subscription/follow mechanism of OpenSocial. """ _name = 'mail.group' @@ -42,26 +42,31 @@ class mail_group(osv.osv): def action_group_leave(self, cr, uid, ids, context={}): return self.message_unsubscribe(cr, uid, ids, context=context); - - def _get_photo_mini(self, cr, uid, ids, name, args, context=None): - result = {} - for obj in self.browse(cr, uid, ids, context=context): - if not obj.photo: - result[obj.id] = False - continue - image_stream = io.BytesIO(obj.photo.decode('base64')) - img = Image.open(image_stream) - img.thumbnail((120, 100), Image.ANTIALIAS) - img_stream = StringIO.StringIO() - img.save(img_stream, "JPEG") - result[obj.id] = img_stream.getvalue().encode('base64') - return result + def onchange_photo_mini(self, cr, uid, ids, value, context=None): + return {'value': {'photo': value, 'photo_mini': self._photo_resize(cr, uid, value) } } def _set_photo_mini(self, cr, uid, id, name, value, args, context=None): self.write(cr, uid, [id], {'photo': value}, context=context) return True + def _photo_resize(self, cr, uid, photo, context=None): + image_stream = io.BytesIO(photo.decode('base64')) + img = Image.open(image_stream) + img.thumbnail((120, 100), Image.ANTIALIAS) + img_stream = StringIO.StringIO() + img.save(img_stream, "JPEG") + return img_stream.getvalue().encode('base64') + + def _get_photo_mini(self, cr, uid, ids, name, args, context=None): + result = {} + for group in self.browse(cr, uid, ids, context=context): + if not group.photo: + result[group.id] = False + else: + result[group.id] = self._photo_resize(cr, uid, group.photo, context=context) + return result + def is_subscriber(self, cr, uid, ids, name, args, context=None): result = {} for id in ids: @@ -83,7 +88,7 @@ class mail_group(osv.osv): def get_members_nbr(self, cr, uid, ids, name, args, context=None): result = {} for id in ids: - result[id] = len(self._message_get_subscribers_ids(cr, uid, [id], context=context)) + result[id] = len(self.message_get_subscribers_ids(cr, uid, [id], context=context)) return result _columns = { @@ -105,6 +110,7 @@ class mail_group(osv.osv): _defaults = { 'public': True, + 'responsible_id': (lambda s, cr, uid, ctx: uid), } mail_group() diff --git a/addons/mail/mail_group_view.xml b/addons/mail/mail_group_view.xml index ce6c3b9eeef..59efecc97cf 100644 --- a/addons/mail/mail_group_view.xml +++ b/addons/mail/mail_group_view.xml @@ -60,7 +60,7 @@ - + From 516ba422a496ff0406ab9d7b9c6c51c738b13141 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 13 Mar 2012 17:35:55 +0100 Subject: [PATCH 08/11] [FIX] Fixed bug in notification push bzr revid: tde@openerp.com-20120313163555-7ya3uejtnq2vtshf --- addons/mail/mail_thread.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 80091b5a4cb..a999c6df111 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -147,8 +147,9 @@ class mail_thread(osv.osv): if thread_obj.need_action_user_id and thread_obj.need_action_user_id.id not in user_to_push_ids: user_to_push_ids.append(thread_obj.need_action_user_id.id) - # effectively subscribe users - self.message_subscribe(cr, uid, [thread_id], user_to_push_ids, context=context) + # effectively push message to users + for id in user_to_push_ids: + notification_obj.create(cr, uid, {'user_id': id, 'message_id': msg_id}, context=context) return msg_id From 5dbd526a19572a3858779d5ddebe7298dc2e85ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 13 Mar 2012 18:06:48 +0100 Subject: [PATCH 09/11] [IMP] Thread widget: reply textarea shown by default when viewing a record. bzr revid: tde@openerp.com-20120313170648-5uln1ozxvhv8yfxx --- addons/mail/static/src/js/mail.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 57c01a77b8c..acd61eb7e69 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -54,7 +54,7 @@ openerp.mail = function(session) { this.sorted_comments = {'root_ids': [], 'root_id_msg_list': {}}; /* Display vars */ this.display = {}; - this.display.show_post_comment = false; + this.display.show_post_comment = this.params.show_post_comment || false; this.display.show_reply = (this.params.thread_level > 0); this.display.show_delete = true; this.display.show_hide = true; @@ -406,7 +406,7 @@ openerp.mail = function(session) { /* create ThreadDisplay widget and render it */ this.$element.find('div.oe_mail_recthread_left').empty(); if (this.thread) this.thread.stop(); - this.thread = new mail.Thread(this, {'res_model': this.view.model, 'res_id': this.view.datarecord.id, 'uid': this.session.uid}); + this.thread = new mail.Thread(this, {'res_model': this.view.model, 'res_id': this.view.datarecord.id, 'uid': this.session.uid, 'show_post_comment': true}); this.thread.appendTo(this.$element.find('div.oe_mail_recthread_left')); return fetch_fol_done && fetch_sub_done; }, From 09a01870ffa7dc4d102d4c60850d7374c8f60b1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 13 Mar 2012 18:22:33 +0100 Subject: [PATCH 10/11] [IMP] Thread widget: cleaned follow/unfollow buttons behavior (text change when mouseover/mouseleave, update followers display) bzr revid: tde@openerp.com-20120313172233-3zgm41f7m7mxzmie --- addons/mail/static/src/js/mail.js | 17 ++++++++--------- addons/mail/static/src/xml/mail.xml | 4 ++-- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index acd61eb7e69..9d117565715 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -377,9 +377,11 @@ openerp.mail = function(session) { var self = this; this._super.apply(this, arguments); /* bind and hide buttons */ - self.$element.find('button.oe_mail_button_followers').bind('click', function () { self.do_toggle_followers(); }); - self.$element.find('button.oe_mail_button_follow').bind('click', function () { self.do_follow(); }).hide(); - self.$element.find('button.oe_mail_button_unfollow').bind('click', function () { self.do_unfollow(); }).hide(); + self.$element.find('button.oe_mail_button_followers').bind('click', function () { self.do_toggle_followers(); }).hide(); + self.$element.find('button.oe_mail_button_follow').click(function () { self.do_follow(); }).hide() + .mouseover(function () { $(this).html('Follow'); }).mouseleave(function () { $(this).html('Not following'); }); + self.$element.find('button.oe_mail_button_unfollow').click(function () { self.do_unfollow(); }).hide() + .mouseover(function () { $(this).html('Unfollow'); }).mouseleave(function () { $(this).html('Following'); }); }, stop: function () { @@ -387,7 +389,6 @@ openerp.mail = function(session) { }, set_value: function() { - console.log('set_value'); var self = this; this._super.apply(this, arguments); this.see_sub = 1; @@ -428,12 +429,12 @@ openerp.mail = function(session) { do_follow: function () { this.do_toggle_follow(); - return this.ds.call('message_subscribe', [[this.view.datarecord.id]]).when(); + return this.ds.call('message_subscribe', [[this.view.datarecord.id]]).then(this.proxy('fetch_subscribers')); }, do_unfollow: function () { this.do_toggle_follow(); - return this.ds.call('message_unsubscribe', [[this.view.datarecord.id]]).when(); + return this.ds.call('message_unsubscribe', [[this.view.datarecord.id]]).then(this.proxy('fetch_subscribers')); }, do_toggle_follow: function () { @@ -450,9 +451,7 @@ openerp.mail = function(session) { }, thread_get_avatar_mini: function(model, field, id) { - id = id || ''; - var url = this.session.prefix + '/web/binary/image?session_id=' + this.session.session_id + '&model=' + model + '&field=' + field + '&id=' + id; - return url; + return this.session.prefix + '/web/binary/image?session_id=' + this.session.session_id + '&model=' + model + '&field=' + field + '&id=' + (id || ''); }, }); diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index 724241e70b3..c2eef5499f7 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -31,8 +31,8 @@
- - + +
From c1e13fdff20f7946b584505f9e1041c6e2c154a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 13 Mar 2012 18:41:05 +0100 Subject: [PATCH 11/11] [IMP] Threzad widget: added unlink mechanism. Still WIP tough. bzr revid: tde@openerp.com-20120313174105-ffncns931oa0ry4o --- addons/mail/mail_thread.py | 2 +- addons/mail/static/src/js/mail.js | 26 ++++++++++++++++++++++---- addons/mail/static/src/xml/mail.xml | 4 ++-- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index a999c6df111..93785c81b9a 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -647,7 +647,7 @@ class mail_thread(osv.osv): def message_append_note(self, cr, uid, ids, subject, body, parent_id=False, type='notification', context=None): return self.message_append(cr, uid, ids, subject, body_text=body, parent_id=parent_id, type=type, context=context) - + #------------------------------------------------------ # Subscription mechanism #------------------------------------------------------ diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 9d117565715..cffce1b5f0a 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -50,6 +50,7 @@ openerp.mail = function(session) { /* DataSets and internal vars */ this.ds = new session.web.DataSet(this, this.params.res_model); this.ds_users = new session.web.DataSet(this, 'res.users'); + this.ds_msg = new session.web.DataSet(this, 'mail.message'); this.name = 'Unknown record' this.sorted_comments = {'root_ids': [], 'root_id_msg_list': {}}; /* Display vars */ @@ -76,10 +77,10 @@ openerp.mail = function(session) { if (event.shiftKey && charCode == 13) { this.value = this.value+"\n"; } else if (charCode == 13) { self.do_comment(); } }); - this.$element.find('div.oe_mail_thread_display').delegate('a.oe_mail_msg_reply', 'click', function (event) { - var act_dom = $(this).parents('div.oe_mail_thread_display').find('div.oe_mail_thread_act:first'); - act_dom.toggle(); - }); + + // add event + this.add_events(); + this.$element.find('div.oe_mail_thread_display').delegate('a.intlink', 'click', function (event) { // lazy implementation: fetch data and try to redirect if (! event.srcElement.dataset.resModel) return false; @@ -109,6 +110,23 @@ openerp.mail = function(session) { return display_done }, + add_events: function() { + var self = this; + // event: click on 'reply' + this.$element.find('div.oe_mail_thread_display').delegate('a.oe_mail_msg_reply', 'click', function (event) { + var act_dom = $(this).parents('div.oe_mail_thread_display').find('div.oe_mail_thread_act:first'); + act_dom.toggle(); + }); + // event: click on 'delete' + this.$element.find('div.oe_mail_thread_display').delegate('a.oe_mail_msg_delete', 'click', function (event) { + console.log('deleting'); + var msg_id = event.srcElement.dataset.id; + if (! msg_id) return false; + self.ds_msg.unlink([parseInt(msg_id)]).then(); + return false; + }); + }, + stop: function () { //this._super.apply(this, arguments); }, diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index c2eef5499f7..c9ab259ddf8 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -77,8 +77,8 @@ on Reply - Delete - Hide + Delete + Hide