From c7474eb65b1a6d2ddedaee99953f1370c3e517e6 Mon Sep 17 00:00:00 2001 From: "Audric Onockx (auon)" Date: Thu, 3 Mar 2022 16:06:21 +0000 Subject: [PATCH] [FIX] hr_timesheet : register ts in multi-company environment Steps : Install project and employee. Create 3 company and an employee for you user in 2 of them. Switch to the one without employee. Create a new project and task. Register a timesheet. Issue : The timesheet has no employee. Fix : Display start button and set an employee on the ts only if user has an employee in the company or has only one employee for all companies. opw-2745733 closes odoo/odoo#86135 X-original-commit: b439485bae49cfbef98ca4e1618c3b295d548109 Related: odoo/enterprise#25145 Signed-off-by: Laurent Stukkens (ltu) --- addons/hr_timesheet/models/hr_timesheet.py | 13 +++--- addons/hr_timesheet/tests/test_timesheet.py | 45 +++++++++++++++++++++ 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/addons/hr_timesheet/models/hr_timesheet.py b/addons/hr_timesheet/models/hr_timesheet.py index 85d5973f751..4a54dea4f3f 100644 --- a/addons/hr_timesheet/models/hr_timesheet.py +++ b/addons/hr_timesheet/models/hr_timesheet.py @@ -121,16 +121,19 @@ class AccountAnalyticLine(models.Model): # Although this make a second loop on the vals, we need to wait the preprocess as it could change the company_id in the vals # TODO To be refactored in master - company_ids_in_vals = list({vals['company_id'] for vals in vals_list if vals.get('company_id', False)}) - employees = self.env['hr.employee'].with_context(active_test=False).search([('user_id', 'in', user_ids), ('company_id', 'in', [self.env.company.id] + company_ids_in_vals)]) - user_map = defaultdict(dict) + employees = self.env['hr.employee'].sudo().with_context(active_test=False).search([('user_id', 'in', user_ids)]) + employee_for_user_company = defaultdict(dict) for employee in employees: - user_map[employee.company_id.id][employee.user_id.id] = employee.id + employee_for_user_company[employee.user_id.id][employee.company_id.id] = employee.id for vals in vals_list: # compute employee only for timesheet lines, makes no sense for other lines if not vals.get('employee_id') and vals.get('project_id'): - vals['employee_id'] = user_map[vals.get('company_id', self.env.company.id)].get(vals.get('user_id', default_user_id), False) + employee_for_company = employee_for_user_company.get(vals.get('user_id', default_user_id), False) + if not employee_for_company: + continue + company_id = list(employee_for_company)[0] if len(employee_for_company) == 1 else vals.get('company_id', self.env.company.id) + vals['employee_id'] = employee_for_company.get(company_id, False) lines = super(AccountAnalyticLine, self).create(vals_list) for line, values in zip(lines, vals_list): diff --git a/addons/hr_timesheet/tests/test_timesheet.py b/addons/hr_timesheet/tests/test_timesheet.py index 3b4e7cb23ed..a3e3889aa1e 100644 --- a/addons/hr_timesheet/tests/test_timesheet.py +++ b/addons/hr_timesheet/tests/test_timesheet.py @@ -349,3 +349,48 @@ class TestTimesheet(TestCommonTimesheet): }) self.assertEqual(timesheet.project_id, second_project, 'The project_id of timesheet should be second_project') + + def test_create_timesheet_employee_not_in_company(self): + ''' ts.employee_id only if the user has an employee in the company or one employee for all companies. + ''' + company_2 = self.env['res.company'].create({'name': 'Company 2'}) + company_3 = self.env['res.company'].create({'name': 'Company 3'}) + + analytic_account = self.env['account.analytic.account'].create({ + 'name': 'Aa Aa', + 'company_id': company_3.id, + }) + project = self.env['project.project'].create({ + 'name': 'Aa Project', + 'company_id': company_3.id, + 'analytic_account_id': analytic_account.id, + }) + task = self.env['project.task'].create({ + 'name': 'Aa Task', + 'project_id': project.id, + }) + + Timesheet = self.env['account.analytic.line'].with_context(allowed_company_ids=[company_3.id, company_2.id, self.env.company.id]) + timesheet = Timesheet.create({ + 'name': 'Timesheet', + 'project_id': project.id, + 'task_id': task.id, + 'unit_amount': 2, + 'user_id': self.user_manager.id, + 'company_id': company_3.id, + }) + self.assertEqual(timesheet.employee_id, self.user_manager.employee_id, 'As there is a unique employee for this user, it must be found') + + self.env['hr.employee'].with_company(company_2).create({ + 'name': 'Employee 2', + 'user_id': self.user_manager.id, + }) + timesheet = Timesheet.create({ + 'name': 'Timesheet', + 'project_id': project.id, + 'task_id': task.id, + 'unit_amount': 2, + 'user_id': self.user_manager.id, + 'company_id': company_3.id, + }) + self.assertFalse(timesheet.employee_id, 'As there are several employees for this user, but none of them in this company, none must be found')