[FIX] sale: apply record rules on order cancellation subject and body

When rendering the sale order cancellation message,
the rendering should apply the current user record rules,
for instance the count of the partner sale orders should
match the count of what the salesman can see in his ui.
Otherwise he doesn't understand why he has a different count
in the UI and in the cancellation message.

In case you want the behavior of seeing all records
and not just the current salesman records only,
then you apply within the template itself the
`sudo()`.

Applying the `sudo` where you actually need it in the template,
and not computing the full subject/body as sudo,
offers more granularity.

closes odoo/odoo#135233

X-original-commit: 5d49a08f60b1f299784e2e983e87cdec178642c1
Signed-off-by: Denis Ledoux (dle) <dle@odoo.com>
This commit is contained in:
Denis Ledoux
2023-09-13 08:20:43 +00:00
parent 87a4a85295
commit 67954c080e
4 changed files with 51 additions and 4 deletions
+2 -2
View File
@@ -21,9 +21,9 @@ class MailComposerMixin(models.AbstractModel):
_description = 'Mail Composer Mixin'
# Content
subject = fields.Char('Subject', compute='_compute_subject', readonly=False, store=True)
subject = fields.Char('Subject', compute='_compute_subject', readonly=False, store=True, compute_sudo=False)
body = fields.Html(
'Contents', compute='_compute_body', readonly=False, store=True,
'Contents', compute='_compute_body', readonly=False, store=True, compute_sudo=False,
render_engine='qweb', render_options={'post_process': True}, sanitize=False)
body_has_template_value = fields.Boolean(
'Body content is the same as the template',
+1
View File
@@ -13,6 +13,7 @@ from . import test_reinvoice
from . import test_sale_flow
from . import test_sale_onboarding
from . import test_sale_order
from . import test_sale_order_cancel
from . import test_sale_prices
from . import test_sale_product_attribute_value_config
from . import test_sale_refund
@@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.tests.common import users
from odoo.addons.sale.tests.common import SaleCommon
from odoo.addons.sales_team.tests.common import TestSalesCommon
class TestSaleOrderCancel(SaleCommon, TestSalesCommon):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.template = cls.env.ref('sale.mail_template_sale_cancellation')
cls.template.write({
'subject': 'I can see {{ len(object.partner_id.sale_order_ids) }} order(s)',
'body_html': 'I can see <t t-out="len(object.partner_id.sale_order_ids)"/> order(s)',
})
cls.partner = cls.env['res.partner'].create({'name': 'foo'})
cls.manager_order, cls.salesman_order = cls.env['sale.order'].create([
{'partner_id': cls.partner.id, 'user_id': cls.user_sales_manager.id},
{'partner_id': cls.partner.id, 'user_id': cls.user_sales_salesman.id}
])
# Invalidate the cache, e.g. to clear the computation of partner.sale_order_ids
cls.env.invalidate_all()
@users('user_sales_salesman')
def test_salesman_record_rules(self):
cancel = self.env['sale.order.cancel'].create({
'template_id': self.template.id,
'order_id': self.salesman_order.id,
})
self.assertEqual(cancel.subject, 'I can see 1 order(s)')
self.assertEqual(cancel.body, 'I can see 1 order(s)')
@users('user_sales_manager')
def test_manager_record_rules(self):
cancel = self.env['sale.order.cancel'].create({
'template_id': self.template.id,
'order_id': self.manager_order.id,
})
self.assertEqual(cancel.subject, 'I can see 2 order(s)')
self.assertEqual(cancel.body, 'I can see 2 order(s)')
+2 -2
View File
@@ -52,7 +52,7 @@ class SaleOrderCancel(models.TransientModel):
@api.depends('order_id')
def _compute_subject(self):
for wizard_su in self.filtered('template_id').sudo():
for wizard_su in self.filtered('template_id'):
wizard_su.subject = wizard_su.template_id._render_field(
'subject',
[wizard_su.order_id.id],
@@ -62,7 +62,7 @@ class SaleOrderCancel(models.TransientModel):
@api.depends('order_id')
def _compute_body(self):
for wizard_su in self.filtered('template_id').sudo():
for wizard_su in self.filtered('template_id'):
wizard_su.body = wizard_su.template_id._render_field(
'body_html',
[wizard_su.order_id.id],