diff --git a/addons/hr/__manifest__.py b/addons/hr/__manifest__.py index 82bbcf4996c..bcbb074f591 100644 --- a/addons/hr/__manifest__.py +++ b/addons/hr/__manifest__.py @@ -37,6 +37,7 @@ 'views/mail_channel_views.xml', 'views/res_users.xml', 'views/res_partner_views.xml', + 'views/hr_templates.xml', 'data/hr_data.xml', ], 'demo': [ diff --git a/addons/hr/models/__init__.py b/addons/hr/models/__init__.py index b891bf1cecf..7e1a795a8ff 100644 --- a/addons/hr/models/__init__.py +++ b/addons/hr/models/__init__.py @@ -11,6 +11,7 @@ from . import hr_departure_reason from . import hr_job from . import hr_plan from . import hr_plan_activity_type +from . import hr_plan_employee_activity from . import hr_work_location from . import mail_alias from . import mail_channel diff --git a/addons/hr/models/hr_plan_employee_activity.py b/addons/hr/models/hr_plan_employee_activity.py new file mode 100644 index 00000000000..ba4b1599809 --- /dev/null +++ b/addons/hr/models/hr_plan_employee_activity.py @@ -0,0 +1,32 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models + + +class HrPlanEmployeeActivity(models.Model): + _name = 'hr.plan.employee.activity' + _description = 'Plan' + _inherit = ['mail.thread', 'mail.activity.mixin'] + _mail_post_access = 'read' + _rec_name = 'employee_id' + + employee_id = fields.Many2one('hr.employee', required=True, ondelete='cascade') + department_id = fields.Many2one(related='employee_id.department_id') + image_128 = fields.Image(related='employee_id.image_128') + company_id = fields.Many2one(related='employee_id.company_id') + user_id = fields.Many2one(related='employee_id.user_id') + summary = fields.Html(compute='_compute_summary') + + @api.depends('activity_ids.summary') + def _compute_summary(self): + for plan in self: + plan.summary = self.env['ir.ui.view']._render_template('hr.hr_employee_plan_activity_summary', { + 'activity_ids': plan.activity_ids, + }) + + @api.autovacuum + def _gc_employee_plan_activity(self): + no_activities = self.env['hr.plan.employee.activity'].search( + [('activity_ids', '=', False)] + ) + no_activities.unlink() diff --git a/addons/hr/security/hr_security.xml b/addons/hr/security/hr_security.xml index 0992af253a6..d8ac61cc9bd 100644 --- a/addons/hr/security/hr_security.xml +++ b/addons/hr/security/hr_security.xml @@ -60,5 +60,17 @@ ['|', ('company_id', '=', False), ('company_id', 'in', company_ids)] + + + Plan Employee Activity: multi-company rule + + ['|', ('company_id', '=', False), ('company_id', 'in', company_ids)] + + + + Plan Employee Activity: own employee or subordinates + + ['|', ('user_id', '=', user.id), ('activity_ids.user_id', '=', user.id)] + diff --git a/addons/hr/security/ir.model.access.csv b/addons/hr/security/ir.model.access.csv index 0f662b3901c..9affc1c6bea 100644 --- a/addons/hr/security/ir.model.access.csv +++ b/addons/hr/security/ir.model.access.csv @@ -18,3 +18,4 @@ access_hr_work_location_user,access_hr_work_location_user,model_hr_work_location access_hr_work_location_manager,access_hr_work_location_manager,model_hr_work_location,group_hr_manager,1,1,1,1 access_hr_departure_reason,access_hr_departure_reason_user,model_hr_departure_reason,group_hr_user,1,1,1,1 access_hr_contract_type_manager,hr.contract.type.manager,model_hr_contract_type,hr.group_hr_user,1,1,1,1 +access_hr_plan_employee_activity,hr.plan.employee.activity,model_hr_plan_employee_activity,base.group_user,1,0,0,0 diff --git a/addons/hr/views/hr_plan_views.xml b/addons/hr/views/hr_plan_views.xml index 2c0b7c35bd8..50d74c41067 100644 --- a/addons/hr/views/hr_plan_views.xml +++ b/addons/hr/views/hr_plan_views.xml @@ -121,5 +121,63 @@ + + hr.plan.employee.activity + + + + +
+
+
+

+ +
+
+ +
+
+ +
+ + Next Activity: + +
+
+
+
+
+
+
+ + + hr.plan.employee.activity + + + + + + + + + + + + hr.plan.employee.activity + +
+ + + + + + + +
+ +
+
+
+
diff --git a/addons/hr/views/hr_templates.xml b/addons/hr/views/hr_templates.xml new file mode 100644 index 00000000000..0065031607d --- /dev/null +++ b/addons/hr/views/hr_templates.xml @@ -0,0 +1,11 @@ + + + + diff --git a/addons/hr/wizard/hr_plan_wizard.py b/addons/hr/wizard/hr_plan_wizard.py index 0cbf893f562..82ce4f4e1fc 100644 --- a/addons/hr/wizard/hr_plan_wizard.py +++ b/addons/hr/wizard/hr_plan_wizard.py @@ -74,17 +74,24 @@ class HrPlanWizard(models.TransientModel): activities = set() for activity_type in self._get_activities_to_schedule(): responsible = activity_type.get_responsible_id(employee)['responsible'] - if self.env['hr.employee'].with_user(responsible).check_access_rights('read', raise_exception=False): - date_deadline = self.env['mail.activity']._calculate_date_deadline(activity_type.activity_type_id) - employee.activity_schedule( - activity_type_id=activity_type.activity_type_id.id, - summary=activity_type.summary, - note=activity_type.note, - user_id=responsible.id, - date_deadline=date_deadline - ) - activity = _('%(activity)s, assigned to %(name)s, due on the %(deadline)s', activity=activity_type.summary, name=responsible.name, deadline=date_deadline) - activities.add(activity) + record = employee + if not self.env['hr.employee'].with_user(responsible).check_access_rights('read', raise_exception=False): + record = self.env['hr.plan.employee.activity'].sudo().search([('employee_id', '=', employee.id)], limit=1) + if not record: + record = self.env['hr.plan.employee.activity'].sudo().create({ + 'employee_id': employee.id, + }) + + date_deadline = self.env['mail.activity']._calculate_date_deadline(activity_type.activity_type_id) + record.activity_schedule( + activity_type_id=activity_type.activity_type_id.id, + summary=activity_type.summary, + note=activity_type.note, + user_id=responsible.id, + date_deadline=date_deadline + ) + activity = _('%(activity)s, assigned to %(name)s, due on the %(deadline)s', activity=activity_type.summary, name=responsible.name, deadline=date_deadline) + activities.add(activity) if activities: body += '