diff --git a/README.md b/README.md index daff2ca4..d3052629 100644 --- a/README.md +++ b/README.md @@ -14,9 +14,11 @@ addon | version | summary --- | --- | --- [mail_attach_existing_attachment](mail_attach_existing_attachment/) | 8.0.1.0.0 | Adding attachment on the object by sending this one [mail_compose_select_lang](mail_compose_select_lang/) | 8.0.1.0.0 | Select language in mail compose window +[mail_follower_custom_notification](mail_follower_custom_notification/) | 8.0.1.0.0 | Let followers choose if they want to receive email notifications for a given subscription [mail_footer_notified_partners](mail_footer_notified_partners/) | 8.0.1.0.0 | This module adds the list of notified partners in the footer of notification e-mails sent by Odoo. [mail_forward](mail_forward/) | 8.0.7.0.0 | Add option to forward messages [mail_full_expand](mail_full_expand/) | 8.0.3.0.0 | Expand mail in a big window +[mail_mandrill](mail_mandrill/) | 8.0.1.0.0 | Mandrill mail events integration [mail_read_new_window](mail_read_new_window/) | 8.0.1.0.0 | Open mail in new window [mail_restrict_follower_selection](mail_restrict_follower_selection/) | 8.0.1.0.0 | Define a domain from which followers can be selected [mail_sent](mail_sent/) | 8.0.1.0.0 | Provide a view of sent mails diff --git a/mail_follower_custom_notification/README.rst b/mail_follower_custom_notification/README.rst new file mode 100644 index 00000000..7f14c572 --- /dev/null +++ b/mail_follower_custom_notification/README.rst @@ -0,0 +1,73 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :alt: License: AGPL-3 + +========================================== +Custom notification settings for followers +========================================== + +In standard Odoo, receiving mail notifications is an all or nothing affair. +This module allows you users to decide per followed record if they want to +receive emails or not. Further, they can choose to receive notification about +their own messages. + +You can also set defaults for this settings on the subtype in question. + +Configuration +============= + +When followers open their subscriptions, they will be offered the choice to +override mail settings and to force being notified about their own messages. + +You can add defaults per message sub type for this settings in Settings / +Technical / Email / Subtypes. Here, you also have the opportunity to apply +those defaults to existing subscriptions. Note that this overrides all +customizations your users already have done. + +Usage +===== + +To use this module, for example you need to: + +- Go to Sales -> Sales -> Customers +- Go Inside any customer and in the right-botton corner press "Follow" button +- Unfold Following menu and check new functionality with "mail notificacions" + + +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/205/8.0 + +For further information, please visit: + +* https://www.odoo.com/forum/help-1 + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed feedback +`here `_. + +Credits +======= + +Contributors +------------ + +* Holger Brunn + +Maintainer +---------- + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +To contribute to this module, please visit http://odoo-community.org. diff --git a/mail_follower_custom_notification/__init__.py b/mail_follower_custom_notification/__init__.py new file mode 100644 index 00000000..968fe660 --- /dev/null +++ b/mail_follower_custom_notification/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# © 2015 Therp BV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from . import models +from . import wizards diff --git a/mail_follower_custom_notification/__openerp__.py b/mail_follower_custom_notification/__openerp__.py new file mode 100644 index 00000000..e15b28ba --- /dev/null +++ b/mail_follower_custom_notification/__openerp__.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# © 2015 Therp BV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +{ + "name": "Custom notification settings for followers", + "version": "8.0.1.0.0", + "author": "Therp BV,Odoo Community Association (OCA)", + "license": "AGPL-3", + "category": "Social Network", + "summary": "Let followers choose if they want to receive email " + "notifications for a given subscription", + "depends": [ + 'mail', + ], + "data": [ + "wizards/mail_subtype_assign_custom_notifications.xml", + "views/mail_message_subtype.xml", + 'views/templates.xml', + ], + "qweb": [ + 'static/src/xml/mail_follower_custom_notification.xml', + ], + "images": [ + 'images/mail_follower_custom_notification.png', + ], + "installable": True, +} diff --git a/mail_follower_custom_notification/images/mail_follower_custom_notification.png b/mail_follower_custom_notification/images/mail_follower_custom_notification.png new file mode 100644 index 00000000..3c63b9a7 Binary files /dev/null and b/mail_follower_custom_notification/images/mail_follower_custom_notification.png differ diff --git a/mail_follower_custom_notification/models/__init__.py b/mail_follower_custom_notification/models/__init__.py new file mode 100644 index 00000000..507fec24 --- /dev/null +++ b/mail_follower_custom_notification/models/__init__.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- +# © 2015 Therp BV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from . import base_patch_models_mixin +from . import mail_followers +from . import mail_thread +from . import mail_message +from . import mail_notification +from . import mail_message_subtype diff --git a/mail_follower_custom_notification/models/base_patch_models_mixin.py b/mail_follower_custom_notification/models/base_patch_models_mixin.py new file mode 100644 index 00000000..21ea5e68 --- /dev/null +++ b/mail_follower_custom_notification/models/base_patch_models_mixin.py @@ -0,0 +1,92 @@ +# -*- coding: utf-8 -*- +# © 2016 Therp BV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +import logging +from openerp import models + + +_logger = logging.getLogger(__file__) + + +# TODO: this should be a helper module to cetralize the point of failure +# in case this introduces tacit bugs +class BasePatchModelsMixin(models.AbstractModel): + """ + This is a mixin class meant to simplify working with patches + on BaseModel or on abstract models like mail.thread. + If you just change them, models created earlier will lack the + attributes you add. Just inherit from this mixin, it will check + which existing models need your changes and apply them. + + In your module, do something like + + class MailThread(models.AbstractModel): + _name = 'mail.thread' + _inherit = ['base.patch.models.mixin', 'mail.thread'] + + in case you need to patch BaseModel, say + + class BaseModel(models.BaseModel): + _name = 'my.unique.model.name' + _inherit = 'base.patch.models.mixin' + + Your code will behave as if it was an inherited class of the class you pass + in the second parameter to _base_patch_models. + """ + _name = 'base.patch.models.mixin' + + def _base_patch_models(self, cr, our_class=None, parent_class=None): + """iterate through existing models to apply our changes there if + necessary""" + if self._name == BasePatchModelsMixin._name: + return + my_bases = self.__class__.__bases__ + for i in range(max(len(my_bases) - 1, 0)): + if my_bases[i]._name == BasePatchModelsMixin._name: + our_class = my_bases[i - 1] + parent_class = my_bases[i + 1] + inherit = [self._inherit]\ + if isinstance(self._inherit, basestring) else self._inherit + for i in range(len(my_bases) - 1, 0, -1): + # this can be different from the above if our mixin is used + # multiple times on the same model + if my_bases[i]._name in inherit: + parent_class = my_bases[i] + break + if self.__class__.__bases__[-1] == BasePatchModelsMixin\ + and not our_class or not parent_class: + our_class = self.__class__.__bases__[-2] + parent_class = models.BaseModel + if not our_class or not parent_class: + _logger.info( + 'Failed to autodetect own class or parent class for %s, ' + 'ignoring', self._name) + return + + for model_name, model_object in self.pool.models.iteritems(): + if not isinstance(model_object, parent_class): + continue + if isinstance(model_object, our_class): + continue + if not isinstance(model_object, models.Model): + continue + bases = list(model_object.__class__.__bases__) + position = 1 + if parent_class == models.BaseModel: + position = len(bases) + else: + for i in range(len(bases) - 1, position, -1): + if bases[i]._name in inherit: + position = i + break + bases.insert(position, our_class) + model_object.__class__.__bases__ = tuple(bases) + + def _register_hook(self, cr): + self._base_patch_models(cr) + for base in self.__class__.__bases__: + if not hasattr(super(base, self), '_register_hook'): + return + if super(base, self)._register_hook != self._register_hook: + return super(base, self)._register_hook.__func__( + super(base, self), cr) diff --git a/mail_follower_custom_notification/models/mail_followers.py b/mail_follower_custom_notification/models/mail_followers.py new file mode 100644 index 00000000..82719402 --- /dev/null +++ b/mail_follower_custom_notification/models/mail_followers.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# © 2015 Therp BV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from openerp import api, fields, models + + +class MailFollowers(models.Model): + _inherit = 'mail.followers' + + force_mail_subtype_ids = fields.Many2many( + 'mail.message.subtype', 'mail_followers_force_mail_rel', + 'mail_followers_id', 'mail_message_subtype_id', + string='Force mails from subtype') + + force_nomail_subtype_ids = fields.Many2many( + 'mail.message.subtype', 'mail_followers_force_nomail_rel', + 'mail_followers_id', 'mail_message_subtype_id', + string='Force no mails from subtype') + + force_own_subtype_ids = fields.Many2many( + 'mail.message.subtype', 'mail_followers_force_own_rel', + 'mail_followers_id', 'mail_message_subtype_id', + string='Force own mails from subtype') + + @api.model + @api.returns('self', lambda x: x.id) + def create(self, values): + this = super(MailFollowers, self).create(values) + for subtype in this.subtype_ids: + if not subtype.res_model and\ + subtype.custom_notification_model_ids and\ + this.res_model not in\ + subtype.custom_notification_model_ids\ + .mapped('model'): + continue + if subtype.custom_notification_mail == 'force_yes': + this.force_mail_subtype_ids += subtype + if subtype.custom_notification_mail == 'force_no': + this.force_nomail_subtype_ids += subtype + if subtype.custom_notification_own: + this.force_own_subtype_ids += subtype + return this diff --git a/mail_follower_custom_notification/models/mail_message.py b/mail_follower_custom_notification/models/mail_message.py new file mode 100644 index 00000000..6ec41b24 --- /dev/null +++ b/mail_follower_custom_notification/models/mail_message.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# © 2015 Therp BV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from openerp import api, models + + +class MailMessage(models.Model): + _inherit = 'mail.message' + + @api.multi + def _notify(self, force_send=False, user_signature=True): + """notify author if she's a follower and turned on force_own""" + self.ensure_one() + if self.subtype_id and self.model and self.res_id: + author_follower = self.env['mail.followers'].search([ + ('res_model', '=', self.model), + ('res_id', '=', self.res_id), + ('partner_id', '=', self.author_id.id), + ('force_own_subtype_ids', '=', self.subtype_id.id), + ]) + self.env['mail.notification']._notify( + self.id, partners_to_notify=author_follower.partner_id.ids, + force_send=force_send, user_signature=user_signature) + return super(MailMessage, self)._notify( + self.id, force_send=force_send, user_signature=user_signature) diff --git a/mail_follower_custom_notification/models/mail_message_subtype.py b/mail_follower_custom_notification/models/mail_message_subtype.py new file mode 100644 index 00000000..f58e199d --- /dev/null +++ b/mail_follower_custom_notification/models/mail_message_subtype.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# © 2015 Therp BV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from openerp import fields, models + + +class MailMessageSubtype(models.Model): + _inherit = 'mail.message.subtype' + + custom_notification_mail = fields.Selection( + [('force_yes', 'Force yes'), ('force_no', 'Force no')], + string='Send mail notification', help='Leave empty to use the ' + 'on the partner\'s form, set to "Force yes" to always send messages ' + 'of this type via email, and "Force no" to never send messages of ' + 'type via email') + custom_notification_own = fields.Boolean( + 'Notify about own messages', help='Check this to have notifications ' + 'generated and sent via email about own messages') + custom_notification_model_ids = fields.Many2many( + 'ir.model', string='Models', help='Choose for which models the ' + 'custom configuration applies. This is only necessary if your subtype ' + 'doesn\'t set a model itself', domain=[('osv_memory', '=', False)]) diff --git a/mail_follower_custom_notification/models/mail_notification.py b/mail_follower_custom_notification/models/mail_notification.py new file mode 100644 index 00000000..c70e0f50 --- /dev/null +++ b/mail_follower_custom_notification/models/mail_notification.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# © 2015 Therp BV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from openerp import api, models + + +class MailNotification(models.Model): + _inherit = 'mail.notification' + + @api.multi + def get_partners_to_email(self, message): + partner_ids = super(MailNotification, self)\ + .get_partners_to_email(message) + for this in self: + follower = self.env['mail.followers'].search([ + ('res_model', '=', message.model), + ('res_id', '=', message.res_id), + ('partner_id', '=', this.partner_id.id), + '|', '|', + ('force_nomail_subtype_ids', '=', message.subtype_id.id), + ('force_mail_subtype_ids', '=', message.subtype_id.id), + ('force_own_subtype_ids', '=', message.subtype_id.id), + ]) + if not follower: + continue + if (message.subtype_id in follower.force_mail_subtype_ids or + message.subtype_id in follower.force_own_subtype_ids) and\ + this.partner_id.id not in partner_ids: + partner_ids.append(this.partner_id.id) + if message.subtype_id in follower.force_nomail_subtype_ids and\ + this.partner_id.id in partner_ids: + partner_ids.remove(this.partner_id.id) + return partner_ids diff --git a/mail_follower_custom_notification/models/mail_thread.py b/mail_follower_custom_notification/models/mail_thread.py new file mode 100644 index 00000000..11c23eb8 --- /dev/null +++ b/mail_follower_custom_notification/models/mail_thread.py @@ -0,0 +1,80 @@ +# -*- coding: utf-8 -*- +# © 2015 Therp BV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from openerp import api, models + + +class MailThread(models.AbstractModel): + _inherit = ['base.patch.models.mixin', 'mail.thread'] + _name = 'mail.thread' + + @api.multi + def _get_subscription_data(self, name, args, user_pid=None): + result = super(MailThread, self)._get_subscription_data( + name, args, user_pid=user_pid) + subtypes = self.env['mail.message.subtype'].search([ + ('hidden', '=', False), + '|', + ('res_model', '=', self._name), + ('res_model', '=', False), + ]) + for follower in self.env['mail.followers'].search([ + ('res_model', '=', self._name), + ('res_id', 'in', result.keys()), + ('partner_id', '=', user_pid or self.env.user.partner_id.id), + ]): + # values are ordered dicts, so we get the correct matches + for subtype, data in zip( + subtypes, + result[follower.res_id]['message_subtype_data'].values()): + data['force_mail'] = 'default' + if subtype in follower.force_mail_subtype_ids: + data['force_mail'] = 'force_yes' + elif subtype in follower.force_nomail_subtype_ids: + data['force_mail'] = 'force_no' + data['force_own'] =\ + subtype in follower.force_own_subtype_ids + return result + + @api.multi + def message_custom_notification_update_user(self, custom_notifications): + """change custom_notifications from user ids to partner ids""" + user2partner = dict( + self.env['res.users'].browse(map(int, custom_notifications.keys())) + .mapped(lambda user: (str(user.id), str(user.partner_id.id))) + ) + return self.message_custom_notification_update({ + user2partner[user_id]: data + for user_id, data in custom_notifications.iteritems() + }) + + @api.multi + def message_custom_notification_update(self, custom_notifications): + """custom_notifications is a dictionary with partner ids as keys + and dictionaries mapping message subtype ids to custom notification + values""" + def ids_with_value(data, key, value): + return map(lambda x: int(x[0]), + filter(lambda x: x[1][key] == value, + data.iteritems())) + + custom_notifications = { + int(key): value + for key, value in custom_notifications.iteritems() + if key != 'False' + } + + for follower in self.env['mail.followers'].search([ + ('res_model', '=', self._name), + ('res_id', 'in', self.ids), + ('partner_id', 'in', custom_notifications.keys()), + ]): + data = custom_notifications[follower.partner_id.id] + follower.write({ + 'force_mail_subtype_ids': [(6, 0, ids_with_value( + data, 'force_mail', 'force_yes'))], + 'force_nomail_subtype_ids': [(6, 0, ids_with_value( + data, 'force_mail', 'force_no'))], + 'force_own_subtype_ids': [(6, 0, ids_with_value( + data, 'force_own', '1'))] + }), diff --git a/mail_follower_custom_notification/static/description/icon.png b/mail_follower_custom_notification/static/description/icon.png new file mode 100644 index 00000000..3a0328b5 Binary files /dev/null and b/mail_follower_custom_notification/static/description/icon.png differ diff --git a/mail_follower_custom_notification/static/src/css/mail_follower_custom_notification.css b/mail_follower_custom_notification/static/src/css/mail_follower_custom_notification.css new file mode 100644 index 00000000..92b9ecb9 --- /dev/null +++ b/mail_follower_custom_notification/static/src/css/mail_follower_custom_notification.css @@ -0,0 +1,5 @@ +.oe_custom_notification legend +{ + font-size: inherit; + margin-bottom: 0px; +} diff --git a/mail_follower_custom_notification/static/src/js/mail_follower_custom_notification.js b/mail_follower_custom_notification/static/src/js/mail_follower_custom_notification.js new file mode 100644 index 00000000..104342b1 --- /dev/null +++ b/mail_follower_custom_notification/static/src/js/mail_follower_custom_notification.js @@ -0,0 +1,79 @@ +//-*- coding: utf-8 -*- +//© 2015 Therp BV +//License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +openerp.mail_follower_custom_notification = function(instance) +{ + instance.mail_followers.Followers.include({ + display_subtypes: function(data, id, dialog) + { + var $list = this.$('.oe_subtype_list ul'); + if (dialog) + { + $list = this.$dialog.$el; + } + $list.empty(); + this._super(data, id, dialog); + $list.find('input[type=checkbox]').change(function() + { + $list.find(_.str.sprintf( + '#custom_notification_%s%s', + jQuery(this).data('id'), + dialog ? '_dialog' : '' + )) + .toggle(jQuery(this).prop('checked')); + }); + if(!dialog) + { + $list.find('.oe_custom_notification input[type=radio]') + .change(this.proxy('do_update_subscription')); + }; + }, + do_update_subscription: function(event, user_pid) + { + /* + if(jQuery(event.currentTarget).parents('.oe_custom_notification') + .length) + { + // mail reacts on all inputs, suppress for our inputs + return jQuery.when(); + } + */ + var self = this, + update_func = 'message_custom_notification_update_user', + follower_ids = [this.session.uid], + custom_notifications = {}, + oe_action = this.$('.oe_actions'); + if(user_pid) + { + update_func = 'message_custom_notification_update'; + follower_ids = [user_pid]; + oe_action = jQuery('.oe_edit_actions'); + } + _(follower_ids).each(function(follower) + { + + var follower_settings = custom_notifications[follower] = {}; + oe_action.find('.oe_custom_notification') + .each(function() + { + var id = parseInt(jQuery(this).data('id')), + settings = follower_settings[id] = {}; + settings['force_mail'] = jQuery(this) + .find('.oe_custom_notification_mail input:checked') + .val(); + settings['force_own'] = jQuery(this) + .find('.oe_custom_notification_own input:checked') + .val(); + }); + }); + return jQuery.when(this._super.apply(this, arguments)) + .then(function() + { + return self.ds_model.call( + update_func, + [[self.view.datarecord.id], custom_notifications]) + }) + }, + }); +} diff --git a/mail_follower_custom_notification/static/src/xml/mail_follower_custom_notification.xml b/mail_follower_custom_notification/static/src/xml/mail_follower_custom_notification.xml new file mode 100644 index 00000000..25fee159 --- /dev/null +++ b/mail_follower_custom_notification/static/src/xml/mail_follower_custom_notification.xml @@ -0,0 +1,38 @@ + + diff --git a/mail_follower_custom_notification/tests/__init__.py b/mail_follower_custom_notification/tests/__init__.py new file mode 100644 index 00000000..ef042795 --- /dev/null +++ b/mail_follower_custom_notification/tests/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# © 2015 Therp BV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from . import test_mail_follower_custom_notification diff --git a/mail_follower_custom_notification/tests/test_mail_follower_custom_notification.py b/mail_follower_custom_notification/tests/test_mail_follower_custom_notification.py new file mode 100644 index 00000000..11bed947 --- /dev/null +++ b/mail_follower_custom_notification/tests/test_mail_follower_custom_notification.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- +# © 2015 Therp BV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from openerp.tests.common import TransactionCase + + +class TestMailFollowerCustomNotification(TransactionCase): + def test_mail_follower_custom_notification(self): + self.env['mail.thread']._register_hook() + followed_partner = self.env['res.partner'].create({ + 'name': 'I\'m followed', + }) + demo_user = self.env.ref('base.user_demo') + followed_partner_demo = followed_partner.sudo(demo_user.id) + followed_partner_demo.message_subscribe_users() + + # see if default subscriptions return default custom settings + subscription_data = followed_partner_demo._get_subscription_data( + None, None) + self.assertEqual( + subscription_data[followed_partner.id]['message_subtype_data'] + ['Discussions']['force_mail'], + 'default') + self.assertEqual( + subscription_data[followed_partner.id]['message_subtype_data'] + ['Discussions']['force_own'], + False) + + # set custom settings + mt_comment = self.env.ref('mail.mt_comment') + followed_partner_demo.message_custom_notification_update_user({ + str(demo_user.id): { + str(mt_comment.id): { + 'force_mail': 'force_yes', + 'force_own': '1', + }, + }, + }) + # see if we can read them back + subscription_data = followed_partner_demo._get_subscription_data( + None, None) + self.assertEqual( + subscription_data[followed_partner.id]['message_subtype_data'] + ['Discussions']['force_mail'], + 'force_yes') + self.assertEqual( + subscription_data[followed_partner.id]['message_subtype_data'] + ['Discussions']['force_own'], + True) + + # post a message and see if we successfully forced a notification to + # ourselves + followed_partner_demo.message_post('hello world', subtype='mt_comment') + self.assertEqual( + followed_partner_demo.message_ids[:-1].notification_ids.partner_id, + demo_user.partner_id) + + # assign default values on message subtype and apply them to all + # followers + mt_comment.custom_notification_model_ids = self.env['ir.model']\ + .search([('model', '=', 'res.partner')]) + wizard = self.env['mail.subtype.assign.custom.notifications']\ + .with_context(active_ids=mt_comment.ids)\ + .create({}) + wizard.button_apply() + subscription_data = followed_partner_demo._get_subscription_data( + None, None) + self.assertEqual( + subscription_data[followed_partner.id]['message_subtype_data'] + ['Discussions']['force_mail'], + 'default') + self.assertEqual( + subscription_data[followed_partner.id]['message_subtype_data'] + ['Discussions']['force_own'], + False) diff --git a/mail_follower_custom_notification/views/mail_message_subtype.xml b/mail_follower_custom_notification/views/mail_message_subtype.xml new file mode 100644 index 00000000..0d60986c --- /dev/null +++ b/mail_follower_custom_notification/views/mail_message_subtype.xml @@ -0,0 +1,18 @@ + + + + + mail.message.subtype + + + + + + + + + + + + + diff --git a/mail_follower_custom_notification/views/templates.xml b/mail_follower_custom_notification/views/templates.xml new file mode 100644 index 00000000..fbfbec8b --- /dev/null +++ b/mail_follower_custom_notification/views/templates.xml @@ -0,0 +1,11 @@ + + + + + + diff --git a/mail_follower_custom_notification/wizards/__init__.py b/mail_follower_custom_notification/wizards/__init__.py new file mode 100644 index 00000000..e968c053 --- /dev/null +++ b/mail_follower_custom_notification/wizards/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# © 2015 Therp BV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from . import mail_subtype_assign_custom_notifications diff --git a/mail_follower_custom_notification/wizards/mail_subtype_assign_custom_notifications.py b/mail_follower_custom_notification/wizards/mail_subtype_assign_custom_notifications.py new file mode 100644 index 00000000..c0413e7e --- /dev/null +++ b/mail_follower_custom_notification/wizards/mail_subtype_assign_custom_notifications.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# © 2015 Therp BV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from openerp import api, fields, models + + +class MailSubtypeAssignCustomNotifications(models.TransientModel): + _name = 'mail.subtype.assign.custom.notifications' + _description = 'Assign custom notification settings to existing followers' + + subtype_ids = fields.Many2many( + 'mail.message.subtype', 'mail_subtype_assign_custom_notifications_rel', + string='Subtypes', required=True, + default=lambda self: [(6, 0, self.env.context.get('active_ids', []))]) + + @api.multi + def button_apply(self): + self.ensure_one() + for subtype in self.subtype_ids: + domain = [('subtype_ids', '=', subtype.id)] + if subtype.custom_notification_model_ids: + domain.append( + ('res_model', 'in', + subtype.custom_notification_model_ids.mapped('model'))) + self.env['mail.followers'].with_context(active_test=False)\ + .search(domain)\ + .write({ + 'force_mail_subtype_ids': [ + (4, subtype.id) + if subtype.custom_notification_mail == 'force_yes' + else + (3, subtype.id) + ], + 'force_nomail_subtype_ids': [ + (4, subtype.id) + if subtype.custom_notification_mail == 'force_no' + else + (3, subtype.id) + ], + 'force_own_subtype_ids': [ + (4, subtype.id) + if subtype.custom_notification_own + else + (3, subtype.id) + ], + }) diff --git a/mail_follower_custom_notification/wizards/mail_subtype_assign_custom_notifications.xml b/mail_follower_custom_notification/wizards/mail_subtype_assign_custom_notifications.xml new file mode 100644 index 00000000..adbab627 --- /dev/null +++ b/mail_follower_custom_notification/wizards/mail_subtype_assign_custom_notifications.xml @@ -0,0 +1,30 @@ + + + + + mail.subtype.assign.custom.notifications + +
+ + + +
+
+
+
+
+ +
+
diff --git a/marketing_security_group/i18n/es.po b/marketing_security_group/i18n/es.po new file mode 100644 index 00000000..3763a689 --- /dev/null +++ b/marketing_security_group/i18n/es.po @@ -0,0 +1,24 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * marketing_security_group +# +# Translators: +# Antonio Trueba, 2016 +msgid "" +msgstr "" +"Project-Id-Version: social (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-01-17 01:37+0000\n" +"PO-Revision-Date: 2016-02-16 12:32+0000\n" +"Last-Translator: Antonio Trueba\n" +"Language-Team: Spanish (http://www.transifex.com/oca/OCA-social-8-0/language/es/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: es\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: marketing_security_group +#: model:ir.model,name:marketing_security_group.model_mail_mass_mailing_test +msgid "Sample Mail Wizard" +msgstr "Asistente para correo de ejemplo" diff --git a/website_mail_snippet_bg_color/views/snippets.xml b/website_mail_snippet_bg_color/views/snippets.xml index 3d83da68..a2ca12bd 100644 --- a/website_mail_snippet_bg_color/views/snippets.xml +++ b/website_mail_snippet_bg_color/views/snippets.xml @@ -10,8 +10,7 @@
*, .bg_color_picker" data-selector-siblings="[data-oe-field='body_html'] > *" data-selector-children="[data-oe-field='body_html']"> diff --git a/website_mail_snippet_responsive/views/templates.xml b/website_mail_snippet_responsive/views/templates.xml index 17819198..8d5dcd0d 100644 --- a/website_mail_snippet_responsive/views/templates.xml +++ b/website_mail_snippet_responsive/views/templates.xml @@ -18,21 +18,14 @@
- - - - - - +
- - -
-
+