diff --git a/addons_extensions/probation_management/__init__.py b/addons_extensions/probation_management/__init__.py new file mode 100644 index 000000000..9a7e03ede --- /dev/null +++ b/addons_extensions/probation_management/__init__.py @@ -0,0 +1 @@ +from . import models \ No newline at end of file diff --git a/addons_extensions/probation_management/__manifest__.py b/addons_extensions/probation_management/__manifest__.py new file mode 100644 index 000000000..9952897fd --- /dev/null +++ b/addons_extensions/probation_management/__manifest__.py @@ -0,0 +1,22 @@ +{ + 'name': 'Probation Management', + 'version': '18.0.1.0.0', + 'category': 'Human Resources', + 'summary': 'Integrate Probation with Employees', + 'author': 'Srivyn Platforms', + 'license': 'LGPL-3', + + 'depends': [ + 'hr', + 'mail', + ], + + 'data': [ + 'security/ir.model.access.csv', + 'views/hr_employee_inherit.xml', + 'views/probation_review_views.xml', + ], + + 'installable': True, + 'application': False, +} \ No newline at end of file diff --git a/addons_extensions/probation_management/models/__init__.py b/addons_extensions/probation_management/models/__init__.py new file mode 100644 index 000000000..5d0b3dd78 --- /dev/null +++ b/addons_extensions/probation_management/models/__init__.py @@ -0,0 +1 @@ +from . import hr_employee_inherit diff --git a/addons_extensions/probation_management/models/hr_employee_inherit.py b/addons_extensions/probation_management/models/hr_employee_inherit.py new file mode 100644 index 000000000..f82801716 --- /dev/null +++ b/addons_extensions/probation_management/models/hr_employee_inherit.py @@ -0,0 +1,159 @@ +from odoo import api, fields, models +from datetime import datetime, time +from dateutil.relativedelta import relativedelta + + +class HrEmployee(models.Model): + _inherit = 'hr.employee' + + emp_type_id = fields.Many2one('hr.contract.type') + probation_state = fields.Selection([ + ('not_applicable', 'Not Applicable'), + ('probation', 'On Probation'), + ('confirmed', 'Confirmed'), + ('extended', 'Extended'), + ('terminated', 'Terminated'), + ], default='not_applicable') + + probation_start_date = fields.Date() + probation_end_date = fields.Date( + compute='_compute_probation_end_date', + store=True + ) + + @api.depends('probation_start_date', 'milestone_days') + def _compute_probation_end_date(self): + for rec in self: + if rec.probation_start_date and rec.milestone_days: + rec.probation_end_date = ( + rec.probation_start_date + + relativedelta(days=rec.milestone_days) + ) + else: + rec.probation_end_date = False + + milestone_days = fields.Integer( + string='Milestone Days', + required=True + ) + + probation_review_ids = fields.One2many( + 'hr.employee.probation.review', + 'employee_id' + ) + + def write(self, vals): + res = super().write(vals) + + for emp in self: + + if ( + emp.emp_type_id + and emp.probation_start_date + and emp.milestone_days + and not emp.probation_review_ids + ): + self.env['hr.employee.probation.review'].create({ + 'employee_id': emp.id, + 'review_date': ( + emp.probation_start_date + + relativedelta(days=emp.milestone_days) + ), + 'milestone_days': emp.milestone_days, + }) + + return res + + def cron_probation_completion(self): + + today = fields.Date.today() + + employees = self.search([ + ('probation_state', '=', 'probation'), + ('probation_end_date', '<=', today) + ]) + + for emp in employees: + + last_review = self.env[ + 'hr.employee.probation.review' + ].search([ + ('employee_id', '=', emp.id) + ], limit=1, order='review_date desc') + + if last_review.outcome == 'confirmed': + emp.probation_state = 'confirmed' + + elif last_review.outcome == 'extended': + emp.probation_state = 'probation' + + emp.probation_end_date = ( + emp.probation_end_date + + relativedelta(months=1) + ) + + elif last_review.outcome == 'terminated': + emp.probation_state = 'terminated' + + else: + pass + +class HrEmployeeProbationReview(models.Model): + _name = 'hr.employee.probation.review' + _description = 'Employee Probation Review' + _rec_name = 'employee_id' + + employee_id = fields.Many2one( + 'hr.employee', + required=True + ) + + review_date = fields.Date(required=True) + + milestone_days = fields.Integer( + string='Milestone Days' + ) + + manager_feedback = fields.Text() + + outcome = fields.Selection([ + ('pending', 'Pending'), + ('confirmed', 'Confirmed'), + ('extended', 'Extended'), + ('terminated', 'Terminated') + ], default='pending') + + extension_days = fields.Integer() + + def write(self, vals): + result = super().write(vals) + + for review in self: + + if vals.get('outcome') == 'confirmed': + review.employee_id.probation_state = 'confirmed' + + elif vals.get('outcome') == 'terminated': + review.employee_id.probation_state = 'terminated' + + elif ( + vals.get('outcome') == 'extended' + and review.extension_days + ): + + review.employee_id.probation_state = 'probation' + + next_review_date = ( + review.review_date + + relativedelta(days=review.extension_days) + ) + + self.create({ + 'employee_id': review.employee_id.id, + 'review_date': next_review_date, + 'milestone_days': review.extension_days, + }) + + review.employee_id.probation_end_date = next_review_date + + return result \ No newline at end of file diff --git a/addons_extensions/probation_management/security/ir.model.access.csv b/addons_extensions/probation_management/security/ir.model.access.csv new file mode 100644 index 000000000..1e1cb8536 --- /dev/null +++ b/addons_extensions/probation_management/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_probation_review_user,probation.review.user,model_hr_employee_probation_review,hr.group_hr_user,1,1,1,1 \ No newline at end of file diff --git a/addons_extensions/probation_management/views/hr_employee_inherit.xml b/addons_extensions/probation_management/views/hr_employee_inherit.xml new file mode 100644 index 000000000..84c393691 --- /dev/null +++ b/addons_extensions/probation_management/views/hr_employee_inherit.xml @@ -0,0 +1,36 @@ + + + + + hr.employee.form.probation + hr.employee + + + + + + > + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/addons_extensions/probation_management/views/probation_review_views.xml b/addons_extensions/probation_management/views/probation_review_views.xml new file mode 100644 index 000000000..36a9ebb66 --- /dev/null +++ b/addons_extensions/probation_management/views/probation_review_views.xml @@ -0,0 +1,81 @@ + + + + + + hr.employee.probation.review.list + hr.employee.probation.review + + + + + + + + + + + + + hr.employee.probation.review.form + hr.employee.probation.review + +
+ + + + + + + + + + + + + + + + + +
+
+
+ + + + Probation Completion Check + + + + + code + + + model.cron_probation_completion() + + + 1 + days + True + + + + + + + Probation Reviews + hr.employee.probation.review + list,form + + + +
\ No newline at end of file