Browse Source
Merge pull request #105 from ArtyomLosev/9.0-mail_private
Merge pull request #105 from ArtyomLosev/9.0-mail_private
[PORT] mail_private for odoo 9.0pull/117/merge
ILMIR
7 years ago
committed by
GitHub
7 changed files with 95 additions and 223 deletions
-
6mail_private/README.rst
-
6mail_private/__openerp__.py
-
6mail_private/doc/changelog.rst
-
8mail_private/models.py
-
257mail_private/static/src/js/mail_private.js
-
8mail_private/static/src/xml/mail_private.xml
-
27mail_private/view.xml
@ -1,11 +1,9 @@ |
|||||
# -*- coding: utf-8 -*- |
# -*- coding: utf-8 -*- |
||||
|
|
||||
from openerp.osv import osv, fields |
|
||||
|
from openerp import models, fields |
||||
|
|
||||
|
|
||||
class MailComposeMessage(osv.TransientModel): |
|
||||
|
class MailComposeMessage(models.TransientModel): |
||||
_inherit = 'mail.compose.message' |
_inherit = 'mail.compose.message' |
||||
|
|
||||
_columns = { |
|
||||
'private': fields.boolean('Send Internal Message'), |
|
||||
} |
|
||||
|
private = fields.Boolean(string='Send Internal Message') |
@ -1,201 +1,100 @@ |
|||||
openerp.mail_private = function(instance){ |
|
||||
|
odoo.define('mail_private', function (require) { |
||||
|
'use strict'; |
||||
|
|
||||
var mail = instance.mail; |
|
||||
|
var core = require('web.core'); |
||||
|
var Chatter = require('mail.Chatter'); |
||||
|
var chat_manager = require('mail.chat_manager'); |
||||
|
var session = require('web.session'); |
||||
|
var Model = require('web.Model'); |
||||
|
|
||||
instance.mail.ThreadComposeMessage.include({ |
|
||||
init: function (parent, datasets, options) { |
|
||||
|
|
||||
|
Chatter.include({ |
||||
|
init: function () { |
||||
this._super.apply(this, arguments); |
this._super.apply(this, arguments); |
||||
this.private = false; |
this.private = false; |
||||
|
this.events['click .oe_compose_post_private'] = 'on_open_composer_private_message'; |
||||
}, |
}, |
||||
bind_events: function(){ |
|
||||
var self = this; |
|
||||
this.$('.oe_compose_post_private').on('click', self.on_toggle_quick_composer_private); |
|
||||
this._super.apply(this, arguments); |
|
||||
}, |
|
||||
on_compose_fullmail: function (default_composition_mode) { |
|
||||
var self = this; |
|
||||
if(!this.do_check_attachment_upload()) { |
|
||||
return false; |
|
||||
} |
|
||||
var recipient_done = $.Deferred(); |
|
||||
if (this.is_log) { |
|
||||
recipient_done.resolve([]); |
|
||||
} |
|
||||
else { |
|
||||
recipient_done = this.check_recipient_partners(); |
|
||||
} |
|
||||
$.when(recipient_done).done(function (partner_ids) { |
|
||||
var context = { |
|
||||
'default_parent_id': self.id, |
|
||||
'default_body': mail.ChatterUtils.get_text2html(self.$el ? (self.$el.find('textarea:not(.oe_compact)').val() || '') : ''), |
|
||||
'default_attachment_ids': _.map(self.attachment_ids, function (file) {return file.id;}), |
|
||||
'default_partner_ids': partner_ids, |
|
||||
'default_is_log': self.is_log, |
|
||||
'default_private': self.private, |
|
||||
'mail_post_autofollow': true, |
|
||||
'mail_post_autofollow_partner_ids': partner_ids, |
|
||||
'is_private': self.is_private |
|
||||
}; |
|
||||
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', |
|
||||
view_mode: 'form', |
|
||||
view_type: 'form', |
|
||||
views: [[false, 'form']], |
|
||||
target: 'new', |
|
||||
context: context, |
|
||||
}; |
|
||||
|
|
||||
self.do_action(action, { |
|
||||
'on_close': function(){ !self.parent_thread.options.view_inbox && self.parent_thread.message_fetch(); } |
|
||||
}); |
|
||||
self.on_cancel(); |
|
||||
|
on_post_message: function (message) { |
||||
|
var self = this; |
||||
|
if (this.private) { |
||||
|
message.subtype = false; |
||||
|
} |
||||
|
var options = {model: this.model, res_id: this.res_id}; |
||||
|
chat_manager.post_message(message, options).then( |
||||
|
function () { |
||||
|
self.close_composer(); |
||||
|
if (message.partner_ids.length) { |
||||
|
self.refresh_followers(); |
||||
|
} |
||||
|
}).fail(function () { |
||||
|
// todo: display notification
|
||||
}); |
}); |
||||
|
}, |
||||
|
|
||||
}, |
|
||||
do_send_message_post: function (partner_ids, log) { |
|
||||
|
on_open_composer_private_message: function (event) { |
||||
var self = this; |
var self = this; |
||||
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': _.extend(this.parent_thread.context, { |
|
||||
'mail_post_autofollow': true, |
|
||||
'mail_post_autofollow_partner_ids': partner_ids, |
|
||||
'default_private': self.private |
|
||||
}), |
|
||||
'type': 'comment', |
|
||||
'content_subtype': 'plaintext', |
|
||||
}; |
|
||||
if (log || self.private) { |
|
||||
values.subtype = false; |
|
||||
} |
|
||||
else { |
|
||||
values.subtype = 'mail.mt_comment'; |
|
||||
} |
|
||||
this.parent_thread.ds_thread._model.call('message_post', [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) { |
|
||||
var thread = thread.parent_message.parent_thread; |
|
||||
} |
|
||||
// create object and attach to the thread object
|
|
||||
thread.message_fetch([["id", "=", message_id]], false, [message_id], function (arg, data) { |
|
||||
var message = thread.create_message_object( data.slice(-1)[0] ); |
|
||||
// insert the message on dom
|
|
||||
thread.insert_message( message, root ? undefined : self.$el, root ); |
|
||||
}); |
|
||||
self.on_cancel(); |
|
||||
self.flag_post = false; |
|
||||
|
this.private = true; |
||||
|
this.get_recipients_for_internal_message().then(function (data) { |
||||
|
var private_message = 'private_message'; |
||||
|
self.recipients_for_internal_message = data; |
||||
|
self.open_composer(private_message); |
||||
}); |
}); |
||||
}, |
}, |
||||
on_toggle_quick_composer: function (event) { |
|
||||
if (event.target.className == 'oe_compose_post') { |
|
||||
this.recipients = []; |
|
||||
this.private = false; |
|
||||
} |
|
||||
|
|
||||
|
on_open_composer_new_message: function () { |
||||
this._super.apply(this, arguments); |
this._super.apply(this, arguments); |
||||
|
this.private = false; |
||||
}, |
}, |
||||
on_toggle_quick_composer_private: function (event) { |
|
||||
this.recipients = []; |
|
||||
var self = this; |
|
||||
var $input = $(event.target); |
|
||||
this.compute_emails_from(); |
|
||||
var email_addresses = _.pluck(this.recipients, 'email_address'); |
|
||||
var suggested_partners = $.Deferred(); |
|
||||
|
|
||||
// if clicked: call for suggested recipients
|
|
||||
if (event.type == 'click') { |
|
||||
this.private = $input.hasClass('oe_compose_post_private'); |
|
||||
this.is_log = false; |
|
||||
suggested_partners = this.parent_thread.get_recipients_for_internal_message([this.context.default_res_id], this.context) |
|
||||
.done(function (additional_recipients) { |
|
||||
var thread_recipients = additional_recipients[self.context.default_res_id]; |
|
||||
_.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': false, |
|
||||
'partner_id': recipient[0], |
|
||||
'full_name': recipient[1], |
|
||||
'name': parsed_email[0], |
|
||||
'email_address': parsed_email[1], |
|
||||
'reason': recipient[2], |
|
||||
}); |
|
||||
} |
|
||||
}); |
|
||||
|
open_composer: function (options) { |
||||
|
var self = this; |
||||
|
this._super.apply(this, arguments); |
||||
|
if (options === 'private_message') { |
||||
|
//Clear existing suggested partners
|
||||
|
for (var i=0; i<self.recipients_for_internal_message.length; i++) { |
||||
|
this.composer.suggested_partners.push({ |
||||
|
checked: true, |
||||
|
partner_id: self.recipients_for_internal_message[i].id, |
||||
|
full_name: self.recipients_for_internal_message[i].name, |
||||
|
name: self.recipients_for_internal_message[i].name, |
||||
|
email_address: self.recipients_for_internal_message[i].email, |
||||
|
reason: _.include(self.recipients_for_internal_message[i].user_ids, self.session.uid) |
||||
|
?'Partner' |
||||
|
:'Follower' |
||||
}); |
}); |
||||
} |
|
||||
else { |
|
||||
suggested_partners.resolve({}); |
|
||||
} |
|
||||
// uncheck partners from compute_emails_from
|
|
||||
_.each(this.recipients, function(r){ |
|
||||
if (!r.partner_id){ |
|
||||
r.checked = false; |
|
||||
} |
|
||||
}); |
|
||||
|
|
||||
// when call for suggested partners finished: re-render the widget
|
|
||||
$.when(suggested_partners).pipe(function (additional_recipients) { |
|
||||
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; |
|
||||
} |
|
||||
}); |
|
||||
|
} |
||||
|
}, |
||||
|
|
||||
instance.mail.Thread.include({ |
|
||||
get_recipients_for_internal_message: function(ids, context){ |
|
||||
|
get_recipients_for_internal_message: function () { |
||||
var self = this; |
var self = this; |
||||
self.result = {}; |
self.result = {}; |
||||
return new instance.web.Model(context.default_model).call( |
|
||||
'read', [ids, ['message_follower_ids', 'partner_id'], context] |
|
||||
).then(function (thread) { |
|
||||
for (var i = 0; i < thread.length; i++) { |
|
||||
var res_id = thread[i].id; |
|
||||
var recipient_ids = thread[i].message_follower_ids; |
|
||||
self.result[res_id] = []; |
|
||||
|
|
||||
// Add customer
|
|
||||
self.customer = thread[i].partner_id; |
|
||||
if (self.customer && !recipient_ids.includes(self.customer[0])) { |
|
||||
recipient_ids.splice(0, 0, self.customer[0]); |
|
||||
} |
|
||||
|
|
||||
return new instance.web.Model('res.partner').call( |
|
||||
'read', [recipient_ids, ['name', 'email', 'user_ids']] |
|
||||
).then(function (res_partners){ |
|
||||
for (var j = 0; j < res_partners.length; j++) { |
|
||||
var partner = res_partners[j]; |
|
||||
if (!_.include(partner.user_ids, self.session.uid)){ |
|
||||
var reason = 'Follower'; |
|
||||
if (self.customer && partner.id == self.customer[0]){ |
|
||||
reason = 'Partner'; |
|
||||
} |
|
||||
self.result[res_id].push( |
|
||||
[partner.id, partner.name + '<' + partner.email + '>', reason] |
|
||||
); |
|
||||
} |
|
||||
} |
|
||||
return self.result; |
|
||||
}); |
|
||||
} |
|
||||
return self.result; |
|
||||
|
return new Model(this.context.default_model).query( |
||||
|
['message_follower_ids', 'partner_id']).filter( |
||||
|
[['id', '=', self.context.default_res_id]]).all(). |
||||
|
then(function (thread) { |
||||
|
var follower_ids = thread[0].message_follower_ids; |
||||
|
self.result[self.context.default_res_id] = []; |
||||
|
self.customer = thread[0].partner_id; |
||||
|
// Fetch partner ids
|
||||
|
return new Model('mail.followers').call( |
||||
|
'read', [follower_ids, ['partner_id']]).then(function (res_partners) { |
||||
|
var res_partners_filtered = []; |
||||
|
// Filter result and push to array
|
||||
|
_.each(res_partners, function (partner) { |
||||
|
if (partner.partner_id[0] && partner.partner_id[0] !== session.partner_id ) { |
||||
|
res_partners_filtered.push(partner.partner_id[0]); |
||||
|
} |
||||
|
}); |
||||
|
return new Model('res.partner').call( |
||||
|
'read', [res_partners_filtered, ['name', 'email', 'user_ids']] |
||||
|
).then(function (recipients) { |
||||
|
return recipients; |
||||
|
}); |
||||
|
}); |
||||
}); |
}); |
||||
} |
} |
||||
}); |
}); |
||||
}; |
|
||||
|
|
||||
|
}); |
@ -1,27 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<openerp> |
|
||||
<data> |
|
||||
<record id="mail_private_email_compose_message_wizard_form" model="ir.ui.view"> |
|
||||
<field name="name">mail.private.mail.compose.message.form</field> |
|
||||
<field name="model">mail.compose.message</field> |
|
||||
<field name="inherit_id" ref="mail.email_compose_message_wizard_form"/> |
|
||||
<field name="arch" type="xml"> |
|
||||
<xpath expr="//div[@groups='base.group_user']" position="replace"> |
|
||||
<div groups="base.group_user" attrs="{'invisible': [('is_log', '=', True)]}"> |
|
||||
<field name="private" invisible="1"/> |
|
||||
<!--<field name="private"/>--> |
|
||||
<span attrs="{'invisible': [('composition_mode', '!=', 'mass_mail')]}"> |
|
||||
<strong>Email mass mailing</strong> on |
|
||||
<span attrs="{'invisible': [('use_active_domain', '=', True)]}">the selected records</span> |
|
||||
<span attrs="{'invisible': [('use_active_domain', '=', False)]}">the current search filter</span>. |
|
||||
</span> |
|
||||
<span attrs="{'invisible':['|', ('composition_mode', '!=', 'comment'), ('private', '=', True)]}">Followers of the document and</span> |
|
||||
<field name="partner_ids" widget="many2many_tags_email" placeholder="Add contacts to notify..." |
|
||||
context="{'force_email':True, 'show_email':True}" |
|
||||
attrs="{'invisible': [('composition_mode', '!=', 'comment')]}"/> |
|
||||
</div> |
|
||||
</xpath> |
|
||||
</field> |
|
||||
</record> |
|
||||
</data> |
|
||||
</openerp> |
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue