From 1701e7764fbda42ff06d34976cc52ac6692a919a Mon Sep 17 00:00:00 2001 From: Mitesh Savani Date: Wed, 27 Aug 2014 12:24:06 +0530 Subject: [PATCH] [IMP] hr_recruitment: stages are now job-related, not department-related anymore. Also added default stages. --- addons/hr_recruitment/hr_recruitment.py | 118 +++++++----------- addons/hr_recruitment/hr_recruitment_data.xml | 8 +- addons/hr_recruitment/hr_recruitment_demo.xml | 9 +- addons/hr_recruitment/hr_recruitment_view.xml | 26 ++-- .../controllers/main.py | 2 +- .../views/templates.xml | 1 + 6 files changed, 82 insertions(+), 82 deletions(-) diff --git a/addons/hr_recruitment/hr_recruitment.py b/addons/hr_recruitment/hr_recruitment.py index e88c55df98c..e7a1f47ae55 100644 --- a/addons/hr_recruitment/hr_recruitment.py +++ b/addons/hr_recruitment/hr_recruitment.py @@ -36,6 +36,7 @@ AVAILABLE_PRIORITIES = [ ('3', 'Excellent') ] + class hr_recruitment_source(osv.osv): """ Sources of HR Recruitment """ _name = "hr.recruitment.source" @@ -95,10 +96,14 @@ class hr_recruitment_stage(osv.osv): _name = "hr.recruitment.stage" _description = "Stage of Recruitment" _order = 'sequence' + _columns = { - 'name': fields.char('Name', required=True, translate=True), + 'name': fields.char('Stage Name', required=True, translate=True), 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of stages."), - 'department_id':fields.many2one('hr.department', 'Specific to a Department', help="Stages of the recruitment process may be different per department. If this stage is common to all departments, keep this field empty."), + 'case_default': fields.boolean( + 'Default for New Recruitment', + help="If you check this field, this stage will be proposed by default on each new Recruitment. It will not assign this stage to existing Recruitments."), + 'job_ids': fields.many2many('hr.job', 'job_stage_rel', 'stage_id', 'job_id', 'Job Stages'), 'requirements': fields.text('Requirements'), 'template_id': fields.many2one('mail.template', 'Use template', help="If set, a message is posted on the applicant using the template when the applicant is set to the stage."), 'legend_priority': fields.text( @@ -108,10 +113,13 @@ class hr_recruitment_stage(osv.osv): help='This stage is folded in the kanban view when' 'there are no records in that stage to display.'), } + _defaults = { 'sequence': 1, + 'job_ids': lambda self, cr, uid, context=None: [context['default_job_id']] if context and context.get('default_job_id') else None, } + class hr_recruitment_degree(osv.osv): """ Degree of HR Recruitment """ _name = "hr.recruitment.degree" @@ -127,6 +135,7 @@ class hr_recruitment_degree(osv.osv): ('name_uniq', 'unique (name)', 'The name of the Degree of Recruitment must be unique!') ] + class hr_applicant(osv.Model): _name = "hr.applicant" _description = "Applicant" @@ -134,30 +143,9 @@ class hr_applicant(osv.Model): _inherit = ['mail.thread', 'ir.needaction_mixin', 'utm.mixin'] _mail_mass_mailing = _('Applicants') - def _get_default_department_id(self, cr, uid, context=None): - """ Gives default department by checking if present in the context """ - return (self._resolve_department_id_from_context(cr, uid, context=context) or False) - def _get_default_stage_id(self, cr, uid, context=None): - """ Gives default stage_id """ - department_id = self._get_default_department_id(cr, uid, context=context) - return self.stage_find(cr, uid, [], department_id, [('fold', '=', False)], context=context) - - def _resolve_department_id_from_context(self, cr, uid, context=None): - """ Returns ID of department based on the value of 'default_department_id' - context key, or None if it cannot be resolved to a single - department. - """ - if context is None: - context = {} - if type(context.get('default_department_id')) in (int, long): - return context.get('default_department_id') - if isinstance(context.get('default_department_id'), basestring): - department_name = context['default_department_id'] - department_ids = self.pool.get('hr.department').name_search(cr, uid, name=department_name, context=context) - if len(department_ids) == 1: - return int(department_ids[0][0]) - return None + job_id = context and context.get('default_job_id') + return self.stage_find(cr, uid, [], job_id, [('fold', '=', False)], context=context) def _get_default_company_id(self, cr, uid, department_id=None, context=None): company_id = False @@ -175,15 +163,14 @@ class hr_applicant(osv.Model): # lame hack to allow reverting search, should just work in the trivial case if read_group_order == 'stage_id desc': order = "%s desc" % order - # retrieve section_id from the context and write the domain - # - ('id', 'in', 'ids'): add columns that should be present - # - OR ('department_id', '=', False), ('fold', '=', False): add default columns that are not folded - # - OR ('department_id', 'in', department_id), ('fold', '=', False) if department_id: add department columns that are not folded - department_id = self._resolve_department_id_from_context(cr, uid, context=context) + # retrieve job_id from the context and write the domain: ids + contextual columns (job or default) + job_id = context and context.get('default_job_id') search_domain = [] - if department_id: - search_domain += ['|', ('department_id', '=', department_id)] - search_domain += ['|', ('id', 'in', ids), ('department_id', '=', False)] + if job_id: + search_domain += ['|', ('job_ids', '=', job_id)] + else: + search_domain += ['|', ('case_default', '=', True)] + search_domain += [('id', 'in', ids)] stage_ids = stage_obj._search(cr, uid, search_domain, order=order, access_rights_uid=access_rights_uid, context=context) result = stage_obj.name_get(cr, access_rights_uid, stage_ids, context=context) # restore order of the search @@ -233,8 +220,9 @@ class hr_applicant(osv.Model): 'partner_id': fields.many2one('res.partner', 'Contact'), 'create_date': fields.datetime('Creation Date', readonly=True, select=True), 'write_date': fields.datetime('Update Date', readonly=True), - 'stage_id': fields.many2one ('hr.recruitment.stage', 'Stage', track_visibility='onchange', - domain="['|', ('department_id', '=', department_id), ('department_id', '=', False)]"), + 'stage_id': fields.many2one( + 'hr.recruitment.stage', 'Stage', track_visibility='onchange', + domain="['|', ('case_default', '=', True), ('job_ids', '=', job_id)]", copy=False, select=1), 'last_stage_id': fields.many2one('hr.recruitment.stage', 'Last Stage', help='Stage of the applicant before being in the current stage. Used for lost cases analysis.'), 'categ_ids': fields.many2many('hr.applicant.category', string='Tags'), @@ -276,9 +264,8 @@ class hr_applicant(osv.Model): _defaults = { 'active': lambda *a: 1, 'user_id': lambda s, cr, uid, c: uid, - 'stage_id': lambda s, cr, uid, c: s._get_default_stage_id(cr, uid, c), - 'department_id': lambda s, cr, uid, c: s._get_default_department_id(cr, uid, c), - 'company_id': lambda s, cr, uid, c: s._get_default_company_id(cr, uid, s._get_default_department_id(cr, uid, c), c), + 'stage_id': _get_default_stage_id, + 'company_id': lambda s, cr, uid, c: s._get_default_company_id(cr, uid, c and c.get('default_department_id'), c), 'color': 0, 'priority': '0', 'date_last_stage_update': fields.datetime.now, @@ -296,23 +283,16 @@ class hr_applicant(osv.Model): action['res_id'] = applicant and applicant.emp_id.id or False return action - def onchange_job(self, cr, uid, ids, job_id=False, context=None): + def onchange_job(self, cr, uid, ids, job_id=False, stage_id=False, context=None): department_id = False user_id = False if job_id: job_record = self.pool.get('hr.job').browse(cr, uid, job_id, context=context) department_id = job_record and job_record.department_id and job_record.department_id.id or False user_id = job_record and job_record.user_id and job_record.user_id.id or False - return {'value': {'department_id': department_id, 'user_id': user_id}} - - def onchange_department_id(self, cr, uid, ids, department_id=False, stage_id=False, context=None): - values = {} - if not stage_id: - values['stage_id'] = self.stage_find(cr, uid, [], department_id, [('fold', '=', False)], context=context) - if department_id: - department = self.pool['hr.department'].browse(cr, uid, department_id, context=context) - values['company_id'] = department.company_id.id - return {'value': values} + if not stage_id and job_id: + stage_id = self.stage_find(cr, uid, [], job_id, [('fold', '=', False)], context=context) + return {'value': {'department_id': department_id, 'user_id': user_id, 'stage_id': stage_id}} def onchange_partner_id(self, cr, uid, ids, partner_id, context=None): data = {'partner_phone': False, @@ -333,30 +313,26 @@ class hr_applicant(osv.Model): return {'value': {'date_closed': fields.datetime.now()}} return {'value': {'date_closed': False}} - def stage_find(self, cr, uid, cases, section_id, domain=[], order='sequence', context=None): + def stage_find(self, cr, uid, applicants, job_id, domain=[], order='sequence', context=None): """ Override of the base.stage method Parameter of the stage search taken from the lead: - - department_id: if set, stages must belong to this section or + - job_id: if set, stages must belong to this section or be a default case """ - if isinstance(cases, (int, long)): - cases = self.browse(cr, uid, cases, context=context) - # collect all section_ids - department_ids = [] - if section_id: - department_ids.append(section_id) - for case in cases: - if case.department_id: - department_ids.append(case.department_id.id) - # OR all section_ids and OR with case_default - search_domain = [] - if department_ids: - search_domain += ['|', ('department_id', 'in', department_ids)] - search_domain.append(('department_id', '=', False)) + if isinstance(applicants, (int, long)): + applicants = self.browse(cr, uid, applicants, context=context) + job_ids = set([applicant.job_id.id for applicant in applicants if applicant.job_id]) + if job_id: + job_ids.add(job_id) + # OR all job_id and OR with applicant_default + if job_ids: + search_domain = ['|', ('case_default', '=', True), ('job_ids', 'in', list(job_ids))] + else: + search_domain = [('case_default', '=', True)] # AND with the domain in parameter search_domain += list(domain) # perform search, return the first found - stage_ids = self.pool.get('hr.recruitment.stage').search(cr, uid, search_domain, order=order, context=context) + stage_ids = self.pool.get('hr.recruitment.stage').search(cr, uid, search_domain, order=order, limit=1, context=context) if stage_ids: return stage_ids[0] return False @@ -605,15 +581,12 @@ class hr_job(osv.osv): _name = "hr.job" _inherits = {'mail.alias': 'alias_id'} - - def _track_subtype(self, cr, uid, ids, init_values, context=None): record = self.browse(cr, uid, ids[0], context=context) if 'state' in init_values and record.state == 'open': return 'hr_recruitment.mt_job_new' return super(hr_job, self)._track_subtype(cr, uid, ids, init_values, context=context) - def _get_attached_docs(self, cr, uid, ids, field_name, arg, context=None): res = {} attachment_obj = self.pool.get('ir.attachment') @@ -646,6 +619,7 @@ class hr_job(osv.osv): 'application_ids': fields.one2many('hr.applicant', 'job_id', 'Applications'), 'application_count': fields.function(_count_all, type='integer', string='Applications', multi=True), 'manager_id': fields.related('department_id', 'manager_id', type='many2one', string='Department Manager', relation='hr.employee', readonly=True, store=True), + 'stage_ids': fields.many2many('hr.recruitment.stage', 'job_stage_rel', 'job_id', 'stage_id', 'Job Stages'), 'document_ids': fields.function(_get_attached_docs, type='one2many', relation='ir.attachment', string='Applications'), 'documents_count': fields.function(_count_all, type='integer', string='Documents', multi=True), 'user_id': fields.many2one('res.users', 'Recruitment Responsible', track_visibility='onchange'), @@ -656,8 +630,12 @@ class hr_job(osv.osv): user = self.pool.get('res.users').browse(cr, uid, uid, context=context) return user.company_id.partner_id.id + def _get_type_common(self, cr, uid, context=None): + return self.pool['hr.recruitment.stage'].search(cr, uid, [('case_default', '=', True)], context=context) + _defaults = { - 'address_id': _address_get + 'address_id': _address_get, + 'stage_ids': _get_type_common, } def _auto_init(self, cr, context=None): diff --git a/addons/hr_recruitment/hr_recruitment_data.xml b/addons/hr_recruitment/hr_recruitment_data.xml index 15a625ecb42..9dc711971de 100644 --- a/addons/hr_recruitment/hr_recruitment_data.xml +++ b/addons/hr_recruitment/hr_recruitment_data.xml @@ -93,30 +93,36 @@ Initial Qualification 1 + First Interview 2 + Second Interview 3 + - Contract Proposed + Contract Proposal 4 + Contract Signed 5 + Refused 6 + diff --git a/addons/hr_recruitment/hr_recruitment_demo.xml b/addons/hr_recruitment/hr_recruitment_demo.xml index 03d31d0851d..8c828a7bde7 100644 --- a/addons/hr_recruitment/hr_recruitment_demo.xml +++ b/addons/hr_recruitment/hr_recruitment_demo.xml @@ -127,34 +127,41 @@ recruit 4 + + + recruit 1 + 1 recruit + recruit 3 + recruit 6 + - --> + hr.applicant diff --git a/addons/hr_recruitment/hr_recruitment_view.xml b/addons/hr_recruitment/hr_recruitment_view.xml index 6cc630bff22..aa7c902430e 100644 --- a/addons/hr_recruitment/hr_recruitment_view.xml +++ b/addons/hr_recruitment/hr_recruitment_view.xml @@ -60,7 +60,7 @@
- +