From 876e53dfcf70ec6ebd61afd60b73d3237c43786a Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Mon, 31 Dec 2012 15:22:50 +0100 Subject: [PATCH 01/14] [IMP] mail: add email_from like partner before opening wizard composer bzr revid: chm@openerp.com-20121231142250-ykdxaqoqfvush1ah --- addons/mail/static/src/js/mail.js | 84 ++++++++++++++++--------------- 1 file changed, 43 insertions(+), 41 deletions(-) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index f8643e94bb3..953cc907f25 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -370,6 +370,7 @@ openerp.mail = function (session) { this.show_compact_message = false; this.show_delete_attachment = true; this.emails_from = []; + this.partners_from = []; }, start: function () { @@ -494,43 +495,41 @@ openerp.mail = function (session) { 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); }, on_compose_fullmail: function (default_composition_mode) { - + var self = this; if(!this.do_check_attachment_upload()) { return false; } - if (default_composition_mode == 'reply') { + // create list of new partners + var extra_email = _.map(_.filter(this.emails_from, function (f) {return f[1]}), function (f) {return f[0]}); + this.check_recipient_partners(extra_email).done(function () { var context = { + 'default_model': default_composition_mode == 'reply' ? undefined : self.context.default_model, + 'default_res_id': default_composition_mode == 'reply' ? undefined : self.context.default_res_id, 'default_composition_mode': default_composition_mode, - 'default_parent_id': this.id, - 'default_body': mail.ChatterUtils.get_text2html(this.$el ? (this.$el.find('textarea:not(.oe_compact)').val() || '') : ''), - 'default_attachment_ids': this.attachment_ids, + 'default_parent_id': self.id, + 'default_body': mail.ChatterUtils.get_text2html(self.$el ? (self.$el.find('textarea:not(.oe_compact)').val() || '') : ''), + 'default_attachment_ids': self.attachment_ids, + 'default_partner_ids': _.map(_.filter(self.partners_from, function (f) {return f[1]}), function (f) {return f[0]}), }; - } else { - var context = { - 'default_model': this.context.default_model, - 'default_res_id': this.context.default_res_id, - 'default_composition_mode': default_composition_mode, - 'default_parent_id': this.id, - 'default_body': mail.ChatterUtils.get_text2html(this.$el ? (this.$el.find('textarea:not(.oe_compact)').val() || '') : ''), - 'default_attachment_ids': this.attachment_ids, + var action = { + type: 'ir.actions.act_window', + res_model: 'mail.compose.message', + view_mode: 'form', + view_type: 'form', + views: [[false, 'form']], + target: 'new', + context: context, }; - } - var action = { - type: 'ir.actions.act_window', - res_model: 'mail.compose.message', - view_mode: 'form', - view_type: 'form', - views: [[false, 'form']], - target: 'new', - context: context, - }; - this.do_action(action); - this.on_cancel(); + self.do_action(action); + self.on_cancel(); + }); + }, reinit: function() { @@ -564,14 +563,13 @@ openerp.mail = function (session) { check_recipient_partners: function (emails) { var self = this; + self.partners_from = []; var deferreds = []; - for (var i = 0; i < emails.length; i++) { - deferreds.push($.Deferred()); - } var ds_partner = new session.web.DataSetSearch(this, 'res.partner'); _.each(emails, function (email) { - ds_partner.call('search', [[['email', 'ilike', email]]]).then(function (partner_ids) { - var deferred = deferreds[_.indexOf(emails, email)]; + var deferred = $.Deferred(); + deferreds.push(deferred); + ds_partner.call('search', [[['email', 'like', email]]]).then(function (partner_ids) { if (!partner_ids.length) { var pop = new session.web.form.FormOpenPopup(this); pop.show_element( @@ -586,17 +584,22 @@ openerp.mail = function (session) { title: _t("Please complete partner's informations"), } ); - pop.on('write_completed, closed', self, function () { + pop.on('closed', self, function () { + deferred.resolve(); + }); + pop.on('saved', self, function (id) { + self.partners_from.push([id, true]); deferred.resolve(); }); } else { + self.partners_from.push([partner_ids[0], true]); deferred.resolve(); } return deferred; }); }); - return $.when.apply( $, deferreds ).done(); + return $.when.apply( $, deferreds ); }, on_message_post: function (event) { @@ -639,7 +642,7 @@ openerp.mail = function (session) { /* convert the compact mode into the compose message */ on_compose_expandable: function (event) { - this.get_emails_from(); + this.get_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(); @@ -664,7 +667,7 @@ openerp.mail = function (session) { } }, - get_emails_from: function () { + get_from: function () { var self = this; var messages = []; @@ -678,13 +681,12 @@ openerp.mail = function (session) { _.each(this.options.root_thread.messages, function (msg) {messages.push(msg); messages.concat(msg.get_childs());}); } - var emails_from = _.map(_.filter(messages, - function (thread) {return thread.author_id && !thread.author_id[0];}), - function (thread) {return thread.author_id[1];}); + _.each(messages, function (thread) { + if (thread.author_id && !thread.author_id[0] && + !_.find(self.emails_from, function (from) {return from[0] == thread.author_id[1];})) { + + self.emails_from.push([thread.author_id[1], true]); - return _.each(emails_from, function (email_from) { - if (!_.find(self.emails_from, function (from) {return from[0] == email_from;})) { - self.emails_from.push([email_from, true]); } }); }, @@ -697,7 +699,7 @@ openerp.mail = function (session) { email_from[1] = $input.is(":checked"); } }); - } + }, }); /** From 8758afd045e7ac7d7f630cfa02b871012c06b547 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Mon, 31 Dec 2012 15:35:33 +0100 Subject: [PATCH 02/14] [IMP] mail: js: get_from back to get_emails_from bzr revid: chm@openerp.com-20121231143533-lpo5f2eg20zkf2el --- 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 953cc907f25..41adf0b2ab0 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -642,7 +642,7 @@ openerp.mail = function (session) { /* convert the compact mode into the compose message */ on_compose_expandable: function (event) { - this.get_from(); + 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(); @@ -667,7 +667,7 @@ openerp.mail = function (session) { } }, - get_from: function () { + get_emails_from: function () { var self = this; var messages = []; From e40b49a83884d68a6c6e37c882e490da93c5a040 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Fri, 4 Jan 2013 12:10:04 +0100 Subject: [PATCH 03/14] [IMP] mail: htmlEntities for the author email, select list of new partner by real email bzr revid: chm@openerp.com-20130104111004-9l0hb6zu33o5b2v6 --- addons/mail/mail_thread.py | 2 +- addons/mail/static/src/js/mail.js | 43 +++++++++++++++++++---------- addons/mail/static/src/xml/mail.xml | 8 +++--- 3 files changed, 33 insertions(+), 20 deletions(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 5054bf89b8c..71ef8fa964a 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -914,7 +914,7 @@ class mail_thread(osv.AbstractModel): for email in extra_emails: partner_id = partner_obj.find_or_create(cr, uid, email, context=context) # link mail with this from mail to the new partner id - partner_msg_ids = mail_message_obj.search(cr, SUPERUSER_ID, [('email_from', '=', email), ('author_id', '=', False)], context=context) + partner_msg_ids = mail_message_obj.search(cr, SUPERUSER_ID, ['|', ('email_from', '=', email), ('email_from', 'ilike', '<%s>' % email), ('author_id', '=', False)], context=context) if partner_id and partner_msg_ids: mail_message_obj.write(cr, SUPERUSER_ID, partner_msg_ids, {'email_from': None, 'author_id': partner_id}, context=context) partner_ids.add((4, partner_id)) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 41adf0b2ab0..56494a3aa91 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -253,7 +253,14 @@ openerp.mail = function (session) { } else { this.avatar = mail.ChatterUtils.get_image(this.session, 'res.users', 'image_small', this.session.uid); } - + if (this.author_id) { + 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]); + } + } }, @@ -505,8 +512,7 @@ openerp.mail = function (session) { } // create list of new partners - var extra_email = _.map(_.filter(this.emails_from, function (f) {return f[1]}), function (f) {return f[0]}); - this.check_recipient_partners(extra_email).done(function () { + this.check_recipient_partners().done(function () { var context = { 'default_model': default_composition_mode == 'reply' ? undefined : self.context.default_model, 'default_res_id': default_composition_mode == 'reply' ? undefined : self.context.default_res_id, @@ -561,22 +567,31 @@ openerp.mail = function (session) { } }, - check_recipient_partners: function (emails) { + check_recipient_partners: function () { var self = this; - self.partners_from = []; + var emails = []; + _.each(this.emails_from, function (email_from) { + if (email_from[1]) { + if (!_.find(emails, function (email) {return email[4] == email_from[0][4];})) { + emails.push(email_from[0]); + } + } + }); var deferreds = []; var ds_partner = new session.web.DataSetSearch(this, 'res.partner'); + this.partners_from = []; _.each(emails, function (email) { var deferred = $.Deferred(); deferreds.push(deferred); - ds_partner.call('search', [[['email', 'like', email]]]).then(function (partner_ids) { + ds_partner.call('search', [[['email', 'like', email[4]]]]).then(function (partner_ids) { if (!partner_ids.length) { var pop = new session.web.form.FormOpenPopup(this); pop.show_element( 'res.partner', 0, { - 'default_email': email, + 'default_email': email[4], + 'default_name': email[3], 'force_email': true, 'ref': "compound_context", }, @@ -606,8 +621,7 @@ openerp.mail = function (session) { var self = this; if (this.do_check_attachment_upload() && (this.attachment_ids.length || this.$('textarea').val().match(/\S+/))) { // create list of new partners - var extra_email = _.map(_.filter(this.emails_from, function (f) {return f[1]}), function (f) {return f[0]}); - this.check_recipient_partners(extra_email).done(function () { + this.check_recipient_partners().done(function () { self.do_send_message_post(); }); } @@ -621,7 +635,7 @@ openerp.mail = function (session) { 'subject': false, 'parent_id': this.context.default_parent_id, 'attachment_ids': _.map(this.attachment_ids, function (file) {return file.id;}), - 'extra_emails': _.map(_.filter(this.emails_from, function (f) {return f[1]}), function (f) {return f[0]}), + 'extra_emails': _.map(_.filter(this.emails_from, function (f) {return f[1]}), function (f) {return f[0][4]}), 'context': this.parent_thread.context, }).done(function (message_id) { var thread = self.parent_thread; @@ -683,19 +697,18 @@ openerp.mail = function (session) { _.each(messages, function (thread) { if (thread.author_id && !thread.author_id[0] && - !_.find(self.emails_from, function (from) {return from[0] == thread.author_id[1];})) { - - self.emails_from.push([thread.author_id[1], true]); - + !_.find(self.emails_from, function (from) {return from[0][4] == thread.author_id[4];})) { + self.emails_from.push([thread.author_id, true]); } }); + return self.emails_from; }, on_checked_email_from: function (event) { var $input = $(event.target); var email = $input.attr("data"); _.each(this.emails_from, function (email_from) { - if (email_from[0] == email) { + if (email_from[0][4] == email) { email_from[1] = $input.is(":checked"); } }); diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index c1a32a2fe89..63f8a10658f 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -132,8 +132,8 @@
@@ -243,8 +243,8 @@
- - + + • • From ee08ed5a57ce978f14054e7eb6b0b714f28e49f4 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Fri, 4 Jan 2013 15:48:33 +0100 Subject: [PATCH 04/14] [FIX] mail: default_partner_ids bzr revid: chm@openerp.com-20130104144833-1wf6fc00jl6vrmri --- addons/mail/static/src/js/mail.js | 18 ++++++++++-------- addons/mail/wizard/mail_compose_message.py | 1 + 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 56494a3aa91..fc6ddb5efde 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -514,14 +514,17 @@ openerp.mail = function (session) { // create list of new partners this.check_recipient_partners().done(function () { var context = { - 'default_model': default_composition_mode == 'reply' ? undefined : self.context.default_model, - 'default_res_id': default_composition_mode == 'reply' ? undefined : self.context.default_res_id, 'default_composition_mode': default_composition_mode, 'default_parent_id': self.id, 'default_body': mail.ChatterUtils.get_text2html(self.$el ? (self.$el.find('textarea:not(.oe_compact)').val() || '') : ''), 'default_attachment_ids': self.attachment_ids, 'default_partner_ids': _.map(_.filter(self.partners_from, function (f) {return f[1]}), function (f) {return f[0]}), }; + if (default_composition_mode != 'reply' && self.context.default_model && self.context.default_res_id) { + context.default_model = self.context.default_model; + context.default_res_id = self.context.default_res_id; + } + var action = { type: 'ir.actions.act_window', res_model: 'mail.compose.message', @@ -570,19 +573,19 @@ openerp.mail = function (session) { check_recipient_partners: function () { var self = this; var emails = []; + var deferreds = []; _.each(this.emails_from, function (email_from) { if (email_from[1]) { if (!_.find(emails, function (email) {return email[4] == email_from[0][4];})) { emails.push(email_from[0]); + deferreds.push($.Deferred()); } } }); - var deferreds = []; - var ds_partner = new session.web.DataSetSearch(this, 'res.partner'); this.partners_from = []; - _.each(emails, function (email) { - var deferred = $.Deferred(); - deferreds.push(deferred); + var ds_partner = new session.web.DataSetSearch(this, 'res.partner'); + _.each(emails, function (email, key) { + var deferred = deferreds[key]; ds_partner.call('search', [[['email', 'like', email[4]]]]).then(function (partner_ids) { if (!partner_ids.length) { var pop = new session.web.form.FormOpenPopup(this); @@ -611,7 +614,6 @@ openerp.mail = function (session) { self.partners_from.push([partner_ids[0], true]); deferred.resolve(); } - return deferred; }); }); return $.when.apply( $, deferreds ); diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py index 0062b5e01bd..229d72455d1 100644 --- a/addons/mail/wizard/mail_compose_message.py +++ b/addons/mail/wizard/mail_compose_message.py @@ -168,6 +168,7 @@ class mail_compose_message(osv.TransientModel): reply_subject = "%s %s" % (re_prefix, reply_subject) # get partner_ids from original message partner_ids = [partner.id for partner in message_data.partner_ids] if message_data.partner_ids else [] + partner_ids += context.get('default_partner_ids') or [] # update the result result = { From fee9f63912c29ea7cac0e22736a17e1445a6e5e3 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Tue, 8 Jan 2013 13:43:10 +0100 Subject: [PATCH 05/14] [IMP] mail: create new partner with email from bzr revid: chm@openerp.com-20130108124310-le3hx95yn3jhfhaq --- addons/mail/mail_thread.py | 54 ++++++++++++++------ addons/mail/static/src/js/mail.js | 83 ++++++++++++++----------------- 2 files changed, 76 insertions(+), 61 deletions(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index b757e80759d..0cdaaeb339b 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -28,6 +28,7 @@ import pytz import time import xmlrpclib from email.message import Message +import re from openerp import tools from openerp import SUPERUSER_ID @@ -906,8 +907,41 @@ class mail_thread(osv.AbstractModel): return mail_message.create(cr, uid, values, context=context) + def new_email_partner(self, cr, uid, emails, context=None): + """ Convert a list of emails into a list partner_ids and a list new_partner_ids + """ + partner_obj = self.pool.get('res.partner') + mail_message_obj = self.pool.get('mail.message') + + partner_ids = [] + new_partner_ids = [] + 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) + if ids: + partner_ids += ids + else: + + partner_id = partner_obj.create(cr, uid, { + 'name': name or email, + 'email': email, + }, context=context) + new_partner_ids.append(partner_id) + + # 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, + } + + def message_post_user_api(self, cr, uid, thread_id, body='', parent_id=False, - attachment_ids=None, extra_emails=None, content_subtype='plaintext', + attachment_ids=None, content_subtype='plaintext', context=None, **kwargs): """ Wrapper on message_post, used for user input : - mail gateway @@ -922,22 +956,8 @@ class mail_thread(osv.AbstractModel): to the related document. Should only be set by Chatter. - extra_email: [ 'Fabien ', 'al@openerp.com' ] """ - partner_obj = self.pool.get('res.partner') mail_message_obj = self.pool.get('mail.message') ir_attachment = self.pool.get('ir.attachment') - extra_emails = extra_emails or [] - - # 1.A.1: pre-process partners and incoming extra_emails - partner_ids = set([]) - for email in extra_emails: - partner_id = partner_obj.find_or_create(cr, uid, email, context=context) - # link mail with this from mail to the new partner id - partner_msg_ids = mail_message_obj.search(cr, SUPERUSER_ID, ['|', ('email_from', '=', email), ('email_from', 'ilike', '<%s>' % email), ('author_id', '=', False)], context=context) - if partner_id and partner_msg_ids: - mail_message_obj.write(cr, SUPERUSER_ID, partner_msg_ids, {'email_from': None, 'author_id': partner_id}, context=context) - partner_ids.add((4, partner_id)) - if partner_ids: - self.message_subscribe(cr, uid, [thread_id], [item[1] for item in partner_ids], context=context) # 1.A.2: add recipients of parent message if parent_id: @@ -948,7 +968,9 @@ class mail_thread(osv.AbstractModel): partner_ids.add((4, parent_message.author_id.id)) # 1.A.3: add specified recipients - partner_ids |= set(kwargs.pop('partner_ids', [])) + partner_ids = set(kwargs.pop('partner_ids', [])) + if partner_ids: + self.message_subscribe(cr, uid, [thread_id], [id for id in partner_ids], context=context) # 1.B: handle body, message_type and message_subtype if content_subtype == 'plaintext': diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index fc6ddb5efde..56e06006e8d 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -512,13 +512,13 @@ openerp.mail = function (session) { } // create list of new partners - this.check_recipient_partners().done(function () { + this.check_recipient_partners().done(function (partner_ids) { var context = { 'default_composition_mode': default_composition_mode, 'default_parent_id': self.id, 'default_body': mail.ChatterUtils.get_text2html(self.$el ? (self.$el.find('textarea:not(.oe_compact)').val() || '') : ''), 'default_attachment_ids': self.attachment_ids, - 'default_partner_ids': _.map(_.filter(self.partners_from, function (f) {return f[1]}), function (f) {return f[0]}), + 'default_partner_ids': partner_ids, }; if (default_composition_mode != 'reply' && self.context.default_model && self.context.default_res_id) { context.default_model = self.context.default_model; @@ -572,72 +572,64 @@ openerp.mail = function (session) { check_recipient_partners: function () { var self = this; + var partners_from = []; var emails = []; - var deferreds = []; _.each(this.emails_from, function (email_from) { - if (email_from[1]) { - if (!_.find(emails, function (email) {return email[4] == email_from[0][4];})) { - emails.push(email_from[0]); - deferreds.push($.Deferred()); - } + if (email_from[1] && !_.find(emails, function (email) {return email == email_from[0][4];})) { + emails.push(email_from[0][1]); } }); - this.partners_from = []; - var ds_partner = new session.web.DataSetSearch(this, 'res.partner'); - _.each(emails, function (email, key) { - var deferred = deferreds[key]; - ds_partner.call('search', [[['email', 'like', email[4]]]]).then(function (partner_ids) { - if (!partner_ids.length) { - var pop = new session.web.form.FormOpenPopup(this); - pop.show_element( - 'res.partner', - 0, - { - 'default_email': email[4], - 'default_name': email[3], - 'force_email': true, - 'ref': "compound_context", - }, - { - title: _t("Please complete partner's informations"), - } - ); - pop.on('closed', self, function () { - deferred.resolve(); - }); - pop.on('saved', self, function (id) { - self.partners_from.push([id, true]); - deferred.resolve(); - }); - } - else { - self.partners_from.push([partner_ids[0], true]); + var deferred_check = $.Deferred(); + self.parent_thread.ds_thread._model.call('new_email_partner', [emails]).then(function (partners) { + partners_from = _.clone(partners.partner_ids); + var deferreds = []; + _.each(partners.new_partner_ids, function (id) { + var deferred = $.Deferred() + deferreds.push(deferred); + var pop = new session.web.form.FormOpenPopup(this); + pop.show_element( + 'res.partner', + id, + { + 'force_email': true, + 'ref': "compound_context", + }, + { + title: _t("Please complete partner's informations"), + } + ); + pop.on('closed', self, function () { deferred.resolve(); - } + }); + partners_from.push(id); + }); + $.when.apply( $, deferreds ).then(function () { + deferred_check.resolve(partners_from); }); }); - return $.when.apply( $, deferreds ); + return deferred_check; }, on_message_post: function (event) { var self = this; 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 () { - self.do_send_message_post(); + this.check_recipient_partners().done(function (partner_ids) { + self.do_send_message_post(partner_ids); }); } }, /*do post a message and fetch the message*/ - do_send_message_post: function () { + do_send_message_post: function (partner_ids) { var self = this; + console.log(partner_ids); this.parent_thread.ds_thread._model.call('message_post_user_api', [this.context.default_res_id], { 'body': this.$('textarea').val(), 'subject': false, 'parent_id': this.context.default_parent_id, 'attachment_ids': _.map(this.attachment_ids, function (file) {return file.id;}), - 'extra_emails': _.map(_.filter(this.emails_from, function (f) {return f[1]}), function (f) {return f[0][4]}), + 'partner_ids': partner_ids, 'context': this.parent_thread.context, }).done(function (message_id) { var thread = self.parent_thread; @@ -1707,7 +1699,6 @@ openerp.mail = function (session) { this.defaults[key.replace(/^search_default_/, '')] = this.context[key]; } } - this.action.params = _.extend({ 'display_indented_thread': 1, 'show_reply_button': true, @@ -1751,11 +1742,13 @@ openerp.mail = function (session) { * @param {Object} defaults ?? */ load_searchview: function (defaults) { + var self = this; var ds_msg = new session.web.DataSetSearch(this, 'mail.message'); this.searchview = new session.web.SearchView(this, ds_msg, false, defaults || {}, false); this.searchview.appendTo(this.$('.oe_view_manager_view_search')) .then(function () { self.searchview.on('search_data', self, self.do_searchview_search); }); + console.log(this.searchview); if (this.searchview.has_defaults) { this.searchview.ready.then(this.searchview.do_search); } From f91fc3b74fdb481fd71305970346457144d7d935 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 8 Jan 2013 14:07:16 +0100 Subject: [PATCH 06/14] [FIX] message_post: now handles partner_ids parameter with extra-caution, creating a set of sets. If partner_ids is a list of ids, or a list of commands under list form, this should work as well. bzr revid: tde@openerp.com-20130108130716-hea1fomxog5an61r --- addons/mail/mail_thread.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index af18abb67e5..fc6d4ad9dd2 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -948,7 +948,15 @@ class mail_thread(osv.AbstractModel): partner_ids.add((4, parent_message.author_id.id)) # 1.A.3: add specified recipients - partner_ids |= set(kwargs.pop('partner_ids', [])) + param_partner_ids = set() + for item in kwargs.pop('partner_ids', []): + if isinstance(item, (list)): + param_partner_ids.add((item[0], item[1])) + elif isinstance(item, (int, long)): + param_partner_ids.add((4, item)) + else: + param_partner_ids.add(item) + partner_ids |= param_partner_ids # 1.B: handle body, message_type and message_subtype if content_subtype == 'plaintext': From a34d7a8edae1b5efcd23c826670abf7f52ed33b4 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Tue, 8 Jan 2013 14:28:19 +0100 Subject: [PATCH 07/14] [IMP] mail: js partner_ids bzr revid: chm@openerp.com-20130108132819-vb7lv8mt11n1r3bv --- addons/mail/static/src/js/mail.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 56e06006e8d..a150f16a4e6 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -623,13 +623,12 @@ openerp.mail = function (session) { /*do post a message and fetch the message*/ do_send_message_post: function (partner_ids) { var self = this; - console.log(partner_ids); this.parent_thread.ds_thread._model.call('message_post_user_api', [this.context.default_res_id], { '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, + 'partner_ids': _.map(partner_ids, function (val){return [4, val];}), 'context': this.parent_thread.context, }).done(function (message_id) { var thread = self.parent_thread; @@ -1748,7 +1747,6 @@ openerp.mail = function (session) { this.searchview = new session.web.SearchView(this, ds_msg, false, defaults || {}, false); this.searchview.appendTo(this.$('.oe_view_manager_view_search')) .then(function () { self.searchview.on('search_data', self, self.do_searchview_search); }); - console.log(this.searchview); if (this.searchview.has_defaults) { this.searchview.ready.then(this.searchview.do_search); } From 10b92b71d82fadfbeec77fb40b2c2060c9eb043d Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Tue, 8 Jan 2013 14:44:24 +0100 Subject: [PATCH 08/14] [IMP] mail: all email checked create a partner and associate the email from bzr revid: chm@openerp.com-20130108134424-dthns93bf0w59juf --- addons/mail/mail_thread.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index f39e04cafaf..ebda706c476 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -921,19 +921,19 @@ class mail_thread(osv.AbstractModel): email = m.group(3) ids = partner_obj.search(cr, SUPERUSER_ID, [('email', '=', email)], context=context) if ids: - partner_ids += ids + partner_id = ids[0] + partner_ids.append(partner_id) else: - partner_id = partner_obj.create(cr, uid, { 'name': name or email, 'email': email, }, context=context) new_partner_ids.append(partner_id) - # 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) + # 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, From 06d08603cc5a09eb7e8eaa064ee572234d49fd30 Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Tue, 8 Jan 2013 15:20:21 +0100 Subject: [PATCH 09/14] [FIX] mail: when creating a new object from incoming mail, don't call default_get before the call to super(). The create method from the orm is adding default missing value itself. It is also the cause of a bug on stage selection because custom code in create() is not run when stage_id is given in vals (and it's filled here by default_get() but return a wrong value as context cannot be used from incomming mail). bzr revid: qdp-launchpad@openerp.com-20130108142021-thtla3868hqvqs0o --- addons/mail/mail_thread.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index af18abb67e5..cb6d5856517 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -647,14 +647,14 @@ class mail_thread(osv.AbstractModel): """ if context is None: context = {} + data = {} + if isinstance(custom_values, dict): + data = custom_values.copy() model = context.get('thread_model') or self._name model_pool = self.pool.get(model) fields = model_pool.fields_get(cr, uid, context=context) - data = model_pool.default_get(cr, uid, fields, context=context) if 'name' in fields and not data.get('name'): data['name'] = msg_dict.get('subject', '') - if custom_values and isinstance(custom_values, dict): - data.update(custom_values) res_id = model_pool.create(cr, uid, data, context=context) return res_id From 161caa2c0ed7de5f8949ae601d2001a56866325c Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Tue, 8 Jan 2013 16:18:05 +0100 Subject: [PATCH 10/14] [IMP] account, usability: changed the label of button to reopen account.period bzr revid: qdp-launchpad@openerp.com-20130108151805-qy4y47q5dnqm33u9 --- addons/account/account_view.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/account/account_view.xml b/addons/account/account_view.xml index c8246a187f5..5e072c3d258 100644 --- a/addons/account/account_view.xml +++ b/addons/account/account_view.xml @@ -97,7 +97,7 @@
From cf4c6b442e6e23a0ee8f2d63125acd4055af3af5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 8 Jan 2013 17:13:32 +0100 Subject: [PATCH 11/14] [CLEAN] Some code cleaning. bzr revid: tde@openerp.com-20130108161332-e1ekhtneh0mryhno --- addons/mail/mail_thread.py | 73 +++++++++++----------- addons/mail/static/src/js/mail.js | 3 +- addons/mail/wizard/mail_compose_message.py | 2 +- 3 files changed, 40 insertions(+), 38 deletions(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index ebda706c476..872623ffe69 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -25,10 +25,10 @@ import dateutil import email import logging import pytz +import re import time import xmlrpclib from email.message import Message -import re from openerp import tools from openerp import SUPERUSER_ID @@ -820,6 +820,41 @@ class mail_thread(osv.AbstractModel): "now deprecated res.log.") self.message_post(cr, uid, [id], message, context=context) + def message_get_partners_from_emails(self, cr, uid, emails, 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 = [] + 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) + if ids: + partner_ids.append(ids[0]) + else: + partner_id = partner_obj.create(cr, uid, { + 'name': name or email, + 'email': email, + }, context=context) + new_partner_ids.append(partner_id) + + # 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, + } + def message_post(self, cr, uid, thread_id, body='', subject=None, type='notification', subtype=None, parent_id=False, attachments=None, context=None, **kwargs): """ Post a new message in an existing thread, returning the new @@ -907,39 +942,6 @@ class mail_thread(osv.AbstractModel): return mail_message.create(cr, uid, values, context=context) - def new_email_partner(self, cr, uid, emails, context=None): - """ Convert a list of emails into a list partner_ids and a list new_partner_ids - """ - partner_obj = self.pool.get('res.partner') - mail_message_obj = self.pool.get('mail.message') - - partner_ids = [] - new_partner_ids = [] - 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) - if ids: - partner_id = ids[0] - partner_ids.append(partner_id) - else: - partner_id = partner_obj.create(cr, uid, { - 'name': name or email, - 'email': email, - }, context=context) - new_partner_ids.append(partner_id) - - # 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, - } - - def message_post_user_api(self, cr, uid, thread_id, body='', parent_id=False, attachment_ids=None, content_subtype='plaintext', context=None, **kwargs): @@ -979,7 +981,8 @@ class mail_thread(osv.AbstractModel): param_partner_ids.add(item) partner_ids |= param_partner_ids - # 1.A.3: add recipients as follower + # 1.A.3: add parameters recipients as follower + # TDE FIXME in 7.1: should check whether this comes from email_list or partner_ids if param_partner_ids: self.message_subscribe(cr, uid, [thread_id], [pid[1] for pid in param_partner_ids], context=context) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 9d77df57d06..d5df305e336 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -580,7 +580,7 @@ openerp.mail = function (session) { } }); var deferred_check = $.Deferred(); - self.parent_thread.ds_thread._model.call('new_email_partner', [emails]).then(function (partners) { + self.parent_thread.ds_thread._model.call('message_get_partners_from_emails', [emails]).then(function (partners) { partners_from = _.clone(partners.partner_ids); var deferreds = []; _.each(partners.new_partner_ids, function (id) { @@ -1741,7 +1741,6 @@ openerp.mail = function (session) { * @param {Object} defaults ?? */ load_searchview: function (defaults) { - var self = this; var ds_msg = new session.web.DataSetSearch(this, 'mail.message'); this.searchview = new session.web.SearchView(this, ds_msg, false, defaults || {}, false); diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py index 229d72455d1..ec0c2a8de06 100644 --- a/addons/mail/wizard/mail_compose_message.py +++ b/addons/mail/wizard/mail_compose_message.py @@ -168,7 +168,7 @@ class mail_compose_message(osv.TransientModel): reply_subject = "%s %s" % (re_prefix, reply_subject) # get partner_ids from original message partner_ids = [partner.id for partner in message_data.partner_ids] if message_data.partner_ids else [] - partner_ids += context.get('default_partner_ids') or [] + partner_ids += context.get('default_partner_ids', []) # update the result result = { From c46be224e6f81309bd2a4bd23b97097a5b1c0051 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Tue, 8 Jan 2013 17:21:30 +0100 Subject: [PATCH 12/14] [IMP] mail_followers: hide hr when there are no subtype bzr revid: chm@openerp.com-20130108162130-e390u7s1duf3yj3r --- addons/mail/static/src/js/mail_followers.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/addons/mail/static/src/js/mail_followers.js b/addons/mail/static/src/js/mail_followers.js index 1fc93781039..9f88116acc7 100644 --- a/addons/mail/static/src/js/mail_followers.js +++ b/addons/mail/static/src/js/mail_followers.js @@ -221,11 +221,14 @@ openerp_mail_followers = function(session, mail) { var nb_subtype = 0; _(records).each(function (record) {nb_subtype++;}); if (nb_subtype > 1) { + this.$('hr').show(); _(records).each(function (record, record_name) { record.name = record_name; record.followed = record.followed || undefined; $(session.web.qweb.render('mail.followers.subtype', {'record': record})).appendTo( self.$('.oe_subtype_list') ); }); + } else { + this.$('hr').hide(); } }, From f43e6599e5f4a6e00f73cc52598e04cca18014a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 8 Jan 2013 17:25:39 +0100 Subject: [PATCH 13/14] [CLEAN] Renamed a method, deleted a now useless comment. bzr revid: tde@openerp.com-20130108162539-0xtqg98v5por2b95 --- addons/mail/mail_thread.py | 3 +-- addons/mail/static/src/js/mail.js | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 872623ffe69..7489779fd17 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -820,7 +820,7 @@ class mail_thread(osv.AbstractModel): "now deprecated res.log.") self.message_post(cr, uid, [id], message, context=context) - def message_get_partners_from_emails(self, cr, uid, emails, context=None): + def message_create_partners_from_emails(self, cr, uid, emails, 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. @@ -956,7 +956,6 @@ class mail_thread(osv.AbstractModel): - type and subtype: comment and mail.mt_comment by default - attachment_ids: supposed not attached to any document; attach them to the related document. Should only be set by Chatter. - - extra_email: [ 'Fabien ', 'al@openerp.com' ] """ mail_message_obj = self.pool.get('mail.message') ir_attachment = self.pool.get('ir.attachment') diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index d5df305e336..e08afdad217 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -580,7 +580,7 @@ openerp.mail = function (session) { } }); var deferred_check = $.Deferred(); - self.parent_thread.ds_thread._model.call('message_get_partners_from_emails', [emails]).then(function (partners) { + 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) { From b8180f4c09995a76e5f1e6ca1ff868a9bdff7d31 Mon Sep 17 00:00:00 2001 From: niv-openerp Date: Tue, 8 Jan 2013 17:41:04 +0100 Subject: [PATCH 14/14] [FIX] problem when multiple instances of the web client run in tabs and we disconnect from one tab, now displays a better error message lp bug: https://launchpad.net/bugs/1093671 fixed bzr revid: nicolas.vanhoren@openerp.com-20130108164104-7wv2yxlrczqmicvb --- addons/web/session.py | 5 +++++ addons/web/static/src/js/chrome.js | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/addons/web/session.py b/addons/web/session.py index fa99f58afa8..30e9308d4e1 100644 --- a/addons/web/session.py +++ b/addons/web/session.py @@ -18,6 +18,9 @@ _logger = logging.getLogger(__name__) class AuthenticationError(Exception): pass +class SessionExpiredException(Exception): + pass + class Service(object): def __init__(self, session, service_name): self.session = session @@ -152,6 +155,8 @@ class OpenERPSession(object): :type model: str :rtype: a model object """ + if self._db == False: + raise SessionExpiredException("Session expired") return Model(self, model) diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index 26d30ea98a2..30a51026684 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -247,6 +247,11 @@ instance.web.CrashManager = instance.web.Class.extend({ if (!this.active) { return; } + // yes, exception handling is shitty + if (error.code === 300 && error.data && error.data.type == "client_exception" && error.data.debug.match("SessionExpiredException")) { + this.show_warning({type: "Session Expired", data: { fault_code: "Your OpenERP session expired. Please refresh the current web page." }}); + return; + } if (error.data.fault_code) { var split = ("" + error.data.fault_code).split('\n')[0].split(' -- '); if (split.length > 1) {