From 7c3e8cf9639daf2f11e21ec2cbe8aad571a6db8d Mon Sep 17 00:00:00 2001 From: "Xavier BOL (xbo)" Date: Tue, 28 Dec 2021 15:31:45 +0100 Subject: [PATCH] [IMP] sale_{project,timesheet}: get sales order items linked to the project This commit renames some methods and add a query into timesheets to also fetch the SOLs linked to the timesheets linked to the projects. So, now all SOLs selected in the project app for that project will be take into account. task-2710808 --- addons/sale_project/models/project.py | 17 ++++++---------- addons/sale_timesheet/models/project.py | 26 +++++++++++++++++++++++-- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/addons/sale_project/models/project.py b/addons/sale_project/models/project.py index 61ad8340a3c..460b550cebf 100644 --- a/addons/sale_project/models/project.py +++ b/addons/sale_project/models/project.py @@ -77,10 +77,6 @@ class Project(models.Model): project_to_invoice.has_any_so_to_invoice = True (self - project_to_invoice).has_any_so_to_invoice = False - def _get_all_sales_orders(self): - self.ensure_one() - return self._fetch_sale_order_items({'project.task': [('is_closed', '=', False)]}).order_id - @api.depends('sale_order_id', 'task_ids.sale_order_id') def _compute_sale_order_count(self): sale_order_items_per_project_id = self._fetch_sale_order_items_per_project_id({'project.task': [('is_closed', '=', False)]}) @@ -89,7 +85,7 @@ class Project(models.Model): def action_view_sos(self): self.ensure_one() - all_sale_orders = self._get_all_sales_orders() + all_sale_orders = self._fetch_sale_order_items({'project.task': [('is_closed', '=', False)]}).order_id action_window = { "type": "ir.actions.act_window", "res_model": "sale.order", @@ -191,13 +187,13 @@ class Project(models.Model): def _get_sale_order_items_query(self, domain_per_model=None): if domain_per_model is None: domain_per_model = {} - billable_project = [('allow_billable', '=', True)] + billable_project_domain = [('allow_billable', '=', True)] project_domain = [('id', 'in', self.ids), ('sale_line_id', '!=', False)] if 'project.project' in domain_per_model: project_domain = expression.AND([ domain_per_model['project.project'], project_domain, - billable_project, + billable_project_domain, ]) project_query = self.env['project.project']._where_calc(project_domain) self._apply_ir_rules(project_query, 'read') @@ -209,19 +205,18 @@ class Project(models.Model): task_domain = expression.AND([ domain_per_model[Task._name], task_domain, - billable_project, ]) task_query = Task._where_calc(task_domain) Task._apply_ir_rules(task_query, 'read') task_query_str, task_params = task_query.select(f'{Task._table}.project_id AS id', f'{Task._table}.sale_line_id') ProjectMilestone = self.env['project.milestone'] - milestone_domain = [('project_id', 'in', self.ids), ('allow_billable', '=', True)] + milestone_domain = [('project_id', 'in', self.ids), ('allow_billable', '=', True), ('sale_line_id', '!=', False)] if ProjectMilestone._name in domain_per_model: milestone_domain = expression.AND([ domain_per_model[ProjectMilestone._name], milestone_domain, - billable_project, + billable_project_domain, ]) milestone_query = ProjectMilestone._where_calc(milestone_domain) ProjectMilestone._apply_ir_rules(milestone_query) @@ -263,7 +258,7 @@ class Project(models.Model): } for sol_read in sols.read(['display_name', 'product_uom_qty', 'qty_delivered', 'qty_invoiced', 'product_uom'])] def _get_sale_items_domain(self, additional_domain=None): - sale_orders = self._get_all_sales_orders() + sale_orders = self._get_sale_order_items().sudo().order_id domain = [('order_id', 'in', sale_orders.ids), ('is_downpayment', '=', False), ('state', 'in', ['sale', 'done'])] if additional_domain: domain = expression.AND([domain, additional_domain]) diff --git a/addons/sale_timesheet/models/project.py b/addons/sale_timesheet/models/project.py index 13662d6f476..103a6ba3186 100644 --- a/addons/sale_timesheet/models/project.py +++ b/addons/sale_timesheet/models/project.py @@ -320,8 +320,28 @@ class Project(models.Model): def _get_sale_order_items_query(self, domain_per_model=None): if domain_per_model is None: - domain_per_model = {} + domain_per_model = {'project.task': [('allow_billable', '=', True)]} + else: + domain_per_model['project.task'] = expression.AND([ + domain_per_model.get('project.task', []), + [('allow_billable', '=', True)], + ]) query = super()._get_sale_order_items_query(domain_per_model) + + Timesheet = self.env['account.analytic.line'] + timesheet_domain = [('project_id', 'in', self.ids), ('so_line', '!=', False), ('project_id.allow_billable', '=', True)] + if Timesheet._name in domain_per_model: + timesheet_domain = expression.AND([ + domain_per_model.get(Timesheet._name, []), + timesheet_domain, + ]) + timesheet_query = Timesheet._where_calc(timesheet_domain) + Timesheet._apply_ir_rules(timesheet_query, 'read') + timesheet_query_str, timesheet_params = timesheet_query.select( + f'{Timesheet._table}.project_id AS id', + f'{Timesheet._table}.so_line AS sale_line_id', + ) + EmployeeMapping = self.env['project.sale.line.employee.map'] employee_mapping_domain = [('project_id', 'in', self.ids), ('project_id.allow_billable', '=', True), ('sale_line_id', '!=', False)] if EmployeeMapping._name in domain_per_model: @@ -335,11 +355,13 @@ class Project(models.Model): f'{EmployeeMapping._table}.project_id AS id', f'{EmployeeMapping._table}.sale_line_id', ) + query._tables['project_sale_order_item'] = ' UNION '.join([ query._tables['project_sale_order_item'], + timesheet_query_str, employee_mapping_query_str, ]) - query._where_params += employee_mapping_params + query._where_params += timesheet_params + employee_mapping_params return query def _get_profitability_items(self):