[FIX] mail, BaseModel, portal_sale: fixes and improvements in the URL
authorThibault Delavallée <tde@openerp.com>
Thu, 7 Aug 2014 12:43:21 +0000 (14:43 +0200)
committerThibault Delavallée <tde@openerp.com>
Thu, 7 Aug 2014 14:47:59 +0000 (16:47 +0200)
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.

addons/mail/mail_followers.py
addons/mail/mail_thread.py
addons/portal/mail_mail.py
addons/portal/tests/test_portal.py
addons/portal_sale/portal_sale.py
addons/portal_sale/portal_sale_data.xml
addons/website_quote/models/order.py
openerp/models.py

index aeb0a2b..e8dd37e 100644 (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
index 9125b77..0eb4d35 100644 (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({
index 79e5be4..44af046 100644 (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)
index 0412228..6a8242b 100644 (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)
index f45acf4..b0997f7 100644 (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):
index 2da55bc..6f8f3b3 100644 (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); ">
 
index 8430ef0..bb3f89a 100644 (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):
index 8beb60d..abe36b3 100644 (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(