From 40b1c95e1a0932f4d1f87bf9894a169b2c9e57ff Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Thu, 20 Dec 2012 13:31:22 +0100 Subject: [PATCH 01/29] [IMP]mail: display checkbox for allow to add email (from email_from value) for creating partner and send email to this new partners. bzr revid: chm@openerp.com-20121220123122-qsqn8w97t1tre3cq --- addons/mail/mail_thread.py | 13 ++++-- addons/mail/res_users.py | 10 +++-- addons/mail/static/src/css/mail.css | 8 ++++ addons/mail/static/src/js/mail.js | 70 +++++++++++++++++++++++------ addons/mail/static/src/xml/mail.xml | 9 +++- 5 files changed, 88 insertions(+), 22 deletions(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 48bdef508d0..cb07cb91a6f 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -749,8 +749,8 @@ class mail_thread(osv.AbstractModel): return mail_message.create(cr, uid, values, context=context) def message_post_user_api(self, cr, uid, thread_id, body='', subject=False, parent_id=False, - attachment_ids=None, context=None, content_subtype='plaintext', - extra_email=[], **kwargs): + attachment_ids=None, extra_email=[], + context=None, content_subtype='plaintext', **kwargs): """ Wrapper on message_post, used for user input : - mail gateway - quick reply in Chatter (refer to mail.js), not @@ -771,13 +771,20 @@ class mail_thread(osv.AbstractModel): if content_subtype == 'plaintext': body = tools.plaintext2html(body) + partner_ids = kwargs.pop('partner_ids', []) + for partner in extra_email: part_ids = self.pool.get('res.partner').search(cr, uid, [('email', '=', partner)], context=context) if not part_ids: part_ids = [self.pool.get('res.partner').name_create(cr, uid, partner, context=context)[0]] self.message_subscribe(cr, uid, [thread_id], part_ids, context=context) - partner_ids = kwargs.pop('partner_ids', []) + message_ids = mail_message.search(cr, uid, [('email_from', '=', partner)], context=context) + if part_ids and message_ids: + mail_message.write(cr, uid, message_ids, {'email_from': None, 'author_id': part_ids[0]}, context=context) + + partner_ids = set(partner_ids) + set(part_ids) + if parent_id: parent_message = self.pool.get('mail.message').browse(cr, uid, parent_id, context=context) partner_ids += [(4, partner.id) for partner in parent_message.partner_ids] diff --git a/addons/mail/res_users.py b/addons/mail/res_users.py index 4c6bf6e150d..24c9c185d4d 100644 --- a/addons/mail/res_users.py +++ b/addons/mail/res_users.py @@ -116,8 +116,10 @@ class res_users(osv.Model): alias_pool.unlink(cr, uid, alias_ids, context=context) return res + def message_post_user_api(self, cr, uid, thread_id, body='', subject=False, parent_id=False, - attachment_ids=None, context=None, content_subtype='plaintext', **kwargs): + attachment_ids=None, extra_email=[], + context=None, content_subtype='plaintext', **kwargs): """ Redirect the posting of message on res.users to the related partner. This is done because when giving the context of Chatter on the various mailboxes, we do not have access to the current partner_id. @@ -128,8 +130,10 @@ class res_users(osv.Model): if isinstance(thread_id, (list, tuple)): thread_id = thread_id[0] partner_id = self.browse(cr, uid, thread_id).partner_id.id - return self.pool.get('res.partner').message_post_user_api(cr, uid, partner_id, body=body, subject=subject, - parent_id=parent_id, attachment_ids=attachment_ids, context=context, content_subtype=content_subtype, **kwargs) + return self.pool.get('res.partner').message_post_user_api(cr, uid, + partner_id, body=body, subject=subject, parent_id=parent_id, + attachment_ids=attachment_ids, extra_email=extra_email, + context=context, content_subtype=content_subtype, **kwargs) def message_post(self, cr, uid, thread_id, context=None, **kwargs): """ Redirect the posting of message on res.users to the related partner. diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css index e154e285f39..886199a668b 100644 --- a/addons/mail/static/src/css/mail.css +++ b/addons/mail/static/src/css/mail.css @@ -253,6 +253,14 @@ .openerp .oe_mail .oe_msg_composer .oe_msg_attachment_list{ display: block; } +.openerp .oe_mail .oe_msg_composer .oe_emails_from label{ + vertical-align: middle; + display: block; + line-height: 16px; +} +.openerp .oe_mail .oe_msg_composer .oe_emails_from input{ + vertical-align: middle; +} .openerp .oe_mail .oe_attachment{ display: inline-block; width: 100px; diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index f873daff9c3..a770b07be17 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -369,6 +369,7 @@ openerp.mail = function (session) { this._super(parent, datasets, options); this.show_compact_message = false; this.show_delete_attachment = true; + this.emails_from = []; }, start: function () { @@ -478,9 +479,11 @@ 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_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_footer').on('mousedown', _.bind( function () { this.stay_open = true; }, this)); + 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)); + var ev_stay = {}; ev_stay.mouseup = ev_stay.keydown = ev_stay.focus = function () { self.stay_open = false; }; this.$('textarea:not(.oe_compact)').on(ev_stay); @@ -491,6 +494,8 @@ openerp.mail = function (session) { // 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); }, on_compose_fullmail: function (default_composition_mode) { @@ -568,21 +573,23 @@ openerp.mail = function (session) { if (this.do_check_attachment_upload() && (this.attachment_ids.length || body.match(/\S+/))) { //session.web.blockUI(); - this.parent_thread.ds_thread.call('message_post_user_api', [ - this.context.default_res_id, - body, - false, - this.context.default_parent_id, - _.map(this.attachment_ids, function (file) {return file.id;}), - this.parent_thread.context - ]).done(function (record) { + var values = [ + this.context.default_res_id, //thread_id + body, //body + false, //subject + this.context.default_parent_id, //parent_id + _.map(this.attachment_ids, function (file) {return file.id;}), //attachment_ids + _.map(_.filter(this.emails_from, function (f) {return f[1]}), function (f) {return f[0]}), //extra_email + this.parent_thread.context, // context + ]; + this.parent_thread.ds_thread.call('message_post_user_api', values).done(function (record) { var thread = self.parent_thread; var root = thread == self.options.root_thread; if (self.options.display_indented_thread < self.thread_level && thread.parent_message) { var thread = thread.parent_message.parent_thread; } // create object and attach to the thread object - thread.message_fetch([['id', 'child_of', [self.id]]], false, [record], function (arg, data) { + thread.message_fetch([["id", "=", record]], false, [record], function (arg, data) { var message = thread.create_message_object( data[0] ); // insert the message on dom thread.insert_message( message, root ? undefined : self.$el, root ); @@ -597,8 +604,8 @@ openerp.mail = function (session) { /* convert the compact mode into the compose message */ on_compose_expandable: function (event) { - - if ((!this.stay_open || (event && event.type == 'click')) && (!this.show_composer || !this.$('textarea:not(.oe_compact)').val().match(/\S+/))) { + 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(); } @@ -620,6 +627,41 @@ openerp.mail = function (session) { if (!this.show_composer) { this.reinit(); } + }, + + get_emails_from: function () { + var self = this; + var messages = []; + + if (this.parent_thread.parent_message) { + // go to the parented message + var message = this.parent_thread.parent_message; + var parent_message = message.parent_id ? message.parent_thread.parent_message : message; + var messages = [parent_message].concat(parent_message.get_childs()); + } else { + // get all wall messages + _.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];}); + + 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]); + } + }); + }, + + 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) { + email_from[1] = $input.is(":checked"); + } + }); } }); @@ -1477,7 +1519,7 @@ openerp.mail = function (session) { $(window).resize( _.bind(this.thread.on_scroll, this.thread) ); this.$el.resize( _.bind(this.thread.on_scroll, this.thread) ); window.setTimeout( _.bind(this.thread.on_scroll, this.thread), 500 ); - } + }, }); diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index 3c510813029..168f32a9d7e 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -27,6 +27,11 @@
+
+ + + +