[FIX] Partial fix of 'hr_evaluation', which is broken by the new 'survey' + code cleaning and simplification

bzr revid: rim@openerp.com-20140211153524-kxupg07ns5dny658
This commit is contained in:
Richard Mathot (OpenERP) 2014-02-11 16:35:24 +01:00
parent 60e4340cee
commit fbbe8631c9
7 changed files with 139 additions and 141 deletions

View File

@ -20,22 +20,24 @@
############################################################################## ##############################################################################
{ {
'name' : 'Employee Appraisals', 'name': 'Employee Appraisals',
'version': '0.1', 'version': '0.1',
'author': 'OpenERP SA', 'author': 'OpenERP SA',
'category': 'Human Resources', 'category': 'Human Resources',
'sequence': 31, 'sequence': 31,
'website': 'http://www.openerp.com', 'website': 'http://www.openerp.com',
'summary': 'Periodical Evaluations, Appraisals, Surveys', 'summary': 'Periodical Evaluations, Appraisals, Surveys',
'images': ['images/hr_evaluation_analysis.jpeg','images/hr_evaluation.jpeg','images/hr_interview_requests.jpeg'], 'images': ['images/hr_evaluation_analysis.jpeg',
'depends': ['hr','calendar','survey'], 'images/hr_evaluation.jpeg',
'images/hr_interview_requests.jpeg'],
'depends': ['hr', 'calendar', 'survey'],
'description': """ 'description': """
Periodical Employees evaluation and appraisals Periodical Employees evaluation and appraisals
============================================== ==============================================
By using this application you can maintain the motivational process by doing periodical evaluations of your employees' performance. The regular assessment of human resources can benefit your people as well your organization. By using this application you can maintain the motivational process by doing periodical evaluations of your employees' performance. The regular assessment of human resources can benefit your people as well your organization.
An evaluation plan can be assigned to each employee. These plans define the frequency and the way you manage your periodic personal evaluations. You will be able to define steps and attach interview forms to each step. An evaluation plan can be assigned to each employee. These plans define the frequency and the way you manage your periodic personal evaluations. You will be able to define steps and attach interview forms to each step.
Manages several types of evaluations: bottom-up, top-down, self-evaluations and the final evaluation by the manager. Manages several types of evaluations: bottom-up, top-down, self-evaluations and the final evaluation by the manager.
@ -47,16 +49,17 @@ Key Features
* Every evaluation filled by employees can be viewed in a PDF form. * Every evaluation filled by employees can be viewed in a PDF form.
* Interview Requests are generated automatically by OpenERP according to employees evaluation plans. Each user receives automatic emails and requests to perform a periodical evaluation of their colleagues. * Interview Requests are generated automatically by OpenERP according to employees evaluation plans. Each user receives automatic emails and requests to perform a periodical evaluation of their colleagues.
""", """,
"demo": ["hr_evaluation_demo.xml"],
"data": [ "data": [
'security/ir.model.access.csv', #'security/ir.model.access.csv',
'security/hr_evaluation_security.xml', #'security/hr_evaluation_security.xml',
'hr_evaluation_view.xml', 'hr_evaluation_view.xml',
'report/hr_evaluation_report_view.xml', 'report/hr_evaluation_report_view.xml',
'board_hr_evaluation_view.xml', 'board_hr_evaluation_view.xml',
'hr_evaluation_data.xml', 'survey_data_appraisal.xml',
'hr_evaluation_installer.xml', # 'hr_evaluation_data.xml',
# 'hr_evaluation_installer.xml',
], ],
# "demo": ["hr_evaluation_demo.xml"],
'test': [ 'test': [
'test/test_hr_evaluation.yml', 'test/test_hr_evaluation.yml',
'test/hr_evalution_demo.yml', 'test/hr_evalution_demo.yml',
@ -65,5 +68,3 @@ Key Features
'installable': True, 'installable': True,
'application': True, 'application': True,
} }
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -27,7 +27,8 @@ import time
from openerp.osv import fields, osv from openerp.osv import fields, osv
from openerp.tools.translate import _ from openerp.tools.translate import _
class hr_evaluation_plan(osv.osv):
class hr_evaluation_plan(osv.Model):
_name = "hr_evaluation.plan" _name = "hr_evaluation.plan"
_description = "Appraisal Plan" _description = "Appraisal Plan"
_columns = { _columns = {
@ -42,11 +43,11 @@ class hr_evaluation_plan(osv.osv):
'active': True, 'active': True,
'month_first': 6, 'month_first': 6,
'month_next': 12, 'month_next': 12,
'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'account.account', context=c), 'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'account.account', context=c),
} }
class hr_evaluation_plan_phase(osv.osv): class hr_evaluation_plan_phase(osv.Model):
_name = "hr_evaluation.plan.phase" _name = "hr_evaluation.plan.phase"
_description = "Appraisal Plan Phase" _description = "Appraisal Plan Phase"
_order = "sequence" _order = "sequence"
@ -54,13 +55,13 @@ class hr_evaluation_plan_phase(osv.osv):
'name': fields.char("Phase", size=64, required=True), 'name': fields.char("Phase", size=64, required=True),
'sequence': fields.integer("Sequence"), 'sequence': fields.integer("Sequence"),
'company_id': fields.related('plan_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True), 'company_id': fields.related('plan_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True),
'plan_id': fields.many2one('hr_evaluation.plan','Appraisal Plan', ondelete='cascade'), 'plan_id': fields.many2one('hr_evaluation.plan', 'Appraisal Plan', ondelete='cascade'),
'action': fields.selection([ 'action': fields.selection([
('top-down','Top-Down Appraisal Requests'), ('top-down', 'Top-Down Appraisal Requests'),
('bottom-up','Bottom-Up Appraisal Requests'), ('bottom-up', 'Bottom-Up Appraisal Requests'),
('self','Self Appraisal Requests'), ('self', 'Self Appraisal Requests'),
('final','Final Interview')], 'Action', required=True), ('final', 'Final Interview')], 'Action', required=True),
'survey_id': fields.many2one('survey','Appraisal Form',required=True), 'survey_id': fields.many2one('survey.survey', 'Appraisal Form', required=True),
'send_answer_manager': fields.boolean('All Answers', 'send_answer_manager': fields.boolean('All Answers',
help="Send all answers to the manager"), help="Send all answers to the manager"),
'send_answer_employee': fields.boolean('All Answers', 'send_answer_employee': fields.boolean('All Answers',
@ -72,15 +73,14 @@ class hr_evaluation_plan_phase(osv.osv):
'wait': fields.boolean('Wait Previous Phases', 'wait': fields.boolean('Wait Previous Phases',
help="Check this box if you want to wait that all preceding phases " + help="Check this box if you want to wait that all preceding phases " +
"are finished before launching this phase."), "are finished before launching this phase."),
'mail_feature': fields.boolean('Send mail for this phase', help="Check this box if you want to send mail to employees"+ 'mail_feature': fields.boolean('Send mail for this phase', help="Check this box if you want to send mail to employees coming under this phase"),
" coming under this phase"),
'mail_body': fields.text('Email'), 'mail_body': fields.text('Email'),
'email_subject':fields.text('char') 'email_subject': fields.text('Subject')
} }
_defaults = { _defaults = {
'sequence': 1, 'sequence': 1,
'email_subject': _('''Regarding '''), 'email_subject': _('''Regarding '''),
'mail_body': lambda *a:_(''' 'mail_body': lambda *a: _('''
Date: %(date)s Date: %(date)s
Dear %(employee_name)s, Dear %(employee_name)s,
@ -98,26 +98,26 @@ Thanks,
} }
class hr_employee(osv.osv): class hr_employee(osv.Model):
_name = "hr.employee" _name = "hr.employee"
_inherit="hr.employee" _inherit = "hr.employee"
_columns = { _columns = {
'evaluation_plan_id': fields.many2one('hr_evaluation.plan', 'Appraisal Plan'), 'evaluation_plan_id': fields.many2one('hr_evaluation.plan', 'Appraisal Plan'),
'evaluation_date': fields.date('Next Appraisal Date', help="The date of the next appraisal is computed by the appraisal plan's dates (first appraisal + periodicity)."), 'evaluation_date': fields.date('Next Appraisal Date', help="The date of the next appraisal is computed by the appraisal plan's dates (first appraisal + periodicity)."),
} }
def run_employee_evaluation(self, cr, uid, automatic=False, use_new_cursor=False, context=None): def run_employee_evaluation(self, cr, uid, automatic=False, use_new_cursor=False, context=None):
now = parser.parse(datetime.now().strftime('%Y-%m-%d')) now = parser.parse(datetime.now().strftime('%Y-%m-%d'))
obj_evaluation = self.pool.get('hr_evaluation.evaluation') obj_evaluation = self.pool.get('hr_evaluation.evaluation')
emp_ids =self.search(cr, uid, [ ('evaluation_plan_id','<>',False), ('evaluation_date','=', False)], context=context) emp_ids = self.search(cr, uid, [('evaluation_plan_id', '<>', False), ('evaluation_date', '=', False)], context=context)
for emp in self.browse(cr, uid, emp_ids, context=context): for emp in self.browse(cr, uid, emp_ids, context=context):
first_date = (now+ relativedelta(months=emp.evaluation_plan_id.month_first)).strftime('%Y-%m-%d') first_date = (now + relativedelta(months=emp.evaluation_plan_id.month_first)).strftime('%Y-%m-%d')
self.write(cr, uid, [emp.id], {'evaluation_date': first_date}, context=context) self.write(cr, uid, [emp.id], {'evaluation_date': first_date}, context=context)
emp_ids =self.search(cr, uid, [ emp_ids = self.search(cr, uid, [
('evaluation_plan_id','<>',False), ('evaluation_date','<=', time.strftime("%Y-%m-%d")), ('evaluation_plan_id', '<>', False), ('evaluation_date', '<=', time.strftime("%Y-%m-%d")),
], context=context) ], context=context)
for emp in self.browse(cr, uid, emp_ids, context=context): for emp in self.browse(cr, uid, emp_ids, context=context):
next_date = (now + relativedelta(months=emp.evaluation_plan_id.month_next)).strftime('%Y-%m-%d') next_date = (now + relativedelta(months=emp.evaluation_plan_id.month_next)).strftime('%Y-%m-%d')
self.write(cr, uid, [emp.id], {'evaluation_date': next_date}, context=context) self.write(cr, uid, [emp.id], {'evaluation_date': next_date}, context=context)
@ -126,8 +126,7 @@ class hr_employee(osv.osv):
return True return True
class hr_evaluation(osv.Model):
class hr_evaluation(osv.osv):
_name = "hr_evaluation.evaluation" _name = "hr_evaluation.evaluation"
_inherit = "mail.thread" _inherit = "mail.thread"
_description = "Employee Appraisal" _description = "Employee Appraisal"
@ -136,24 +135,22 @@ class hr_evaluation(osv.osv):
'date': fields.date("Appraisal Deadline", required=True, select=True), 'date': fields.date("Appraisal Deadline", required=True, select=True),
'employee_id': fields.many2one('hr.employee', "Employee", required=True), 'employee_id': fields.many2one('hr.employee', "Employee", required=True),
'note_summary': fields.text('Appraisal Summary'), 'note_summary': fields.text('Appraisal Summary'),
'note_action': fields.text('Action Plan', 'note_action': fields.text('Action Plan', help="If the evaluation does not meet the expectations, you can propose an action plan"),
help="If the evaluation does not meet the expectations, you can propose"+
"an action plan"),
'rating': fields.selection([ 'rating': fields.selection([
('0','Significantly bellow expectations'), ('0', 'Significantly below expectations'),
('1','Did not meet expectations'), ('1', 'Do not meet expectations'),
('2','Meet expectations'), ('2', 'Meet expectations'),
('3','Exceeds expectations'), ('3', 'Exceeds expectations'),
('4','Significantly exceeds expectations'), ('4', 'Significantly exceeds expectations'),
], "Appreciation", help="This is the appreciation on which the evaluation is summarized."), ], "Appreciation", help="This is the appreciation on which the evaluation is summarized."),
'survey_request_ids': fields.one2many('hr.evaluation.interview','evaluation_id','Appraisal Forms'), 'survey_request_ids': fields.one2many('hr.evaluation.interview', 'evaluation_id', 'Appraisal Forms'),
'plan_id': fields.many2one('hr_evaluation.plan', 'Plan', required=True), 'plan_id': fields.many2one('hr_evaluation.plan', 'Plan', required=True),
'state': fields.selection([ 'state': fields.selection([
('draft','New'), ('draft', 'New'),
('cancel','Cancelled'), ('cancel', 'Cancelled'),
('wait','Plan In Progress'), ('wait', 'Plan In Progress'),
('progress','Waiting Appreciation'), ('progress', 'Waiting Appreciation'),
('done','Done'), ('done', 'Done'),
], 'Status', required=True, readonly=True), ], 'Status', required=True, readonly=True),
'date_close': fields.date('Ending Date', select=True), 'date_close': fields.date('Ending Date', select=True),
} }
@ -183,7 +180,6 @@ class hr_evaluation(osv.osv):
return {'value': vals} return {'value': vals}
def button_plan_in_progress(self, cr, uid, ids, context=None): def button_plan_in_progress(self, cr, uid, ids, context=None):
mail_message = self.pool.get('mail.message')
hr_eval_inter_obj = self.pool.get('hr.evaluation.interview') hr_eval_inter_obj = self.pool.get('hr.evaluation.interview')
if context is None: if context is None:
context = {} context = {}
@ -214,7 +210,7 @@ class hr_evaluation(osv.osv):
if (not wait) and phase.mail_feature: if (not wait) and phase.mail_feature:
body = phase.mail_body % {'employee_name': child.name, 'user_signature': child.user_id.signature, body = phase.mail_body % {'employee_name': child.name, 'user_signature': child.user_id.signature,
'eval_name': phase.survey_id.title, 'date': time.strftime('%Y-%m-%d'), 'time': time } 'eval_name': phase.survey_id.title, 'date': time.strftime('%Y-%m-%d'), 'time': time}
sub = phase.email_subject sub = phase.email_subject
if child.work_email: if child.work_email:
vals = {'state': 'outgoing', vals = {'state': 'outgoing',
@ -224,32 +220,32 @@ class hr_evaluation(osv.osv):
'email_from': evaluation.employee_id.work_email} 'email_from': evaluation.employee_id.work_email}
self.pool.get('mail.mail').create(cr, uid, vals, context=context) self.pool.get('mail.mail').create(cr, uid, vals, context=context)
self.write(cr, uid, ids, {'state':'wait'}, context=context) self.write(cr, uid, ids, {'state': 'wait'}, context=context)
return True return True
def button_final_validation(self, cr, uid, ids, context=None): def button_final_validation(self, cr, uid, ids, context=None):
request_obj = self.pool.get('hr.evaluation.interview') request_obj = self.pool.get('hr.evaluation.interview')
self.write(cr, uid, ids, {'state':'progress'}, context=context) self.write(cr, uid, ids, {'state': 'progress'}, context=context)
for evaluation in self.browse(cr, uid, ids, context=context): for evaluation in self.browse(cr, uid, ids, context=context):
if evaluation.employee_id and evaluation.employee_id.parent_id and evaluation.employee_id.parent_id.user_id: if evaluation.employee_id and evaluation.employee_id.parent_id and evaluation.employee_id.parent_id.user_id:
self.message_subscribe_users(cr, uid, [evaluation.id], user_ids=[evaluation.employee_id.parent_id.user_id.id], context=context) self.message_subscribe_users(cr, uid, [evaluation.id], user_ids=[evaluation.employee_id.parent_id.user_id.id], context=context)
if len(evaluation.survey_request_ids) != len(request_obj.search(cr, uid, [('evaluation_id', '=', evaluation.id),('state', 'in', ['done','cancel'])], context=context)): if len(evaluation.survey_request_ids) != len(request_obj.search(cr, uid, [('evaluation_id', '=', evaluation.id), ('state', 'in', ['done', 'cancel'])], context=context)):
raise osv.except_osv(_('Warning!'),_("You cannot change state, because some appraisal(s) are in waiting answer or draft state.")) raise osv.except_osv(_('Warning!'), _("You cannot change state, because some appraisal(s) are in waiting answer or draft state."))
return True return True
def button_done(self, cr, uid, ids, context=None): def button_done(self, cr, uid, ids, context=None):
self.write(cr, uid, ids,{'state':'done', 'date_close': time.strftime('%Y-%m-%d')}, context=context) self.write(cr, uid, ids, {'state': 'done', 'date_close': time.strftime('%Y-%m-%d')}, context=context)
return True return True
def button_cancel(self, cr, uid, ids, context=None): def button_cancel(self, cr, uid, ids, context=None):
interview_obj=self.pool.get('hr.evaluation.interview') interview_obj = self.pool.get('hr.evaluation.interview')
evaluation = self.browse(cr, uid, ids[0], context) evaluation = self.browse(cr, uid, ids[0], context)
interview_obj.survey_req_cancel(cr, uid, [r.id for r in evaluation.survey_request_ids]) interview_obj.survey_req_cancel(cr, uid, [r.id for r in evaluation.survey_request_ids])
self.write(cr, uid, ids,{'state':'cancel'}, context=context) self.write(cr, uid, ids, {'state': 'cancel'}, context=context)
return True return True
def button_draft(self, cr, uid, ids, context=None): def button_draft(self, cr, uid, ids, context=None):
self.write(cr, uid, ids,{'state': 'draft'}, context=context) self.write(cr, uid, ids, {'state': 'draft'}, context=context)
return True return True
def copy(self, cr, uid, id, default=None, context=None): def copy(self, cr, uid, id, default=None, context=None):
@ -260,7 +256,7 @@ class hr_evaluation(osv.osv):
default = default.copy() default = default.copy()
default['survey_request_ids'] = [] default['survey_request_ids'] = []
return super(hr_evaluation, self).copy(cr, uid, id, default, context=context) return super(hr_evaluation, self).copy(cr, uid, id, default, context=context)
def write(self, cr, uid, ids, vals, context=None): def write(self, cr, uid, ids, vals, context=None):
if vals.get('employee_id'): if vals.get('employee_id'):
employee_id = self.pool.get('hr.employee').browse(cr, uid, vals.get('employee_id'), context=context) employee_id = self.pool.get('hr.employee').browse(cr, uid, vals.get('employee_id'), context=context)
@ -275,26 +271,27 @@ class hr_evaluation(osv.osv):
return super(hr_evaluation, self).write(cr, uid, ids, vals, context=context) return super(hr_evaluation, self).write(cr, uid, ids, vals, context=context)
class survey_request(osv.osv): class hr_evaluation_interview(osv.Model):
_inherit = "survey.request"
_columns = {
'is_evaluation': fields.boolean('Is Appraisal?'),
}
class hr_evaluation_interview(osv.osv):
_name = 'hr.evaluation.interview' _name = 'hr.evaluation.interview'
_inherits = {'survey.request': 'request_id'} _inherit = 'mail.thread'
_inherit = 'mail.thread'
_rec_name = 'request_id' _rec_name = 'request_id'
_description = 'Appraisal Interview' _description = 'Appraisal Interview'
_columns = { _columns = {
'request_id': fields.many2one('survey.request','Request_id', ondelete='cascade', required=True), 'request_id': fields.many2one('survey.user_input', 'Survey Request', ondelete='cascade', required=True),
'user_to_review_id': fields.many2one('hr.employee', 'Employee to Interview'), 'user_to_review_id': fields.many2one('hr.employee', 'Employee to Interview'),
'evaluation_id': fields.many2one('hr_evaluation.evaluation', 'Appraisal Form'), 'evaluation_id': fields.many2one('hr_evaluation.evaluation', 'Appraisal Form'),
'user_id': fields.many2one('res.users', 'Interviewer'),
'state': fields.selection([('draft', "Draft"),
('waiting_answer', "In progress"),
('done', "Done"),
('cancel', "Cancelled")],
string="State", required=True),
# fields from request_id
'survey_id': fields.related('request_id', 'survey_id', string="Appraisal Form", type="many2one", relation="survey.survey"),
'deadline': fields.related('request_id', 'deadline', string="Deadline"),
} }
_defaults = { _defaults = {
'is_evaluation': True, 'state': 'draft'
} }
def name_get(self, cr, uid, ids, context=None): def name_get(self, cr, uid, ids, context=None):
@ -308,7 +305,7 @@ class hr_evaluation_interview(osv.osv):
return res return res
def survey_req_waiting_answer(self, cr, uid, ids, context=None): def survey_req_waiting_answer(self, cr, uid, ids, context=None):
self.write(cr, uid, ids, { 'state': 'waiting_answer'}, context=context) self.write(cr, uid, ids, {'state': 'waiting_answer'}, context=context)
return True return True
def survey_req_done(self, cr, uid, ids, context=None): def survey_req_done(self, cr, uid, ids, context=None):
@ -317,7 +314,7 @@ class hr_evaluation_interview(osv.osv):
flag = False flag = False
wating_id = 0 wating_id = 0
if not id.evaluation_id.id: if not id.evaluation_id.id:
raise osv.except_osv(_('Warning!'),_("You cannot start evaluation without Appraisal.")) raise osv.except_osv(_('Warning!'), _("You cannot start evaluation without Appraisal."))
records = hr_eval_obj.browse(cr, uid, [id.evaluation_id.id], context=context)[0].survey_request_ids records = hr_eval_obj.browse(cr, uid, [id.evaluation_id.id], context=context)[0].survey_request_ids
for child in records: for child in records:
if child.state == "draft": if child.state == "draft":
@ -327,15 +324,15 @@ class hr_evaluation_interview(osv.osv):
flag = True flag = True
if not flag and wating_id: if not flag and wating_id:
self.survey_req_waiting_answer(cr, uid, [wating_id], context=context) self.survey_req_waiting_answer(cr, uid, [wating_id], context=context)
self.write(cr, uid, ids, { 'state': 'done'}, context=context) self.write(cr, uid, ids, {'state': 'done'}, context=context)
return True return True
def survey_req_draft(self, cr, uid, ids, context=None): def survey_req_draft(self, cr, uid, ids, context=None):
self.write(cr, uid, ids, { 'state': 'draft'}, context=context) self.write(cr, uid, ids, {'state': 'draft'}, context=context)
return True return True
def survey_req_cancel(self, cr, uid, ids, context=None): def survey_req_cancel(self, cr, uid, ids, context=None):
self.write(cr, uid, ids, { 'state': 'cancel'}, context=context) self.write(cr, uid, ids, {'state': 'cancel'}, context=context)
return True return True
def action_print_survey(self, cr, uid, ids, context=None): def action_print_survey(self, cr, uid, ids, context=None):
@ -353,7 +350,7 @@ class hr_evaluation_interview(osv.osv):
context = {} context = {}
record = self.browse(cr, uid, ids, context=context) record = self.browse(cr, uid, ids, context=context)
record = record and record[0] record = record and record[0]
context.update({'survey_id': record.survey_id.id, 'response_id': [record.response.id], 'response_no':0,}) context.update({'survey_id': record.survey_id.id, 'response_id': [record.response.id], 'response_no': 0})
value = self.pool.get("survey").action_print_survey(cr, uid, ids, context=context) value = self.pool.get("survey").action_print_survey(cr, uid, ids, context=context)
return value return value

View File

@ -16,7 +16,7 @@
<field name="body"><![CDATA[<p>Manage employee reviews: you can define an appraisal campaign with several steps, with specific evaluation surveys according to hierarchy levels. Evaluations filled by employees may be exported as pdf files.</p>]]></field> <field name="body"><![CDATA[<p>Manage employee reviews: you can define an appraisal campaign with several steps, with specific evaluation surveys according to hierarchy levels. Evaluations filled by employees may be exported as pdf files.</p>]]></field>
</record> </record>
<record id="survey_2" model="survey"> <!-- <record id="survey_2" model="survey">
<field name="title">Self Appraisal</field> <field name="title">Self Appraisal</field>
<field name="max_response_limit">20</field> <field name="max_response_limit">20</field>
<field eval="[(6,0,[])]" name="users"/> <field eval="[(6,0,[])]" name="users"/>
@ -1153,6 +1153,7 @@ Once the form had been filled, the employee send it to his supervisor.
<field name="question_id" ref="survey_question_6"/> <field name="question_id" ref="survey_question_6"/>
<field eval="5" name="sequence"/> <field eval="5" name="sequence"/>
</record> </record>
-->
</data> </data>
<data noupdate="1"> <data noupdate="1">
@ -1175,8 +1176,8 @@ Once the form had been filled, the employee send it to his supervisor.
<field name="action">self</field> <field name="action">self</field>
<field eval="0" name="send_anonymous_employee"/> <field eval="0" name="send_anonymous_employee"/>
<field eval="0" name="send_answer_employee"/> <field eval="0" name="send_answer_employee"/>
<field name="survey_id" ref="hr_evaluation.survey_2"/> <!-- <field name="survey_id" ref="hr_evaluation.survey_2"/>
<field eval="0" name="send_answer_manager"/> --> <field eval="0" name="send_answer_manager"/>
<field eval="0" name="wait"/> <field eval="0" name="wait"/>
</record> </record>
</data> </data>

View File

@ -21,24 +21,26 @@
<field name="model">hr_evaluation.plan</field> <field name="model">hr_evaluation.plan</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Appraisal Plan" version="7.0"> <form string="Appraisal Plan" version="7.0">
<group col="4"> <sheet>
<group> <group col="4">
<field name="name"/> <group>
<field name="company_id" widget="selection" groups="base.group_multi_company"/> <field name="name"/>
<field name="active"/> <field name="company_id" widget="selection" groups="base.group_multi_company"/>
<field name="active"/>
</group>
<group>
<field name="month_first"/>
<field name="month_next"/>
</group>
</group> </group>
<group> <notebook>
<field name="month_first"/> <page string="Appraisal Phases">
<field name="month_next"/>
</group>
</group>
<notebook>
<page string="Appraisal Phases">
<field name="phase_ids"/> <field name="phase_ids"/>
</page> </page>
</notebook> </notebook>
</sheet>
</form> </form>
</field> </field>
</record> </record>
<record model="ir.ui.view" id="view_hr_evaluation_plan_tree"> <record model="ir.ui.view" id="view_hr_evaluation_plan_tree">
<field name="name">hr_evaluation.plan.form</field> <field name="name">hr_evaluation.plan.form</field>
@ -58,9 +60,9 @@
<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>
</record> </record>
<!-- Appraisal Interviews Action --> <!-- Appraisal Interviews Action -->
<record id="act_hr_employee_2_hr__evaluation_interview" model="ir.actions.act_window"> <record id="act_hr_employee_2_hr__evaluation_interview" model="ir.actions.act_window">
<field name="res_model">hr.evaluation.interview</field> <field name="res_model">hr.evaluation.interview</field>
<field name="view_type">form</field> <field name="view_type">form</field>
@ -165,11 +167,9 @@
</header> </header>
<sheet> <sheet>
<label for="employee_id" class="oe_edit_only"/> <label for="employee_id" class="oe_edit_only"/>
<h1><field name="employee_id" class="oe_inline" <h1>
attrs="{'readonly': [('state', '=', 'done')]}" <field name="employee_id" class="oe_inline" attrs="{'readonly': [('state', '=', 'done')]}" on_change="onchange_employee_id(employee_id)"/>
on_change="onchange_employee_id(employee_id)"/>, <field name="date" attrs="{'readonly': [('state', '=', 'done')]}"/>
<field name="date"
attrs="{'readonly': [('state', '=', 'done')]}"/>
</h1> </h1>
<label for="plan_id" class="oe_edit_only"/> <label for="plan_id" class="oe_edit_only"/>
<h2><field name="plan_id" attrs="{'readonly': [('state', '=', 'done')]}"/></h2> <h2><field name="plan_id" attrs="{'readonly': [('state', '=', 'done')]}"/></h2>
@ -183,8 +183,8 @@
<field nolabel="1" name="survey_request_ids" attrs="{'readonly': [('state', '=', 'done')]}"> <field nolabel="1" name="survey_request_ids" attrs="{'readonly': [('state', '=', 'done')]}">
<form string="Interview Appraisal" version="7.0"> <form string="Interview Appraisal" version="7.0">
<div class="oe_right oe_button_box"> <div class="oe_right oe_button_box">
<button name="%(survey.action_view_survey_question_message)d" string="Answer Survey" type="action" states="waiting_answer" icon="gtk-execute" context="{'survey_id': survey_id, 'response_id': [response], 'response_no':0, 'active' : response,'request' : True, 'object' : 'hr.evaluation.interview', 'cur_id' : active_id}" attrs="{'readonly':[('survey_id','=',False)]}"/> <button string="Answer Survey" states="waiting_answer" icon="gtk-execute" context="{'survey_id': survey_id, 'response_id': [response], 'response_no':0, 'active' : response,'request' : True, 'object' : 'hr.evaluation.interview', 'cur_id' : active_id}" attrs="{'readonly':[('survey_id','=',False)]}"/>
<button name="%(survey.survey_browse_response)d" string="Print Interview" type="action" states="done" icon="gtk-print" context="{'survey_id': survey_id, 'response_id' : [response], 'response_no':0,}" attrs="{'readonly':[('response','=',False)]}" /> <button string="Print Interview" states="done" icon="gtk-print" context="{'survey_id': survey_id, 'response_id' : [response], 'response_no':0,}" attrs="{'readonly':[('response_id','=',False)]}" />
</div> </div>
<group> <group>
<group> <group>
@ -192,9 +192,9 @@
<field name="user_to_review_id"/> <field name="user_to_review_id"/>
<field name="user_id" string="Interviewer" context="{'default_groups_ref': ['base.group_user', 'base.group_partner_manager', 'base.group_hr_manager']}"/> <field name="user_id" string="Interviewer" context="{'default_groups_ref': ['base.group_user', 'base.group_partner_manager', 'base.group_hr_manager']}"/>
</group> </group>
<group> <group>
<field name="date_deadline"/> <field name="deadline"/>
<field name="response" readonly="1"/> <field name="request_id" readonly="1"/>
</group> </group>
</group> </group>
<group col="4" string="Status" invisible="1"> <group col="4" string="Status" invisible="1">
@ -230,7 +230,6 @@
<field name="employee_id"/> <field name="employee_id"/>
<field name="plan_id"/> <field name="plan_id"/>
<field name="date"/> <field name="date"/>
<!--field name="progress" widget="progressbar"/-->
<field name="rating"/> <field name="rating"/>
<field name="state"/> <field name="state"/>
</tree> </tree>
@ -294,7 +293,7 @@
attrs="{'readonly':[('survey_id','=',False)]}" class="oe_highlight"/> attrs="{'readonly':[('survey_id','=',False)]}" class="oe_highlight"/>
<button string="Send Request" name="survey_req_waiting_answer" type="object" <button string="Send Request" name="survey_req_waiting_answer" type="object"
states="draft" class="oe_highlight"/> states="draft" class="oe_highlight"/>
<button string="Answer Survey" name="%(survey.action_view_survey_question_message)d" type="action" <button string="Answer Survey" name="#" type="action"
states="waiting_answer" class="oe_highlight" states="waiting_answer" class="oe_highlight"
context="{'survey_id': survey_id, 'response_id': [response], 'response_no':0, 'active' : response,'request' : True, 'object' : 'hr.evaluation.interview', 'cur_id' : active_id}" context="{'survey_id': survey_id, 'response_id': [response], 'response_no':0, 'active' : response,'request' : True, 'object' : 'hr.evaluation.interview', 'cur_id' : active_id}"
attrs="{'readonly':[('survey_id','=',False)]}"/> attrs="{'readonly':[('survey_id','=',False)]}"/>
@ -316,8 +315,8 @@
<field name="user_id" string="Interviewer" context="{'default_groups_ref': ['base.group_user', 'base.group_partner_manager', 'base.group_hr_manager']}"/> <field name="user_id" string="Interviewer" context="{'default_groups_ref': ['base.group_user', 'base.group_partner_manager', 'base.group_hr_manager']}"/>
</group> </group>
<group> <group>
<field name="date_deadline"/> <field name="deadline"/>
<field name="response" readonly="1"/> <field name="request_id" readonly="1"/>
<field name="evaluation_id" string="Appraisal Plan"/> <field name="evaluation_id" string="Appraisal Plan"/>
</group> </group>
</group> </group>
@ -326,17 +325,17 @@
</field> </field>
</record> </record>
<record model="ir.ui.view" id="view_hr_evaluation_interview_tree"> <record model="ir.ui.view" id="view_hr_evaluation_interview_tree">
<field name="name">hr_evaluation.interview.tree</field> <field name="name">hr_evaluation.interview.tree</field>
<field name="model">hr.evaluation.interview</field> <field name="model">hr.evaluation.interview</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="Interview Appraisal"> <tree string="Interview Appraisal">
<field name="date_deadline" string="Deadline Date"/> <field name="deadline" string="Deadline Date"/>
<field name="survey_id"/> <field name="survey_id"/>
<field name="user_id" string="Interviewer"/> <field name="user_id" string="Interviewer"/>
<field name="user_to_review_id"/> <field name="user_to_review_id"/>
<field name="response" readonly="1" invisible="True"/> <field name="request_id" readonly="1" invisible="True"/>
<button name="%(survey.action_view_survey_question_message)d" string="Answer Survey" type="action" states="waiting_answer" icon="gtk-execute" context="{'survey_id': survey_id, 'response_id': [response], 'response_no':0, 'active' : response, 'request' : True, 'object' : 'hr.evaluation.interview', 'cur_id' : active_id}" attrs="{'readonly':[('survey_id','=',False)]}"/> <button name="#" string="Answer Survey" type="action" states="waiting_answer" icon="gtk-execute" context="{'survey_id': survey_id, 'response_id': [response], 'response_no':0, 'active' : response, 'request' : True, 'object' : 'hr.evaluation.interview', 'cur_id' : active_id}" attrs="{'readonly':[('survey_id','=',False)]}"/>
<button name="action_print_survey" string="Print Survey" type="object" icon="gtk-print" context="{'survey_id': survey_id, 'response_id': [response], 'response_no':0}" attrs="{'readonly':[('survey_id','=',False)]}"/> <button name="action_print_survey" string="Print Survey" type="object" icon="gtk-print" context="{'survey_id': survey_id, 'response_id': [response], 'response_no':0}" attrs="{'readonly':[('survey_id','=',False)]}"/>
<button name="%(mail.action_email_compose_message_wizard)d" string="Send Reminder Email" icon="terp-mail-message-new" type="action" states="waiting_answer"/> <button name="%(mail.action_email_compose_message_wizard)d" string="Send Reminder Email" icon="terp-mail-message-new" type="action" states="waiting_answer"/>
<field name="state"/> <field name="state"/>
@ -351,7 +350,7 @@
<field name="model">hr.evaluation.interview</field> <field name="model">hr.evaluation.interview</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<search string="Search Appraisal"> <search string="Search Appraisal">
<field name="date_deadline"/> <field name="deadline"/>
<filter icon="terp-gtk-go-back-rtl" string="To Do" name="todo" domain="[('state','=','waiting_answer')]"/> <filter icon="terp-gtk-go-back-rtl" string="To Do" name="todo" domain="[('state','=','waiting_answer')]"/>
<field name="user_to_review_id"/> <field name="user_to_review_id"/>
<field name="user_id" string="Interviewer"/> <field name="user_id" string="Interviewer"/>
@ -368,7 +367,7 @@
<field name="name">Interview Requests</field> <field name="name">Interview Requests</field>
<field name="model">hr.evaluation.interview</field> <field name="model">hr.evaluation.interview</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<calendar string="Interview Request" color="user_to_review_id" date_start="date_deadline"> <calendar string="Interview Request" color="user_to_review_id" date_start="deadline">
<field name="request_id"/> <field name="request_id"/>
</calendar> </calendar>
</field> </field>
@ -379,12 +378,11 @@
<field name="res_model">hr.evaluation.interview</field> <field name="res_model">hr.evaluation.interview</field>
<field name="view_type">form</field> <field name="view_type">form</field>
<field name="view_id" eval="False"/> <field name="view_id" eval="False"/>
<field name="domain">[('is_evaluation' ,'=', True)]</field> <field name="context">{"search_default_todo":1,"search_default_user_id":uid}</field>
<field name="context">{'default_is_evaluation': True, "search_default_todo":1,"search_default_user_id":uid}</field>
<field name="search_view_id" ref="view_hr_evaluation_interview_search"/> <field name="search_view_id" ref="view_hr_evaluation_interview_search"/>
<field name="help" type="html"> <field name="help" type="html">
<p class="oe_view_nocontent_create"> <p class="oe_view_nocontent_create">
Click to create a new interview request related to a personal evaluation. Click to create a new interview request related to a personal evaluation.
</p><p> </p><p>
Interview requests are usually generated automatically by Interview requests are usually generated automatically by
OpenERP according to an employee's appraisal plan. Each user OpenERP according to an employee's appraisal plan. Each user

View File

@ -22,41 +22,43 @@
from openerp import tools from openerp import tools
from openerp.osv import fields, osv from openerp.osv import fields, osv
class hr_evaluation_report(osv.osv):
class hr_evaluation_report(osv.Model):
_name = "hr.evaluation.report" _name = "hr.evaluation.report"
_description = "Evaluations Statistics" _description = "Evaluations Statistics"
_auto = False _auto = False
_columns = { _columns = {
'create_date': fields.date('Create Date', readonly=True), 'create_date': fields.date('Create Date', readonly=True),
'delay_date':fields.float('Delay to Start', digits=(16,2),readonly=True), 'delay_date': fields.float('Delay to Start', digits=(16, 2), readonly=True),
'overpass_delay':fields.float('Overpassed Deadline', digits=(16,2), readonly=True), 'overpass_delay': fields.float('Overpassed Deadline', digits=(16, 2), readonly=True),
'day': fields.char('Day', size=128, readonly=True), 'day': fields.char('Day', size=128, readonly=True),
'deadline': fields.date("Deadline", readonly=True), 'deadline': fields.date("Deadline", readonly=True),
'request_id': fields.many2one('survey.request', 'Request_id', readonly=True), 'request_id': fields.many2one('survey.user_input', 'Request_id', readonly=True),
'closed': fields.date("closed", readonly=True), 'closed': fields.date("closed", readonly=True),
'year': fields.char('Year', size=4, readonly=True), 'year': fields.char('Year', size=4, readonly=True),
'month':fields.selection([('01','January'), ('02','February'), ('03','March'), ('04','April'), 'month': fields.selection([('01', 'January'), ('02', 'February'), ('03', 'March'), ('04', 'April'),
('05','May'), ('06','June'), ('07','July'), ('08','August'), ('09','September'), ('05', 'May'), ('06', 'June'), ('07', 'July'), ('08', 'August'), ('09', 'September'),
('10','October'), ('11','November'), ('12','December')], 'Month',readonly=True), ('10', 'October'), ('11', 'November'), ('12', 'December')], 'Month', readonly=True),
'plan_id': fields.many2one('hr_evaluation.plan', 'Plan', readonly=True), 'plan_id': fields.many2one('hr_evaluation.plan', 'Plan', readonly=True),
'employee_id': fields.many2one('hr.employee', "Employee", readonly=True), 'employee_id': fields.many2one('hr.employee', "Employee", readonly=True),
'rating': fields.selection([ 'rating': fields.selection([
('0','Significantly bellow expectations'), ('0', 'Significantly bellow expectations'),
('1','Did not meet expectations'), ('1', 'Did not meet expectations'),
('2','Meet expectations'), ('2', 'Meet expectations'),
('3','Exceeds expectations'), ('3', 'Exceeds expectations'),
('4','Significantly exceeds expectations'), ('4', 'Significantly exceeds expectations'),
], "Overall Rating", readonly=True), ], "Overall Rating", readonly=True),
'nbr':fields.integer('# of Requests', readonly=True), 'nbr': fields.integer('# of Requests', readonly=True),
'state': fields.selection([ 'state': fields.selection([
('draft','Draft'), ('draft', 'Draft'),
('wait','Plan In Progress'), ('wait', 'Plan In Progress'),
('progress','Final Validation'), ('progress', 'Final Validation'),
('done','Done'), ('done', 'Done'),
('cancel','Cancelled'), ('cancel', 'Cancelled'),
], 'Status',readonly=True), ], 'Status', readonly=True),
} }
_order = 'create_date desc' _order = 'create_date desc'
def init(self, cr): def init(self, cr):
tools.drop_view_if_exists(cr, 'hr_evaluation_report') tools.drop_view_if_exists(cr, 'hr_evaluation_report')
cr.execute(""" cr.execute("""

View File

@ -47,7 +47,6 @@ sent mails with personal token for the invitation of the survey.
], ],
'demo': ['data/survey_demo_user.xml', 'demo': ['data/survey_demo_user.xml',
'data/survey_demo_feedback.xml', 'data/survey_demo_feedback.xml',
'data/survey_demo_appraisal.xml',
'data/survey.user_input.csv', 'data/survey.user_input.csv',
'data/survey.user_input_line.csv'], 'data/survey.user_input_line.csv'],
'installable': True, 'installable': True,