[FIX] hr_timesheet: show all tasks assigned to user

Versions:
---------
- 15.0+

Steps to reproduce:
-------------------
1. install project & hr_timesheet;
2. create a follower-only project with timesheets enabled;
3. assign a task to a non-follower with user-level access rights;
4. log in as user;
5. go to timesheets app;
6. add a line.

Issue:
------
The assigned task doesn't show in the search results.

Cause:
------
The task's `allow_timesheets` field is set to be `related` to its
project's `allow_timesheets` field. This field is inaccessible for
private projects the user doesn't follow, so it doesn't show up when
searching tasks assigned to user where `allow_timesheets=True`.

Solution:
---------
Add compute and search methods to have `sudo` access without having to
make to field storable.

opw-3450671

closes odoo/odoo#141760

X-original-commit: 06e67687cf944ea14d38d3bf0272aece15d44faf
Signed-off-by: Xavier Bol (xbo) <xbo@odoo.com>
This commit is contained in:
Levi Siuzdak (sile)
2023-11-13 19:03:32 +00:00
parent 1bcc41f7fe
commit dec902180f
3 changed files with 18 additions and 3 deletions
+1 -1
View File
@@ -50,7 +50,7 @@ class AccountAnalyticLine(models.Model):
task_id = fields.Many2one(
'project.task', 'Task', index='btree_not_null',
compute='_compute_task_id', store=True, readonly=False,
domain="[('project_id.allow_timesheets', '=', True), ('project_id', '=?', project_id)]")
domain="[('allow_timesheets', '=', True), ('project_id', '=?', project_id)]")
parent_task_id = fields.Many2one('project.task', related='task_id.parent_id', store=True)
project_id = fields.Many2one(
'project.project', 'Project', domain=_domain_project_id, index=True,
+16 -1
View File
@@ -27,7 +27,11 @@ class Task(models.Model):
project_id = fields.Many2one(domain="['|', ('company_id', '=', False), ('company_id', '=?', company_id), ('is_internal_project', '=', False)]")
analytic_account_active = fields.Boolean("Active Analytic Account", compute='_compute_analytic_account_active', compute_sudo=True, recursive=True)
allow_timesheets = fields.Boolean("Allow timesheets", related="project_id.allow_timesheets", help="Timesheets can be logged on this task.", readonly=True, recursive=True)
allow_timesheets = fields.Boolean(
"Allow timesheets",
compute='_compute_allow_timesheets', search='_search_allow_timesheets',
compute_sudo=True, readonly=True,
help="Timesheets can be logged on this task.")
remaining_hours = fields.Float("Remaining Hours", compute='_compute_remaining_hours', store=True, readonly=True, help="Number of allocated hours minus the number of hours spent.")
remaining_hours_percentage = fields.Float(compute='_compute_remaining_hours_percentage', search='_search_remaining_hours_percentage')
effective_hours = fields.Float("Hours Spent", compute='_compute_effective_hours', compute_sudo=True, store=True)
@@ -60,6 +64,17 @@ class Task(models.Model):
def _compute_encode_uom_in_days(self):
self.encode_uom_in_days = self._uom_in_days()
@api.depends('project_id.allow_timesheets')
def _compute_allow_timesheets(self):
for task in self:
task.allow_timesheets = task.project_id.allow_timesheets
def _search_allow_timesheets(self, operator, value):
query = self.env['project.project'].sudo()._search([
('allow_timesheets', operator, value),
])
return [('project_id', 'in', query)]
@api.depends('analytic_account_id.active', 'project_id.analytic_account_id.active')
def _compute_analytic_account_active(self):
""" Overridden in sale_timesheet """
@@ -10,7 +10,7 @@ class AccountAnalyticLine(models.Model):
holiday_id = fields.Many2one("hr.leave", string='Time Off Request', copy=False)
global_leave_id = fields.Many2one("resource.calendar.leaves", string="Global Time Off", ondelete='cascade')
task_id = fields.Many2one(domain="[('project_id.allow_timesheets', '=', True), ('project_id', '=?', project_id), ('is_timeoff_task', '=', False)]")
task_id = fields.Many2one(domain="[('allow_timesheets', '=', True), ('project_id', '=?', project_id), ('is_timeoff_task', '=', False)]")
def _get_redirect_action(self):
leave_form_view_id = self.env.ref('hr_holidays.hr_leave_view_form').id