To: {to}
@@ -223,6 +224,7 @@ class TestMailgateway(TestMailBase):
self.assertEqual(mail.reply_to, 'someone@example.com',
'mail_mail: reply_to should equal the rpely_to given to create')
+ @mute_logger('openerp.addons.mail.mail_thread', 'openerp.osv.orm')
def test_10_message_process(self):
""" Testing incoming emails processing. """
cr, uid, user_raoul = self.cr, self.uid, self.user_raoul
@@ -465,6 +467,7 @@ class TestMailgateway(TestMailBase):
self.assertEqual(msg.body, '\nPlease call me as soon as possible this afternoon!\n\n--\nSylvie\n
',
'message_process: plaintext incoming email incorrectly parsed')
+ @mute_logger('openerp.addons.mail.mail_thread', 'openerp.osv.orm')
def test_20_thread_parent_resolution(self):
""" Testing parent/child relationships are correctly established when processing incoming mails """
cr, uid = self.cr, self.uid
diff --git a/addons/portal/__init__.py b/addons/portal/__init__.py
index e7026986ea4..1f60accc83d 100644
--- a/addons/portal/__init__.py
+++ b/addons/portal/__init__.py
@@ -20,6 +20,7 @@
##############################################################################
import portal
+import mail_thread
import mail_mail
import mail_message
import wizard
diff --git a/addons/portal/mail_mail.py b/addons/portal/mail_mail.py
index 967822c7d60..e412732fdc9 100644
--- a/addons/portal/mail_mail.py
+++ b/addons/portal/mail_mail.py
@@ -28,11 +28,10 @@ class mail_mail(osv.Model):
""" Update of mail_mail class, to add the signin URL to notifications. """
_inherit = 'mail.mail'
- def send_get_mail_body_footer(self, cr, uid, mail, partner=None, context=None):
- """ add a signin link inside the body of a mail.mail
- :param mail: mail.mail browse_record
- :param partner: browse_record of the specific recipient partner
- :return: the resulting body_html
+ def _get_partner_access_link(self, cr, uid, mail, partner=None, context=None):
+ """ Generate URLs for links in mails:
+ - partner is not an user: signup_url
+ - partner is an user: fallback on classic URL
"""
if context is None:
context = {}
@@ -44,4 +43,4 @@ class mail_mail(osv.Model):
context=contex_signup)[partner.id]
return _("""Access your messages and documents through our Customer Portal""") % signup_url
else:
- return super(mail_mail, self).send_get_mail_body_footer(cr, uid, mail, partner=partner, context=context)
+ return super(mail_mail, self)._get_partner_access_link(cr, uid, mail, partner=partner, context=context)
diff --git a/addons/portal/mail_thread.py b/addons/portal/mail_thread.py
new file mode 100644
index 00000000000..44bc4d0bde8
--- /dev/null
+++ b/addons/portal/mail_thread.py
@@ -0,0 +1,43 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2013-TODAY OpenERP S.A ().
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+from openerp import SUPERUSER_ID
+from openerp.osv import osv
+
+
+class mail_thread(osv.AbstractModel):
+ """ Update of mail_mail class, to add the signin URL to notifications. """
+ _inherit = 'mail.thread'
+
+ def _get_inbox_action_xml_id(self, cr, uid, context=None):
+ """ For a given message, return an action that either
+ - opens the form view of the related document if model, res_id, and
+ read access to the document
+ - opens the Inbox with a default search on the conversation if model,
+ res_id
+ - opens the Inbox with context propagated
+ """
+ cur_user = self.pool.get('res.users').browse(cr, SUPERUSER_ID, uid, context=context)
+ # if uid is a portal user -> action is different
+ if any(group.is_portal for group in cur_user.groups_id):
+ return ('portal', 'action_mail_inbox_feeds_portal')
+ else:
+ return super(mail_thread, self)._get_inbox_action_xml_id(cr, uid, context=context)
diff --git a/addons/portal/security/ir.model.access.csv b/addons/portal/security/ir.model.access.csv
index 31bd7332c2f..26b0b4895e8 100644
--- a/addons/portal/security/ir.model.access.csv
+++ b/addons/portal/security/ir.model.access.csv
@@ -3,7 +3,7 @@ access_mail_message_portal,mail.message.portal,mail.model_mail_message,group_por
access_mail_mail_portal,mail.mail.portal,mail.model_mail_mail,group_portal,1,1,1,0
access_mail_notification_portal,mail.notification.portal,mail.model_mail_notification,group_portal,1,1,1,0
access_mail_followers_portal,mail.followers.portal,mail.model_mail_followers,group_portal,1,1,0,0
-access_res_partner,res.partner,base.model_res_partner,portal.group_portal,1,0,0,0
+access_res_partner_portal,res.partner.portal,base.model_res_partner,portal.group_portal,1,0,0,0
access_acquirer,portal.payment.acquirer,portal.model_portal_payment_acquirer,,1,0,0,0
access_acquirer_all,portal.payment.acquirer,portal.model_portal_payment_acquirer,base.group_system,1,1,1,1
access_ir_attachment_group_portal,ir.attachment group_portal,base.model_ir_attachment,portal.group_portal,1,0,1,0
\ No newline at end of file
diff --git a/addons/portal/tests/test_portal.py b/addons/portal/tests/test_portal.py
index e96cbc263f6..e2b66e65af6 100644
--- a/addons/portal/tests/test_portal.py
+++ b/addons/portal/tests/test_portal.py
@@ -133,7 +133,73 @@ class test_portal(TestMailBase):
self.assertTrue(partner_carine.signup_url in sent_email.get('body'),
'invite: body of invitation email does not contain signup url')
- def test_20_message_read(self):
+ def test_20_notification_url(self):
+ """ Tests designed to test the URL added in notification emails. """
+ cr, uid, group_pigs = self.cr, self.uid, self.group_pigs
+
+ # Partner data
+ partner_raoul = self.res_partner.browse(cr, uid, self.partner_raoul_id)
+ partner_bert_id = self.res_partner.create(cr, uid, {'name': 'bert'})
+ partner_bert = self.res_partner.browse(cr, uid, partner_bert_id)
+ # Mail data
+ mail_mail_id = self.mail_mail.create(cr, uid, {'state': 'exception'})
+ mail = self.mail_mail.browse(cr, uid, mail_mail_id)
+
+ # Test: link for nobody -> None
+ url = self.mail_mail._get_partner_access_link(cr, uid, mail)
+ self.assertEqual(url, None,
+ 'notification email: mails not send to a specific partner should not have any URL')
+
+ # Test: link for partner -> signup URL
+ url = self.mail_mail._get_partner_access_link(cr, uid, mail, partner=partner_bert)
+ self.assertIn(partner_bert.signup_url, url,
+ 'notification email: mails send to a not-user partner should contain the signup URL')
+
+ # Test: link for user -> signin
+ url = self.mail_mail._get_partner_access_link(cr, uid, mail, partner=partner_raoul)
+ self.assertIn('action=mail.action_mail_redirect', url,
+ 'notification email: link should contain the redirect action')
+ self.assertIn('login=%s' % partner_raoul.user_ids[0].login, url,
+ 'notification email: link should contain the user login')
+
+ @mute_logger('openerp.addons.mail.mail_thread', 'openerp.osv.orm')
+ def test_21_inbox_redirection(self):
+ """ Tests designed to test the inbox redirection of emails notification URLs. """
+ cr, uid, user_admin, group_pigs = self.cr, self.uid, self.user_admin, self.group_pigs
+ model, act_id = self.ir_model_data.get_object_reference(cr, uid, 'mail', 'action_mail_inbox_feeds')
+ model, port_act_id = self.ir_model_data.get_object_reference(cr, uid, 'portal', 'action_mail_inbox_feeds_portal')
+ # Data: post a message on pigs
+ msg_id = self.group_pigs.message_post(body='My body', partner_ids=[self.partner_bert_id, self.partner_chell_id], type='comment', subtype='mail.mt_comment')
+
+ # No specific parameters -> should redirect to Inbox
+ action = self.mail_thread.message_redirect_action(cr, self.user_raoul_id, {'params': {}})
+ self.assertEqual(action.get('type'), 'ir.actions.client',
+ 'URL redirection: action without parameters should redirect to client action Inbox')
+ self.assertEqual(action.get('id'), act_id,
+ 'URL redirection: action without parameters should redirect to client action Inbox')
+
+ # Bert has read access to Pigs -> should redirect to form view of Pigs
+ action = self.mail_thread.message_redirect_action(cr, self.user_raoul_id, {'params': {'message_id': msg_id}})
+ self.assertEqual(action.get('type'), 'ir.actions.act_window',
+ 'URL redirection: action with message_id for read-accredited user should redirect to Pigs')
+ self.assertEqual(action.get('res_id'), group_pigs.id,
+ 'URL redirection: action with message_id for read-accredited user should redirect to Pigs')
+
+ # Bert has no read access to Pigs -> should redirect to Inbox
+ action = self.mail_thread.message_redirect_action(cr, self.user_bert_id, {'params': {'message_id': msg_id}})
+ self.assertEqual(action.get('type'), 'ir.actions.client',
+ 'URL redirection: action without parameters should redirect to client action Inbox')
+ self.assertEqual(action.get('id'), act_id,
+ 'URL redirection: action without parameters should redirect to client action Inbox')
+
+ # Chell has no read access to pigs -> should redirect to Portal Inbox
+ action = self.mail_thread.message_redirect_action(cr, self.user_chell_id, {'params': {'message_id': msg_id}})
+ self.assertEqual(action.get('type'), 'ir.actions.client',
+ 'URL redirection: action without parameters should redirect to client action Inbox')
+ self.assertEqual(action.get('id'), port_act_id,
+ 'URL redirection: action without parameters should redirect to client action Inbox')
+
+ def test_30_message_read(self):
cr, uid, group_port_id = self.cr, self.uid, self.group_port_id
# Data: custom subtypes