[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:
parent
e9f9bb5802
commit
2e5412fc1d
|
@ -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
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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); ">
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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(
|
||||
|
|
Loading…
Reference in New Issue