[FIX] mail, BaseModel, portal_sale: fixes and improvements in the URL

management to access documents in notification emails, as well as for the
'view quotation' link in portal_sale module.

models: added a get_access_action method: basically, returns the action to
access a document. It uses the get_formview_action by default (form view
of the document). However for some documents we want to directly go to the
website, leading to an act_url action for some documents. This method allows
this behavior.

portal_sale: get_signup_url now uses the mail.action_mail_redirect method
instead of directly redirecting towards a portal menu. This allows to fall
back on a standard behavior.

portal_sale: get_formview_action updated, to match actions tailored for
portal users.

website_quote: get_access_action of sale order updated. If the sale order
has a template defined, the returned action is an act_url (website view
of the quotation), not the form action anymore.

mail: fixed signature + company signature in notification emails. Even without
user signature, the company signature + access link should be correct.

portal: signup url in notification emali was not using the mail redirection
as action. It is now the case.
This commit is contained in:
Thibault Delavallée 2014-08-07 14:43:21 +02:00
parent e9f9bb5802
commit 2e5412fc1d
8 changed files with 76 additions and 35 deletions

View File

@ -120,7 +120,7 @@ class mail_notification(osv.Model):
notify_pids.append(partner.id)
return notify_pids
def get_signature_footer(self, cr, uid, user_id, res_model=None, res_id=None, context=None):
def get_signature_footer(self, cr, uid, user_id, res_model=None, res_id=None, context=None, user_signature=True):
""" Format a standard footer for notification emails (such as pushed messages
notification or invite emails).
Format:
@ -137,11 +137,13 @@ class mail_notification(osv.Model):
# add user signature
user = self.pool.get("res.users").browse(cr, SUPERUSER_ID, [user_id], context=context)[0]
if user.signature:
signature = user.signature
else:
signature = "--<br />%s" % user.name
footer = tools.append_content_to_html(footer, signature, plaintext=False)
if user_signature:
if user.signature:
signature = user.signature
else:
signature = "--<br />%s" % user.name
footer = tools.append_content_to_html(footer, signature, plaintext=False)
# add company signature
if user.company_id.website:
website_url = ('http://%s' % user.company_id.website) if not user.company_id.website.lower().startswith(('http:', 'https:')) \
@ -187,9 +189,9 @@ class mail_notification(osv.Model):
# compute email body (signature, company data)
body_html = message.body
# add user signature except for mail groups, where users are usually adding their own signatures already
if user_signature and message.model != 'mail.group':
user_id = message.author_id and message.author_id.user_ids and message.author_id.user_ids[0] and message.author_id.user_ids[0].id or None
signature_company = self.get_signature_footer(cr, uid, user_id, res_model=message.model, res_id=message.res_id, context=context)
user_id = message.author_id and message.author_id.user_ids and message.author_id.user_ids[0] and message.author_id.user_ids[0].id or None
signature_company = self.get_signature_footer(cr, uid, user_id, res_model=message.model, res_id=message.res_id, context=context, user_signature=(user_signature and message.model != 'mail.group'))
if signature_company:
body_html = tools.append_content_to_html(body_html, signature_company, plaintext=False, container_tag='div')
# compute email references

View File

@ -627,7 +627,7 @@ class mail_thread(osv.AbstractModel):
if params:
msg_id = params.get('message_id')
model = params.get('model')
res_id = params.get('res_id')
res_id = params.get('res_id', params.get('id')) # signup automatically generated id instead of res_id
if not msg_id and not (model and res_id):
return action
if msg_id and not (model and res_id):
@ -641,7 +641,7 @@ class mail_thread(osv.AbstractModel):
if model_obj.check_access_rights(cr, uid, 'read', raise_exception=False):
try:
model_obj.check_access_rule(cr, uid, [res_id], 'read', context=context)
action = model_obj.get_formview_action(cr, uid, res_id, context=context)
action = model_obj.get_access_action(cr, uid, res_id, context=context)
except (osv.except_osv, orm.except_orm):
pass
action.update({

View File

@ -39,6 +39,7 @@ class mail_mail(osv.Model):
if partner and not partner.user_ids:
contex_signup = dict(context, signup_valid=True)
signup_url = partner_obj._get_signup_url_for_action(cr, SUPERUSER_ID, [partner.id],
action='mail.action_mail_redirect',
model=mail.model, res_id=mail.res_id,
context=contex_signup)[partner.id]
return _(""", <span class='oe_mail_footer_access'><small>access %s %s through <a style='color:inherit' href="%s">our Customer Portal</a></small></span>""") % (context.get('model_name', ''), mail.record_name, signup_url)

View File

@ -131,12 +131,11 @@ class test_portal(TestMail):
self.assertEqual(len(self._build_email_kwargs_list), 1, 'sent email number incorrect, should be only for Bert')
for sent_email in self._build_email_kwargs_list:
self.assertEqual(sent_email.get('subject'), 'Invitation to follow Discussion group: Pigs',
'invite: subject of invitation email is incorrect')
'invite: subject of invitation email is incorrect')
self.assertIn('Administrator invited you to follow Discussion group document: Pigs', sent_email.get('body'),
'invite: body of invitation email is incorrect')
invite_url = partner_carine._get_signup_url_for_action(model='mail.group', res_id=self.group_pigs_id)[partner_carine.id]
self.assertTrue(invite_url in sent_email.get('body'),
'invite: body of invitation email does not contain signup url')
'invite: body of invitation email is incorrect')
self.assertIn(partner_carine.signup_token, sent_email.get('body'),
'invite: body of invitation email does not contain signup token')
def test_20_notification_url(self):
""" Tests designed to test the URL added in notification emails. """
@ -157,8 +156,8 @@ class test_portal(TestMail):
# 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')
self.assertIn(partner_bert.signup_token, url,
'notification email: mails send to a not-user partner should contain the signup token')
# Test: link for user -> signin
url = self.mail_mail._get_partner_access_link(cr, uid, mail, partner=partner_raoul)

View File

@ -19,6 +19,7 @@
#
##############################################################################
from openerp import SUPERUSER_ID
from openerp.osv import osv, fields
@ -67,10 +68,19 @@ class sale_order(osv.Model):
def get_signup_url(self, cr, uid, ids, context=None):
assert len(ids) == 1
document = self.browse(cr, uid, ids[0], context=context)
partner = document.partner_id
action = 'portal_sale.action_quotations_portal' if document.state in ('draft', 'sent') else 'portal_sale.action_orders_portal'
partner.signup_prepare()
return partner._get_signup_url_for_action(action=action, view_type='form', res_id=document.id)[partner.id]
contex_signup = dict(context, signup_valid=True)
return self.pool['res.partner']._get_signup_url_for_action(
cr, uid, [document.partner_id.id], action='mail.action_mail_redirect',
model=self._name, res_id=document.id, context=contex_signup,
)[document.partner_id.id]
def get_formview_action(self, cr, uid, id, context=None):
user = self.pool['res.users'].browse(cr, SUPERUSER_ID, uid, context=context)
if user.share:
document = self.browse(cr, uid, id, context=context)
action_xmlid = 'action_quotations_portal' if document.state in ('draft', 'sent') else 'action_orders_portal'
return self.pool['ir.actions.act_window'].for_xml_id(cr, uid, 'portal_sale', action_xmlid, context=context)
return super(sale_order, self).get_formview_action(cr, uid, id, context=context)
class account_invoice(osv.Model):
@ -117,10 +127,17 @@ class account_invoice(osv.Model):
def get_signup_url(self, cr, uid, ids, context=None):
assert len(ids) == 1
document = self.browse(cr, uid, ids[0], context=context)
partner = document.partner_id
action = 'portal_sale.portal_action_invoices'
partner.signup_prepare()
return partner._get_signup_url_for_action(action=action, view_type='form', res_id=document.id)[partner.id]
contex_signup = dict(context, signup_valid=True)
return self.pool['res.partner']._get_signup_url_for_action(
cr, uid, [document.partner_id.id], action='mail.action_mail_redirect',
model=self._name, res_id=document.id, context=contex_signup,
)[document.partner_id.id]
def get_formview_action(self, cr, uid, id, context=None):
user = self.pool['res.users'].browse(cr, SUPERUSER_ID, uid, context=context)
if user.share:
return self.pool['ir.actions.act_window'].for_xml_id(cr, uid, 'portal_sale', 'portal_action_invoices', context=context)
return super(sale_order, self).get_formview_action(cr, uid, id, context=context)
class mail_mail(osv.osv):

View File

@ -14,6 +14,7 @@
<field name="report_template" ref="sale.report_sale_order"/>
<field name="report_name">${(object.name or '').replace('/','_')}_${object.state == 'draft' and 'draft' or ''}</field>
<field name="lang">${object.partner_id.lang}</field>
<field name="user_signature" eval="True"/>
<field name="body_html"><![CDATA[
<div style="font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 12px; color: rgb(34, 34, 34); background-color: rgb(255, 255, 255); ">

View File

@ -183,7 +183,19 @@ class sale_order(osv.osv):
for line in order_line:
products += line.product_id.product_tmpl_id.recommended_products(context=context)
return products
def get_access_action(self, cr, uid, id, context=None):
""" Override method that generated the link to access the document. Instead
of the classic form view, redirect to the online quote if exists. """
quote = self.browse(cr, uid, id, context=context)
if not quote.template_id:
return super(sale_order, self).get_access_action(cr, uid, id, context=context)
return {
'type': 'ir.actions.act_url',
'url': '/quote/%s' % id,
'target': 'self',
'res_id': id,
}
class sale_quote_option(osv.osv):

View File

@ -1593,14 +1593,23 @@ class BaseModel(object):
"""
view_id = self.get_formview_id(cr, uid, id, context=context)
return {
'type': 'ir.actions.act_window',
'res_model': self._name,
'view_type': 'form',
'view_mode': 'form',
'views': [(view_id, 'form')],
'target': 'current',
'res_id': id,
}
'type': 'ir.actions.act_window',
'res_model': self._name,
'view_type': 'form',
'view_mode': 'form',
'views': [(view_id, 'form')],
'target': 'current',
'res_id': id,
}
def get_access_action(self, cr, uid, id, context=None):
""" Return an action to open the document. This method is meant to be
overridden in addons that want to give specific access to the document.
By default it opens the formview of the document.
:paramt int id: id of the document to open
"""
return self.get_formview_action(cr, uid, id, context=context)
def _view_look_dom_arch(self, cr, uid, node, view_id, context=None):
return self.pool['ir.ui.view'].postprocess_and_fields(