From 3e3ab4cb2828c0a0b1f4dab91f8965943384c793 Mon Sep 17 00:00:00 2001 From: ommo73 Date: Tue, 19 Mar 2019 19:07:14 +0500 Subject: [PATCH 01/12] :zap: mail_base New: added ability to select channels for private message sending --- mail_base/README.rst | 2 +- mail_base/__init__.py | 1 + mail_base/__manifest__.py | 6 +++++- mail_base/controllers/main.py | 3 +++ mail_base/doc/changelog.rst | 4 ++++ mail_base/models.py | 7 +++++-- mail_base/static/lib/base.js | 6 +++++- 7 files changed, 24 insertions(+), 5 deletions(-) diff --git a/mail_base/README.rst b/mail_base/README.rst index 44fc4108..93135709 100644 --- a/mail_base/README.rst +++ b/mail_base/README.rst @@ -6,7 +6,7 @@ Mail Base * fixes toggling left bar * fixes Recipients field. Out-of-box this field could be empty. -One can say, that the module do this todo from `addons/mail/static/src/js/chat_manager.js `__ +One can say, that the module do this todo from `addons/mail/static/src/js/chat_manager.js `__ // to do: move this to mail.utils diff --git a/mail_base/__init__.py b/mail_base/__init__.py index c3d410ea..811556a9 100644 --- a/mail_base/__init__.py +++ b/mail_base/__init__.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +# License LGPL-3.0 (https://www.gnu.org/licenses/lgpl.html) from . import models from . import controllers diff --git a/mail_base/__manifest__.py b/mail_base/__manifest__.py index adf46b68..8cd75b8a 100644 --- a/mail_base/__manifest__.py +++ b/mail_base/__manifest__.py @@ -1,10 +1,14 @@ # -*- coding: utf-8 -*- +# Copyright 2016 x620 +# Copyright 2018 Ruslan Ronzhin +# Copyright 2016-2019 Ivan Yelizariev +# License LGPL-3.0 (https://www.gnu.org/licenses/lgpl.html) { "name": "Mail Base", "summary": """Makes Mail extendable""", "category": "Discuss", "images": [], - "version": "10.0.1.0.5", + "version": "10.0.1.1.0", "author": "IT-Projects LLC, Pavel Romanchenko", "support": "apps@it-projects.info", diff --git a/mail_base/controllers/main.py b/mail_base/controllers/main.py index 8463aed3..429e6f9f 100644 --- a/mail_base/controllers/main.py +++ b/mail_base/controllers/main.py @@ -1,4 +1,7 @@ # -*- coding: utf-8 -*- +# Copyright 2017 mikaelh +# Copyright 2017-2019 Ivan Yelizariev +# License LGPL-3.0 (https://www.gnu.org/licenses/lgpl.html) from openerp.http import request from openerp.addons.bus.controllers.main import BusController diff --git a/mail_base/doc/changelog.rst b/mail_base/doc/changelog.rst index d1474d81..8825558c 100644 --- a/mail_base/doc/changelog.rst +++ b/mail_base/doc/changelog.rst @@ -1,3 +1,7 @@ +`1.1.0` +------- +- **New**: added ability to select channels for private message sending. + `1.0.5` ------- **FIX**: polling errors on heavy server load diff --git a/mail_base/models.py b/mail_base/models.py index 953f49fa..cdce4535 100644 --- a/mail_base/models.py +++ b/mail_base/models.py @@ -1,4 +1,7 @@ # -*- coding: utf-8 -*- +# Copyright 2016 x620 +# Copyright 2017 Ivan Yelizariev +# License LGPL-3.0 (https://www.gnu.org/licenses/lgpl.html) from openerp import api, models @@ -13,8 +16,8 @@ def write(self, values): values['partner_ids'] = [] for triplet in values.get('needaction_partner_ids'): if triplet[0] == 6: - for id in triplet[2]: - values['partner_ids'].append((4, id, False)) + for i in triplet[2]: + values['partner_ids'].append((4, i, False)) return super(MailMessage, self).write(values) diff --git a/mail_base/static/lib/base.js b/mail_base/static/lib/base.js index ce597647..4842521d 100644 --- a/mail_base/static/lib/base.js +++ b/mail_base/static/lib/base.js @@ -1,3 +1,6 @@ +/* Copyright 2017 Artyom Losev + Copyright 2019 Artem Rafailov + License LGPL-3.0 (https://www.gnu.org/licenses/lgpl.html). */ odoo.define('mail_base.base', function (require) { "use strict"; @@ -215,7 +218,7 @@ var MailComposer = composer.BasicComposer.extend({ var parsed_email = utils.parse_email(recipient[1]); if (_.indexOf(email_addresses, parsed_email[1]) === -1) { self.suggested_partners.push({ - checked: true, + checked: false, partner_id: recipient[0], full_name: recipient[1], name: parsed_email[0], @@ -1059,6 +1062,7 @@ chat_manager.post_message = function (data, options) { options = options || {}; var msg = { partner_ids: data.partner_ids, + channel_ids: data.channel_ids, body: _.str.trim(data.content), attachment_ids: data.attachment_ids }; From 1ccc657f75fc0a47cdd469aea7fbe0c15d5be84a Mon Sep 17 00:00:00 2001 From: ommo73 Date: Tue, 19 Mar 2019 19:08:21 +0500 Subject: [PATCH 02/12] :zap: mail_private New: added ability to select channels for private message sending --- mail_private/__init__.py | 1 + mail_private/__manifest__.py | 10 +- mail_private/doc/changelog.rst | 6 ++ mail_private/full_composer_wizard.xml | 4 + mail_private/models.py | 73 +++++++++++++++ mail_private/static/src/js/mail_private.js | 98 +++++++++++++++++++- mail_private/static/src/xml/mail_private.xml | 16 ++++ mail_private/template.xml | 2 + 8 files changed, 204 insertions(+), 6 deletions(-) diff --git a/mail_private/__init__.py b/mail_private/__init__.py index cde864ba..aa407583 100644 --- a/mail_private/__init__.py +++ b/mail_private/__init__.py @@ -1,3 +1,4 @@ # -*- coding: utf-8 -*- +# License LGPL-3.0 (https://www.gnu.org/licenses/lgpl.html) from . import models diff --git a/mail_private/__manifest__.py b/mail_private/__manifest__.py index 6c0e4211..36720c37 100644 --- a/mail_private/__manifest__.py +++ b/mail_private/__manifest__.py @@ -1,10 +1,18 @@ # -*- coding: utf-8 -*- +# Copyright 2016 x620 +# Copyright 2016 Ilmir Karamov +# Copyright 2016 Ivan Yelizariev +# Copyright 2017 Artyom Losev +# Copyright 2018 Ruslan Ronzhin +# Copyright 2018 Kolushov Alexandr +# Copyright 2019 Artem Rafailov +# License LGPL-3.0 (https://www.gnu.org/licenses/lgpl.html). { "name": """Internal Messaging""", "summary": """Send private messages to specified recipients, regardless of who are in followers list.""", "category": "Discuss", "images": ['images/mail_private_image.png'], - "version": "10.0.1.0.1", + "version": "10.0.1.1.0", "application": False, "author": "IT-Projects LLC, Pavel Romanchenko", diff --git a/mail_private/doc/changelog.rst b/mail_private/doc/changelog.rst index f3b7c081..01b747ca 100644 --- a/mail_private/doc/changelog.rst +++ b/mail_private/doc/changelog.rst @@ -1,3 +1,9 @@ +`1.1.0` +------- + +- **New**: added ability to select channels for private message sending. +- **New**: internal users are flagged automatically. + `1.0.1` ------- diff --git a/mail_private/full_composer_wizard.xml b/mail_private/full_composer_wizard.xml index 9f57a207..46daeb59 100644 --- a/mail_private/full_composer_wizard.xml +++ b/mail_private/full_composer_wizard.xml @@ -1,4 +1,8 @@ + + diff --git a/mail_private/models.py b/mail_private/models.py index 1f69756d..33d45202 100644 --- a/mail_private/models.py +++ b/mail_private/models.py @@ -1,4 +1,10 @@ # -*- coding: utf-8 -*- +# Copyright 2016 x620 +# Copyright 2016 manawi +# Copyright 2017 Artyom Losev +# Copyright 2019 Artem Rafailov +# License LGPL-3.0 (https://www.gnu.org/licenses/lgpl.html). + from odoo import models, fields, api @@ -7,8 +13,75 @@ class MailComposeMessage(models.TransientModel): is_private = fields.Boolean(string='Send Internal Message') + def get_internal_users_ids(self): + internal_users_ids = self.env['res.users'].search([('share', '=', False)]).ids + return internal_users_ids + @api.multi def send_mail(self, auto_commit=False): for w in self: w.is_log = True if w.is_private else w.is_log super(MailComposeMessage, self).send_mail(auto_commit=False) + + +class MailMessage(models.Model): + _inherit = 'mail.message' + + @api.multi + def _notify(self, force_send=False, send_after_commit=True, user_signature=True): + self_sudo = self.sudo() + if 'is_private' not in self_sudo._context or not self_sudo._context['is_private']: + super(MailMessage, self)._notify(force_send, send_after_commit, user_signature) + else: + self._notify_mail_private(force_send, send_after_commit, user_signature) + + @api.multi + def _notify_mail_private(self, force_send=False, send_after_commit=True, user_signature=True): + """ The method was partially copied from Odoo. + In the current method, the way of getting channels for a private message is changed. + """ + # have a sudoed copy to manipulate partners (public can go here with + # website modules like forum / blog / ... + + # TDE CHECK: add partners / channels as arguments to be able to notify a message with / without computation ?? + self.ensure_one() # tde: not sure, just for testinh, will see + + partners = self.env['res.partner'] | self.partner_ids + channels = self.env['mail.channel'] | self.channel_ids + + # update message, with maybe custom values + message_values = { + 'channel_ids': [(6, 0, channels.ids)], + 'needaction_partner_ids': [(6, 0, partners.ids)] + } + if self.model and self.res_id and hasattr(self.env[self.model], 'message_get_message_notify_values'): + message_values.update( + self.env[self.model].browse(self.res_id).message_get_message_notify_values(self, message_values)) + self.write(message_values) + + # notify partners and channels + partners._notify(self, force_send=force_send, send_after_commit=send_after_commit, + user_signature=user_signature) + channels._notify(self) + + # Discard cache, because child / parent allow reading and therefore + # change access rights. + if self.parent_id: + self.parent_id.invalidate_cache() + + return True + + +class MailThread(models.AbstractModel): + _inherit = 'mail.thread' + + @api.multi + @api.returns('self', lambda value: value.id) + def message_post(self, body='', subject=None, message_type='notification', + subtype=None, parent_id=False, attachments=None, + content_subtype='html', **kwargs): + if 'channel_ids' in kwargs: + kwargs['channel_ids'] = [(4, pid) for pid in kwargs['channel_ids']] + return super(MailThread, self).message_post(body, subject, message_type, + subtype, parent_id, attachments, + content_subtype, **kwargs) diff --git a/mail_private/static/src/js/mail_private.js b/mail_private/static/src/js/mail_private.js index d311b3cd..72045853 100644 --- a/mail_private/static/src/js/mail_private.js +++ b/mail_private/static/src/js/mail_private.js @@ -1,3 +1,9 @@ +/* Copyright 2016 x620 + Copyright 2016 Ivan Yelizariev + Copyright 2016 manawi + Copyright 2017 Artyom Losev + Copyright 2019 Artem Rafailov + License LGPL-3.0 (https://www.gnu.org/licenses/lgpl.html). */ odoo.define('mail_private', function (require) { 'use strict'; @@ -22,6 +28,7 @@ Chatter.include({ var self = this; if (this.private) { message.subtype = false; + message.channel_ids = this.get_checked_channels_ids(); } var options = {model: this.model, res_id: this.res_id}; chat_manager.post_message(message, options).then( @@ -33,32 +40,38 @@ Chatter.include({ }).fail(function () { // todo: display notification }); - }, + }, on_open_composer_private_message: function (event) { var self = this; this.private = true; this.get_recipients_for_internal_message().then(function (data) { self.recipients_for_internal_message = data; - self.open_composer({is_private: true}); + return self.get_channels_for_internal_message(); + }).then(function (data) { + self.channels_for_internal_message = data; + self.get_internal_users_ids().then(function(res_ids){ + self.open_composer({is_private: true, internal_ids: res_ids}); + }); }); }, on_open_composer_new_message: function () { this._super.apply(this, arguments); this.private = false; + this.context.is_private = false; }, open_composer: function (options) { var self = this; this._super.apply(this, arguments); if (options && options.is_private) { - + self.internal_users_ids = options.internal_ids; this.composer.options.is_private = options.is_private; _.each(self.recipients_for_internal_message, function (partner) { self.composer.suggested_partners.push({ - checked: (partner.user_ids.length > 0), + checked: _.intersection(self.internal_users_ids, partner.user_ids).length > 0, partner_id: partner.id, full_name: partner.name, name: partner.name, @@ -68,6 +81,15 @@ Chatter.include({ :'Follower' }); }); + + _.each(self.channels_for_internal_message, function (channel) { + self.composer.suggested_channels.push({ + checked: true, + channel_id: channel.id, + full_name: channel.name, + name: ('# ' + channel.name), + }); + }); } }, @@ -101,13 +123,68 @@ Chatter.include({ }); }); }); - } + }, + + get_channels_for_internal_message: function () { + var self = this; + 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 channels ids + return new Model('mail.followers').call( + 'read', [follower_ids, ['channel_id']]).then(function (res_channels) { + // Filter result and push to array + var res_channels_filtered = _.map(res_channels, function (channel) { + if (channel.channel_id[0]) { + return channel.channel_id[0]; + } + }).filter(function (channel) { + return typeof channel !== 'undefined'; + }); + + return new Model('mail.channel').call( + 'read', [res_channels_filtered, ['name', 'id']] + ).then(function (recipients) { + return recipients; + }); + }); + }); + }, + + get_internal_users_ids: function () { + var ResUser = new Model('mail.compose.message'); + this.users_ids = ResUser.call('get_internal_users_ids', [[]]).then( function (users_ids) { + return users_ids; + }); + return this.users_ids; + }, + + get_checked_channels_ids: function () { + var self = this; + var checked_channels = []; + this.$('.o_composer_suggested_channels input:checked').each(function() { + var full_name = $(this).data('fullname').toString(); + _.each(self.channels_for_internal_message, function(item) { + if (full_name === item.name) { + checked_channels.push(item.id); + } + }); + }); + return checked_channels; + }, }); MailComposer.include({ init: function (parent, dataset, options) { this._super(parent, dataset, options); this.events['click .oe_composer_uncheck'] = 'on_uncheck_recipients'; + this.suggested_channels = []; }, @@ -115,6 +192,17 @@ MailComposer.include({ this.$('.o_composer_suggested_partners input:checked').each(function() { $(this).prop('checked', false); }); + this.$('.o_composer_suggested_channels input:checked').each(function() { + $(this).prop('checked', false); + }); + }, + + preprocess_message: function () { + var self = this; + if (self.options.is_private) { + self.context.is_private = true; + } + return this._super(); }, on_open_full_composer: function() { diff --git a/mail_private/static/src/xml/mail_private.xml b/mail_private/static/src/xml/mail_private.xml index 5607c9e9..cebfd85c 100644 --- a/mail_private/static/src/xml/mail_private.xml +++ b/mail_private/static/src/xml/mail_private.xml @@ -1,4 +1,10 @@ +