Browse Source

[ADD] Create mail_private module: add button which allow send message only selected users instead all followers

pull/50/head
x620 8 years ago
parent
commit
db5af2fab8
  1. 29
      mail_private/README.rst
  2. 3
      mail_private/__init__.py
  3. 35
      mail_private/__openerp__.py
  4. 7
      mail_private/doc/changelog.rst
  5. 30
      mail_private/doc/index.rst
  6. 13
      mail_private/models.py
  7. 183
      mail_private/static/src/js/mail_private.js
  8. 8
      mail_private/static/src/xml/mail_private.xml
  9. 15
      mail_private/template.xml
  10. 27
      mail_private/view.xml

29
mail_private/README.rst

@ -0,0 +1,29 @@
====================
Internal Messaging
====================
При отправке сообщения в карточке сообщение по умолчанию отправляется всем подписанным пользователям. Но часто бывают случаи, когда отправлять сообщения нужно только определенным лицам. Данный модуль дает возможность выбирать получателей отпрвляемого сообщения и не рассылать его всем подписанным пользователям.
Credits
=======
Contributors
------------
* Pavel Romanchenko <romanchenko@it-projects.info>
Sponsors
--------
* `IT-Projects LLC <https://it-projects.info>`_
Further information
===================
Demo: http://runbot.it-projects.info/demo/mail-addons/8.0
HTML Description: https://apps.odoo.com/apps/modules/8.0/mail_private/
Usage instructions: `<doc/index.rst>`_
Changelog: `<doc/changelog.rst>`_
Tested on Odoo 8.0 0af32f3f84bae07b11abb8538d02e35c7369a348

3
mail_private/__init__.py

@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
import models

35
mail_private/__openerp__.py

@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
{
"name": """Internal Messaging""",
"summary": """Allows you to send private messages to specified recipients only no matter who are in followers list.""",
"category": "Social Network",
"images": [],
"version": "1.0.0",
"application": False,
"author": "IT-Projects LLC, Pavel Romanchenko",
"website": "https://it-projects.info",
"license": "GPL-3",
#"price": 9.00,
#"currency": "EUR",
"depends": [
"mail",
],
"external_dependencies": {"python": [], "bin": []},
"data": [
'template.xml',
'view.xml',
],
"qweb": [
'static/src/xml/mail_private.xml',
],
"demo": [],
"post_load": None,
"pre_init_hook": None,
"post_init_hook": None,
"auto_install": False,
"installable": True,
}

7
mail_private/doc/changelog.rst

@ -0,0 +1,7 @@
Changelog
=========
`1.0.0`
-------
- Init version

30
mail_private/doc/index.rst

@ -0,0 +1,30 @@
====================
Internal Messaging
====================
Installation
============
Nothing special is needed to install this module.
Usage
=====
Для того чтобы отправить сообщение только выбранным получателям:
* Кликните по кнопке ``[Send Private Message]``
* По умолчанию все подписанные пользователи отключены. Включите флажки тем пользователям, которым вы хотите отправить сообщение.
* Если вы хотите добавить получателей из числа неподписанных пользователей, нажмите на кнопку ``[Open the full mail composer]`` в правом верхнем углу блока отправки сообщения.
* В поле **Recipient** добавьте получателей.
* Нажмите кнопку ``[Send]``.
Для проверки подпишите на какую-нибудь карточку двух получателей: Demo User и любого другого. Отправьте сообщение, выбрав в числе получателей только второго подписанного пользователя. Залогиньтесь как Demo User и проверьте, что ему сообщение не пришло.
Uninstallation
==============
Nothing special is needed to uninstall this module.

13
mail_private/models.py

@ -0,0 +1,13 @@
# -*- coding: utf-8 -*-
from openerp import api
from openerp.osv import osv, fields
from openerp import SUPERUSER_ID
class mail_compose_message(osv.TransientModel):
_inherit = 'mail.compose.message'
_columns = {
'private': fields.boolean('Send Internal Message'),
}

183
mail_private/static/src/js/mail_private.js

@ -0,0 +1,183 @@
openerp.mail_private = function(instance){
var mail = instance.mail;
instance.mail.ThreadComposeMessage.include({
init: function (parent, datasets, options) {
this._super.apply(this, arguments);
this.private = false;
},
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();
});
},
do_send_message_post: function (partner_ids, log) {
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;
});
},
on_toggle_quick_composer: function (event) {
if (event.target.className == 'oe_compose_post') {
this.recipients = [];
this.private = false;
}
this._super.apply(this, arguments);
},
on_toggle_quick_composer_private: function (event) {
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],
})
}
});
});
}
else {
suggested_partners.resolve({});
}
// 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){
var self = this;
self.result = {};
return new instance.web.Model(context.default_model).call(
'read', [ids, ['message_follower_ids'], context]
).then(function (thread) {
for (var i = 0; i < thread.length; i++) {
var res_id = thread[i].id;
var followers = thread[i].message_follower_ids;
self.result[res_id] = [];
return new instance.web.Model('res.partner').call(
'read', [followers, ['name', 'email', 'user_ids']]
).then(function (res_partners){
for (var j = 0; j < res_partners.length; j++) {
if (!_.include(res_partners[j].user_ids, self.session.uid)){
var partner = res_partners[j];
self.result[res_id].push(
[partner.id, partner.name + '<' + partner.email + '>']
);
}
}
return self.result;
});
}
return self.result;
});
}
});
};

8
mail_private/static/src/xml/mail_private.xml

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<template>
<t t-extend="mail.compose_message">
<t t-jquery="a[title='Send a message to all followers of the document']" t-operation="after">
<span class="oe_grey oe_sep_word">or</span><a class="oe_compose_post_private" t-if="!widget.options.compose_placeholder and !widget.options.view_mailbox" title="Send a message to all followers of the document">Send internal message</a>
</t>
</t>
</template>

15
mail_private/template.xml

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<template
id="assets_backend"
name="mail_private_assets_backend"
inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<script
type="text/javascript"
src="/mail_private/static/src/js/mail_private.js"></script>
</xpath>
</template>
</data>
</openerp>

27
mail_private/view.xml

@ -0,0 +1,27 @@
<?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>
Loading…
Cancel
Save