[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) <ltu@odoo.com>
This commit is contained in:
Audric Onockx (auon)
2022-03-09 17:05:17 +00:00
parent 6354cd0e5c
commit c7474eb65b
2 changed files with 53 additions and 5 deletions
+8 -5
View File
@@ -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):
@@ -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')