diff --git a/addons/project/static/src/js/right_panel/project_right_panel.js b/addons/project/static/src/js/right_panel/project_right_panel.js index da6715789cb..1460d4cbc1c 100644 --- a/addons/project/static/src/js/right_panel/project_right_panel.js +++ b/addons/project/static/src/js/right_panel/project_right_panel.js @@ -98,9 +98,14 @@ export default class ProjectRightPanel extends LegacyComponent { } }); } - this._doAction(action, { - additional_context: additionalContext - }); + const options = { + additional_context: additionalContext, + }; + if (dataset.res_id) { + options.res_id = Number(dataset.res_id); + options.view_type = 'form'; + } + this._doAction(action, options); } _doAction(action, options) { diff --git a/addons/sale_project/models/project.py b/addons/sale_project/models/project.py index d1a86881814..f6fea590504 100644 --- a/addons/sale_project/models/project.py +++ b/addons/sale_project/models/project.py @@ -266,8 +266,8 @@ class Project(models.Model): def get_action(sol_id): """ Return the action vals to call it in frontend if the user can access to the SO related """ - action = action_per_sol.get(sol_id) - return {'action': action, 'additional_context': json.dumps({'active_id': sol_id})} if action else {} + action, res_id = action_per_sol.get(sol_id, (None, None)) + return {'action': action, 'res_id': res_id, 'additional_context': json.dumps({'active_id': sol_id})} if action else {} return [{ **sol_read, diff --git a/addons/sale_project/static/src/right_panel/project_right_panel.xml b/addons/sale_project/static/src/right_panel/project_right_panel.xml index ed944b12d3d..0bef6915f10 100644 --- a/addons/sale_project/static/src/right_panel/project_right_panel.xml +++ b/addons/sale_project/static/src/right_panel/project_right_panel.xml @@ -35,6 +35,7 @@ diff --git a/addons/sale_project_stock/models/sale_order_line.py b/addons/sale_project_stock/models/sale_order_line.py index 79d008f4a7c..a94b4a39192 100644 --- a/addons/sale_project_stock/models/sale_order_line.py +++ b/addons/sale_project_stock/models/sale_order_line.py @@ -1,19 +1,11 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo import fields, models +from odoo import models class SaleOrderLine(models.Model): _inherit = 'sale.order.line' - stock_move_count = fields.Integer(compute='_compute_stock_move_count') - - def _compute_stock_move_count(self): - stock_move_read_group = self.env['stock.move']._read_group([('sale_line_id', 'in', self.ids)], ['sale_line_id'], ['sale_line_id']) - stock_move_count_per_sol = {res['sale_line_id'][0]: res['sale_line_id_count'] for res in stock_move_read_group} - for sol in self: - sol.stock_move_count = stock_move_count_per_sol.get(sol.id, 0) - def _get_action_per_item(self): """ Get action per Sales Order Item to display the stock moves linked @@ -21,7 +13,12 @@ class SaleOrderLine(models.Model): """ action_per_sol = super()._get_action_per_item() stock_move_action = self.env.ref('sale_project_stock.stock_move_per_sale_order_line_action').id + stock_move_ids_per_sol = {} + if self.user_has_groups('stock.group_stock_user'): + stock_move_read_group = self.env['stock.move']._read_group([('sale_line_id', 'in', self.ids)], ['sale_line_id', 'ids:array_agg(id)'], ['sale_line_id']) + stock_move_ids_per_sol = {res['sale_line_id'][0]: res['ids'] for res in stock_move_read_group} for sol in self: - if not sol.is_service and sol.stock_move_count > 0: - action_per_sol[sol.id] = stock_move_action + stock_move_ids = stock_move_ids_per_sol.get(sol.id, []) + if not sol.is_service and stock_move_ids: + action_per_sol[sol.id] = stock_move_action, stock_move_ids[0] if len(stock_move_ids) == 1 else False return action_per_sol diff --git a/addons/sale_timesheet/models/sale_order.py b/addons/sale_timesheet/models/sale_order.py index 02769cc7597..4eb2d0f747e 100644 --- a/addons/sale_timesheet/models/sale_order.py +++ b/addons/sale_timesheet/models/sale_order.py @@ -121,7 +121,6 @@ class SaleOrderLine(models.Model): remaining_hours_available = fields.Boolean(compute='_compute_remaining_hours_available', compute_sudo=True) remaining_hours = fields.Float('Remaining Hours on SO', compute='_compute_remaining_hours', compute_sudo=True, store=True) has_displayed_warning_upsell = fields.Boolean('Has Displayed Warning Upsell') - timesheet_count = fields.Integer(compute='_compute_timesheet_count', groups='hr_timesheet.group_hr_timesheet_user') def name_get(self): res = super(SaleOrderLine, self).name_get() @@ -219,12 +218,6 @@ class SaleOrderLine(models.Model): for line in lines_by_timesheet: line.qty_delivered = mapping.get(line.id or line._origin.id, 0.0) - def _compute_timesheet_count(self): - timesheet_read_group = self.env['account.analytic.line']._read_group([('so_line', 'in', self.ids), ('project_id', '!=', False)], ['so_line'], ['so_line']) - timesheet_count_per_sol = {res['so_line'][0]: res['so_line_count'] for res in timesheet_read_group} - for sol in self: - sol.timesheet_count = timesheet_count_per_sol.get(sol.id, 0) - def _timesheet_compute_delivered_quantity_domain(self): """ Hook for validated timesheet in addionnal module """ domain = [('project_id', '!=', False)] @@ -299,7 +292,12 @@ class SaleOrderLine(models.Model): """ action_per_sol = super()._get_action_per_item() timesheet_action = self.env.ref('sale_timesheet.timesheet_action_from_sales_order_item').id + timesheet_ids_per_sol = {} + if self.user_has_groups('hr_timesheet.group_hr_timesheet_user'): + timesheet_read_group = self.env['account.analytic.line']._read_group([('so_line', 'in', self.ids), ('project_id', '!=', False)], ['so_line', 'ids:array_agg(id)'], ['so_line']) + timesheet_ids_per_sol = {res['so_line'][0]: res['ids'] for res in timesheet_read_group} for sol in self: - if sol.is_service and sol.timesheet_count > 0: - action_per_sol[sol.id] = timesheet_action + timesheet_ids = timesheet_ids_per_sol.get(sol.id, []) + if sol.is_service and len(timesheet_ids) > 0: + action_per_sol[sol.id] = timesheet_action, timesheet_ids[0] if len(timesheet_ids) == 1 else False return action_per_sol