From 02c4000506c09ccfaadee5c44571781aa7ec6ad5 Mon Sep 17 00:00:00 2001 From: "Xavier BOL (xbo)" Date: Wed, 17 Mar 2021 17:53:18 +0100 Subject: [PATCH] [IMP] sale_timesheet: set default SOL for employee rate project Before this commit, the user can define some employee mappings and let the default sales order item of the project empty. This commit adds a default SOL when the first employee mapping is added by the user in the project form view. This default SOL is either the one with a service product and remaining hours is greater than 0 for the same customer than the SOL choose in the first employee mapping or the SOL given in the first employee mapping. task-2442683 closes #66181 --- addons/sale_timesheet/models/project.py | 14 ++++++++++++++ .../sale_timesheet/tests/test_project_billing.py | 6 ++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/addons/sale_timesheet/models/project.py b/addons/sale_timesheet/models/project.py index e01376ea872..6fd059a195f 100644 --- a/addons/sale_timesheet/models/project.py +++ b/addons/sale_timesheet/models/project.py @@ -147,6 +147,20 @@ class Project(models.Model): sol = project.sale_line_id or project.sale_line_employee_ids.sale_line_id[:1] project.partner_id = sol.order_partner_id + @api.depends('partner_id') + def _compute_sale_line_id(self): + super()._compute_sale_line_id() + for project in self.filtered(lambda p: not p.sale_line_id and p.partner_id and p.pricing_type == 'employee_rate'): + # Give a SOL by default either the last SOL with service product and remaining_hours > 0 + sol = self.env['sale.order.line'].search([ + ('is_service', '=', True), + ('order_partner_id', 'child_of', project.partner_id.commercial_partner_id.id), + ('is_expense', '=', False), + ('state', 'in', ['sale', 'done']), + ('remaining_hours', '>', 0) + ], limit=1) + project.sale_line_id = sol or project.sale_line_employee_ids.sale_line_id[:1] # get the first SOL containing in the employee mappings if no sol found in the search + @api.constrains('sale_line_id') def _check_sale_line_type(self): for project in self.filtered(lambda project: project.sale_line_id): diff --git a/addons/sale_timesheet/tests/test_project_billing.py b/addons/sale_timesheet/tests/test_project_billing.py index 9ddaa94399e..6556fb578ca 100644 --- a/addons/sale_timesheet/tests/test_project_billing.py +++ b/addons/sale_timesheet/tests/test_project_billing.py @@ -249,6 +249,8 @@ class TestProjectBilling(TestCommonSaleTimesheet): self.assertEqual(task.sale_line_id, self.project_employee_rate.sale_line_id, "Task created in a project billed on 'employee rate' should be linked to the SOL defined in the project.") self.assertEqual(task.partner_id, task.project_id.partner_id, "Task created in a project billed on 'employee rate' should have the same customer as the one from the project") + task.write({'sale_line_id': False}) # remove the SOL to check if the timesheet has no SOL when there is no SOL in the task + # log timesheet on task timesheet1 = Timesheet.create({ 'name': 'Test Line', @@ -395,10 +397,10 @@ class TestProjectBilling(TestCommonSaleTimesheet): }) subtask._onchange_project() - self.assertFalse(task.sale_line_id, "Task moved in a employee rate billable project have empty so line") + self.assertEqual(task.sale_line_id, task.project_id.sale_line_id, "Task moved in a employee rate billable project have the SOL of the project") self.assertEqual(task.partner_id, task.project_id.partner_id, "Task created in a project billed on 'employee rate' should have the same customer as the one from the project") - self.assertFalse(subtask.sale_line_id, "Subask moved in a employee rate billable project have empty so line") + self.assertEqual(subtask.sale_line_id, task.project_id.sale_line_id, "Subask moved in a employee rate billable project have the SOL of the project") self.assertEqual(subtask.partner_id, task.project_id.partner_id, "Subask created in a project billed on 'employee rate' should have the same customer as the one from the project") def test_customer_change_in_project(self):