Merge branch '8.0' into responsive-date

pull/44/head
Jairo Llopis 2016-02-24 17:10:06 +01:00
commit 2e550af02b
26 changed files with 753 additions and 17 deletions

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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,
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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)])

View File

@ -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

View File

@ -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'))]
}),

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@ -0,0 +1,5 @@
.oe_custom_notification legend
{
font-size: inherit;
margin-bottom: 0px;
}

View File

@ -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])
})
},
});
}

View File

@ -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>

View File

@ -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

View File

@ -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)

View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -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)
],
})

View File

@ -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>

View File

@ -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"

View File

@ -10,8 +10,7 @@
<xpath expr="//div[@id='snippet_options']">
<div
data-snippet-option-id='bg_color_picker'
data-selector="[data-oe-field='body_html'] > div,
.oe_snippet_body,
data-selector="[data-oe-field='body_html'] > *,
.bg_color_picker"
data-selector-siblings="[data-oe-field='body_html'] > *"
data-selector-children="[data-oe-field='body_html']">

View File

@ -18,21 +18,14 @@
<div
class="oe_snippet_body"
style="padding:0px; width:100%; background-color:#ececec; color:rgb(0,0,0); line-height:20px; font-family:Arial,sans-serif; font-size:9pt">
<table class="fluid" align="center" cellpadding="0" cellspacing="0" style="max-width: 600px; border-collapse: collapse; background: inherit; color: inherit;">
<tbody>
<tr>
<td class="bg_color_picker" style="background-color:#ececec; padding:10px 15px 0 15px;">
<table
style="width: 100%; max-width: 570px; border-collapse: collapse; background: inherit; color: inherit; background: #FFFFFF"
cellpadding="0"
cellspacing="0"
align="center"
bgcolor="#FFFFFF">
<t t-raw="0"/>
</table>
</td>
</tr>
</tbody>
<table
style="width: 100%; max-width: 570px; border-collapse: collapse; background: inherit; color: inherit; background: #FFFFFF"
class="bg_color_picker"
cellpadding="0"
cellspacing="0"
align="center"
bgcolor="#FFFFFF">
<t t-raw="0"/>
</table>
</div>
</div>