[REF] hr_recruitment stage management cleaning

Using stages and states is not easy to manage. Indeed those two fields mess with the same basic concept. This task remove the state on hr.applicant model, leaving only stages.

Main features:
- removed base_stage inheritance on hr.applicant model
- removed state field on hr.applicant model
- removed state field on hr.recruitment.stage model
- removed date field on hr.applicant model, not used anywhere; other date fields are considered as sufficient
- added date_last_stage_update on hr.applicant model, holding the date of the last stage change, allowing reporting and analysis on time spend in stages
- date_open is set when assigning an user to the applicant; date_open now means assignation date

This allows to remove nearly all buttons on the form view. As the statusbar is clickable, the only remaining action is to create an employee from the applicant, which is a link button in the form view.

Subtypes have been updated :
- new applicant: stage_id.sequence=1
- other: stage change

Misc:
- [IMP] views accordingly;
- [IMP] reports accordingly, added date_last_stage_update in reports;
- [IMP] subtypes: New, Stage Changed and Hired are kept;
- [REM] removed some tests because they are not applicable anymore;
- [DOC] doc directory + changelog + stage explanation;
- [REM] removed hired.employee wizard

bzr revid: tde@openerp.com-20130709115904-o9ac29fesu3lreol
This commit is contained in:
Thibault Delavallée 2013-07-09 13:59:04 +02:00
commit 9e2c08219d
14 changed files with 184 additions and 312 deletions

View File

@ -47,7 +47,6 @@ You can define the different phases of interviews and easily rate the applicant
'fetchmail', 'fetchmail',
], ],
'data': [ 'data': [
'wizard/hr_recruitment_employee_hired.xml',
'wizard/hr_recruitment_create_partner_job_view.xml', 'wizard/hr_recruitment_create_partner_job_view.xml',
'hr_recruitment_view.xml', 'hr_recruitment_view.xml',
'hr_recruitment_menu.xml', 'hr_recruitment_menu.xml',

View File

@ -22,7 +22,7 @@
<field name="res_model">hr.applicant</field> <field name="res_model">hr.applicant</field>
<field name="view_type">form</field> <field name="view_type">form</field>
<field name="view_mode">tree,form</field> <field name="view_mode">tree,form</field>
<field name="domain">[('state','in',('draft','open'))]</field> <field name="domain">[('stage_id.fold', '!=', True)]</field>
<field name="view_id" ref="view_applicants_status_tree"/> <field name="view_id" ref="view_applicants_status_tree"/>
</record> </record>

View File

@ -0,0 +1,16 @@
.. _changelog:
Changelog
=========
`trunk (saas-2)`
----------------
- Stage/state update
- ``hr.applicant``: removed inheritance from ``base_stage`` class and removed
``state`` field. Added ``date_last_stage_update`` field holding last stage_id
modification. Removed ``date`` field not used anywhere. Updated reports.
- ``hr.recruitment.stage``: removed ``state`` field.
- Removed ``hired.employee`` wizard.

View File

@ -0,0 +1,22 @@
=====================
HR Recruitment DevDoc
=====================
Hr Recruitment module documentation
===================================
Documentation topics
''''''''''''''''''''
.. toctree::
:maxdepth: 1
stage_status.rst
Changelog
'''''''''
.. toctree::
:maxdepth: 1
changelog.rst

View File

@ -0,0 +1,54 @@
.. _stage_status:
Stage and Status
================
.. versionchanged:: 8.0 saas-2 state/stage cleaning
Stage
+++++
This revision removed the concept of state on hr.applicant objects. The ``state``
field has been totally removed and replaced by stages, using ``stage_id``. The
following models are impacted:
- ``hr.applicant`` now use only stages. However a convention still exists about
'New' stage. An applicant is consdered as ``new`` when it has the following
properties:
- ``stage_id and stage_id.sequence = 1``
- ``hr.recruitment.stage`` do not have any ``state`` field anymore.
- ``hr.recruitment.report`` do not have any ``state`` field anymore.
By default a newly created applicant be in a new stage. It means that it will
fetch the stage having ``sequence = 1``. Stage mangement is done using the
kanban view or the clikable statusbar. It is not done using buttons anymore.
Employee creation is still feasible directly from a link button in the form view.
Stage analysis
++++++++++++++
Stage analysis can be performed using the newly introduced ``date_last_stage_update``
datetime field. This field is updated everytime ``stage_id`` is updated.
``hr.recruitment.report`` model also uses the ``date_last_stage_update`` field.
This allows to group and analyse the time spend in the various stages.
Open / Assignation date
+++++++++++++++++++++++
The ``date_open`` field meaning has been updated. It is now set when the ``user_id``
(responsible) is set. It is therefore the assignation date.
Subtypes
++++++++
The following subtypes are triggered on ``hr.applicant``:
- ``mt_applicant_new``: new applicants. Condition: ``obj.stage_id and obj.stage_id.sequence == 1``
- ``mt_applicant_stage_changed``: stage changed. Condition: ``obj.stage_id and obj.stage_id.sequence != 1``
The following subtype is trigerred on ``hr.job``:
- ``mt_job_new_applicant``: new applicant in the job.

View File

@ -19,23 +19,13 @@
# #
############################################################################## ##############################################################################
import time
from openerp import tools from openerp import tools
from openerp.addons.base_status.base_stage import base_stage
from datetime import datetime from datetime import datetime
from openerp.osv import fields, osv from openerp.osv import fields, osv
from openerp.tools.translate import _ from openerp.tools.translate import _
from openerp.tools import html2plaintext from openerp.tools import html2plaintext
AVAILABLE_STATES = [
('draft', 'New'),
('cancel', 'Refused'),
('open', 'In Progress'),
('pending', 'Pending'),
('done', 'Hired')
]
AVAILABLE_PRIORITIES = [ AVAILABLE_PRIORITIES = [
('', ''), ('', ''),
('5', 'Not Good'), ('5', 'Not Good'),
@ -62,13 +52,11 @@ class hr_recruitment_stage(osv.osv):
'name': fields.char('Name', size=64, required=True, translate=True), 'name': fields.char('Name', size=64, required=True, translate=True),
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of stages."), '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."), '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."),
'state': fields.selection(AVAILABLE_STATES, 'Status', required=True, help="The related status for the stage. The status of your document will automatically change according to the selected stage. Example, a stage is related to the status 'Close', when your document reach this stage, it will be automatically closed."),
'fold': fields.boolean('Hide in views if empty', help="This stage is not visible, for example in status bar or kanban view, when there are no records in that stage to display."), 'fold': fields.boolean('Hide in views if empty', help="This stage is not visible, for example in status bar or kanban view, when there are no records in that stage to display."),
'requirements': fields.text('Requirements'), 'requirements': fields.text('Requirements'),
} }
_defaults = { _defaults = {
'sequence': 1, 'sequence': 1,
'state': 'draft',
'fold': False, 'fold': False,
} }
@ -87,18 +75,15 @@ class hr_recruitment_degree(osv.osv):
('name_uniq', 'unique (name)', 'The name of the Degree of Recruitment must be unique!') ('name_uniq', 'unique (name)', 'The name of the Degree of Recruitment must be unique!')
] ]
class hr_applicant(base_stage, osv.Model): class hr_applicant(osv.Model):
_name = "hr.applicant" _name = "hr.applicant"
_description = "Applicant" _description = "Applicant"
_order = "id desc" _order = "id desc"
_inherit = ['mail.thread', 'ir.needaction_mixin'] _inherit = ['mail.thread', 'ir.needaction_mixin']
_track = { _track = {
'state': {
'hr_recruitment.mt_applicant_hired': lambda self, cr, uid, obj, ctx=None: obj.state == 'done',
'hr_recruitment.mt_applicant_refused': lambda self, cr, uid, obj, ctx=None: obj.state == 'cancel',
},
'stage_id': { 'stage_id': {
'hr_recruitment.mt_stage_changed': lambda self, cr, uid, obj, ctx=None: obj.state not in ['done', 'cancel'], 'hr_recruitment.mt_applicant_new': lambda self, cr, uid, obj, ctx=None: obj.stage_id and obj.stage_id.sequence == 1,
'hr_recruitment.mt_applicant_stage_changed': lambda self, cr, uid, obj, ctx=None: obj.stage_id and obj.stage_id.sequence != 1,
}, },
} }
@ -109,7 +94,7 @@ class hr_applicant(base_stage, osv.Model):
def _get_default_stage_id(self, cr, uid, context=None): def _get_default_stage_id(self, cr, uid, context=None):
""" Gives default stage_id """ """ Gives default stage_id """
department_id = self._get_default_department_id(cr, uid, context=context) department_id = self._get_default_department_id(cr, uid, context=context)
return self.stage_find(cr, uid, [], department_id, [('state', '=', 'draft')], context=context) return self.stage_find(cr, uid, [], department_id, [('sequence', '=', '1')], context=context)
def _resolve_department_id_from_context(self, cr, uid, context=None): def _resolve_department_id_from_context(self, cr, uid, context=None):
""" Returns ID of department based on the value of 'default_department_id' """ Returns ID of department based on the value of 'default_department_id'
@ -197,20 +182,12 @@ class hr_applicant(base_stage, osv.Model):
'write_date': fields.datetime('Update Date', readonly=True), 'write_date': fields.datetime('Update Date', readonly=True),
'stage_id': fields.many2one ('hr.recruitment.stage', 'Stage', track_visibility='onchange', 'stage_id': fields.many2one ('hr.recruitment.stage', 'Stage', track_visibility='onchange',
domain="['|', ('department_id', '=', department_id), ('department_id', '=', False)]"), domain="['|', ('department_id', '=', department_id), ('department_id', '=', False)]"),
'state': fields.related('stage_id', 'state', type="selection", store=True,
selection=AVAILABLE_STATES, string="Status", readonly=True,
help='The status is set to \'Draft\', when a case is created.\
If the case is in progress the status is set to \'Open\'.\
When the case is over, the status is set to \'Done\'.\
If the case needs to be reviewed then the status is \
set to \'Pending\'.'),
'categ_ids': fields.many2many('hr.applicant_category', string='Tags'), 'categ_ids': fields.many2many('hr.applicant_category', string='Tags'),
'company_id': fields.many2one('res.company', 'Company'), 'company_id': fields.many2one('res.company', 'Company'),
'user_id': fields.many2one('res.users', 'Responsible', track_visibility='onchange'), 'user_id': fields.many2one('res.users', 'Responsible', track_visibility='onchange'),
# Applicant Columns
'date_closed': fields.datetime('Closed', readonly=True, select=True), 'date_closed': fields.datetime('Closed', readonly=True, select=True),
'date_open': fields.datetime('Opened', readonly=True, select=True), 'date_open': fields.datetime('Assigned', readonly=True, select=True),
'date': fields.datetime('Date'), 'date_last_stage_update': fields.datetime('Last Stage Update', select=True),
'date_action': fields.date('Next Action Date'), 'date_action': fields.date('Next Action Date'),
'title_action': fields.char('Next Action', size=64), 'title_action': fields.char('Next Action', size=64),
'priority': fields.selection(AVAILABLE_PRIORITIES, 'Appreciation'), 'priority': fields.selection(AVAILABLE_PRIORITIES, 'Appreciation'),
@ -234,35 +211,35 @@ class hr_applicant(base_stage, osv.Model):
'day_close': fields.function(_compute_day, string='Days to Close', \ 'day_close': fields.function(_compute_day, string='Days to Close', \
multi='day_close', type="float", store=True), multi='day_close', type="float", store=True),
'color': fields.integer('Color Index'), 'color': fields.integer('Color Index'),
'emp_id': fields.many2one('hr.employee', 'employee'), 'emp_id': fields.many2one('hr.employee', string='Employee',
help='Employee linked to the applicant.'),
'user_email': fields.related('user_id', 'email', type='char', string='User Email', readonly=True), 'user_email': fields.related('user_id', 'email', type='char', string='User Email', readonly=True),
} }
_defaults = { _defaults = {
'active': lambda *a: 1, 'active': lambda *a: 1,
'user_id': lambda s, cr, uid, c: uid, 'user_id': lambda s, cr, uid, c: uid,
'email_from': lambda s, cr, uid, c: s._get_default_email(cr, uid, c),
'stage_id': lambda s, cr, uid, c: s._get_default_stage_id(cr, uid, c), '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), 'department_id': lambda s, cr, uid, c: s._get_default_department_id(cr, uid, c),
'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'hr.applicant', context=c), 'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'hr.applicant', context=c),
'color': 0, 'color': 0,
'date_last_stage_update': fields.datetime.now(),
} }
_group_by_full = { _group_by_full = {
'stage_id': _read_group_stage_ids 'stage_id': _read_group_stage_ids
} }
def onchange_job(self, cr, uid, ids, job, context=None): def onchange_job(self, cr, uid, ids, job_id=False, context=None):
if job: if job_id:
job_record = self.pool.get('hr.job').browse(cr, uid, job, context=context) job_record = self.pool.get('hr.job').browse(cr, uid, job_id, context=context)
if job_record and job_record.department_id: if job_record and job_record.department_id:
return {'value': {'department_id': job_record.department_id.id}} return {'value': {'department_id': job_record.department_id.id}}
return {} return {}
def onchange_department_id(self, cr, uid, ids, department_id=False, context=None): def onchange_department_id(self, cr, uid, ids, department_id=False, stage_id=False, context=None):
obj_recru_stage = self.pool.get('hr.recruitment.stage') if not stage_id:
stage_ids = obj_recru_stage.search(cr, uid, ['|',('department_id','=',department_id),('department_id','=',False)], context=context) stage_id = self.stage_find(cr, uid, [], department_id, [('sequence', '=', '1')], context=context)
stage_id = stage_ids and stage_ids[0] or False
return {'value': {'stage_id': stage_id}} return {'value': {'stage_id': stage_id}}
def onchange_partner_id(self, cr, uid, ids, partner_id, context=None): def onchange_partner_id(self, cr, uid, ids, partner_id, context=None):
@ -412,21 +389,20 @@ class hr_applicant(base_stage, osv.Model):
self.pool.get('hr.job').message_post(cr, uid, [applicant.job_id.id], body=_('Applicant <b>created</b>'), subtype="hr_recruitment.mt_job_new_applicant", context=context) self.pool.get('hr.job').message_post(cr, uid, [applicant.job_id.id], body=_('Applicant <b>created</b>'), subtype="hr_recruitment.mt_job_new_applicant", context=context)
return obj_id return obj_id
def case_open(self, cr, uid, ids, context=None): def write(self, cr, uid, ids, vals, context=None):
""" if isinstance(ids, (int, long)):
open Request of the applicant for the hr_recruitment ids = [ids]
""" # stage change: update date_last_stage_update
res = super(hr_applicant, self).case_open(cr, uid, ids, context) if 'stage_id' in vals:
date = self.read(cr, uid, ids, ['date_open'])[0] vals['date_last_stage_update'] = fields.datetime.now()
if not date['date_open']: # user_id change: update date_start
self.write(cr, uid, ids, {'date_open': time.strftime('%Y-%m-%d %H:%M:%S'),}) if vals.get('user_id'):
return res vals['date_start'] = fields.datetime.now()
def case_close(self, cr, uid, ids, context=None): return super(hr_applicant, self).write(cr, uid, ids, vals, context=context)
res = super(hr_applicant, self).case_close(cr, uid, ids, context)
return res
def case_close_with_emp(self, cr, uid, ids, context=None): def create_employee_from_applicant(self, cr, uid, ids, context=None):
""" Create an hr.employee from the hr.applicants """
if context is None: if context is None:
context = {} context = {}
hr_employee = self.pool.get('hr.employee') hr_employee = self.pool.get('hr.employee')
@ -436,17 +412,16 @@ class hr_applicant(base_stage, osv.Model):
for applicant in self.browse(cr, uid, ids, context=context): for applicant in self.browse(cr, uid, ids, context=context):
address_id = contact_name = False address_id = contact_name = False
if applicant.partner_id: if applicant.partner_id:
address_id = self.pool.get('res.partner').address_get(cr,uid,[applicant.partner_id.id],['contact'])['contact'] address_id = self.pool.get('res.partner').address_get(cr, uid, [applicant.partner_id.id], ['contact'])['contact']
contact_name = self.pool.get('res.partner').name_get(cr,uid,[applicant.partner_id.id])[0][1] contact_name = self.pool.get('res.partner').name_get(cr, uid, [applicant.partner_id.id])[0][1]
if applicant.job_id and (applicant.partner_name or contact_name): if applicant.job_id and (applicant.partner_name or contact_name):
applicant.job_id.write({'no_of_recruitment': applicant.job_id.no_of_recruitment - 1}) applicant.job_id.write({'no_of_recruitment': applicant.job_id.no_of_recruitment - 1})
emp_id = hr_employee.create(cr,uid,{'name': applicant.partner_name or contact_name, emp_id = hr_employee.create(cr, uid, {'name': applicant.partner_name or contact_name,
'job_id': applicant.job_id.id, 'job_id': applicant.job_id.id,
'address_home_id': address_id, 'address_home_id': address_id,
'department_id': applicant.department_id.id 'department_id': applicant.department_id.id
}) })
self.write(cr, uid, [applicant.id], {'emp_id': emp_id}, context=context) self.write(cr, uid, [applicant.id], {'emp_id': emp_id}, context=context)
self.case_close(cr, uid, [applicant.id], context)
else: else:
raise osv.except_osv(_('Warning!'), _('You must define an Applied Job and a Contact Name for this applicant.')) raise osv.except_osv(_('Warning!'), _('You must define an Applied Job and a Contact Name for this applicant.'))
@ -457,26 +432,6 @@ class hr_applicant(base_stage, osv.Model):
dict_act_window['view_mode'] = 'form,tree' dict_act_window['view_mode'] = 'form,tree'
return dict_act_window return dict_act_window
def case_cancel(self, cr, uid, ids, context=None):
"""Overrides cancel for crm_case for setting probability
"""
res = super(hr_applicant, self).case_cancel(cr, uid, ids, context)
self.write(cr, uid, ids, {'probability': 0.0})
return res
def case_pending(self, cr, uid, ids, context=None):
"""Marks case as pending"""
res = super(hr_applicant, self).case_pending(cr, uid, ids, context)
self.write(cr, uid, ids, {'probability': 0.0})
return res
def case_reset(self, cr, uid, ids, context=None):
"""Resets case as draft
"""
res = super(hr_applicant, self).case_reset(cr, uid, ids, context)
self.write(cr, uid, ids, {'date_open': False, 'date_closed': False})
return res
def set_priority(self, cr, uid, ids, priority, *args): def set_priority(self, cr, uid, ids, priority, *args):
"""Set applicant priority """Set applicant priority
""" """

View File

@ -51,34 +51,29 @@
<field name="name">Doctoral Degree</field> <field name="name">Doctoral Degree</field>
<field name="sequence">4</field> <field name="sequence">4</field>
</record> </record>
<record model="hr.recruitment.stage" id="stage_job1"> <record model="hr.recruitment.stage" id="stage_job1">
<field name="name">Initial Qualification</field> <field name="name">Initial Qualification</field>
<field name="state">draft</field>
<field name="sequence">1</field> <field name="sequence">1</field>
</record> </record>
<record model="hr.recruitment.stage" id="stage_job2"> <record model="hr.recruitment.stage" id="stage_job2">
<field name="name">First Interview</field> <field name="name">First Interview</field>
<field name="state">open</field>
<field name="sequence">2</field> <field name="sequence">2</field>
</record> </record>
<record model="hr.recruitment.stage" id="stage_job3"> <record model="hr.recruitment.stage" id="stage_job3">
<field name="name">Second Interview</field> <field name="name">Second Interview</field>
<field name="state">open</field>
<field name="sequence">3</field> <field name="sequence">3</field>
</record> </record>
<record model="hr.recruitment.stage" id="stage_job4"> <record model="hr.recruitment.stage" id="stage_job4">
<field name="name">Contract Proposed</field> <field name="name">Contract Proposed</field>
<field name="state">pending</field>
<field name="sequence">4</field> <field name="sequence">4</field>
</record> </record>
<record model="hr.recruitment.stage" id="stage_job5"> <record model="hr.recruitment.stage" id="stage_job5">
<field name="name">Contract Signed</field> <field name="name">Contract Signed</field>
<field name="state">done</field>
<field name="sequence">5</field> <field name="sequence">5</field>
</record> </record>
<record model="hr.recruitment.stage" id="stage_job6"> <record model="hr.recruitment.stage" id="stage_job6">
<field name="name">Refused</field> <field name="name">Refused</field>
<field name="state">cancel</field>
<field name="sequence">6</field> <field name="sequence">6</field>
<field name="fold" eval="True"/> <field name="fold" eval="True"/>
</record> </record>
@ -467,24 +462,24 @@
<field name="res_model">hr.job</field> <field name="res_model">hr.job</field>
</record> </record>
<!-- Applicant-related subtypes for messaging / Chatter --> <!-- Applicant-related subtypes for messaging / Chatter -->
<record id="mt_stage_changed" model="mail.message.subtype"> <record id="mt_applicant_new" model="mail.message.subtype">
<field name="name">New Applicant</field>
<field name="res_model">hr.applicant</field>
<field name="default" eval="False"/>
<field name="description">Applicant created</field>
</record>
<record id="mt_applicant_stage_changed" model="mail.message.subtype">
<field name="name">Stage Changed</field> <field name="name">Stage Changed</field>
<field name="res_model">hr.applicant</field> <field name="res_model">hr.applicant</field>
<field name="default" eval="False"/> <field name="default" eval="False"/>
<field name="description">Stage changed</field> <field name="description">Stage changed</field>
</record> </record>
<record id="mt_applicant_hired" model="mail.message.subtype"> <record id="mt_applicant_employee" model="mail.message.subtype">
<field name="name">Applicant Hired</field> <field name="name">Applicant Hired</field>
<field name="res_model">hr.applicant</field> <field name="res_model">hr.applicant</field>
<field name="default" eval="False"/> <field name="default" eval="False"/>
<field name="description">Applicant hired</field> <field name="description">Applicant hired</field>
</record> </record>
<record id="mt_applicant_refused" model="mail.message.subtype">
<field name="name">Applicant Refused</field>
<field name="res_model">hr.applicant</field>
<field name="default" eval="False"/>
<field name="description">Applicant refused</field>
</record>
<!-- Applicant Categories(Tag) --> <!-- Applicant Categories(Tag) -->
<record id="tag_applicant_reserve" model="hr.applicant_category"> <record id="tag_applicant_reserve" model="hr.applicant_category">
<field name="name">Reserve</field> <field name="name">Reserve</field>

View File

@ -39,9 +39,10 @@
<field name="name">Applicants</field> <field name="name">Applicants</field>
<field name="model">hr.applicant</field> <field name="model">hr.applicant</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="Applicants" fonts="bold:message_unread==True" colors="grey:state in ('cancel','done');blue:state=='pending'"> <tree string="Applicants" fonts="bold:message_unread==True">
<field name="message_unread" invisible="1"/> <field name="message_unread" invisible="1"/>
<field name="create_date"/> <field name="create_date"/>
<field name="date_last_stage_update" invisible="1"/>
<field name="name" string="Subject"/> <field name="name" string="Subject"/>
<field name="partner_name"/> <field name="partner_name"/>
<field name="email_from"/> <field name="email_from"/>
@ -58,7 +59,6 @@
<field name="availability" invisible="1"/> <field name="availability" invisible="1"/>
<field name="department_id" invisible="context.get('invisible_department', True)"/> <field name="department_id" invisible="context.get('invisible_department', True)"/>
<field name="user_id"/> <field name="user_id"/>
<field name="state" invisible="1"/>
</tree> </tree>
</field> </field>
</record> </record>
@ -69,13 +69,7 @@
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Jobs - Recruitment Form" version="7.0"> <form string="Jobs - Recruitment Form" version="7.0">
<header> <header>
<button name="case_close_with_emp" string="Hire &amp; Create Employee" type="object"
class="oe_highlight"
attrs="{'invisible':['|', ('emp_id','!=',False), ('state','=','cancel')]}"/>
<button name="case_cancel" string="Refuse" type="object"
states="draft,open,pending" class="oe_highlight"/>
<field name="stage_id" widget="statusbar" clickable="True"/> <field name="stage_id" widget="statusbar" clickable="True"/>
<field name="emp_id" invisible="1"/>
</header> </header>
<sheet> <sheet>
<div class="oe_right oe_button_box"> <div class="oe_right oe_button_box">
@ -93,9 +87,12 @@
<label for="name" class="oe_edit_only"/> <label for="name" class="oe_edit_only"/>
<h1><field name="name"/></h1> <h1><field name="name"/></h1>
<label for="partner_name" class="oe_edit_only"/> <label for="partner_name" class="oe_edit_only"/>
<h2> <h2 style="display: inline-block;">
<field name="partner_name" class="oe_inline"/> <field name="partner_name" class="oe_inline"/>
</h2> </h2>
<button string="Create Employee" name="create_employee_from_applicant" type="object"
class="oe_link oe_inline" style="margin-left: 8px;"
attrs="{'invisible': [('emp_id', '!=', False)]}"/>
</div> </div>
<group> <group>
<group> <group>
@ -115,7 +112,6 @@
<field name="title_action" class="oe_inline" placeholder="e.g. Call for interview"/> <field name="title_action" class="oe_inline" placeholder="e.g. Call for interview"/>
</div> </div>
<field name="priority"/> <field name="priority"/>
<field name="state" invisible="1"/>
<field name="source_id"/> <field name="source_id"/>
<field name="reference"/> <field name="reference"/>
</group> </group>
@ -123,7 +119,7 @@
<field name="survey" invisible="1"/> <field name="survey" invisible="1"/>
<field name="response" invisible="1"/> <field name="response" invisible="1"/>
<field name="job_id" on_change="onchange_job(job_id)"/> <field name="job_id" on_change="onchange_job(job_id)"/>
<field name="department_id" on_change="onchange_department_id(department_id)"/> <field name="department_id" on_change="onchange_department_id(department_id, stage_id)"/>
<label for="availability"/> <label for="availability"/>
<div> <div>
<field name="availability" class="oe_inline"/> <label string="Day(s)" class="oe_inline"/> <field name="availability" class="oe_inline"/> <label string="Day(s)" class="oe_inline"/>
@ -142,6 +138,7 @@
<span class="oe_inline" attrs="{'invisible':[('salary_proposed_extra','=',False)]}"> + </span> <span class="oe_inline" attrs="{'invisible':[('salary_proposed_extra','=',False)]}"> + </span>
<field name="salary_proposed_extra" class="oe_inline" placeholder="Extra advantages..."/> <field name="salary_proposed_extra" class="oe_inline" placeholder="Extra advantages..."/>
</div> </div>
<field name="emp_id" readonly="1"/>
</group> </group>
</group> </group>
<group> <group>
@ -165,7 +162,7 @@
<graph string="Cases By Stage and Estimates" type="bar" orientation="vertical"> <graph string="Cases By Stage and Estimates" type="bar" orientation="vertical">
<field name="job_id"/> <field name="job_id"/>
<field name="salary_expected" operator="+"/> <field name="salary_expected" operator="+"/>
<field name="state" group="True"/> <field name="stage_id" group="True"/>
</graph> </graph>
</field> </field>
</record> </record>
@ -174,23 +171,22 @@
<field name="name">Jobs - Recruitment Search</field> <field name="name">Jobs - Recruitment Search</field>
<field name="model">hr.applicant</field> <field name="model">hr.applicant</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<search string="Search Jobs"> <search string="Search Applicants">
<field name="partner_name" filter_domain="['|','|',('name','ilike',self),('partner_name','ilike',self),('email_from','ilike',self)]" string="Subject / Applicant"/> <field name="partner_name" filter_domain="['|','|',('name','ilike',self),('partner_name','ilike',self),('email_from','ilike',self)]" string="Subject / Applicant"/>
<filter string="Unassigned" domain="[('user_id', '=', False)]"/>
<filter string="My" domain="[('user_id', '=', uid)]"/>
<separator/>
<filter string="Unread Messages" name="message_unread" domain="[('message_unread','=',True)]"/> <filter string="Unread Messages" name="message_unread" domain="[('message_unread','=',True)]"/>
<separator/> <separator/>
<filter string="New" domain="[('state','=','draft')]" help="All Initial Jobs"/>
<filter string="In Progress" domain="[('state','=','open')]" help="Open Jobs"/>
<filter string="Pending" domain="[('state','=','pending')]" help="Pending Jobs"/>
<separator/>
<filter string="Unassigned Recruitments" domain="[('user_id','=',False)]" help="Unassigned Recruitments"/>
<separator/>
<filter string="Next Actions" context="{'invisible_next_action':False, 'invisible_next_date':False}" <filter string="Next Actions" context="{'invisible_next_action':False, 'invisible_next_date':False}"
domain="[('date_action','&lt;&gt;',False)]" help="Filter and view on next actions and date"/> domain="[('date_action','&lt;&gt;',False)]" help="Filter and view on next actions and date"/>
<field name="job_id"/> <field name="job_id"/>
<field name="department_id"/> <field name="department_id"/>
<field name="user_id"/> <field name="user_id"/>
<field name="stage_id" domain="[]"/>
<separator/> <separator/>
<field name="categ_ids"/> <field name="categ_ids"/>
<separator/>
<group expand="0" string="Group By..."> <group expand="0" string="Group By...">
<filter string="Responsible" domain="[]" context="{'group_by':'user_id'}"/> <filter string="Responsible" domain="[]" context="{'group_by':'user_id'}"/>
<filter string="Department" domain="[]" context="{'group_by':'department_id'}"/> <filter string="Department" domain="[]" context="{'group_by':'department_id'}"/>
@ -201,6 +197,7 @@
<filter string="Stage" domain="[]" context="{'group_by':'stage_id'}"/> <filter string="Stage" domain="[]" context="{'group_by':'stage_id'}"/>
<filter string="Source" domain="[]" context="{'group_by':'source_id'}"/> <filter string="Source" domain="[]" context="{'group_by':'source_id'}"/>
<filter string="Creation Date" domain="[]" context="{'group_by':'create_date'}"/> <filter string="Creation Date" domain="[]" context="{'group_by':'create_date'}"/>
<filter string="Last Stage Update" context="{'group_by':'date_last_stage_update'}"/>
</group> </group>
</search> </search>
</field> </field>
@ -343,7 +340,6 @@
<field name="sequence" invisible="1"/> <field name="sequence" invisible="1"/>
<field name="name"/> <field name="name"/>
<field name="department_id"/> <field name="department_id"/>
<field name="state"/>
</tree> </tree>
</field> </field>
</record> </record>
@ -361,7 +357,6 @@
<field name="department_id"/> <field name="department_id"/>
</group> </group>
<group> <group>
<field name="state"/>
<field name="sequence"/> <field name="sequence"/>
<field name="fold"/> <field name="fold"/>
</group> </group>

View File

@ -18,30 +18,24 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
############################################################################## ##############################################################################
from openerp import tools from openerp import tools
from openerp.osv import fields,osv from openerp.osv import fields, osv
from .. import hr_recruitment from .. import hr_recruitment
from openerp.addons.decimal_precision import decimal_precision as dp from openerp.addons.decimal_precision import decimal_precision as dp
AVAILABLE_STATES = [ class hr_recruitment_report(osv.Model):
('draft','New'),
('open','Open'),
('cancel', 'Refused'),
('done', 'Hired'),
('pending','Pending')
]
class hr_recruitment_report(osv.osv):
_name = "hr.recruitment.report" _name = "hr.recruitment.report"
_description = "Recruitments Statistics" _description = "Recruitments Statistics"
_auto = False _auto = False
_rec_name = 'date' _rec_name = 'date_create'
_order = 'date_create desc'
_columns = { _columns = {
'user_id': fields.many2one('res.users', 'User', readonly=True), 'user_id': fields.many2one('res.users', 'User', readonly=True),
'nbr': fields.integer('# of Applications', readonly=True), 'nbr': fields.integer('# of Applications', readonly=True),
'state': fields.selection(AVAILABLE_STATES, 'Status', size=16, readonly=True), # TDE TODO: use MONTHS
'month':fields.selection([('01', 'January'), ('02', 'February'), \ 'month':fields.selection([('01', 'January'), ('02', 'February'), \
('03', 'March'), ('04', 'April'),\ ('03', 'March'), ('04', 'April'),\
('05', 'May'), ('06', 'June'), \ ('05', 'May'), ('06', 'June'), \
@ -51,7 +45,8 @@ class hr_recruitment_report(osv.osv):
'company_id': fields.many2one('res.company', 'Company', readonly=True), 'company_id': fields.many2one('res.company', 'Company', readonly=True),
'day': fields.char('Day', size=128, readonly=True), 'day': fields.char('Day', size=128, readonly=True),
'year': fields.char('Year', size=4, readonly=True), 'year': fields.char('Year', size=4, readonly=True),
'date': fields.date('Date', readonly=True), 'date_create': fields.date('Create Date', readonly=True),
'date_last_stage_update': fields.datetime('Last Stage Update', readonly=True),
'date_closed': fields.date('Closed', readonly=True), 'date_closed': fields.date('Closed', readonly=True),
'job_id': fields.many2one('hr.job', 'Applied Job',readonly=True), 'job_id': fields.many2one('hr.job', 'Applied Job',readonly=True),
'stage_id': fields.many2one ('hr.recruitment.stage', 'Stage'), 'stage_id': fields.many2one ('hr.recruitment.stage', 'Stage'),
@ -67,19 +62,19 @@ class hr_recruitment_report(osv.osv):
'delay_close': fields.float('Avg. Delay to Close', digits=(16,2), readonly=True, group_operator="avg", 'delay_close': fields.float('Avg. Delay to Close', digits=(16,2), readonly=True, group_operator="avg",
help="Number of Days to close the project issue"), help="Number of Days to close the project issue"),
} }
_order = 'date desc'
def init(self, cr): def init(self, cr):
tools.drop_view_if_exists(cr, 'hr_recruitment_report') tools.drop_view_if_exists(cr, 'hr_recruitment_report')
cr.execute(""" cr.execute("""
create or replace view hr_recruitment_report as ( create or replace view hr_recruitment_report as (
select select
min(s.id) as id, min(s.id) as id,
date_trunc('day',s.create_date) as date, date_trunc('day',s.create_date) as date_create,
date_trunc('day',s.date_closed) as date_closed, date_trunc('day',s.date_closed) as date_closed,
date_trunc('day',s.date_last_stage_update) as date_last_stage_update,
to_char(s.create_date, 'YYYY') as year, to_char(s.create_date, 'YYYY') as year,
to_char(s.create_date, 'MM') as month, to_char(s.create_date, 'MM') as month,
to_char(s.create_date, 'YYYY-MM-DD') as day, to_char(s.create_date, 'YYYY-MM-DD') as day,
s.state,
s.partner_id, s.partner_id,
s.company_id, s.company_id,
s.user_id, s.user_id,
@ -93,7 +88,7 @@ class hr_recruitment_report(osv.osv):
(sum(salary_proposed)/count(*)) as salary_prop_avg, (sum(salary_proposed)/count(*)) as salary_prop_avg,
sum(salary_expected) as salary_exp, sum(salary_expected) as salary_exp,
(sum(salary_expected)/count(*)) as salary_exp_avg, (sum(salary_expected)/count(*)) as salary_exp_avg,
extract('epoch' from (s.date_closed-s.create_date))/(3600*24) as delay_close, extract('epoch' from (s.date_closed-s.create_date))/(3600*24) as delay_close,
count(*) as nbr count(*) as nbr
from hr_applicant s from hr_applicant s
group by group by
@ -105,7 +100,7 @@ class hr_recruitment_report(osv.osv):
s.date_open, s.date_open,
s.create_date, s.create_date,
s.date_closed, s.date_closed,
s.state, s.date_last_stage_update,
s.partner_id, s.partner_id,
s.company_id, s.company_id,
s.user_id, s.user_id,

View File

@ -6,7 +6,7 @@
<field name="model">hr.recruitment.report</field> <field name="model">hr.recruitment.report</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="Recruitment Analysis" create="false"> <tree string="Recruitment Analysis" create="false">
<field name="date" invisible="1"/> <field name="date_create" invisible="1"/>
<field name="user_id" invisible="1"/> <field name="user_id" invisible="1"/>
<field name="job_id"/> <field name="job_id"/>
<field name="stage_id" invisible="1" /> <field name="stage_id" invisible="1" />
@ -14,10 +14,10 @@
<field name="type_id" invisible="1"/> <field name="type_id" invisible="1"/>
<field name="partner_id" invisible="1"/> <field name="partner_id" invisible="1"/>
<field name="company_id" groups="base.group_multi_company" invisible="1"/> <field name="company_id" groups="base.group_multi_company" invisible="1"/>
<field name="state" invisible="1"/>
<field name="year" invisible="1"/> <field name="year" invisible="1"/>
<field name="day" invisible="1"/> <field name="day" invisible="1"/>
<field name="month" invisible="1"/> <field name="month" invisible="1"/>
<field name="date_last_stage_update" invisible="1"/>
<field name="nbr" sum="# of Applications"/> <field name="nbr" sum="# of Applications"/>
<field name="available" sum="Available"/> <field name="available" sum="Available"/>
<field name="salary_exp" sum="Expected Salary"/> <field name="salary_exp" sum="Expected Salary"/>
@ -46,34 +46,33 @@
<field name="model">hr.recruitment.report</field> <field name="model">hr.recruitment.report</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<search string="Recruitment Analysis"> <search string="Recruitment Analysis">
<filter string="New" icon="terp-document-new" domain="[('state','=','draft')]" help = "Draft recruitment"/>
<filter string="In progress" icon="terp-camera_test" domain="[('state', '=' ,'open')]" help = "In progress recruitment"/>
<filter string="Pending" icon="terp-gtk-media-pause" domain="[('state','=','pending')]" help = "Pending recruitment"/>
<filter string="Hired" icon="terp-camera_test" domain="[('state','=','done')]" help = "Hired employees"/>
<separator/>
<filter icon="terp-personal" string="My Recruitment" help="My Recruitment" domain="[('user_id','=',uid)]"/>
<field name="job_id"/> <field name="job_id"/>
<field name="department_id"/> <field name="department_id"/>
<field name="user_id" string="Responsible"/> <field name="user_id"/>
<filter string="New" domain="[('sequence', '=', 1)]"/>
<separator/>
<filter string="Unassigned" domain="[('user_id', '=', False)]"/>
<filter string="My" domain="[('user_id', '=', uid)]"/>
<separator/>
<group expand="0" string="Extended Filters..."> <group expand="0" string="Extended Filters...">
<!--field name="job_id"/-->
<field name="priority"/> <field name="priority"/>
<field name="stage_id"/> <field name="stage_id"/>
<field name="company_id" groups="base.group_multi_company"/> <field name="company_id" groups="base.group_multi_company"/>
<field name="date" string="Creation Date"/> <field name="date_create"/>
<field name="date_closed"/> <field name="date_closed"/>
</group> </group>
<group expand="1" string="Group By ..."> <group expand="1" string="Group By ...">
<filter string="Responsible" name='User' icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/> <filter string="Responsible" name='User' context="{'group_by':'user_id'}"/>
<filter string="Company" icon="terp-go-home" domain="[]" context="{'group_by':'company_id'}" groups="base.group_multi_company"/> <filter string="Company" context="{'group_by':'company_id'}" groups="base.group_multi_company"/>
<filter string="Partner" icon="terp-partner" domain="[]" context="{'group_by':'partner_id'}" /> <filter string="Partner" context="{'group_by':'partner_id'}" />
<filter string="Jobs" name="job" icon="terp-gtk-select-all" domain="[]" context="{'group_by':'job_id'}"/> <filter string="Jobs" name="job" context="{'group_by':'job_id'}"/>
<filter string="Department" name="department" icon="terp-personal+" domain="[]" context="{'group_by':'department_id'}"/> <filter string="Department" name="department" context="{'group_by':'department_id'}"/>
<filter string="Degree" name="degree" icon="terp-gtk-select-all" domain="[]" context="{'group_by':'type_id'}"/> <filter string="Degree" name="degree" context="{'group_by':'type_id'}"/>
<filter string="Stage" icon="terp-stage" domain="[]" context="{'group_by':'stage_id'}" /> <filter string="Stage" context="{'group_by':'stage_id'}" />
<filter string="Day" name = "day" icon="terp-go-today" domain="[]" context="{'group_by':'day'}" help="Creation Date"/> <filter string="Last Stage Update" context="{'group_by':'date_last_stage_update'}" />
<filter string="Month" icon="terp-go-month" domain="[]" context="{'group_by':'month'}" help="Creation Date"/> <filter string="Day" name="day" context="{'group_by':'day'}" help="Creation Date"/>
<filter string="Year" icon="terp-go-year" domain="[]" context="{'group_by':'year'}" help="Creation Date"/> <filter string="Month" context="{'group_by':'month'}" help="Creation Date"/>
<filter string="Year" context="{'group_by':'year'}" help="Creation Date"/>
</group> </group>
</search> </search>
</field> </field>

View File

@ -17,33 +17,8 @@
resume_ids = self.pool.get('ir.attachment').search(cr, uid, [('datas_fname','=','resume.pdf'),('res_model','=',self._name),('res_id','=',applicant.id)]) resume_ids = self.pool.get('ir.attachment').search(cr, uid, [('datas_fname','=','resume.pdf'),('res_model','=',self._name),('res_id','=',applicant.id)])
assert applicant.name == "Application for the post of Jr.application Programmer.", "Applicant name does not match." assert applicant.name == "Application for the post of Jr.application Programmer.", "Applicant name does not match."
assert applicant.stage_id.id == ref('hr_recruitment.stage_job1'), "Stage should be 'Initial qualification' and is '%s'." % (applicant.stage_id.name) assert applicant.stage_id.id == ref('hr_recruitment.stage_job1'), "Stage should be 'Initial qualification' and is '%s'." % (applicant.stage_id.name)
assert applicant.state == "draft", "Applicant state should be 'draft'." assert applicant.stage_id.sequence == 1, "Applicant stage sequence should be 1."
assert len(resume_ids), "Resume is not attached." assert len(resume_ids), "Resume is not attached."
-
I refuse the applicant (hr_case_programmer)
-
!python {model: hr.applicant}: |
self.case_cancel(cr, uid, [ref("hr_case_programmer")])
-
I check the details of the refused applicant.
-
!python {model: hr.applicant}: |
applicant = self.browse(cr, uid, ref("hr_case_programmer"), context=context)
assert applicant.stage_id.id == ref('hr_recruitment.stage_job6'), "Stage should be 'Refused' and is %s." % (applicant.stage_id.name)
assert applicant.state == 'cancel', "Applicant is not in 'cancel' state."
-
I reset and re-open the previously refused applicant.
-
!python {model: hr.applicant}: |
self.case_reset(cr, uid, [ref("hr_case_programmer")])
self.case_open(cr, uid, [ref("hr_case_programmer")])
-
I check the details of the re-opened applicant.
-
!python {model: hr.applicant}: |
applicant = self.browse(cr, uid, ref("hr_case_programmer"), context=context)
assert applicant.stage_id.id == ref('hr_recruitment.stage_job2'), "Stage should be 'First interview' and is '%s'." % (applicant.stage_id.name)
assert applicant.state == "open", "Applicant state should be 'open'."
- -
I assign the Job position to the applicant I assign the Job position to the applicant
- -
@ -54,21 +29,6 @@
- -
!python {model: hr.applicant}: | !python {model: hr.applicant}: |
self.action_makeMeeting(cr, uid, [ref('hr_case_programmer')]) self.action_makeMeeting(cr, uid, [ref('hr_case_programmer')])
-
I check Initial Qualification of applicant.
-
!python {model: hr.applicant}: |
self.stage_next(cr, uid, [ref('hr_case_programmer')])
-
I schedule First Interview of applicant.
-
!python {model: hr.applicant}: |
self.stage_next(cr, uid, [ref('hr_case_programmer')])
-
On a successful First Interview of applicant, I schedule Second Interview.
-
!python {model: hr.applicant}: |
self.stage_next(cr, uid, [ref('hr_case_programmer')])
- -
Applicant fillup the answer of the interview quetion. Applicant fillup the answer of the interview quetion.
- -
@ -83,40 +43,8 @@
I print Applicant fill up the interview quetion I print Applicant fill up the interview quetion
- -
!python {model: hr.applicant}: | !python {model: hr.applicant}: |
self.action_print_survey(cr, uid, [ref('hr_case_programmer')])
-
On a successful Second Interview of applicant Contract is Proposed to applicant.
-
!python {model: hr.applicant}: |
self.stage_next(cr, uid, [ref('hr_case_programmer')])
self.stage_previous(cr, uid, [ref('hr_case_programmer')])
-
I Hired Applicant.
-
!python {model: hr.applicant}: |
self.case_close_with_emp(cr, uid, [ref('hr_case_programmer')])
-
I check that applicant is "Hired".
-
!assert {model: hr.applicant, id: hr_case_programmer, string: Applicant state is done}:
- state == 'done'
-
I do not give employment to the hired the applicant.
-
!python {model: hired.employee}: |
context.update({'active_model': 'hr.applicant', 'active_ids': [ref("hr_recruitment.hr_case_programmer")], 'active_id': ref("hr_recruitment.hr_case_programmer")}) context.update({'active_model': 'hr.applicant', 'active_ids': [ref("hr_recruitment.hr_case_programmer")], 'active_id': ref("hr_recruitment.hr_case_programmer")})
emp_id = self.create(cr, uid, {}, context=context) self.action_print_survey(cr, uid, [ref('hr_case_programmer')])
self.case_close(cr, uid, [emp_id], context=context)
-
Now I give employment to hired applicant .
-
!python {model: hr.applicant}: |
hired_emp_obj = self.pool.get('hired.employee')
self.case_reset(cr, uid, [ref("hr_case_programmer")])
self.case_open(cr, uid, [ref("hr_case_programmer")])
context.update({'active_model': 'hr.applicant', 'active_ids': [ref("hr_recruitment.hr_case_programmer")], 'active_id': ref("hr_recruitment.hr_case_programmer")})
emp_hr_id = hired_emp_obj.create(cr, uid, {}, context=context)
hired_emp_obj.case_close_with_emp(cr, uid, [emp_hr_id], context=context)
- -
Now hired employee want to be a partner of company. Now hired employee want to be a partner of company.
- -

View File

@ -2,7 +2,7 @@
############################################################################## ##############################################################################
# #
# OpenERP, Open Source Management Solution # OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). # Copyright (C) 2004-Today OpenERP (<http://www.openerp.com>).
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -19,9 +19,7 @@
# #
############################################################################## ##############################################################################
import hr_recruitment_create_partner_job import hr_recruitment_create_partner_job
import hr_recruitment_employee_hired
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,54 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
# $Id$
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv import fields, osv
from openerp.tools.translate import _
class hired_employee(osv.osv_memory):
_name = 'hired.employee'
_description = 'Create Employee'
def case_close(self, cr, uid, ids, context=None):
"""
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of case's Ids
@param *args: Give Tuple Value
"""
if context is None:
context = {}
self.pool.get('hr.applicant').case_close(cr, uid,context.get('active_ids',[]))
return {}
def case_close_with_emp(self, cr, uid, ids, context=None):
"""
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of case's Ids
"""
if context is None:
context = {}
return self.pool.get('hr.applicant').case_close_with_emp(cr, uid,context.get('active_ids', []))
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,30 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_hr_recruitment_hired_employee" model="ir.ui.view">
<field name="name">hr.recruitment.hired2employee.form</field>
<field name="model">hired.employee</field>
<field name="arch" type="xml">
<form string="Create New Employee" version="7.0">
<header>
<button name="case_close_with_emp" string="Yes" type="object" class="oe_highlight" />
<button name="case_close" string="No" type="object"/>
or
<button string="Cancel" class="oe_link" special="cancel" />
</header>
<label string="Would you like to create an employee ?"/>
</form>
</field>
</record>
<record id="action_hr_recruitment_hired_employee" model="ir.actions.act_window">
<field name="name">Create Employee</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">hired.employee</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</data>
</openerp>