289 lines
14 KiB
Python
289 lines
14 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
from odoo import api, fields, models, _, exceptions, Command
|
|
from datetime import date
|
|
|
|
|
|
class EmployeesAppraisal(models.Model):
|
|
_name = 'hr.group.employee.appraisal'
|
|
_inherit = ['mail.thread', 'mail.activity.mixin']
|
|
_rec_name = 'name'
|
|
_description = 'Appraisal'
|
|
|
|
name = fields.Char()
|
|
date = fields.Date()
|
|
state = fields.Selection([
|
|
("draft", "Draft"),
|
|
("gen_appraisal", "Generate Appraisal"),
|
|
("start_appraisal", "Start Appraisal"),
|
|
("finish_appraisal", "Direct Manager"),
|
|
("hr_approval", "Department Manager"),
|
|
("gm_approval", "HR Approval"),
|
|
("done", "Done")
|
|
], default='draft', tracking=True)
|
|
|
|
# Relational fields
|
|
department_id = fields.Many2one('hr.department')
|
|
manager_id = fields.Many2one('hr.employee', related='department_id.manager_id')
|
|
employee_ids = fields.Many2many('hr.employee')
|
|
appraisal_id = fields.One2many('hr.employee.appraisal', 'employee_appraisal')
|
|
appraisal_plan_id = fields.Many2one('appraisal.plan')
|
|
|
|
totals_great_level = fields.Float(compute='fill_totals_great_level', tracking=True)
|
|
totals_level_achieved = fields.Float(compute='fill_totals_great_level', tracking=True)
|
|
totals_level_achieved_percentage = fields.Float(compute='fill_totals_great_level', tracking=True)
|
|
totals_appraisal_result = fields.Many2one('appraisal.result', tracking=True, compute='fill_totals_great_level')
|
|
company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.company)
|
|
|
|
appraisal_type = fields.Selection(selection=[('performance', 'Performance'),
|
|
('trial', 'Trial Period'),
|
|
('training', 'Training'),
|
|
('mission', 'Mission'),
|
|
('general', 'General'),
|
|
('other', 'Other')], string='Appraisal Type')
|
|
employee_protest = fields.Boolean(
|
|
readonly=True
|
|
)
|
|
|
|
|
|
# Dynamic domain for manager_id
|
|
@api.onchange('department_id')
|
|
def manager_domain(self):
|
|
for item in self:
|
|
if item.department_id:
|
|
employee_ids = self.env['hr.employee'].search([])
|
|
employee_list = []
|
|
|
|
# Domain for manager_id
|
|
if not item.department_id.manager_id:
|
|
item.manager_id = False
|
|
for line in employee_ids:
|
|
if line.department_id:
|
|
if line.department_id == item.department_id:
|
|
employee_list.append(line.id)
|
|
return {'domain': {'manager_id': [('id', 'in', employee_list)]}}
|
|
|
|
# Dynamic domain for employee_ids
|
|
|
|
@api.onchange('department_id')
|
|
def employee_ids_domain(self):
|
|
for item in self:
|
|
if item.department_id:
|
|
department_ids = self.env['hr.department'].search([])
|
|
employee_ids = self.env['hr.employee'].search([])
|
|
|
|
department_list, employee_list = [], []
|
|
|
|
# Adding the selected department to department_list
|
|
department_list.append(item.department_id.id)
|
|
|
|
# Domain for employee_ids
|
|
for line in department_ids:
|
|
if line.parent_id:
|
|
if line.parent_id == item.department_id:
|
|
department_list.append(line.id)
|
|
for sub_line in department_ids:
|
|
if sub_line.parent_id == line:
|
|
department_list.append(sub_line.id)
|
|
for line in employee_ids:
|
|
if line.department_id:
|
|
if line.department_id.id in department_list:
|
|
employee_list.append(line.id)
|
|
if item.department_id:
|
|
return {'domain': {'employee_ids': [('id', 'in', employee_list)]}}
|
|
|
|
# Create records in hr.employee.appraisal when change state to Generate Appraisal
|
|
|
|
def gen_appraisal(self):
|
|
for item in self:
|
|
if item.employee_ids:
|
|
appraisal_lines = []
|
|
|
|
# Fill employee appraisal
|
|
for element in item.employee_ids:
|
|
standard_appraisal_list, manager_appraisal_list = [], []
|
|
|
|
if not item.appraisal_plan_id.is_manager:
|
|
# Fill standard_appraisal_employee_line_ids to complete
|
|
for line in item.appraisal_plan_id.standard_appraisal_id:
|
|
standard_appraisal_list.append({
|
|
'great_level': line.great_level,
|
|
'question': line.question
|
|
})
|
|
else:
|
|
# Fill manager_appraisal_line_id to complete
|
|
for line in item.appraisal_plan_id.manager_appraisal_id:
|
|
complete_manager_appraisal_list = []
|
|
for record in line.question_id.customize_appraisal_id:
|
|
complete_manager_appraisal_list.append({
|
|
'question': record.question,
|
|
'great_degree_level': record.great_degree_level,
|
|
'degree_id': record.degree_id.id
|
|
})
|
|
record = self.env['manager.appraisal.complete.line'].create({
|
|
'name': line.question_id.name,
|
|
'great_level': line.great_level,
|
|
'customize_appraisal_id': [Command.create(value) for value in complete_manager_appraisal_list]
|
|
})
|
|
manager_appraisal_list.append({
|
|
'appraisal_name': line.appraisal_name,
|
|
'question_id': line.question_id.id,
|
|
'question_complete_id': record.id
|
|
})
|
|
appraisal_line = {
|
|
'employee_id': element.id,
|
|
'appraisal_date': date.today(),
|
|
'is_manager': item.appraisal_plan_id.is_manager,
|
|
'appraisal_plan_id': item.appraisal_plan_id.id,
|
|
'appraisal_type': item.appraisal_type,
|
|
'standard_appraisal_employee_line_ids': [Command.create(value) for value in standard_appraisal_list],
|
|
'manager_appraisal_line_id': [Command.create(value) for value in manager_appraisal_list],
|
|
'employee_protest': item.employee_protest
|
|
}
|
|
line_id = self.env['hr.employee.appraisal'].create(appraisal_line)
|
|
|
|
# Initialize
|
|
total_greed, total_great_level, line_id.level_achieved, line_id.great_level = 0.0, 0.0, 0.0, 0.0
|
|
appraisal_result_list = []
|
|
|
|
if not line_id.is_manager:
|
|
for line in line_id.standard_appraisal_employee_line_ids:
|
|
# Update level achieved values when changed in lines
|
|
total_greed += line.greed
|
|
total_great_level += line.great_level
|
|
line_id.great_level = total_great_level
|
|
line_id.level_achieved = total_greed
|
|
|
|
# Update level achieved percentage when changed in lines
|
|
if line_id.level_achieved > 0.0 and line_id.great_level > 0.0:
|
|
line_id.level_achieved_percentage = (line_id.level_achieved * 100) / line_id.great_level
|
|
|
|
# Determine which appraisal result from appraisal percentage
|
|
appraisal_result = self.env['appraisal.result'].search([
|
|
('result_from', '<', line_id.level_achieved_percentage),
|
|
('result_to', '>=', line_id.level_achieved_percentage)])
|
|
|
|
if len(appraisal_result) > 1:
|
|
for line in appraisal_result:
|
|
appraisal_result_list.append(line.name)
|
|
raise exceptions.UserError(
|
|
_('Please check appraisal result configuration , there is more than result for '
|
|
'percentage %s are %s ') % (
|
|
round(line_id.level_achieved_percentage, 2), appraisal_result_list))
|
|
else:
|
|
line_id.appraisal_result = appraisal_result.id
|
|
|
|
elif line_id.is_manager:
|
|
for line in line_id.manager_appraisal_line_id:
|
|
# Update level achieved values when changed in lines
|
|
total_greed += line.total
|
|
total_great_level += line.great_level
|
|
line_id.great_level = total_great_level
|
|
line_id.level_achieved = total_greed
|
|
|
|
# Update level achieved percentage when changed in lines
|
|
if line_id.level_achieved > 0.0 and line_id.great_level > 0.0:
|
|
line_id.level_achieved_percentage = (line_id.level_achieved * 100) / line_id.great_level
|
|
|
|
# Determine which appraisal result from appraisal percentage
|
|
appraisal_result = self.env['appraisal.result'].search([
|
|
('result_from', '<', line_id.level_achieved_percentage),
|
|
('result_to', '>=', line_id.level_achieved_percentage)])
|
|
|
|
if len(appraisal_result) > 1:
|
|
for line in appraisal_result:
|
|
appraisal_result_list.append(line.name)
|
|
raise exceptions.UserError(
|
|
_('Please check appraisal result configuration , there is more than result for '
|
|
'percentage %s are %s ') % (
|
|
round(line_id.level_achieved_percentage, 2), appraisal_result_list))
|
|
else:
|
|
line_id.appraisal_result = appraisal_result.id
|
|
appraisal_lines.append(line_id.id)
|
|
item.appraisal_id = self.env['hr.employee.appraisal'].browse(appraisal_lines)
|
|
else:
|
|
raise exceptions.UserError(_('Please select at least one employee to make appraisal.'))
|
|
item.state = 'gen_appraisal'
|
|
|
|
def start_appraisal(self):
|
|
self.state = 'start_appraisal'
|
|
|
|
def finish_appraisal(self):
|
|
# Check if there is appraisal for employee in not in state done
|
|
if self.appraisal_id:
|
|
employee_appraisal_list = []
|
|
for line in self.appraisal_id:
|
|
if line.state != 'state_done':
|
|
employee_appraisal_list.append(line.employee_id.name)
|
|
if employee_appraisal_list:
|
|
raise exceptions.UserError(
|
|
_('Appraisal for employees "%s" is not in state done') % employee_appraisal_list)
|
|
|
|
self.state = 'finish_appraisal'
|
|
|
|
def hr_approval(self):
|
|
self.state = 'hr_approval'
|
|
|
|
def gm_approval(self):
|
|
self.state = 'gm_approval'
|
|
|
|
def state_done(self):
|
|
# make all appraisal for all employees done
|
|
if self.appraisal_id:
|
|
for line in self.appraisal_id:
|
|
line.state = 'closed'
|
|
self.state = 'done'
|
|
|
|
def draft(self):
|
|
# Delete all appraisal when re-draft
|
|
if self.appraisal_id:
|
|
for line in self.appraisal_id:
|
|
|
|
if line.state == 'draft':
|
|
line.unlink()
|
|
self.state = 'draft'
|
|
|
|
elif line.state == 'closed':
|
|
line.state = 'state_done'
|
|
self.state = 'start_appraisal'
|
|
|
|
elif line.state == 'state_done':
|
|
self.state = 'start_appraisal'
|
|
|
|
# Override unlink function
|
|
def unlink(self):
|
|
for i in self:
|
|
if i.state != 'draft':
|
|
raise exceptions.UserError(_('You can not delete record in state not in draft'))
|
|
return super(EmployeesAppraisal, self).unlink()
|
|
|
|
# Fill total great level
|
|
|
|
@api.depends('appraisal_id')
|
|
def fill_totals_great_level(self):
|
|
for item in self:
|
|
item.totals_great_level = 0
|
|
item.totals_level_achieved = 0
|
|
item.totals_level_achieved_percentage = 0
|
|
item.totals_appraisal_result = False
|
|
for element in item.appraisal_id:
|
|
count_elment = 0
|
|
appraisal_result_list = []
|
|
# for line in element:
|
|
count_elment += len(item.appraisal_id)
|
|
item.totals_great_level += element.great_level / count_elment
|
|
item.totals_level_achieved += element.level_achieved / count_elment
|
|
item.totals_level_achieved_percentage = (item.totals_level_achieved / item.totals_great_level) * 100
|
|
|
|
totals_appraisal_result = self.env['appraisal.result'].search([
|
|
('result_from', '<=', item.totals_level_achieved_percentage),
|
|
('result_to', '>=', item.totals_level_achieved_percentage)])
|
|
if len(totals_appraisal_result) > 1:
|
|
for line in totals_appraisal_result:
|
|
appraisal_result_list.append(line.name)
|
|
raise exceptions.UserError(
|
|
_('Please check appraisal result configuration , there is more than result for percentage %s are %s ') % (
|
|
round(item.totals_level_achieved_percentage, 2), appraisal_result_list))
|
|
else:
|
|
item.totals_appraisal_result = totals_appraisal_result.id
|