From 43bb9e18b5ca37e10a15b7a83cfa2e34f98faa66 Mon Sep 17 00:00:00 2001 From: "Hugo Carlier (Huca)" Date: Thu, 26 Oct 2023 13:03:49 +0200 Subject: [PATCH] [FIX] sale_timesheet: avoid access error for timesheets in project sharing Steps ===== - Install sale_timesheet - Create a project shared (in edition) with a portal user - Creata a task with a subtask and log timesheets for the subtask - As a portal user open the parent task form - Go in the timesheet tab - Click on the button "Sub-tasks Hours/Days Spent" at the bottom of the page Issue ===== An access error appears for a res.partner record. Cause ===== https://github.com/odoo/odoo/pull/135528 introduced the field allowed_so_line_ids on model account.analytic.line. This field is computed based on the values of the field commercial_partner_id (res.partner relation). However, portal users have no access to res.partner records and the presence of this field in account.analytic.line view (for timesheet) therefore raises an access error for portal user. Fix === A sudo is used in method _default_sale_line_domain to be able to fetch the ids of the partners linked to the timesheet, even as a portal user. task-3572112 closes odoo/odoo#139866 Signed-off-by: Xavier Bol (xbo) --- addons/sale_timesheet/models/account.py | 2 +- addons/sale_timesheet/tests/__init__.py | 1 + .../tests/test_sale_timesheet_portal.py | 38 +++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 addons/sale_timesheet/tests/test_sale_timesheet_portal.py diff --git a/addons/sale_timesheet/models/account.py b/addons/sale_timesheet/models/account.py index c535335a337..3e3444f3567 100644 --- a/addons/sale_timesheet/models/account.py +++ b/addons/sale_timesheet/models/account.py @@ -37,7 +37,7 @@ class AccountAnalyticLine(models.Model): ('is_service', '=', True), ('is_expense', '=', False), ('state', '=', 'sale'), - ('order_partner_id', 'child_of', self.commercial_partner_id.ids) + ('order_partner_id', 'child_of', self.sudo().commercial_partner_id.ids) ], super()._default_sale_line_domain()]) @api.depends('commercial_partner_id') diff --git a/addons/sale_timesheet/tests/__init__.py b/addons/sale_timesheet/tests/__init__.py index 3136159e53c..21e63afa4ba 100644 --- a/addons/sale_timesheet/tests/__init__.py +++ b/addons/sale_timesheet/tests/__init__.py @@ -12,6 +12,7 @@ from . import test_project_billing_multicompany from . import test_upsell_warning from . import test_edit_so_line_timesheet from . import test_so_line_determined_in_timesheet +from . import test_sale_timesheet_portal from . import test_sale_timesheet_ui from . import test_project_pricing_type from . import test_project_update diff --git a/addons/sale_timesheet/tests/test_sale_timesheet_portal.py b/addons/sale_timesheet/tests/test_sale_timesheet_portal.py new file mode 100644 index 00000000000..9051839fffa --- /dev/null +++ b/addons/sale_timesheet/tests/test_sale_timesheet_portal.py @@ -0,0 +1,38 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import Command +from odoo.tests import tagged + +from odoo.addons.project.tests.test_project_sharing import TestProjectSharingCommon +from odoo.addons.sale_timesheet.tests.common import TestCommonSaleTimesheet + +@tagged('post_install', '-at_install') +class TestSaleTimesheetPortal(TestProjectSharingCommon, TestCommonSaleTimesheet): + + def test_ensure_allowed_so_line_field_access(self): + """ Ensure that the field so_line of account.analytic.line is accessible for portal user""" + # A portal collaborator is added to a project to enable the rule analytic.account.analytic.line.timesheet.portal.user + self.project_task_rate.write({ + 'collaborator_ids': [ + Command.create({'partner_id': self.user_portal.partner_id.id}), + ], + 'privacy_visibility': 'portal', + 'message_partner_ids': [ + Command.link(self.user_portal.partner_id.id), + ], + }) + task1 = self.env['project.task'].create({ + 'name': 'Test Task', + 'project_id': self.project_task_rate.id, + }) + # log some timesheets (on the project accessible in portal) + timesheet1 = self.env['account.analytic.line'].create({ + 'name': 'Test Line', + 'project_id': self.project_task_rate.id, + 'task_id': task1.id, + 'unit_amount': 10.5, + 'employee_id': self.employee_user.id, + }) + # Accessing field allowed_so_line_ids as a portal user should not raise any access error + self.env.invalidate_all() + timesheet1.with_user(self.user_portal).read(['allowed_so_line_ids'])