Jairo Llopis
9 years ago
26 changed files with 753 additions and 17 deletions
-
2README.md
-
73mail_follower_custom_notification/README.rst
-
5mail_follower_custom_notification/__init__.py
-
27mail_follower_custom_notification/__openerp__.py
-
BINmail_follower_custom_notification/images/mail_follower_custom_notification.png
-
9mail_follower_custom_notification/models/__init__.py
-
92mail_follower_custom_notification/models/base_patch_models_mixin.py
-
42mail_follower_custom_notification/models/mail_followers.py
-
25mail_follower_custom_notification/models/mail_message.py
-
22mail_follower_custom_notification/models/mail_message_subtype.py
-
33mail_follower_custom_notification/models/mail_notification.py
-
80mail_follower_custom_notification/models/mail_thread.py
-
BINmail_follower_custom_notification/static/description/icon.png
-
5mail_follower_custom_notification/static/src/css/mail_follower_custom_notification.css
-
79mail_follower_custom_notification/static/src/js/mail_follower_custom_notification.js
-
38mail_follower_custom_notification/static/src/xml/mail_follower_custom_notification.xml
-
4mail_follower_custom_notification/tests/__init__.py
-
75mail_follower_custom_notification/tests/test_mail_follower_custom_notification.py
-
18mail_follower_custom_notification/views/mail_message_subtype.xml
-
11mail_follower_custom_notification/views/templates.xml
-
4mail_follower_custom_notification/wizards/__init__.py
-
46mail_follower_custom_notification/wizards/mail_subtype_assign_custom_notifications.py
-
30mail_follower_custom_notification/wizards/mail_subtype_assign_custom_notifications.xml
-
24marketing_security_group/i18n/es.po
-
3website_mail_snippet_bg_color/views/snippets.xml
-
23website_mail_snippet_responsive/views/templates.xml
@ -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 <https://github.com/OCA/social/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 <https://github.com/OCA/social/issues/new?body=module:%20mail_follower_custom_notification%0Aversion:%208.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. |
|||
|
|||
Credits |
|||
======= |
|||
|
|||
Contributors |
|||
------------ |
|||
|
|||
* Holger Brunn <hbrunn@therp.nl> |
|||
|
|||
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. |
@ -0,0 +1,5 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2015 Therp BV <http://therp.nl> |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
from . import models |
|||
from . import wizards |
@ -0,0 +1,27 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2015 Therp BV <http://therp.nl> |
|||
# 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, |
|||
} |
After Width: 451 | Height: 156 | Size: 8.6 KiB |
@ -0,0 +1,9 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2015 Therp BV <http://therp.nl> |
|||
# 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 |
@ -0,0 +1,92 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2016 Therp BV <http://therp.nl> |
|||
# 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) |
@ -0,0 +1,42 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2015 Therp BV <http://therp.nl> |
|||
# 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 |
@ -0,0 +1,25 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2015 Therp BV <http://therp.nl> |
|||
# 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) |
@ -0,0 +1,22 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2015 Therp BV <http://therp.nl> |
|||
# 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)]) |
@ -0,0 +1,33 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2015 Therp BV <http://therp.nl> |
|||
# 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 |
@ -0,0 +1,80 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2015 Therp BV <http://therp.nl> |
|||
# 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'))] |
|||
}), |
After Width: 128 | Height: 128 | Size: 9.2 KiB |
@ -0,0 +1,5 @@ |
|||
.oe_custom_notification legend |
|||
{ |
|||
font-size: inherit; |
|||
margin-bottom: 0px; |
|||
} |
@ -0,0 +1,79 @@ |
|||
//-*- coding: utf-8 -*-
|
|||
//© 2015 Therp BV <http://therp.nl>
|
|||
//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]) |
|||
}) |
|||
}, |
|||
}); |
|||
} |
@ -0,0 +1,38 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<template> |
|||
<t t-extend="mail.followers.subtype"> |
|||
<t t-jquery="table" t-operation="append"> |
|||
<tr class="oe_custom_notification" t-att-style="record.followed ? '' : 'display: none'" t-attf-id="custom_notification_#{record.id}#{dialog ? '_dialog' : ''}" t-att-data-id="record.id"> |
|||
<td /> |
|||
<td> |
|||
<fieldset class="oe_custom_notification_mail"> |
|||
<legend>Mail notifications</legend> |
|||
<div> |
|||
<input type="radio" t-att-checked="record.force_mail=='default' ? 'checked' : null" t-attf-name="custom_notification_mail_#{record.id}" t-attf-id="custom_notification_mail_default_#{record.id}#{dialog ? '_dialog' : ''}" value="default" /> |
|||
<label t-attf-for="custom_notification_mail_default_#{record.id}#{dialog ? '_dialog' : ''}">Use default mail preferences</label> |
|||
</div> |
|||
<div> |
|||
<input type="radio" t-att-checked="record.force_mail=='force_yes' ? 'checked' : null" t-attf-name="custom_notification_mail_#{record.id}" t-attf-id="custom_notification_mail_force_#{record.id}#{dialog ? '_dialog' : ''}" value="force_yes" /> |
|||
<label t-attf-for="custom_notification_mail_force_#{record.id}#{dialog ? '_dialog' : ''}">Force sending mails</label> |
|||
</div> |
|||
<div> |
|||
<input type="radio" t-att-checked="record.force_mail=='force_no' ? 'checked' : null" t-attf-name="custom_notification_mail_#{record.id}" t-attf-id="custom_notification_mail_force_no_#{record.id}#{dialog ? '_dialog' : ''}" value="force_no" /> |
|||
<label t-attf-for="custom_notification_mail_force_no_#{record.id}#{dialog ? '_dialog' : ''}">Force not sending mails</label> |
|||
</div> |
|||
</fieldset> |
|||
<fieldset class="oe_custom_notification_own"> |
|||
<legend>Own messages</legend> |
|||
<div> |
|||
<input type="radio" t-att-checked="!record.force_own ? 'checked' : null" t-attf-name="custom_notification_own_#{record.id}" t-attf-id="custom_notification_own_no_#{record.id}#{dialog ? '_dialog' : ''}" value="" /> |
|||
<label t-attf-for="custom_notification_own_no_#{record.id}#{dialog ? '_dialog' : ''}">No notification</label> |
|||
</div> |
|||
<div> |
|||
<input type="radio" t-att-checked="record.force_own ? 'checked' : null" t-attf-name="custom_notification_own_#{record.id}" t-attf-id="custom_notification_own_yes_#{record.id}#{dialog ? '_dialog' : ''}" value="1" /> |
|||
<label t-attf-for="custom_notification_own_yes_#{record.id}#{dialog ? '_dialog' : ''}">Notify me</label> |
|||
</div> |
|||
</fieldset> |
|||
</td> |
|||
</tr> |
|||
</t> |
|||
</t> |
|||
</template> |
@ -0,0 +1,4 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2015 Therp BV <http://therp.nl> |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
from . import test_mail_follower_custom_notification |
@ -0,0 +1,75 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2015 Therp BV <http://therp.nl> |
|||
# 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) |
@ -0,0 +1,18 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<openerp> |
|||
<data> |
|||
<record id="view_mail_message_subtype_form" model="ir.ui.view"> |
|||
<field name="model">mail.message.subtype</field> |
|||
<field name="inherit_id" ref="mail.view_mail_message_subtype_form" /> |
|||
<field name="arch" type="xml"> |
|||
<group position="inside"> |
|||
<group string="Custom notifications"> |
|||
<field name="custom_notification_mail" /> |
|||
<field name="custom_notification_own" /> |
|||
<field name="custom_notification_model_ids" attrs="{'invisible': [('res_model', '!=', False)]}" widget="many2many_tags" /> |
|||
</group> |
|||
</group> |
|||
</field> |
|||
</record> |
|||
</data> |
|||
</openerp> |
@ -0,0 +1,11 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<openerp> |
|||
<data> |
|||
<template id="assets_backend" name="mail_follower_custom_notification assets" inherit_id="web.assets_backend"> |
|||
<xpath expr="." position="inside"> |
|||
<script type="text/javascript" src="/mail_follower_custom_notification/static/src/js/mail_follower_custom_notification.js"></script> |
|||
<link rel="stylesheet" href="/mail_follower_custom_notification/static/src/css/mail_follower_custom_notification.css"/> |
|||
</xpath> |
|||
</template> |
|||
</data> |
|||
</openerp> |
@ -0,0 +1,4 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2015 Therp BV <http://therp.nl> |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
from . import mail_subtype_assign_custom_notifications |
@ -0,0 +1,46 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2015 Therp BV <http://therp.nl> |
|||
# 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) |
|||
], |
|||
}) |
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<openerp> |
|||
<data> |
|||
<record id="view_mail_subtype_assign_custom_notifications" model="ir.ui.view"> |
|||
<field name="model">mail.subtype.assign.custom.notifications</field> |
|||
<field name="arch" type="xml"> |
|||
<form> |
|||
<group> |
|||
<field name="subtype_ids" widget="many2many_tags" /> |
|||
</group> |
|||
<footer> |
|||
<button type="object" name="button_apply" string="Apply" |
|||
class="oe_highlight" /> |
|||
or |
|||
<button type="special" special="cancel" string="Cancel" |
|||
class="oe_link" /> |
|||
</footer> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
<act_window id="action_mail_subtype_assign_custom_notifications" |
|||
name="Update existing subscriptions" |
|||
src_model="mail.message.subtype" |
|||
res_model="mail.subtype.assign.custom.notifications" |
|||
view_id="view_mail_subtype_assign_custom_notifications" |
|||
multi="False" |
|||
key2="client_action_multi" |
|||
target="new" /> |
|||
</data> |
|||
</openerp> |
@ -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" |
Write
Preview
Loading…
Cancel
Save
Reference in new issue