[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)
|
notify_pids.append(partner.id)
|
||||||
return notify_pids
|
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
|
""" Format a standard footer for notification emails (such as pushed messages
|
||||||
notification or invite emails).
|
notification or invite emails).
|
||||||
Format:
|
Format:
|
||||||
|
@ -137,11 +137,13 @@ class mail_notification(osv.Model):
|
||||||
|
|
||||||
# add user signature
|
# add user signature
|
||||||
user = self.pool.get("res.users").browse(cr, SUPERUSER_ID, [user_id], context=context)[0]
|
user = self.pool.get("res.users").browse(cr, SUPERUSER_ID, [user_id], context=context)[0]
|
||||||
if user.signature:
|
if user_signature:
|
||||||
signature = user.signature
|
if user.signature:
|
||||||
else:
|
signature = user.signature
|
||||||
signature = "--<br />%s" % user.name
|
else:
|
||||||
footer = tools.append_content_to_html(footer, signature, plaintext=False)
|
signature = "--<br />%s" % user.name
|
||||||
|
footer = tools.append_content_to_html(footer, signature, plaintext=False)
|
||||||
|
|
||||||
# add company signature
|
# add company signature
|
||||||
if user.company_id.website:
|
if user.company_id.website:
|
||||||
website_url = ('http://%s' % user.company_id.website) if not user.company_id.website.lower().startswith(('http:', 'https:')) \
|
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)
|
# compute email body (signature, company data)
|
||||||
body_html = message.body
|
body_html = message.body
|
||||||
# add user signature except for mail groups, where users are usually adding their own signatures already
|
# 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
|
||||||
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'))
|
||||||
signature_company = self.get_signature_footer(cr, uid, user_id, res_model=message.model, res_id=message.res_id, context=context)
|
if signature_company:
|
||||||
body_html = tools.append_content_to_html(body_html, signature_company, plaintext=False, container_tag='div')
|
body_html = tools.append_content_to_html(body_html, signature_company, plaintext=False, container_tag='div')
|
||||||
|
|
||||||
# compute email references
|
# compute email references
|
||||||
|
|
|
@ -627,7 +627,7 @@ class mail_thread(osv.AbstractModel):
|
||||||
if params:
|
if params:
|
||||||
msg_id = params.get('message_id')
|
msg_id = params.get('message_id')
|
||||||
model = params.get('model')
|
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):
|
if not msg_id and not (model and res_id):
|
||||||
return action
|
return action
|
||||||
if msg_id and not (model and res_id):
|
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):
|
if model_obj.check_access_rights(cr, uid, 'read', raise_exception=False):
|
||||||
try:
|
try:
|
||||||
model_obj.check_access_rule(cr, uid, [res_id], 'read', context=context)
|
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):
|
except (osv.except_osv, orm.except_orm):
|
||||||
pass
|
pass
|
||||||
action.update({
|
action.update({
|
||||||
|
|
|
@ -39,6 +39,7 @@ class mail_mail(osv.Model):
|
||||||
if partner and not partner.user_ids:
|
if partner and not partner.user_ids:
|
||||||
contex_signup = dict(context, signup_valid=True)
|
contex_signup = dict(context, signup_valid=True)
|
||||||
signup_url = partner_obj._get_signup_url_for_action(cr, SUPERUSER_ID, [partner.id],
|
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,
|
model=mail.model, res_id=mail.res_id,
|
||||||
context=contex_signup)[partner.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)
|
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')
|
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:
|
for sent_email in self._build_email_kwargs_list:
|
||||||
self.assertEqual(sent_email.get('subject'), 'Invitation to follow Discussion group: Pigs',
|
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'),
|
self.assertIn('Administrator invited you to follow Discussion group document: Pigs', sent_email.get('body'),
|
||||||
'invite: body of invitation email is incorrect')
|
'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.assertIn(partner_carine.signup_token, sent_email.get('body'),
|
||||||
self.assertTrue(invite_url in sent_email.get('body'),
|
'invite: body of invitation email does not contain signup token')
|
||||||
'invite: body of invitation email does not contain signup url')
|
|
||||||
|
|
||||||
def test_20_notification_url(self):
|
def test_20_notification_url(self):
|
||||||
""" Tests designed to test the URL added in notification emails. """
|
""" Tests designed to test the URL added in notification emails. """
|
||||||
|
@ -157,8 +156,8 @@ class test_portal(TestMail):
|
||||||
|
|
||||||
# Test: link for partner -> signup URL
|
# Test: link for partner -> signup URL
|
||||||
url = self.mail_mail._get_partner_access_link(cr, uid, mail, partner=partner_bert)
|
url = self.mail_mail._get_partner_access_link(cr, uid, mail, partner=partner_bert)
|
||||||
self.assertIn(partner_bert.signup_url, url,
|
self.assertIn(partner_bert.signup_token, url,
|
||||||
'notification email: mails send to a not-user partner should contain the signup URL')
|
'notification email: mails send to a not-user partner should contain the signup token')
|
||||||
|
|
||||||
# Test: link for user -> signin
|
# Test: link for user -> signin
|
||||||
url = self.mail_mail._get_partner_access_link(cr, uid, mail, partner=partner_raoul)
|
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
|
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):
|
def get_signup_url(self, cr, uid, ids, context=None):
|
||||||
assert len(ids) == 1
|
assert len(ids) == 1
|
||||||
document = self.browse(cr, uid, ids[0], context=context)
|
document = self.browse(cr, uid, ids[0], context=context)
|
||||||
partner = document.partner_id
|
contex_signup = dict(context, signup_valid=True)
|
||||||
action = 'portal_sale.action_quotations_portal' if document.state in ('draft', 'sent') else 'portal_sale.action_orders_portal'
|
return self.pool['res.partner']._get_signup_url_for_action(
|
||||||
partner.signup_prepare()
|
cr, uid, [document.partner_id.id], action='mail.action_mail_redirect',
|
||||||
return partner._get_signup_url_for_action(action=action, view_type='form', res_id=document.id)[partner.id]
|
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):
|
class account_invoice(osv.Model):
|
||||||
|
@ -117,10 +127,17 @@ class account_invoice(osv.Model):
|
||||||
def get_signup_url(self, cr, uid, ids, context=None):
|
def get_signup_url(self, cr, uid, ids, context=None):
|
||||||
assert len(ids) == 1
|
assert len(ids) == 1
|
||||||
document = self.browse(cr, uid, ids[0], context=context)
|
document = self.browse(cr, uid, ids[0], context=context)
|
||||||
partner = document.partner_id
|
contex_signup = dict(context, signup_valid=True)
|
||||||
action = 'portal_sale.portal_action_invoices'
|
return self.pool['res.partner']._get_signup_url_for_action(
|
||||||
partner.signup_prepare()
|
cr, uid, [document.partner_id.id], action='mail.action_mail_redirect',
|
||||||
return partner._get_signup_url_for_action(action=action, view_type='form', res_id=document.id)[partner.id]
|
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):
|
class mail_mail(osv.osv):
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
<field name="report_template" ref="sale.report_sale_order"/>
|
<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="report_name">${(object.name or '').replace('/','_')}_${object.state == 'draft' and 'draft' or ''}</field>
|
||||||
<field name="lang">${object.partner_id.lang}</field>
|
<field name="lang">${object.partner_id.lang}</field>
|
||||||
|
<field name="user_signature" eval="True"/>
|
||||||
<field name="body_html"><![CDATA[
|
<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); ">
|
<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); ">
|
||||||
|
|
||||||
|
|
|
@ -184,6 +184,18 @@ class sale_order(osv.osv):
|
||||||
products += line.product_id.product_tmpl_id.recommended_products(context=context)
|
products += line.product_id.product_tmpl_id.recommended_products(context=context)
|
||||||
return products
|
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):
|
class sale_quote_option(osv.osv):
|
||||||
|
|
|
@ -1593,14 +1593,23 @@ class BaseModel(object):
|
||||||
"""
|
"""
|
||||||
view_id = self.get_formview_id(cr, uid, id, context=context)
|
view_id = self.get_formview_id(cr, uid, id, context=context)
|
||||||
return {
|
return {
|
||||||
'type': 'ir.actions.act_window',
|
'type': 'ir.actions.act_window',
|
||||||
'res_model': self._name,
|
'res_model': self._name,
|
||||||
'view_type': 'form',
|
'view_type': 'form',
|
||||||
'view_mode': 'form',
|
'view_mode': 'form',
|
||||||
'views': [(view_id, 'form')],
|
'views': [(view_id, 'form')],
|
||||||
'target': 'current',
|
'target': 'current',
|
||||||
'res_id': id,
|
'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):
|
def _view_look_dom_arch(self, cr, uid, node, view_id, context=None):
|
||||||
return self.pool['ir.ui.view'].postprocess_and_fields(
|
return self.pool['ir.ui.view'].postprocess_and_fields(
|
||||||
|
|
Loading…
Reference in New Issue