diff --git a/addons/hr_recruitment/__init__.py b/addons/hr_recruitment/__init__.py index 8134f974fbf..52497701d2b 100644 --- a/addons/hr_recruitment/__init__.py +++ b/addons/hr_recruitment/__init__.py @@ -2,3 +2,4 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from . import models +from . import wizard diff --git a/addons/hr_recruitment/__manifest__.py b/addons/hr_recruitment/__manifest__.py index d1e5abc2fd8..73f6719ff1b 100644 --- a/addons/hr_recruitment/__manifest__.py +++ b/addons/hr_recruitment/__manifest__.py @@ -31,6 +31,7 @@ 'views/hr_job_views.xml', 'views/mail_activity_views.xml', 'views/digest_views.xml', + 'wizard/applicant_refuse_reason_views.xml', ], 'demo': [ 'data/hr_recruitment_demo.xml', diff --git a/addons/hr_recruitment/data/hr_recruitment_data.xml b/addons/hr_recruitment/data/hr_recruitment_data.xml index 66f75fe5fc3..1bfcfc3cd11 100644 --- a/addons/hr_recruitment/data/hr_recruitment_data.xml +++ b/addons/hr_recruitment/data/hr_recruitment_data.xml @@ -382,5 +382,16 @@ + + + Doesn't fit the job requirements + + + The applicant is not interested anymore + + + The applicant gets a better offer + + diff --git a/addons/hr_recruitment/data/hr_recruitment_demo.xml b/addons/hr_recruitment/data/hr_recruitment_demo.xml index c31f1317f0f..193cfe6b3f4 100644 --- a/addons/hr_recruitment/data/hr_recruitment_demo.xml +++ b/addons/hr_recruitment/data/hr_recruitment_demo.xml @@ -44,6 +44,7 @@ Sales Manager + @@ -68,6 +69,7 @@ Developer PHP + @@ -92,6 +94,7 @@ Developer Python + @@ -160,6 +163,7 @@ Marketing Job + @@ -170,6 +174,7 @@ More than 5 yrs Experience in PHP + diff --git a/addons/hr_recruitment/models/hr_recruitment.py b/addons/hr_recruitment/models/hr_recruitment.py index e7b8595092e..f0ebe71a7f5 100644 --- a/addons/hr_recruitment/models/hr_recruitment.py +++ b/addons/hr_recruitment/models/hr_recruitment.py @@ -165,6 +165,7 @@ class Applicant(models.Model): legend_normal = fields.Char(related='stage_id.legend_normal', string='Kanban Ongoing', readonly=False) application_count = fields.Integer(compute='_compute_application_count', help='Applications with the same email') meeting_count = fields.Integer(compute='_compute_meeting_count', help='Meeting Count') + refuse_reason_id = fields.Many2one('hr.applicant.refuse.reason', string='Refuse Reason', tracking=True) @api.depends('date_open', 'date_closed') def _compute_day(self): @@ -488,12 +489,39 @@ class Applicant(models.Model): return dict_act_window def archive_applicant(self): - self.write({'active': False}) + return { + 'type': 'ir.actions.act_window', + 'name': _('Refuse Reason'), + 'res_model': 'applicant.get.refuse.reason', + 'view_mode': 'form', + 'target': 'new', + 'context': {'default_applicant_ids': self.ids, 'active_test': False}, + 'views': [[False, 'form']] + } def reset_applicant(self): """ Reinsert the applicant into the recruitment pipe in the first stage""" - default_stage_id = self._default_stage_id() - self.write({'active': True, 'stage_id': default_stage_id}) + default_stage = dict() + for job_id in self.mapped('job_id'): + default_stage[job_id.id] = self.env['hr.recruitment.stage'].search( + ['|', + ('job_ids', '=', False), + ('job_ids', '=', job_id.id), + ('fold', '=', False) + ], order='sequence asc', limit=1).id + for applicant in self: + applicant.write( + {'stage_id': default_stage[applicant.job_id.id], 'refuse_reason_id': False}) + + def toggle_active(self): + res = super(Applicant, self).toggle_active() + applicant_active = self.filtered(lambda applicant: applicant.active) + if applicant_active: + applicant_active.reset_applicant() + applicant_inactive = self.filtered(lambda applicant: not applicant.active) + if applicant_inactive: + return applicant_inactive.archive_applicant() + return res class ApplicantCategory(models.Model): @@ -506,3 +534,11 @@ class ApplicantCategory(models.Model): _sql_constraints = [ ('name_uniq', 'unique (name)', "Tag name already exists !"), ] + + +class ApplicantRefuseReason(models.Model): + _name = "hr.applicant.refuse.reason" + _description = 'Refuse Reason of Applicant' + + name = fields.Char('Description', required=True, translate=True) + active = fields.Boolean('Active', default=True) diff --git a/addons/hr_recruitment/security/ir.model.access.csv b/addons/hr_recruitment/security/ir.model.access.csv index a30b91b9667..c33c641e7b7 100644 --- a/addons/hr_recruitment/security/ir.model.access.csv +++ b/addons/hr_recruitment/security/ir.model.access.csv @@ -3,6 +3,7 @@ access_hr_applicant_user,hr.applicant.user,model_hr_applicant,group_hr_recruitme access_hr_recruitment_stage_user,hr.recruitment.stage.user,model_hr_recruitment_stage,group_hr_recruitment_user,1,0,0,0 access_hr_recruitment_stage_manager,hr.recruitment.stage.manager,model_hr_recruitment_stage,group_hr_recruitment_user,1,1,1,1 access_hr_recruitment_degree,hr.recruitment.degree,model_hr_recruitment_degree,group_hr_recruitment_user,1,1,1,1 +access_hr_recruitment_refuse_reason,hr.applicant.refuse.reason,model_hr_applicant_refuse_reason,group_hr_recruitment_user,1,1,1,1 access_res_partner_hr_user,res.partner.user,base.model_res_partner,group_hr_recruitment_user,1,1,1,1 access_calendar_event_hruser,calendar.event.hruser,calendar.model_calendar_event,group_hr_recruitment_user,1,1,1,1 access_hr_recruitment_source_hr_officer,hr.recruitment.source,model_hr_recruitment_source,group_hr_recruitment_user,1,1,1,1 diff --git a/addons/hr_recruitment/views/hr_recruitment_views.xml b/addons/hr_recruitment/views/hr_recruitment_views.xml index 6d47e50c0e9..3b515db7953 100644 --- a/addons/hr_recruitment/views/hr_recruitment_views.xml +++ b/addons/hr_recruitment/views/hr_recruitment_views.xml @@ -71,8 +71,8 @@
@@ -108,6 +108,7 @@ + @@ -189,6 +190,7 @@ + @@ -213,6 +215,7 @@ + @@ -501,6 +504,46 @@
+ + + Applicant refuse reason form + hr.applicant.refuse.reason + +
+ + +
+
+
+

+ +

+ +
+
+
+
+
+ + + Applicant refuse reason tree + hr.applicant.refuse.reason + + + + + + + + + Refuse Reasons + hr.applicant.refuse.reason + tree,form + + ######################## JOB OPPORTUNITIES (menu) ########################### Applications @@ -570,6 +613,13 @@ + + + + diff --git a/addons/hr_recruitment/wizard/__init__.py b/addons/hr_recruitment/wizard/__init__.py new file mode 100644 index 00000000000..6a456a24112 --- /dev/null +++ b/addons/hr_recruitment/wizard/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import applicant_refuse_reason diff --git a/addons/hr_recruitment/wizard/applicant_refuse_reason.py b/addons/hr_recruitment/wizard/applicant_refuse_reason.py new file mode 100644 index 00000000000..ffb0259a571 --- /dev/null +++ b/addons/hr_recruitment/wizard/applicant_refuse_reason.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- + +from odoo import api, fields, models + + +class ApplicantGetRefuseReason(models.TransientModel): + _name = 'applicant.get.refuse.reason' + _description = 'Get Refuse Reason' + + refuse_reason_id = fields.Many2one('hr.applicant.refuse.reason', 'Refuse Reason') + applicant_ids = fields.Many2many('hr.applicant') + + def action_refuse_reason_apply(self): + return self.applicant_ids.write({'refuse_reason_id': self.refuse_reason_id.id}) diff --git a/addons/hr_recruitment/wizard/applicant_refuse_reason_views.xml b/addons/hr_recruitment/wizard/applicant_refuse_reason_views.xml new file mode 100644 index 00000000000..7de80d1d11f --- /dev/null +++ b/addons/hr_recruitment/wizard/applicant_refuse_reason_views.xml @@ -0,0 +1,28 @@ + + + + applicant.get.refuse.reason.form + applicant.get.refuse.reason + +
+ + + + +
+
+
+
+
+ + + Refuse Reason + ir.actions.act_window + applicant.get.refuse.reason + form + + new + +