From ecde0aa380867bfcdd8636d757681a15a4279a36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 14 Feb 2013 09:55:06 +0100 Subject: [PATCH 01/46] [IMP] Chatter: now displays the 'To' that is the notified people of a given message. bzr revid: tde@openerp.com-20130214085506-5akyw06ho9vq1xd9 --- addons/mail/mail_message.py | 6 +++--- addons/mail/static/src/js/mail.js | 8 ++++++++ addons/mail/static/src/xml/mail.xml | 17 ++++++++++++++++- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index 77573f0d2f8..91d46098b4b 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -301,8 +301,8 @@ class mail_message(osv.Model): for key, message in message_tree.iteritems(): if message.author_id: partner_ids |= set([message.author_id.id]) - if message.partner_ids: - partner_ids |= set([partner.id for partner in message.partner_ids]) + if message.notified_partner_ids: + partner_ids |= set([partner.id for partner in message.notified_partner_ids]) if message.attachment_ids: attachment_ids |= set([attachment.id for attachment in message.attachment_ids]) # Read partners as SUPERUSER -> display the names like classic m2o even if no access @@ -322,7 +322,7 @@ class mail_message(osv.Model): else: author = (0, message.email_from) partner_ids = [] - for partner in message.partner_ids: + for partner in message.notified_partner_ids: if partner.id in partner_tree: partner_ids.append(partner_tree[partner.id]) attachment_ids = [] diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 0872d049162..2c5b8d77dd1 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -262,6 +262,14 @@ openerp.mail = function (session) { this.author_id.push(_.str.escapeHTML(email[0]), _.str.trim(email[1]), email[2]); } } + if (this.partner_ids && this.partner_ids.length > 3) { + this.extra_partners_nbr = this.partner_ids.length - 3; + this.extra_partners_str = '' + var extra_partners = this.partner_ids.slice(3); + for (var key in extra_partners) { + this.extra_partners_str += extra_partners[key][1]; + } + } }, diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index 4693adeb1ee..574d65a6458 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -243,7 +243,22 @@
- + From: + • + To: + + Nobody + + + + + + + , + + + and more + • From 4bcd2325dd35fd96d230aae21d08b0cbc7717843 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 14 Feb 2013 10:39:23 +0100 Subject: [PATCH 02/46] [IMP] Chatter: File -> Attach a file. bzr revid: tde@openerp.com-20130214093923-64459u87eda0yr47 --- addons/mail/static/src/xml/mail.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index 574d65a6458..738a9d5d0e7 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -57,7 +57,7 @@ - File + Attach a File /web/binary/upload_attachment From f33db4543c8624f2bb098ff8482354af4e293ede Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Thu, 14 Feb 2013 12:19:25 +0100 Subject: [PATCH 03/46] [IMP] mail: 'Advanced wizard' in upper-right corner bzr revid: chm@openerp.com-20130214111925-dnknlv4jdkpxx8se --- addons/mail/static/src/css/mail.css | 20 +++++++++++--------- addons/mail/static/src/xml/mail.xml | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css index e4e112cdfaf..5c0817b3ff0 100644 --- a/addons/mail/static/src/css/mail.css +++ b/addons/mail/static/src/css/mail.css @@ -458,18 +458,20 @@ .openerp .oe_mail .oe_hidden_input_file, .openerp .oe_mail .oe_hidden_input_file form{ display:inline; } -.openerp .oe_mail .oe_msg_footer button.oe_full{ - width:24px; - overflow:hidden; +.openerp .oe_mail .oe_msg_center button.oe_full{ + width: 24px; + height: 22px; + overflow: hidden; float: right; - filter:none; + filter: none; } -.openerp .oe_mail .oe_msg_footer button.oe_full .oe_e{ +.openerp .oe_mail .oe_msg_center button.oe_full .oe_e{ position: relative; - top: -4px; - margin-left: -9px; - vertical-align: middle; - filter:none; + top: -9px; + margin-left: -5px; + vertical-align: top; + filter: none; + height: 14px; } .openerp .oe_mail button.oe_attach, .openerp .oe_mail button.oe_full{ background: transparent; diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index 738a9d5d0e7..9a98f52d779 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -26,6 +26,7 @@
+
@@ -34,7 +35,6 @@ -
From ca76cb8d32a12217cffd50a445565312e4beb0c1 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Thu, 14 Feb 2013 12:20:36 +0100 Subject: [PATCH 04/46] [IMP] mail: 'Post' to 'Send to followers' bzr revid: chm@openerp.com-20130214112036-qgekbxegb8a3ihjh --- addons/mail/static/src/xml/mail.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index 9a98f52d779..4a5473981d5 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -32,7 +32,7 @@ From 6f1f3f8a03ab4edc3dddd874786bc167b834f229 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Thu, 14 Feb 2013 12:37:02 +0100 Subject: [PATCH 05/46] [IMP] mail: add 'Log a note' button right after 'Send to followers' button bzr revid: chm@openerp.com-20130214113702-ste98tekdcj4kt4w --- addons/mail/static/src/css/mail.css | 3 ++- addons/mail/static/src/js/mail.js | 17 ++++++++++++++--- addons/mail/static/src/xml/mail.xml | 1 + 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css index 5c0817b3ff0..72ecb5d4d07 100644 --- a/addons/mail/static/src/css/mail.css +++ b/addons/mail/static/src/css/mail.css @@ -439,7 +439,8 @@ line-height: 12px; vertical-align: middle; } -.openerp .oe_mail .oe_msg_footer button.oe_post{ +.openerp .oe_mail .oe_msg_footer button.oe_post, +.openerp .oe_mail .oe_msg_footer button.oe_log{ position: relative; z-index: 2; } diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 2c5b8d77dd1..5c36c32c15a 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -495,6 +495,7 @@ openerp.mail = function (session) { this.$('.oe_cancel').on('click', _.bind( this.on_cancel, this) ); this.$('.oe_post').on('click', _.bind( this.on_message_post, this) ); + this.$('.oe_log').on('click', _.bind( this.on_message_log, this) ); this.$('.oe_full').on('click', _.bind( this.on_compose_fullmail, this, this.id ? 'reply' : 'comment') ); /* stack for don't close the compose form if the user click on a button */ this.$('.oe_msg_left, .oe_msg_center').on('mousedown', _.bind( function () { this.stay_open = true; }, this)); @@ -632,17 +633,27 @@ openerp.mail = function (session) { } }, + on_message_log: function (event) { + if (this.do_check_attachment_upload() && (this.attachment_ids.length || this.$('textarea').val().match(/\S+/))) { + this.do_send_message_post([], true); + } + }, + /*do post a message and fetch the message*/ - do_send_message_post: function (partner_ids) { + do_send_message_post: function (partner_ids, log) { var self = this; - this.parent_thread.ds_thread._model.call('message_post_user_api', [this.context.default_res_id], { + var values = { 'body': this.$('textarea').val(), 'subject': false, 'parent_id': this.context.default_parent_id, 'attachment_ids': _.map(this.attachment_ids, function (file) {return file.id;}), 'partner_ids': partner_ids, 'context': this.parent_thread.context, - }).done(function (message_id) { + }; + if (log) { + values['subtype'] = false; + } + this.parent_thread.ds_thread._model.call('message_post_user_api', [this.context.default_res_id], values).done(function (message_id) { var thread = self.parent_thread; var root = thread == self.options.root_thread; if (self.options.display_indented_thread < self.thread_level && thread.parent_message) { diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index 4a5473981d5..bc8a8dc30ed 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -33,6 +33,7 @@ From 58de3dfad7ace01ba81d2ab52e80a094e342de17 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Thu, 14 Feb 2013 12:47:55 +0100 Subject: [PATCH 06/46] [IMP] mail: background color lighter for log message bzr revid: chm@openerp.com-20130214114755-esrkjiay6rcb00f3 --- addons/mail/static/src/css/mail.css | 3 +++ addons/mail/static/src/xml/mail.xml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css index 72ecb5d4d07..c441499ddd8 100644 --- a/addons/mail/static/src/css/mail.css +++ b/addons/mail/static/src/css/mail.css @@ -54,6 +54,9 @@ min-height: 42px; border: solid 1px rgba(0,0,0,0.03); } +.openerp .oe_mail .oe_msg.oe_msg_nobody{ + background: #F8F8F8; +} .openerp .oe_mail .oe_msg .oe_msg_left{ position: absolute; left:0; top: 0; bottom: 0; width: 40px; diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index bc8a8dc30ed..e9c5f7bc424 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -213,7 +213,7 @@ -
+
From b419e8b6c2f81980604a47c6cab9c6b5f673fe86 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Thu, 14 Feb 2013 15:34:17 +0100 Subject: [PATCH 07/46] [IMP] mail: _get_message_data: display only number of new messages bzr revid: chm@openerp.com-20130214143417-suf0tyonrewh2a7l --- addons/mail/mail_thread.py | 21 ++++++++++----------- addons/project/project_view.xml | 2 +- addons/project_issue/project_issue_view.xml | 4 ++++ 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 46052b07fdf..03f681ce501 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -35,6 +35,7 @@ from openerp import SUPERUSER_ID from openerp.addons.mail.mail_message import decode from openerp.osv import fields, osv from openerp.tools.safe_eval import safe_eval as eval +from openerp.tools.translate import _ _logger = logging.getLogger(__name__) @@ -92,23 +93,21 @@ class mail_thread(osv.AbstractModel): """ Computes: - message_unread: has uid unread message for the document - message_summary: html snippet summarizing the Chatter for kanban views """ - res = dict((id, dict(message_unread=False, message_summary='')) for id in ids) + res = dict((id, dict(message_unread=False, message_summary=' ')) for id in ids) user_pid = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=context)['partner_id'][0] # search for unread messages, directly in SQL to improve performances - cr.execute(""" SELECT m.res_id FROM mail_message m + cr.execute(""" SELECT m.res_id, COUNT(n.message_id) as nb FROM mail_message m RIGHT JOIN mail_notification n ON (n.message_id = m.id AND n.partner_id = %s AND (n.read = False or n.read IS NULL)) - WHERE m.model = %s AND m.res_id in %s""", + WHERE m.model = %s AND m.res_id in %s + GROUP BY m.res_id""", (user_pid, self._name, tuple(ids),)) - msg_ids = [result[0] for result in cr.fetchall()] - for msg_id in msg_ids: - res[msg_id]['message_unread'] = True - - for thread in self.browse(cr, uid, ids, context=context): - cls = res[thread.id]['message_unread'] and ' class="oe_kanban_mail_new"' or '' - res[thread.id]['message_summary'] = "9 %d + %d" % (cls, len(thread.message_ids), len(thread.message_follower_ids)) - + for result in cr.fetchall(): + res[result[0]]['message_unread'] = True + if result[1]: + title = result[1] > 1 and _("There are %d messages unread") % result[1] or _("There is 1 message unread") + res[result[0]]['message_summary'] = "9 %d %s" % (title, result[1], _("New")) return res def _get_subscription_data(self, cr, uid, ids, name, args, context=None): diff --git a/addons/project/project_view.xml b/addons/project/project_view.xml index b102c01193d..b49d61c8e98 100644 --- a/addons/project/project_view.xml +++ b/addons/project/project_view.xml @@ -476,7 +476,6 @@ - @@ -523,6 +522,7 @@
diff --git a/addons/project_issue/project_issue_view.xml b/addons/project_issue/project_issue_view.xml index 77375450e9a..60afb7a90f3 100644 --- a/addons/project_issue/project_issue_view.xml +++ b/addons/project_issue/project_issue_view.xml @@ -201,6 +201,7 @@ +
    @@ -251,6 +252,9 @@
+
From fd315b66f27665418ac2c24bf44d4cfc40330cc3 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Thu, 14 Feb 2013 15:39:38 +0100 Subject: [PATCH 08/46] [IMP] mail: You have one unread message bzr revid: chm@openerp.com-20130214143938-aeemq70wl5gnf3k1 --- addons/mail/mail_thread.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 03f681ce501..d026f62667a 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -106,7 +106,7 @@ class mail_thread(osv.AbstractModel): for result in cr.fetchall(): res[result[0]]['message_unread'] = True if result[1]: - title = result[1] > 1 and _("There are %d messages unread") % result[1] or _("There is 1 message unread") + title = result[1] > 1 and _("You have %d unread messages") % result[1] or _("You have one unread message") res[result[0]]['message_summary'] = "9 %d %s" % (title, result[1], _("New")) return res From d374ffba59d64408098f4931be10a70e6a05cb51 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Thu, 14 Feb 2013 16:09:49 +0100 Subject: [PATCH 09/46] [IMP] mail_followers: When unfollowing: confirmation box bzr revid: chm@openerp.com-20130214150949-hgdlxvd4g18734mu --- addons/mail/static/src/js/mail_followers.js | 28 +++++++++++++-------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/addons/mail/static/src/js/mail_followers.js b/addons/mail/static/src/js/mail_followers.js index 03351c24ac2..8cc85bf1449 100644 --- a/addons/mail/static/src/js/mail_followers.js +++ b/addons/mail/static/src/js/mail_followers.js @@ -106,9 +106,12 @@ openerp_mail_followers = function(session, mail) { on_remove_follower: function (event) { var partner_id = $(event.target).data('id'); - var context = new session.web.CompoundContext(this.build_context(), {}); - return this.ds_model.call('message_unsubscribe', [[this.view.datarecord.id], [partner_id], context]) - .then(this.proxy('read_value')); + var name = $(event.target).parent().find("a").html(); + if (confirm(_.str.sprintf(_t("Warning! \n %s won't be notified of any email or discussion on this document. Do you really want to remove him from the followers ?"), name))) { + var context = new session.web.CompoundContext(this.build_context(), {}); + return this.ds_model.call('message_unsubscribe', [[this.view.datarecord.id], [partner_id], context]) + .then(this.proxy('read_value')); + } }, read_value: function () { @@ -246,12 +249,15 @@ openerp_mail_followers = function(session, mail) { }, do_unfollow: function () { - _(this.$('.oe_msg_subtype_check')).each(function (record) { - $(record).attr('checked',false); - }); - var context = new session.web.CompoundContext(this.build_context(), {}); - return this.ds_model.call('message_unsubscribe_users', [[this.view.datarecord.id], [this.session.uid], context]) - .then(this.proxy('read_value')); + if (confirm(_t("Warning! \nYou won't be notified of any email or discussion on this document. Do you really want to unfollow this document ?"))) { + _(this.$('.oe_msg_subtype_check')).each(function (record) { + $(record).attr('checked',false); + }); + var context = new session.web.CompoundContext(this.build_context(), {}); + return this.ds_model.call('message_unsubscribe_users', [[this.view.datarecord.id], [this.session.uid], context]) + .then(this.proxy('read_value')); + } + return false; }, do_update_subscription: function (event) { @@ -265,7 +271,9 @@ openerp_mail_followers = function(session, mail) { }); if (!checklist.length) { - this.do_unfollow(); + if (!this.do_unfollow()) { + $(event.target).attr("checked", "checked") + } } else { var context = new session.web.CompoundContext(this.build_context(), {}); return this.ds_model.call('message_subscribe_users', [[this.view.datarecord.id], [this.session.uid], checklist, context]) From 336f7cb9a5d439dbb12f52f6b379bdd30042be5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 14 Feb 2013 17:19:50 +0100 Subject: [PATCH 10/46] [FIX] Chatter: fixed from/to that werebadly placed. bzr revid: tde@openerp.com-20130214161950-gnmtyktm1p88ge8t --- addons/mail/static/src/xml/mail.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index e9c5f7bc424..4c003cbeae1 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -245,6 +245,7 @@
From: + • To: @@ -260,7 +261,6 @@ and more - • • From 3a8426e5c5b1ae91904d7333ed91f48044da45cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 14 Feb 2013 17:20:11 +0100 Subject: [PATCH 11/46] [IMP] mail: message_new in mailgateway is done with nolog context: no 'document created' message. bzr revid: tde@openerp.com-20130214162011-0xhjo7l5y8733usr --- addons/mail/mail_thread.py | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index d026f62667a..4539d3357a8 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -605,6 +605,7 @@ class mail_thread(osv.AbstractModel): if thread_id and hasattr(model_pool, 'message_update'): model_pool.message_update(cr, user_id, [thread_id], msg, context=nosub_ctx) else: + nosub_ctx = dict(nosub_ctx, mail_create_nolog=True) thread_id = model_pool.message_new(cr, user_id, msg, custom_values, context=nosub_ctx) else: assert thread_id == 0, "Posting a message without model should be with a null res_id, to create a private message." From c3b6408715a3603f0baae8e394a5d085da24ad23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 20 Feb 2013 13:49:23 +0100 Subject: [PATCH 12/46] [IMP] Chatter: refactoring of 'include new emails/partners' in Chatter compose. It does not create partner everytime; discarding the creation popup discards the creation and addition as recipient. bzr revid: tde@openerp.com-20130220124923-w3e9hxomniphadj7 --- addons/crm/crm_lead.py | 9 + addons/mail/mail_thread.py | 45 ++--- addons/mail/static/src/css/mail.css | 8 +- addons/mail/static/src/js/mail.js | 242 ++++++++++++++++-------- addons/mail/static/src/xml/mail.xml | 13 +- addons/mail/tests/test_mail_features.py | 6 +- 6 files changed, 209 insertions(+), 114 deletions(-) diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index 294adc863b5..4fd2bcfcfd1 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -963,6 +963,15 @@ class crm_lead(base_stage, format_address, osv.osv): return [lead.section_id.message_get_reply_to()[0] if lead.section_id else False for lead in self.browse(cr, uid, ids, context=context)] + def message_get_suggested_recipients(self, cr, uid, ids, context=None): + recipients = super(crm_lead, self).message_get_suggested_recipients(cr, uid, ids, context=context) + for lead in self.browse(cr, uid, ids, context=context): + if lead.partner_id: + recipients[lead.id].append([lead.partner_id.id, '%s<%s>' % (lead.partner_id.name, lead.partner_id.email)]) + elif lead.email_from: + recipients[lead.id].append([False, lead.email_from]) + return recipients + def message_new(self, cr, uid, msg, custom_values=None, context=None): """ Overrides mail_thread message_new that is called by the mailgateway through message_process. diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index d9ad86af1e7..1ccb4b318cc 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -820,41 +820,42 @@ class mail_thread(osv.AbstractModel): "now deprecated res.log.") self.message_post(cr, uid, [id], message, context=context) - def message_create_partners_from_emails(self, cr, uid, emails, context=None): + def message_get_suggested_recipients(self, cr, uid, ids, context=None): + return dict.fromkeys(ids, list()) + + def message_get_partner_info_from_emails(self, cr, uid, emails, link_mail=False, context=None): """ Convert a list of emails into a list partner_ids and a list new_partner_ids. The return value is non conventional because it is meant to be used by the mail widget. :return dict: partner_ids and new_partner_ids """ - partner_obj = self.pool.get('res.partner') mail_message_obj = self.pool.get('mail.message') - - partner_ids = [] - new_partner_ids = [] + partner_obj = self.pool.get('res.partner') + partner_info = dict() for email in emails: m = re.search(r"((.+?)\s*<)?([^<>]+@[^<>]+)>?", email, re.IGNORECASE | re.DOTALL) - name = m.group(2) or m.group(0) - email = m.group(3) - ids = partner_obj.search(cr, SUPERUSER_ID, [('email', '=', email)], context=context) + email_address = m.group(3) + partner_info.setdefault(email_address, dict()).setdefault('full_name', email) + ids = partner_obj.search(cr, SUPERUSER_ID, [('email', '=', email_address)], context=context) if ids: - partner_ids.append(ids[0]) - partner_id = ids[0] + partner_info[email_address]['partner_id'] = ids[0] else: - partner_id = partner_obj.create(cr, uid, { - 'name': name or email, - 'email': email, - }, context=context) - new_partner_ids.append(partner_id) + partner_info[email_address]['partner_id'] = False # link mail with this from mail to the new partner id - message_ids = mail_message_obj.search(cr, SUPERUSER_ID, ['|', ('email_from', '=', email), ('email_from', 'ilike', '<%s>' % email), ('author_id', '=', False)], context=context) - if message_ids: - mail_message_obj.write(cr, SUPERUSER_ID, message_ids, {'email_from': None, 'author_id': partner_id}, context=context) - return { - 'partner_ids': partner_ids, - 'new_partner_ids': new_partner_ids, - } + if link_mail and ids: + print email, ids + message_ids = mail_message_obj.search(cr, SUPERUSER_ID, [ + '|', + ('email_from', '=', email), + ('email_from', 'ilike', '<%s>' % email), + ('author_id', '=', False) + ], context=context) + if message_ids: + # mail_message_obj.write(cr, SUPERUSER_ID, message_ids, {'author_id': ids[0]}, context=context) + print 'found', message_ids + return partner_info def message_post(self, cr, uid, thread_id, body='', subject=None, type='notification', subtype=None, parent_id=False, attachments=None, context=None, **kwargs): diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css index c441499ddd8..18010937a11 100644 --- a/addons/mail/static/src/css/mail.css +++ b/addons/mail/static/src/css/mail.css @@ -272,20 +272,20 @@ margin-top: 4px; margin-bottom: 4px; } -.openerp .oe_mail .oe_msg_composer .oe_msg_attachment_list{ +.openerp .oe_mail .oe_msg_composer .oe_msg_attachment_list { display: block; } -.openerp .oe_mail .oe_msg_composer .oe_emails_from{ +.openerp .oe_mail .oe_msg_composer .oe_recipients { font-size: 12px; margin-left: 20px; margin-bottom: 2px; } -.openerp .oe_mail .oe_msg_composer .oe_emails_from label{ +.openerp .oe_mail .oe_msg_composer .oe_recipients label{ vertical-align: middle; display: block; line-height: 14px; } -.openerp .oe_mail .oe_msg_composer .oe_emails_from input{ +.openerp .oe_mail .oe_msg_composer .oe_recipients input{ vertical-align: middle; } .openerp .oe_mail .oe_attachment{ diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 5c36c32c15a..777f17f1ceb 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -21,6 +21,15 @@ openerp.mail = function (session) { mail.ChatterUtils = { + /** parse text to find email: Tagada -> [Tagada, address@mail.fr] or False */ + parse_email: function (text) { + var email = text.match(/(.*)<(.*@.*)>/); + if (! email) { + return [text, false]; + } + return [_.str.trim(email[1]), email[2]]; + }, + /* Get an image in /web/binary/image?... */ get_image: function (session, model, field, id, resize) { var r = resize ? encodeURIComponent(resize) : ''; @@ -255,12 +264,8 @@ openerp.mail = function (session) { this.avatar = mail.ChatterUtils.get_image(this.session, 'res.users', 'image_small', this.session.uid); } if (this.author_id && this.author_id[1]) { - var email = this.author_id[1].match(/(.*)<(.*@.*)>/); - if (!email) { - this.author_id.push(_.str.escapeHTML(this.author_id[1]), '', this.author_id[1]); - } else { - this.author_id.push(_.str.escapeHTML(email[0]), _.str.trim(email[1]), email[2]); - } + var parsed_email = mail.ChatterUtils.parse_email(this.author_id[1]); + this.author_id.push(parsed_email[0], parsed_email[1]); } if (this.partner_ids && this.partner_ids.length > 3) { this.extra_partners_nbr = this.partner_ids.length - 3; @@ -379,14 +384,23 @@ openerp.mail = function (session) { * @param {Object} [context] context passed to the * mail.compose.message DataSetSearch. Please refer to this model * for more details about fields and default values. + * @param {Object} recipients = [ + { + 'email_address': [str], + 'partner_id': False/[int], + 'name': [str], + 'full_name': name, + }, + { ... }, + ] */ init: function (parent, datasets, options) { this._super(parent, datasets, options); this.show_compact_message = false; this.show_delete_attachment = true; - this.emails_from = []; - this.partners_from = []; + this.recipients = []; + this.recipient_ids = []; }, start: function () { @@ -487,16 +501,12 @@ openerp.mail = function (session) { bind_events: function () { var self = this; - - this.$('.oe_compact').on('click', _.bind( this.on_compose_expandable, this)); - - // set the function called when attachments are added - this.$('input.oe_form_binary_file').on('change', _.bind( this.on_attachment_change, this) ); - - this.$('.oe_cancel').on('click', _.bind( this.on_cancel, this) ); - this.$('.oe_post').on('click', _.bind( this.on_message_post, this) ); - this.$('.oe_log').on('click', _.bind( this.on_message_log, this) ); - this.$('.oe_full').on('click', _.bind( this.on_compose_fullmail, this, this.id ? 'reply' : 'comment') ); + this.$('.oe_compact').on('click', _.bind( this.on_toggle_quick_composer, this)); + this.$('input.oe_form_binary_file').on('change', _.bind( this.on_attachment_change, this)); + this.$('.oe_cancel').on('click', _.bind( this.on_cancel, this)); + this.$('.oe_post').on('click', _.bind( this.on_message_post, this)); + this.$('.oe_log').on('click', _.bind( this.on_message_post, this)); + this.$('.oe_full').on('click', _.bind( this.on_compose_fullmail, this, this.id ? 'reply' : 'comment')); /* stack for don't close the compose form if the user click on a button */ this.$('.oe_msg_left, .oe_msg_center').on('mousedown', _.bind( function () { this.stay_open = true; }, this)); this.$('.oe_msg_left, .oe_msg_content').on('mouseup', _.bind( function () { this.$('textarea').focus(); }, this)); @@ -506,13 +516,12 @@ openerp.mail = function (session) { this.$('textarea').autosize(); // auto close - this.$('textarea').on('blur', _.bind( this.on_compose_expandable, this)); + this.$('textarea').on('blur', _.bind( this.on_toggle_quick_composer, this)); // event: delete child attachments off the oe_msg_attachment_list box this.$(".oe_msg_attachment_list").on('click', '.oe_delete', this.on_attachment_delete); - this.$(".oe_emails_from").on('change', 'input', this.on_checked_email_from); - this.$(".oe_partners_from").on('change', 'input', this.on_checked_partner_from); + this.$(".oe_recipients").on('change', 'input', this.on_checked_recipient); }, on_compose_fullmail: function (default_composition_mode) { @@ -582,64 +591,92 @@ openerp.mail = function (session) { check_recipient_partners: function () { var self = this; - var partners_from = []; - var emails = []; - _.each(this.emails_from, function (email_from) { - if (email_from[1] && !_.find(emails, function (email) {return email == email_from[0][4];})) { - emails.push(email_from[0][1]); - } - }); - var deferred_check = $.Deferred(); - if (emails.length == 0) { - return deferred_check.resolve(partners_from); + var check_done = $.Deferred(); + + var recipients = _.filter(this.recipients, function (recipient) { return recipient.checked }); + var recipients_to_check = _.filter(recipients, function (recipient) { return (! recipient.partner_id || ! recipient.email_address) }); + var names_to_check = _.pluck(recipients_to_check, 'full_name'); + var names_to_remove = []; + var recipient_ids = _.pluck(_.filter(recipients, function (recipient) { return recipient.partner_id && recipient.email_address }), 'partner_id'); + + // some debug + console.group('check_recipient_partners'); + console.log('recipients', recipients); + console.log('recipient_ids', recipient_ids); + console.log('recipients_to_check', recipients_to_check); + console.log('names_to_check', names_to_check); + + // no emails -> do not make call, proceed to next step + if (names_to_check.length == 0) { + console.groupEnd(); + return check_done.resolve(recipient_ids); } - self.parent_thread.ds_thread._model.call('message_create_partners_from_emails', [emails]).then(function (partners) { - partners_from = _.clone(partners.partner_ids); - var deferreds = []; - _.each(partners.new_partner_ids, function (id) { + + // for each unknown email -> filter already existing partners + self.parent_thread.ds_thread._model.call('message_get_partner_info_from_emails', [names_to_check]).done(function (result) { + var emails_deferred = []; + _.each(result, function (partner_info) { var deferred = $.Deferred() - deferreds.push(deferred); - var pop = new session.web.form.FormOpenPopup(this); + emails_deferred.push(deferred); + + var partner_name = partner_info.full_name; + var partner_id = partner_info.partner_id; + var parsed_email = mail.ChatterUtils.parse_email(partner_name); + console.log('checking', partner_name, 'parsed email', parsed_email); + + var pop = new session.web.form.FormOpenPopup(this); pop.show_element( 'res.partner', - id, - { - 'force_email': true, + partner_id, + { 'force_email': true, 'ref': "compound_context", - }, - { + 'default_name': parsed_email[0], + 'default_email': parsed_email[1], + }, { title: _t("Please complete partner's informations"), } ); pop.on('closed', self, function () { deferred.resolve(); }); - partners_from.push(id); + pop.view_form.on('on_button_cancel', self, function () { + names_to_remove.push(partner_name); + }); }); - $.when.apply( $, deferreds ).then(function () { - deferred_check.resolve(partners_from); + $.when.apply($, emails_deferred).then(function () { + console.log('post truc', names_to_remove); + var new_names_to_check = _.difference(names_to_check, names_to_remove); + self.parent_thread.ds_thread._model.call('message_get_partner_info_from_emails', [new_names_to_check, true]).done(function (result) { + _.each(result, function (partner_info) { + recipient_ids.push(partner_info.partner_id); + }); + }).pipe(function (caca) { + console.log('caca', caca); + check_done.resolve(recipient_ids); + }); }); }); - return deferred_check; + console.groupEnd(); + return check_done; }, on_message_post: function (event) { var self = this; + var is_log = $(event.target).data('is_log'); + console.log(is_log); if (this.do_check_attachment_upload() && (this.attachment_ids.length || this.$('textarea').val().match(/\S+/))) { - // create list of new partners - this.check_recipient_partners().done(function (partner_ids) { - self.do_send_message_post(partner_ids); - }); + if (is_log) { + self.do_send_message_post([], is_log); + } + else { + this.check_recipient_partners().done(function (partner_ids) { + self.do_send_message_post(partner_ids, is_log); + }); + } } }, - on_message_log: function (event) { - if (this.do_check_attachment_upload() && (this.attachment_ids.length || this.$('textarea').val().match(/\S+/))) { - this.do_send_message_post([], true); - } - }, - - /*do post a message and fetch the message*/ + /* do post a message and fetch the message */ do_send_message_post: function (partner_ids, log) { var self = this; var values = { @@ -669,18 +706,60 @@ openerp.mail = function (session) { }); }, - /* convert the compact mode into the compose message - */ - on_compose_expandable: function (event) { - this.get_emails_from(); - if ((!this.stay_open || (event && event.type == 'click')) && (!this.show_composer || !this.$('textarea:not(.oe_compact)').val().match(/\S+/) && !this.attachment_ids.length)) { - this.show_composer = !this.show_composer || this.stay_open; - this.reinit(); + /* Quick composer: toggle minimal / expanded mode + * - toggle minimal (one-liner) / expanded (textarea, buttons) mode + * - when going into expanded mode: + * - call `message_get_suggested_partners` to have a list of partners to add + * - compute email_from list (list of unknown email_from to propose to create partners) + */ + on_toggle_quick_composer: function (event) { + var self = this; + this.compute_emails_from(); + var email_addresses = _.pluck(this.recipients, 'email_address'); + var suggested_partners = $.Deferred(); + + // some debug + console.group('on_toggle_quick_composer'); + console.log('event', event); + console.log('computed recipients', this.recipients); + + // if clicked: call for suggested recipients + if (event.type == 'click') { + suggested_partners = this.parent_thread.ds_thread.call('message_get_suggested_recipients', [[this.context.default_res_id]]).done(function (additional_recipients) { + var thread_recipients = additional_recipients[self.context.default_res_id]; + console.log('message_get_suggested_recipients:', thread_recipients); + _.each(thread_recipients, function (recipient) { + var parsed_email = mail.ChatterUtils.parse_email(recipient[1]); + if (_.indexOf(email_addresses, parsed_email[1]) == -1) { + self.recipients.push({ + 'checked': true, + 'partner_id': recipient[0], + 'full_name': recipient[1], + 'name': parsed_email[0], + 'email_address': parsed_email[1], + }) + } + }); + }); } - if (!this.stay_open && this.show_composer && (!event || event.type != 'blur')) { - this.$('textarea:not(.oe_compact):first').focus(); + else { + suggested_partners.resolve({}); } - return true; + + // when call for suggested partners finished: re-render the widget + $.when(suggested_partners).pipe(function (additional_recipients) { + console.log('recipients after toogle', self.recipients); + console.groupEnd(); + if ((!self.stay_open || (event && event.type == 'click')) && (!self.show_composer || !self.$('textarea:not(.oe_compact)').val().match(/\S+/) && !self.attachment_ids.length)) { + self.show_composer = !self.show_composer || self.stay_open; + self.reinit(); + } + if (!self.stay_open && self.show_composer && (!event || event.type != 'blur')) { + self.$('textarea:not(.oe_compact):first').focus(); + } + }); + + return suggested_partners; }, do_hide_compact: function () { @@ -697,7 +776,10 @@ openerp.mail = function (session) { } }, - get_emails_from: function () { + /** Compute the list of unknown email_from the the given thread + * TDE FIXME: seems odd to delegate to the composer + * TDE TODO: please de-obfuscate and comment your code */ + compute_emails_from: function () { var self = this; var messages = []; @@ -710,22 +792,26 @@ openerp.mail = function (session) { // get all wall messages if is not a mail.Wall _.each(this.options.root_thread.messages, function (msg) {messages.push(msg); messages.concat(msg.get_childs());}); } - + _.each(messages, function (thread) { if (thread.author_id && !thread.author_id[0] && - !_.find(self.emails_from, function (from) {return from[0][4] == thread.author_id[4];})) { - self.emails_from.push([thread.author_id, true]); + !_.find(self.recipients, function (recipient) {return recipient.email_address == thread.author_id[3];})) { + self.recipients.push({ 'full_name': thread.author_id[1], + 'name': thread.author_id[2], + 'email_address': thread.author_id[3], + 'partner_id': false, + 'checked': true }); } }); - return self.emails_from; + return self.recipients; }, - on_checked_email_from: function (event) { + on_checked_recipient: function (event) { var $input = $(event.target); var email = $input.attr("data"); - _.each(this.emails_from, function (email_from) { - if (email_from[0][4] == email) { - email_from[1] = $input.is(":checked"); + _.each(this.recipients, function (recipient) { + if (recipient.email_address == email) { + recipient.checked = $input.is(":checked"); } }); }, @@ -1255,12 +1341,12 @@ openerp.mail = function (session) { /** *If compose_message doesn't exist, instantiate the compose message. - * Call the on_compose_expandable method to allow the user to write his message. + * Call the on_toggle_quick_composer method to allow the user to write his message. * (Is call when a user click on "Reply" button) */ on_compose_message: function (event) { this.instantiate_compose_message(); - this.compose_message.on_compose_expandable(event); + this.compose_message.on_toggle_quick_composer(event); return false; }, diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index 4c003cbeae1..dfd560c52d9 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -33,9 +33,8 @@ @@ -130,11 +129,11 @@ <<< -
- -
- - Write to the followers of this document... - Share with my followers... + + + Share a message + Share with my followers + + or + Log a note
@@ -129,7 +135,7 @@ <<<
-
+
-
- + + + Share with my followers... +
+ + + +
From 94c07f4d6ec798634abeb6227b19361133f262ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 26 Feb 2013 11:02:06 +0100 Subject: [PATCH 28/46] [IMP] mail: mail_group chatter placeholder improvement. bzr revid: tde@openerp.com-20130226100206-yqzmnn02yfupd438 --- addons/mail/mail_group_view.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/mail/mail_group_view.xml b/addons/mail/mail_group_view.xml index fba192b18bc..77c0b8f6c86 100644 --- a/addons/mail/mail_group_view.xml +++ b/addons/mail/mail_group_view.xml @@ -106,7 +106,7 @@
- +
From 6c3aa520c71e30be0b7a436c43c915f395d7a67b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 26 Feb 2013 11:57:55 +0100 Subject: [PATCH 29/46] [IMP] mail_followers: improved _notify, to better manage notifications. An optional (to provide compatibility) parameter has been added, that allows to notify partners of a given messages. It checks whether a notification already exists, setting it back as unread, or create a notification pushed by email. bzr revid: tde@openerp.com-20130226105755-gvkn1ocpwkcndzpl --- addons/mail/mail_followers.py | 36 +++++++++++++++++++++++++++-------- addons/mail/mail_message.py | 5 ++--- addons/mail/mail_thread.py | 8 +------- 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/addons/mail/mail_followers.py b/addons/mail/mail_followers.py index a9d33f4585d..25772d7bb33 100644 --- a/addons/mail/mail_followers.py +++ b/addons/mail/mail_followers.py @@ -75,16 +75,21 @@ class mail_notification(osv.Model): if not cr.fetchone(): cr.execute('CREATE INDEX mail_notification_partner_id_read_starred_message_id ON mail_notification (partner_id, read, starred, message_id)') - def get_partners_to_notify(self, cr, uid, message, context=None): + def get_partners_to_notify(self, cr, uid, message, partners_to_notify=None, context=None): """ Return the list of partners to notify, based on their preferences. :param browse_record message: mail.message to notify + :param list partners_to_notify: optional list of partner ids restricting + the notifications to process """ notify_pids = [] for notification in message.notification_ids: if notification.read: continue partner = notification.partner_id + # If partners_to_notify specified: restrict to them + if partners_to_notify and partner.id not in partners_to_notify: + continue # Do not send to partners without email address defined if not partner.email: continue @@ -100,16 +105,35 @@ class mail_notification(osv.Model): notify_pids.append(partner.id) return notify_pids - def _notify(self, cr, uid, msg_id, context=None): - """ Send by email the notification depending on the user preferences """ + def _notify(self, cr, uid, msg_id, partners_to_notify=None, context=None): + """ Send by email the notification depending on the user preferences + + :param list partners_to_notify: optional list of partner ids restricting + the notifications to process + """ if context is None: context = {} + mail_message_obj = self.pool.get('mail.message') + + # optional list of partners to notify: subscribe them if not already done or update the notification + if partners_to_notify: + notifications_to_update = [] + notified_partners = [] + notif_ids = self.search(cr, SUPERUSER_ID, [('message_id', '=', msg_id), ('partner_id', 'in', partners_to_notify)], context=context) + for notification in self.browse(cr, SUPERUSER_ID, notif_ids, context=context): + notified_partners.append(notification.partner_id.id) + notifications_to_update.append(notification.id) + partners_to_notify = filter(lambda item: item not in notified_partners, partners_to_notify) + if notifications_to_update: + self.write(cr, SUPERUSER_ID, notifications_to_update, {'read': False}, context=context) + mail_message_obj.write(cr, uid, msg_id, {'notified_partner_ids': [(4, id) for id in partners_to_notify]}, context=context) + # mail_notify_noemail (do not send email) or no partner_ids: do not send, return if context.get('mail_notify_noemail'): return True # browse as SUPERUSER_ID because of access to res_partner not necessarily allowed msg = self.pool.get('mail.message').browse(cr, SUPERUSER_ID, msg_id, context=context) - notify_partner_ids = self.get_partners_to_notify(cr, uid, msg, context=context) + notify_partner_ids = self.get_partners_to_notify(cr, uid, msg, partners_to_notify=partners_to_notify, context=context) if not notify_partner_ids: return True @@ -136,16 +160,12 @@ class mail_notification(osv.Model): mail_values = { 'mail_message_id': msg.id, - 'email_to': [], 'auto_delete': True, 'body_html': body_html, 'email_from': email_from, - 'state': 'outgoing', } - mail_values['email_to'] = ', '.join(mail_values['email_to']) email_notif_id = mail_mail.create(cr, uid, mail_values, context=context) try: return mail_mail.send(cr, uid, [email_notif_id], recipient_ids=notify_partner_ids, context=context) except Exception: return False - diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index 91d46098b4b..2f56e620543 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -861,7 +861,7 @@ class mail_message(osv.Model): # message has no subtype_id: pure log message -> no partners, no one notified if not message.subtype_id: return True - + # all followers of the mail.message document have to be added as partners and notified if message.model and message.res_id: fol_obj = self.pool.get("mail.followers") @@ -884,8 +884,7 @@ class mail_message(osv.Model): # notify if partners_to_notify: - self.write(cr, SUPERUSER_ID, [newid], {'notified_partner_ids': [(4, p.id) for p in partners_to_notify]}, context=context) - notification_obj._notify(cr, uid, newid, context=context) + notification_obj._notify(cr, uid, newid, partners_to_notify=[p.id for p in partners_to_notify], context=context) message.refresh() # An error appear when a user receive a notification without notifying diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index e4b282060cd..1c7ec4bf4fb 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -1135,7 +1135,6 @@ class mail_thread(osv.AbstractModel): # find first email message, set it as unread for auto_subscribe fields for them to have a notification if user_id_partner_ids: - notification_obj = self.pool.get('mail.notification') msg_ids = self.pool.get('mail.message').search(cr, uid, [ ('model', '=', self._name), ('res_id', '=', record.id), @@ -1143,12 +1142,7 @@ class mail_thread(osv.AbstractModel): if not msg_ids and record.message_ids: msg_ids = [record.message_ids[-1].id] if msg_ids: - for partner_id in user_id_partner_ids: - notif_ids = notification_obj.search(cr, uid, [('partner_id', '=', partner_id), ('message_id', '=', msg_ids[0])], context=context) - if notif_ids: - notification_obj.write(cr, uid, notif_ids, {'read': False}, context=context) - else: - notification_obj.create(cr, uid, {'partner_id': partner_id, 'message_id': msg_ids[0], 'read': False}, context=context) + self.pool.get('mail.notification')._notify(cr, uid, msg_ids[0], partners_to_notify=user_id_partner_ids, context=context) return True From e4baaa666eb05ae6db9897c4229d741de2bd7354 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 26 Feb 2013 12:33:27 +0100 Subject: [PATCH 30/46] [CLEAN] Chatter: removed log. bzr revid: tde@openerp.com-20130226113327-ig0n4ou44nh82pm9 --- addons/mail/static/src/js/mail.js | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 4449a73b1a8..bb200aedf95 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -606,14 +606,6 @@ openerp.mail = function (session) { var names_to_remove = []; var recipient_ids_to_remove = []; - // some debug - console.group('check_recipient_partners'); - console.log('recipients', recipients); - console.log('recipient_ids', recipient_ids); - console.log('recipients_to_find', recipients_to_find); - console.log('recipients_to_check', recipients_to_check); - console.log('names_to_find', names_to_find); - // have unknown names -> call message_get_partner_info_from_emails to try to find partner_id var find_done = $.Deferred(); if (names_to_find.length > 0) { @@ -660,7 +652,6 @@ openerp.mail = function (session) { }); $.when.apply($, emails_deferred).then(function () { - console.log('final call', names_to_remove, recipient_ids_to_remove); var new_names_to_find = _.difference(names_to_find, names_to_remove); find_done = $.Deferred(); if (new_names_to_find.length > 0) { @@ -678,7 +669,6 @@ openerp.mail = function (session) { }); }).pipe(function () { check_done.resolve(recipient_ids); - console.groupEnd(); }); }); }); @@ -748,17 +738,11 @@ openerp.mail = function (session) { var email_addresses = _.pluck(this.recipients, 'email_address'); var suggested_partners = $.Deferred(); - // some debug - console.group('on_toggle_quick_composer'); - console.log('event', event); - console.log('computed recipients', this.recipients); - // if clicked: call for suggested recipients if (event.type == 'click') { this.is_log = $input.hasClass('oe_compose_log'); suggested_partners = this.parent_thread.ds_thread.call('message_get_suggested_recipients', [[this.context.default_res_id]]).done(function (additional_recipients) { var thread_recipients = additional_recipients[self.context.default_res_id]; - console.log('message_get_suggested_recipients:', thread_recipients); _.each(thread_recipients, function (recipient) { var parsed_email = mail.ChatterUtils.parse_email(recipient[1]); if (_.indexOf(email_addresses, parsed_email[1]) == -1) { @@ -779,8 +763,6 @@ openerp.mail = function (session) { // when call for suggested partners finished: re-render the widget $.when(suggested_partners).pipe(function (additional_recipients) { - console.log('recipients after toogle', self.recipients); - console.groupEnd(); if ((!self.stay_open || (event && event.type == 'click')) && (!self.show_composer || !self.$('textarea:not(.oe_compact)').val().match(/\S+/) && !self.attachment_ids.length)) { self.show_composer = !self.show_composer || self.stay_open; self.reinit(); From c5e395ec499688a566d203551ff02c470bd6b6bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 26 Feb 2013 12:36:24 +0100 Subject: [PATCH 31/46] [REM] Crm: removed 'send mail' button and related function. Cleaned poportunity basic template. bzr revid: tde@openerp.com-20130226113624-0znlq3eihuzfbutm --- addons/crm/crm_data.xml | 3 +-- addons/crm/crm_lead.py | 35 ----------------------------------- addons/crm/crm_lead_view.xml | 1 - 3 files changed, 1 insertion(+), 38 deletions(-) diff --git a/addons/crm/crm_data.xml b/addons/crm/crm_data.xml index 3726c744b2e..613141b5818 100644 --- a/addons/crm/crm_data.xml +++ b/addons/crm/crm_data.xml @@ -80,8 +80,7 @@ basis for email recipients, name and to ease the definition of a further elaborated template. --> Opportunity - Send Emails - ${object.user_id.email or ''} - Opportunity ${object.name | h}) + ${object.name} ${object.partner_id.id} diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index 6d00ac19b51..9911a412a9c 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -917,41 +917,6 @@ class crm_lead(base_stage, format_address, osv.osv): vals['probability'] = stage.probability return super(crm_lead, self).write(cr, uid, ids, vals, context=context) - def new_mail_send(self, cr, uid, ids, context=None): - ''' - This function opens a window to compose an email, with the edi sale template message loaded by default - ''' - assert len(ids) == 1, 'This option should only be used for a single id at a time.' - ir_model_data = self.pool.get('ir.model.data') - try: - template_id = ir_model_data.get_object_reference(cr, uid, 'crm', 'email_template_opportunity_mail')[1] - except ValueError: - template_id = False - try: - compose_form_id = ir_model_data.get_object_reference(cr, uid, 'mail', 'email_compose_message_wizard_form')[1] - except ValueError: - compose_form_id = False - if context is None: - context = {} - ctx = context.copy() - ctx.update({ - 'default_model': 'crm.lead', - 'default_res_id': ids[0], - 'default_use_template': bool(template_id), - 'default_template_id': template_id, - 'default_composition_mode': 'comment', - }) - return { - 'type': 'ir.actions.act_window', - 'view_type': 'form', - 'view_mode': 'form', - 'res_model': 'mail.compose.message', - 'views': [(compose_form_id, 'form')], - 'view_id': compose_form_id, - 'target': 'new', - 'context': ctx, - } - # ---------------------------------------- # Mail Gateway # ---------------------------------------- diff --git a/addons/crm/crm_lead_view.xml b/addons/crm/crm_lead_view.xml index 87c130547cd..843c00c4f4d 100644 --- a/addons/crm/crm_lead_view.xml +++ b/addons/crm/crm_lead_view.xml @@ -377,7 +377,6 @@ states="draft,open,pending" class="oe_highlight"/> @@ -51,7 +51,7 @@
- Share a message + Send a message or Log a note From 6de2650299da568e81576692b524e415f06a8a53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 28 Feb 2013 18:05:46 +0100 Subject: [PATCH 44/46] [IMP] Suggested recipients: check whether an email is linked to a partner. bzr revid: tde@openerp.com-20130228170546-t04n73pvuwtp20jh --- addons/crm/crm_lead.py | 4 ++-- addons/hr_recruitment/hr_recruitment.py | 4 ++-- addons/mail/mail_thread.py | 12 ++++++++---- addons/mail/res_partner.py | 2 +- addons/project_issue/project_issue.py | 4 ++-- 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index f61f5ef9717..2b7d9a7672d 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -965,9 +965,9 @@ class crm_lead(base_stage, format_address, osv.osv): recipients = super(crm_lead, self).message_get_suggested_recipients(cr, uid, ids, context=context) for lead in self.browse(cr, uid, ids, context=context): if lead.partner_id: - self._message_add_suggested_recipient(recipients, lead, partner=lead.partner_id, reason=_('Customer')) + self._message_add_suggested_recipient(cr, uid, recipients, lead, partner=lead.partner_id, reason=_('Customer')) elif lead.email_from: - self._message_add_suggested_recipient(recipients, lead, email=lead.email_from, reason=_('Customer Email')) + self._message_add_suggested_recipient(cr, uid, recipients, lead, email=lead.email_from, reason=_('Customer Email')) return recipients def message_new(self, cr, uid, msg, custom_values=None, context=None): diff --git a/addons/hr_recruitment/hr_recruitment.py b/addons/hr_recruitment/hr_recruitment.py index a65ca038688..c2ee322bda9 100644 --- a/addons/hr_recruitment/hr_recruitment.py +++ b/addons/hr_recruitment/hr_recruitment.py @@ -344,9 +344,9 @@ class hr_applicant(base_stage, osv.Model): recipients = super(hr_applicant, self).message_get_suggested_recipients(cr, uid, ids, context=context) for applicant in self.browse(cr, uid, ids, context=context): if applicant.partner_id: - self._message_add_suggested_recipient(recipients, applicant, partner=applicant.partner_id, reason=_('Contact')) + self._message_add_suggested_recipient(cr, uid, recipients, applicant, partner=applicant.partner_id, reason=_('Contact')) elif applicant.email_from: - self._message_add_suggested_recipient(recipients, applicant, email=applicant.email_from, reason=_('Contact Email')) + self._message_add_suggested_recipient(cr, uid, recipients, applicant, email=applicant.email_from, reason=_('Contact Email')) return recipients def message_new(self, cr, uid, msg, custom_values=None, context=None): diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 282675e8859..b4258c79e36 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -817,16 +817,20 @@ class mail_thread(osv.AbstractModel): "now deprecated res.log.") self.message_post(cr, uid, [id], message, context=context) - def _message_add_suggested_recipient(self, result, obj, partner=None, email=None, reason='', context=None): + def _message_add_suggested_recipient(self, cr, uid, result, obj, partner=None, email=None, reason='', context=None): """ Called by message_get_suggested_recipients, to add a suggested recipient in the result dictionary. The form is : partner_id, partner_name or partner_name, reason """ + if email and not partner: + partner_info = self.message_get_partner_info_from_emails(cr, uid, [email], context=context)[0] + if partner_info.get('partner_id'): + partner = self.pool.get('res.partner').browse(cr, SUPERUSER_ID, [partner_info.get('partner_id')], context=context)[0] + if email and email in [val[1] for val in result[obj.id]]: # already existing email -> skip + return result if partner and partner in obj.message_follower_ids: # recipient already in the followers -> skip return result if partner and partner in [val[0] for val in result[obj.id]]: # already existing partner ID -> skip return result - if email and email in [val[1] for val in result[obj.id]]: # already existing email -> skip - return result if partner and partner.email: # complete profile: id, name result[obj.id].append((partner.id, '%s<%s>' % (partner.name, partner.email), reason)) elif partner: # incomplete profile: id, name @@ -843,7 +847,7 @@ class mail_thread(osv.AbstractModel): for obj in self.browse(cr, SUPERUSER_ID, ids, context=context): # SUPERUSER because of a read on res.users that would crash otherwise if not obj.user_id or not obj.user_id.partner_id: continue - self._message_add_suggested_recipient(result, obj, partner=obj.user_id.partner_id, reason=self._all_columns['user_id'].column.string, context=context) + self._message_add_suggested_recipient(cr, uid, result, obj, partner=obj.user_id.partner_id, reason=self._all_columns['user_id'].column.string, context=context) return result def message_get_partner_info_from_emails(self, cr, uid, emails, link_mail=False, context=None): diff --git a/addons/mail/res_partner.py b/addons/mail/res_partner.py index f2dde7e65d9..ceed7346a00 100644 --- a/addons/mail/res_partner.py +++ b/addons/mail/res_partner.py @@ -46,7 +46,7 @@ class res_partner_mail(osv.Model): def message_get_suggested_recipients(self, cr, uid, ids, context=None): recipients = super(res_partner_mail, self).message_get_suggested_recipients(cr, uid, ids, context=context) for partner in self.browse(cr, uid, ids, context=context): - self._message_add_suggested_recipient(recipients, partner, partner=partner, reason=_('Customer')) + self._message_add_suggested_recipient(cr, uid, recipients, partner, partner=partner, reason=_('Customer')) return recipients def message_post(self, cr, uid, thread_id, **kwargs): diff --git a/addons/project_issue/project_issue.py b/addons/project_issue/project_issue.py index c3d2379911e..f5a08b37aeb 100644 --- a/addons/project_issue/project_issue.py +++ b/addons/project_issue/project_issue.py @@ -489,9 +489,9 @@ class project_issue(base_stage, osv.osv): recipients = super(project_issue, self).message_get_suggested_recipients(cr, uid, ids, context=context) for issue in self.browse(cr, uid, ids, context=context): if issue.partner_id: - self._message_add_suggested_recipient(recipients, issue, partner=issue.partner_id, reason=_('Customer')) + self._message_add_suggested_recipient(cr, uid, recipients, issue, partner=issue.partner_id, reason=_('Customer')) elif issue.email_from: - self._message_add_suggested_recipient(recipients, issue, email=issue.email_from, reason=_('Customer Email')) + self._message_add_suggested_recipient(cr, uid, recipients, issue, email=issue.email_from, reason=_('Customer Email')) return recipients def message_new(self, cr, uid, msg, custom_values=None, context=None): From f70cc7c46b142cb9163c6382113fdf05db43f38b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 28 Feb 2013 18:23:20 +0100 Subject: [PATCH 45/46] [IMP] Chatter: reason of adding someone added in tooltip. bzr revid: tde@openerp.com-20130228172320-d0m7ibobhyfvtqht --- addons/mail/res_partner.py | 2 +- addons/mail/static/src/js/mail.js | 5 ++++- addons/mail/static/src/xml/mail.xml | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/addons/mail/res_partner.py b/addons/mail/res_partner.py index ceed7346a00..218b5ae3cb7 100644 --- a/addons/mail/res_partner.py +++ b/addons/mail/res_partner.py @@ -46,7 +46,7 @@ class res_partner_mail(osv.Model): def message_get_suggested_recipients(self, cr, uid, ids, context=None): recipients = super(res_partner_mail, self).message_get_suggested_recipients(cr, uid, ids, context=context) for partner in self.browse(cr, uid, ids, context=context): - self._message_add_suggested_recipient(cr, uid, recipients, partner, partner=partner, reason=_('Customer')) + self._message_add_suggested_recipient(cr, uid, recipients, partner, partner=partner, reason=_('Partner Profile')) return recipients def message_post(self, cr, uid, thread_id, **kwargs): diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 0d78cb4fd76..4e58ca48bb1 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -765,6 +765,7 @@ openerp.mail = function (session) { 'full_name': recipient[1], 'name': parsed_email[0], 'email_address': parsed_email[1], + 'reason': recipient[2], }) } }); @@ -826,7 +827,9 @@ openerp.mail = function (session) { 'name': thread.author_id[2], 'email_address': thread.author_id[3], 'partner_id': false, - 'checked': true }); + 'checked': true, + 'reason': 'Incoming email author' + }); } }); return self.recipients; diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index fb2c44509e8..2b63865ce8d 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -144,7 +144,7 @@
-