diff --git a/addons/hr/models/hr_employee.py b/addons/hr/models/hr_employee.py index 9b7ea3026c0..a001fdab00a 100644 --- a/addons/hr/models/hr_employee.py +++ b/addons/hr/models/hr_employee.py @@ -168,16 +168,16 @@ class HrEmployeePrivate(models.Model): super()._compute_avatar_128() def _compute_avatar(self, avatar_field, image_field): - employee_wo_user_or_image_ids = [] + employee_wo_user_and_image = self.env['hr.employee'] for employee in self: - if not (employee.user_id or employee._origin[image_field]): - employee_wo_user_or_image_ids.append(employee.id) + if not employee.user_id and not employee._origin[image_field]: + employee_wo_user_and_image += employee continue avatar = employee._origin[image_field] if not avatar and employee.user_id: avatar = employee.user_id.sudo()[avatar_field] employee[avatar_field] = avatar - super(HrEmployeePrivate, self.browse(employee_wo_user_or_image_ids))._compute_avatar(avatar_field, image_field) + super(HrEmployeePrivate, employee_wo_user_and_image)._compute_avatar(avatar_field, image_field) @api.depends('name', 'permit_no') def _compute_work_permit_name(self): @@ -383,6 +383,12 @@ class HrEmployeePrivate(models.Model): vals.update(self._sync_user(user, bool(vals.get('image_1920')))) vals['name'] = vals.get('name', user.name) employees = super().create(vals_list) + # Sudo in case HR officer doesn't have the Contact Creation group + employees.filtered(lambda e: not e.work_contact_id).sudo()._create_work_contacts() + for employee_sudo in employees.sudo(): + if not employee_sudo.image_1920: + employee_sudo.image_1920 = employee_sudo._avatar_generate_svg() + employee_sudo.work_contact_id.image_1920 = employee_sudo.image_1920 if self.env.context.get('salary_simulation'): return employees employee_departments = employees.department_id diff --git a/addons/hr/models/hr_employee_base.py b/addons/hr/models/hr_employee_base.py index 23e0e130a92..2dd17e40acd 100644 --- a/addons/hr/models/hr_employee_base.py +++ b/addons/hr/models/hr_employee_base.py @@ -198,21 +198,31 @@ class HrEmployeeBase(models.AbstractModel): employee.mobile_phone = employee.work_contact_id.mobile employee.work_email = employee.work_contact_id.email + def _create_work_contacts(self): + if any(employee.work_contact_id for employee in self): + raise UserError(_('Some employee already have a work contact')) + work_contacts = self.env['res.partner'].create([{ + 'email': employee.work_email, + 'mobile': employee.mobile_phone, + 'name': employee.name, + 'image_1920': employee.image_1920, + 'company_id': employee.company_id.id + } for employee in self]) + for employee, work_contact in zip(self, work_contacts): + employee.work_contact_id = work_contact + def _inverse_work_contact_details(self): + employees_without_work_contact = self.env['hr.employee'] for employee in self: if not employee.work_contact_id: - employee.work_contact_id = self.env['res.partner'].sudo().create({ - 'email': employee.work_email, - 'mobile': employee.mobile_phone, - 'name': employee.name, - 'image_1920': employee.image_1920, - 'company_id': employee.company_id.id - }) + employees_without_work_contact += employee else: employee.work_contact_id.sudo().write({ 'email': employee.work_email, 'mobile': employee.mobile_phone, }) + if employees_without_work_contact: + employees_without_work_contact.sudo()._create_work_contacts() @api.depends('company_id') def _compute_address_id(self): diff --git a/addons/hr/tests/test_hr_employee.py b/addons/hr/tests/test_hr_employee.py index 9e16144cf63..d6d939710b0 100644 --- a/addons/hr/tests/test_hr_employee.py +++ b/addons/hr/tests/test_hr_employee.py @@ -242,3 +242,23 @@ class TestHrEmployee(TestHrCommon): # change user back -> check that there is no company error with Form(test_employee) as employee_form: employee_form.user_id = test_user + + def test_avatar(self): + # Check simple employee has a generated image (initials) + employee_georgette = self.env['hr.employee'].create({'name': 'Georgette Pudubec'}) + self.assertTrue(employee_georgette.image_1920) + self.assertTrue(employee_georgette.avatar_1920) + + self.assertTrue(employee_georgette.work_contact_id) + self.assertTrue(employee_georgette.work_contact_id.image_1920) + self.assertTrue(employee_georgette.work_contact_id.avatar_1920) + + # Check user has a generate image + user_norbert = self.env['res.users'].create({'name': 'Norbert Comidofisse', 'login': 'Norbert6870'}) + self.assertTrue(user_norbert.image_1920) + self.assertTrue(user_norbert.avatar_1920) + + # Check that linked employee got user image + employee_norbert = self.env['hr.employee'].create({'name': 'Norbert Employee', 'user_id': user_norbert.id}) + self.assertEqual(employee_norbert.image_1920, user_norbert.image_1920) + self.assertEqual(employee_norbert.avatar_1920, user_norbert.avatar_1920) diff --git a/addons/hr_holidays/tests/test_company_leave.py b/addons/hr_holidays/tests/test_company_leave.py index a45bc025403..12f11506ac8 100644 --- a/addons/hr_holidays/tests/test_company_leave.py +++ b/addons/hr_holidays/tests/test_company_leave.py @@ -293,7 +293,7 @@ class TestCompanyLeave(TransactionCase): }) company_leave._compute_date_from_to() - with self.assertQueryCount(__system__=830): # 770 community + with self.assertQueryCount(__system__=1350): # 770 community # Original query count: 1987 # Without tracking/activity context keys: 5154 company_leave.action_validate() diff --git a/addons/hr_work_entry_holidays/tests/test_performance.py b/addons/hr_work_entry_holidays/tests/test_performance.py index 31fe439f7b9..340ee3398b7 100644 --- a/addons/hr_work_entry_holidays/tests/test_performance.py +++ b/addons/hr_work_entry_holidays/tests/test_performance.py @@ -32,7 +32,7 @@ class TestWorkEntryHolidaysPerformance(TestWorkEntryHolidaysBase): self.richard_emp.generate_work_entries(date(2018, 1, 1), date(2018, 1, 2)) leave = self.create_leave(datetime(2018, 1, 1, 7, 0), datetime(2018, 1, 1, 18, 0)) - with self.assertQueryCount(__system__=101, admin=103): # com 96/97 + with self.assertQueryCount(__system__=107, admin=108): # com 96/97 leave.action_validate() leave.action_refuse() diff --git a/odoo/addons/base/models/res_users.py b/odoo/addons/base/models/res_users.py index 5fd5f04f645..141aeec193e 100644 --- a/odoo/addons/base/models/res_users.py +++ b/odoo/addons/base/models/res_users.py @@ -612,6 +612,10 @@ class Users(models.Model): if user.partner_id.company_id: user.partner_id.company_id = user.company_id user.partner_id.active = user.active + # Generate employee initals as avatar for internal users without image + if not user.image_1920 and not user.share and user.name: + user.image_1920 = user.partner_id._avatar_generate_svg() + return users def _apply_groups_to_existing_employees(self): diff --git a/odoo/addons/base/tests/test_avatar_mixin.py b/odoo/addons/base/tests/test_avatar_mixin.py index 934c1fbb0d7..a183e2e706f 100644 --- a/odoo/addons/base/tests/test_avatar_mixin.py +++ b/odoo/addons/base/tests/test_avatar_mixin.py @@ -10,16 +10,17 @@ class TestAvatarMixin(TransactionCase): """ tests the avatar mixin """ def setUp(self): super().setUp() + # Set partner manually to fake seed create_date + partner_without_image = self.env['res.partner'].create({'name': 'Marc Demo', 'create_date': '2015-11-12 00:00:00'}) self.user_without_image = self.env['res.users'].create({ 'name': 'Marc Demo', 'email': 'mark.brown23@example.com', 'image_1920': False, 'create_date': '2015-11-12 00:00:00', 'login': 'demo_1', - 'password': 'demo_1' + 'password': 'demo_1', + 'partner_id': partner_without_image.id, }) - self.user_without_image.partner_id.create_date = '2015-11-12 00:00:00' - self.user_without_name = self.env['res.users'].create({ 'name': '', 'email': 'marc.grey25@example.com',