add module exp_hr_appraisal_kpi

This commit is contained in:
Mazen Abdo 2024-11-19 08:26:54 +02:00
parent d2d13fa08c
commit b21115b02e
25 changed files with 3131 additions and 0 deletions

View File

@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
from . import models

View File

@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
###################################################################################
{
'name': 'Appraisal KPI',
'version': '11.0.1.0.0',
'category': 'HR-Odex',
'summary': 'Manage Appraisal KPI',
'description': """
Helps you to manage Appraisal of your company's staff.
""",
'author': 'Expert Co. Ltd.',
'company': 'Exp-co-ltd',
'maintainer': 'Cybrosys Techno Solutions',
'website': 'http://exp-sa.com',
'depends': [
'exp_hr_appraisal', 'base','kpi_scorecard', 'hr','kpi_scorecard', 'account', 'exp_hr_payroll', 'mail', 'hr_base', 'hr_contract', 'hr_contract_custom'
],
'data': [
'security/group.xml',
'security/ir.model.access.csv',
'views/kpi_category.xml',
'views/kpi_item.xml',
'views/kpi_period.xml',
'views/kpi_skills.xml',
'views/skill_appraisal.xml',
'views/years_employee_goals.xml',
'views/employee_performance_evaluation.xml',
'views/appraisal_percentage.xml',
'views/employee_apprisal.xml',
],
'installable': True,
'auto_install': False,
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,9 @@
from . import kpi_item
from . import kpi_period
from . import kpi_skill
from . import skill_apprisal
from . import years_employee_goals
from . import employee_performance_evaluation
from . import appraisal_percentage
from . import employee_apprisal

View File

@ -0,0 +1,23 @@
from odoo import fields, models, api,_
from odoo.exceptions import ValidationError
class AppraisalPercentage(models.Model):
_name = 'job.class.apprisal'
_description = 'Appraisal Percentage'
name = fields.Char(string='Name')
percentage_kpi = fields.Float(string="Percentage of indicator Appraisal%",)
percentage_skills = fields.Float(string="Percentage of Skills Appraisal%",)
job_ids = fields.Many2many(
comodel_name='hr.job',
string='Jobs')
# Constraint to ensure total percentage is 100
@api.constrains('percentage_kpi', 'percentage_skills')
def _check_percentage_total(self):
for record in self:
total_percentage = record.percentage_kpi + record.percentage_skills
if total_percentage != 1:
raise ValidationError(_("Total percentage should be 100."))
if self.job_ids:
for rec in self.job_ids:
rec.appraisal_percentages_id = self.id

View File

@ -0,0 +1,162 @@
from odoo import models, fields,_,api,exceptions
class EmployeeApprisal(models.Model):
_inherit = 'hr.group.employee.appraisal'
year_id = fields.Many2one(comodel_name='kpi.period',string='Year',required=True)
appraisal_ids = fields.One2many('hr.employee.appraisal', 'employee_appraisal2')
def gen_appraisal(self):
for item in self:
if item.employee_ids:
appraisal_lines_list = []
# Fill employee appraisal
for element in item.employee_ids:
standard_appraisal_list, manager_appraisal_list = [], []
year_goal_obj = self.env['years.employee.goals'].search([('employee_id','=',element.id),('year_id','=',self.year_id.id)])
print('year = ',year_goal_obj)
goal_ids = year_goal_obj.ids if year_goal_obj else []
appraisal_line = {
'employee_id': element.id,
'manager_id': item.manager_id.id,
'year_id': item.year_id.id,
'department_id': item.department_id.id,
'job_id': element.job_id.id,
'appraisal_date': item.date,
'goal_ids': [(6, 0, goal_ids)],
}
line_id = self.env['hr.employee.appraisal'].create(appraisal_line)
line_id.compute_apprisal()
appraisal_lines_list.append(line_id.id)
item.appraisal_ids = self.env['hr.employee.appraisal'].browse(appraisal_lines_list)
else:
raise exceptions.Warning(_('Please select at least one employee to make appraisal.'))
item.state = 'gen_appraisal'
def draft(self):
print('draft ..............')
# Delete all appraisals when re-draft
if self.appraisal_ids:
print('if appr line.............')
for line in self.appraisal_ids:
print('for..................')
if line.state == 'draft':
print('state...........')
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'
# Call the original draft method using super()
class EmployeeApprisal(models.Model):
_inherit = 'hr.employee.appraisal'
employee_appraisal2 = fields.Many2one('hr.group.employee.appraisal') # Inverse field
employee_id = fields.Many2one('hr.employee', string='Employee',tracking=True,required=True)
manager_id = fields.Many2one('hr.employee', string='Manager',readonly=False,tracking=True,required=True,default=lambda item: item.get_user_id())
year_id = fields.Many2one(comodel_name='kpi.period',string='Year',required=True)
period_goals_id = fields.Many2one('kpi.period.notes',force_save=1,string='Period',tracking=True,)
department_id = fields.Many2one('hr.department',required=True,readonly=False,store=True,compute='compute_depart_job', tracking=True,string='Department')
job_id = fields.Many2one('hr.job',force_save=1,readonly=True,store=True, string='Job Title',related='employee_id.job_id',tracking=True,)
goals_mark = fields.Float(store=True,string='Goals Apprisal Mark',readonly=True,tracking=True)
skill_mark = fields.Float(store=True,string='Skills Apprisal Mark',readonly=True,tracking=True)
total_score = fields.Float(string='Total Mark',store=True,readonly=True,compute='compute_total_score',tracking=True)
apprisal_result = fields.Many2one('appraisal.result',string='Apprisal Result',store=True,tracking=True)
notes= fields.Text(string='Notes',required=False)
goal_ids = fields.One2many('years.employee.goals', 'employee_apprisal_id', string='Goals')
skill_ids = fields.One2many('skill.item.employee.table', 'employee_apprisal_id', string='Skills')
@api.constrains('employee_id', 'year_id')
def check_unique_employee_year_period_goals(self):
for record in self:
if self.search_count([
('employee_id', '=', record.employee_id.id),
('year_id', '=', record.year_id.id),
('id', '!=', record.id),
]) > 0:
raise exceptions.ValidationError(_("Employee Apprisal must be unique per Employee, Year, and Period!"))
@api.depends('skill_mark','goals_mark',)
def compute_total_score(self):
appraisal_result_list = []
for rec in self:
if rec.skill_mark and rec.goals_mark and rec.job_id.appraisal_percentages_id.percentage_kpi>0.0 and rec.job_id.appraisal_percentages_id.percentage_skills>0.0:
skill_mark_precentage = rec.skill_mark*rec.job_id.appraisal_percentages_id.percentage_skills
goal_mark_precentage = rec.goals_mark*rec.job_id.appraisal_percentages_id.percentage_kpi
rec.total_score = (skill_mark_precentage+goal_mark_precentage)
appraisal_result = self.env['appraisal.result'].search([
('result_from', '<', rec.total_score),
('result_to', '>=', rec.total_score)])
if rec.total_score and len(appraisal_result) > 1:
for line in appraisal_result:
appraisal_result_list.append(line.name)
raise exceptions.Warning(
_('Please check appraisal result configuration , there is more than result for '
'percentage %s are %s ') % (
round(rec.total_score, 2), appraisal_result_list))
else:
rec.appraisal_result = appraisal_result.id
def get_user_id(self):
employee_id = self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1)
if employee_id:
return employee_id.id
else:
return False
@api.depends('employee_id')
def compute_depart_job(self):
for rec in self:
if rec.employee_id:
rec.department_id = rec.employee_id.department_id.id
def compute_apprisal(self):
year_goal_obj = self.env['years.employee.goals'].search([('employee_id','=',self.employee_id.id),('year_id','=',self.year_id.id)])
if year_goal_obj:
print('if goal...........')
self.goal_ids = year_goal_obj.ids
#
sum2 = 0
for rec in self.goal_ids:
sum2 = sum2+ ((rec.weight*int(rec.choiec))/100)
self.goals_mark = sum2
#
item_lines=[(5,0,0)]
skill_apprisal = self.env['skill.appraisal'].search([('employee_id','=',self.employee_id.id),('year_id','=',self.year_id.id),('job_id','=',self.job_id.id)])
dic_item = {}
print('s a = ',skill_apprisal)
for obj in skill_apprisal:
for rec in obj.items_ids:
if rec.mark and rec.item_id:
if rec.item_id.name in dic_item:
dic_item[rec.item_id.name].append(rec.mark)
else:
dic_item.update({rec.item_id.name:[rec.mark]})
print('dic_item = ',dic_item)
averages = {}
for key, values in dic_item.items():
# Convert values to integers and calculate sum
total = sum(int(value) for value in values)
# Calculate average
avg = total / len(values)
# Store the average in the dictionary
averages[key] = avg
if self.job_id:
for line in self.job_id.item_job_ids:
line_item = {'item_id':line.item_id.id,'name':line.name,'level':line.level,}
if line.item_id.name in averages:
line_item.update({'mark_avg':averages[line.item_id.name]})
item_lines.append((0,0,line_item))
self.skill_ids = item_lines
# Calculate the average of averages
if len(averages)!=0:
average_of_averages = sum(averages.values()) / len(averages)
self.skill_mark = average_of_averages

View File

@ -0,0 +1,149 @@
from odoo import fields, models, exceptions, api, _
from odoo.exceptions import UserError, ValidationError
from lxml import etree
import json
class EmployeePerformanceEvaluation(models.Model):
_name = 'employee.performance.evaluation'
_rec_name = 'employee_id'
_inherit = ['mail.thread']
_description = "Employee performance evaluation"
recommendations = fields.Text(string='Recommendations', tracking=True, required=False)
total = fields.Float(string='Total Mark', readonly=True, store=True, tracking=True, )
mark_apprisal = fields.Float(string='Mark Apprisal', readonly=False, store=True, tracking=True,
compute='total_mark')
date_apprisal = fields.Date(default=lambda self: fields.Date.today(), string='Apprisal Date', tracking=True, )
employee_id = fields.Many2one('hr.employee', string='Employee', tracking=True, required=True)
manager_id = fields.Many2one('hr.employee', string='Employee m', readonly=False, tracking=True, required=False,
default=lambda item: item.get_user_id())
year_id = fields.Many2one(comodel_name='kpi.period', string='Year')
period_goals_id = fields.Many2one('kpi.period.notes', force_save=1, string='Period', tracking=True, )
department_id = fields.Many2one('hr.department', readonly=False, store=True, compute='compute_depart_job',
tracking=True, string='Department')
job_id = fields.Many2one('hr.job', force_save=1, readonly=True, store=True, string='Job Title',
related='employee_id.job_id', tracking=True, )
state = fields.Selection([
('draft', 'Draft'), ('dir_manager', 'Wait Employee Accept'),
('wait_dir_manager', 'Wait Manager Accept'),
('wait_hr_manager', 'Wait HR Manager Accept'),
('approve', 'Accept'),
('refuse', 'Refused')
], string='State', tracking=True, default='draft')
emp_goal_ids = fields.One2many(comodel_name='period.goals', inverse_name='employee_eval_id',
string='Employee Goals', copy=True)
@api.constrains('employee_id', 'year_id', 'period_goals_id')
def check_unique_employee_year_period_goals(self):
for record in self:
if self.search_count([
('employee_id', '=', record.employee_id.id),
('year_id', '=', record.year_id.id),
('period_goals_id', '=', record.period_goals_id.id),
('id', '!=', record.id),
]) > 0:
raise exceptions.ValidationError(
_("Employee Goals Apprisal must be unique per Employee, Year, and Period!"))
def get_user_id(self):
employee_id = self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1)
if employee_id:
return employee_id.id
else:
return False
@api.depends('employee_id')
def compute_depart_job(self):
for rec in self:
if rec.employee_id:
rec.department_id = rec.employee_id.department_id.id
@api.model
def fields_view_get(self, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
res = super(EmployeePerformanceEvaluation, self).fields_view_get(view_id=view_id, view_type=view_type,
toolbar=toolbar,
submenu=submenu)
doc = etree.XML(res['arch'])
emp_group = self.env.ref('exp_hr_appraisal.group_appraisal_employee').id
user_group = self.env.ref('exp_hr_appraisal.group_appraisal_user').id
manager_group = self.env.ref('exp_hr_appraisal.group_appraisal_manager').id
current_user_gids = self.env.user.groups_id.mapped('id')
if ((emp_group in current_user_gids) and (user_group not in current_user_gids) and (
manager_group not in current_user_gids)):
if view_type == 'tree' or view_type == 'form':
print('if node1.....')
# if view_type == 'tree':
for node in doc.xpath("//tree"):
print('if node.....')
node.set('create', 'false')
node.set('delete', 'false')
node.set('edit', 'false')
for node in doc.xpath("//form"):
node.set('create', 'false')
node.set('delete', 'false')
node.set('edit', 'false')
res['arch'] = etree.tostring(doc)
elif ((user_group in current_user_gids or manager_group in current_user_gids)):
if view_type == 'tree' or view_type == 'form':
print('if node2.....')
# if view_type == 'tree':
for node in doc.xpath("//tree"):
print('for..node')
node.set('create', 'true')
node.set('edit', 'true')
for node in doc.xpath("//form"):
node.set('create', 'true')
node.set('edit', 'true')
res['arch'] = etree.tostring(doc)
elif (
user_group in current_user_gids and manager_group in current_user_gids and emp_group in current_user_gids):
if view_type == 'tree' or view_type == 'form':
print('if node3.....')
# if view_type == 'tree':
for node in doc.xpath("//tree"):
print('for..node')
node.set('create', 'true')
node.set('edit', 'true')
for node in doc.xpath("//form"):
node.set('create', 'true')
node.set('edit', 'true')
res['arch'] = etree.tostring(doc)
return res
def send(self):
self.state = 'wait_dir_manager'
def reset_draft(self):
self.state = 'draft'
def action_approval(self):
if self.state == 'dir_manager':
self.state = 'wait_dir_manager'
elif self.state == 'wait_dir_manager':
self.state = 'wait_hr_manager'
else:
self.state = 'approve'
def action_refuse(self):
self.state = 'refuse'
def onchange_emp_goal_ids(self):
goals_lines = [(5, 0, 0)]
sum = 0
period_goal_obj = self.env['period.goals'].search(
[('period_goals_id', '=', self.period_goals_id.id), ('employee_id', '=', self.employee_id.id),
('year_id', '=', self.year_id.id)])
self.emp_goal_ids = period_goal_obj.ids
for rec in self.emp_goal_ids:
sum = sum + ((rec.weight * rec.mark_evaluation) / 100)
self.mark_apprisal = sum
def unlink(self):
for rec in self:
if rec.state != 'draft':
raise ValidationError(_("You can't delete a Goal apprisal not in Draft State , archive it instead."))
return super().unlink()

View File

@ -0,0 +1,150 @@
from odoo import fields, models, api,_
from lxml import etree
import json
from odoo.exceptions import MissingError, UserError, ValidationError, AccessError
class KPICategory(models.Model):
_inherit = 'kpi.category'
@api.model
def fields_view_get(self, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
res = super(KPICategory, self).fields_view_get(view_id=view_id, view_type=view_type, toolbar=toolbar,
submenu=submenu)
doc = etree.XML(res['arch'])
emp_group = self.env.ref('exp_hr_appraisal.group_appraisal_employee').id
user_group = self.env.ref('exp_hr_appraisal.group_appraisal_user').id
manager_group = self.env.ref('exp_hr_appraisal.group_appraisal_manager').id
current_user_gids = self.env.user.groups_id.mapped('id')
if ((emp_group in current_user_gids) and (user_group not in current_user_gids )and(manager_group not in current_user_gids)):
if view_type=='tree' or view_type=='form':
print('if node1.....')
# if view_type == 'tree':
for node in doc.xpath("//tree"):
print('if node.....')
node.set('create', 'false')
node.set('delete', 'false')
node.set('edit', 'false')
for node in doc.xpath("//form"):
node.set('create', 'false')
node.set('delete', 'false')
node.set('edit', 'false')
res['arch'] = etree.tostring(doc)
elif ((user_group in current_user_gids or manager_group in current_user_gids)):
if view_type=='tree' or view_type=='form':
print('if node2.....')
# if view_type == 'tree':
for node in doc.xpath("//tree"):
print('for..node')
node.set('create', 'true')
node.set('edit', 'true')
for node in doc.xpath("//form"):
node.set('create', 'true')
node.set('edit', 'true')
res['arch'] = etree.tostring(doc)
elif (user_group in current_user_gids and manager_group in current_user_gids and emp_group in current_user_gids):
if view_type=='tree' or view_type=='form':
print('if node3.....')
# if view_type == 'tree':
for node in doc.xpath("//tree"):
print('for..node')
node.set('create', 'true')
node.set('edit', 'true')
for node in doc.xpath("//form"):
node.set('create', 'true')
node.set('edit', 'true')
res['arch'] = etree.tostring(doc)
return res
class KPIitem(models.Model):
_inherit = 'kpi.item'
department_item_id = fields.Many2one(comodel_name='hr.department',string='Department')
responsible_item_id = fields.Many2one(comodel_name='hr.employee',string='Responsible')
mark_ids = fields.One2many(comodel_name='mark.mark',inverse_name='kip_id')
method_of_calculate = fields.Selection(
string='Method Of Calculate',
selection=[('accumulative', 'Accumulative'),
('avrerage', 'Average'),('undefined', 'Undefined'),],
required=False,default='accumulative')
@api.model
def fields_view_get(self, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
res = super(KPIitem, self).fields_view_get(view_id=view_id, view_type=view_type, toolbar=toolbar,
submenu=submenu)
doc = etree.XML(res['arch'])
emp_group = self.env.ref('exp_hr_appraisal.group_appraisal_employee').id
user_group = self.env.ref('exp_hr_appraisal.group_appraisal_user').id
manager_group = self.env.ref('exp_hr_appraisal.group_appraisal_manager').id
current_user_gids = self.env.user.groups_id.mapped('id')
if ((emp_group in current_user_gids) and (user_group not in current_user_gids )and(manager_group not in current_user_gids)):
if view_type=='tree' or view_type=='form':
print('if node1.....')
# if view_type == 'tree':
for node in doc.xpath("//tree"):
print('if node.....')
node.set('create', 'false')
node.set('delete', 'false')
node.set('edit', 'false')
for node in doc.xpath("//form"):
node.set('create', 'false')
node.set('delete', 'false')
node.set('edit', 'false')
res['arch'] = etree.tostring(doc)
elif ((user_group in current_user_gids or manager_group in current_user_gids)):
if view_type=='tree' or view_type=='form':
print('if node2.....')
# if view_type == 'tree':
for node in doc.xpath("//tree"):
print('for..node')
node.set('create', 'true')
node.set('edit', 'true')
for node in doc.xpath("//form"):
node.set('create', 'true')
node.set('edit', 'true')
res['arch'] = etree.tostring(doc)
elif (user_group in current_user_gids and manager_group in current_user_gids and emp_group in current_user_gids):
if view_type=='tree' or view_type=='form':
print('if node3.....')
# if view_type == 'tree':
for node in doc.xpath("//tree"):
print('for..node')
node.set('create', 'true')
node.set('edit', 'true')
for node in doc.xpath("//form"):
node.set('create', 'true')
node.set('edit', 'true')
res['arch'] = etree.tostring(doc)
return res
@api.onchange('department_item_id')
def onchange_responsible(self):
domain = []
if self.department_item_id:
# Define your dynamic domain based on field1's value
domain = [('department_id', '=', self.department_item_id.id)]
return {'domain': {'responsible_item_id': domain}}
class Marks(models.Model):
_name = 'mark.mark'
choiec = fields.Selection(string='Choiec',selection=[('1', '1'), ('2', '2'), ('3', '3'), ('4', '4'),('5','5'),])
target = fields.Float(string='From(Done)',)
to = fields.Float(string='To(Target)',)
kip_id = fields.Many2one(comodel_name='kpi.item',string='Kip_id')
@api.constrains('target', 'to', 'kip_id')
def _check_target_to_values(self):
for record in self:
if record.to <= record.target:
raise ValidationError(_('The To value must be greater than the From value.'))
# Get previous marks for the same KPI sorted by target
# previous_marks = self.env['mark.mark'].search([('kip_id', '=', record.kip_id.id), ('id', '!=', record.id)], order='target')
# for prev_mark in previous_marks:
# if record.target <= prev_mark.to:
# raise ValidationError(_('The From value must be greater than the previous To value.'))

View File

@ -0,0 +1,64 @@
from odoo import fields, models, api,_
from odoo.exceptions import ValidationError
from odoo import models, api, exceptions
from datetime import timedelta
class KPIPeriod(models.Model):
_inherit = 'kpi.period'
kpi_periods_ids = fields.One2many(
comodel_name='kpi.period.notes',
inverse_name='kpi_period_id',
ondelete='cascade') # Add this line to enable cascade deletion
kpi_goals_periods_ids = fields.One2many(
comodel_name='kpi.period.notes',
inverse_name='kpi_goal_period_id',
ondelete='cascade' ) # Add this line to enable cascade deletion
class KIPSkills (models.Model):
_name = 'kpi.period.notes'
name = fields.Char(string='Name',)
sequence = fields.Char(string='Sequence',)
date_start_k = fields.Date(string='Star Date',)
date_end_k = fields.Date(string='End Date',)
kpi_period_id = fields.Many2one(comodel_name='kpi.period',ondelete='cascade')
kpi_goal_period_id = fields.Many2one(comodel_name='kpi.period',ondelete='cascade')
def create_apprisal_goals_employee(self):
employee_objs = self.env['hr.employee'].search([('state','=','open')])
employee_id = self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1)
for item in self:
# Fill employee appraisal
for element in employee_objs:
appraisal_line = {
'employee_id': element.id,
'year_id': item.kpi_goal_period_id.id,
'department_id': element.department_id.id,
'job_id': element.job_id.id,
'manager_id': employee_id.id,
'date_apprisal': fields.Date.today(),
'period_goals_id': item.id,
}
line_id = self.env['employee.performance.evaluation'].create(appraisal_line)
line_id.onchange_emp_goal_ids()
@api.constrains('date_start_k','kpi_goal_period_id','date_end_k')
def _check_period_overlap(self):
print('in constriant..2222.........')
for record in self:
if record.kpi_goal_period_id:
periods = record.kpi_goal_period_id.kpi_goals_periods_ids.sorted(key=lambda r: r.date_start_k)
for i in range(1, len(periods)):
if periods[i-1].date_end_k >= periods[i].date_start_k:
raise ValidationError(_("Overlap detected between periods!"))
@api.constrains('date_start_k','kpi_period_id','date_end_k')
def _check_period_overlap2(self):
print('in constriant...........')
for record in self:
if record.kpi_period_id:
periods = record.kpi_period_id.kpi_periods_ids.sorted(key=lambda r: r.date_start_k)
for i in range(1, len(periods)):
if periods[i-1].date_end_k >= periods[i].date_start_k:
raise ValidationError(_("Overlap detected between periods!"))

View File

@ -0,0 +1,61 @@
from odoo import fields, models, api
class Skill(models.Model):
_name = 'skill.skill'
_inherit = ['mail.thread']
name = fields.Char(string='Name', required=True,tracking=True,)
description = fields.Text(string='Description',tracking=True,)
items_ids = fields.One2many('skill.item', 'skill_id', string='Items',tracking=True,)
class SkillItems(models.Model):
_name = 'skill.item'
skill_id = fields.Many2one('skill.skill', string='Skill',ondelete='cascade')
skill_appraisal_id = fields.Many2one(comodel_name='skill.appraisal')
name = fields.Char(string='Description')
level = fields.Selection([('beginner', '1'),('intermediate', '2'),('advanced', '3')],string='Level', default='beginner')
mark = fields.Selection([('1', '1'),('2', '2'),('3', '3'),('4', '4'),('5', '5')],string='Mark',Ccopy=False)
mark_avg = fields.Float(string='Mark',Ccopy=False)
item_id = fields.Many2one(comodel_name='item.item',string='Item')
display_type = fields.Selection([
('line_section', "Section"),
('line_note', "Note")],default=False, help="Technical field for UX purpose.")
employee_apprisal_id = fields.Many2one(
comodel_name='hr.employee.appraisal')
sequence = fields.Integer(string='Sequence', default=10)
class SkillItems(models.Model):
_name = 'skill.item.table'
skill_id = fields.Many2one('skill.skill', string='Skill')
skill_appraisal_id = fields.Many2one(comodel_name='skill.appraisal',ondelete='cascade')
name = fields.Char(string='Description')
level = fields.Selection([('beginner', '1'),('intermediate', '2'),('advanced', '3')],string='Level', default='beginner')
mark = fields.Selection([('1', '1'),('2', '2'),('3', '3'),('4', '4'),('5', '5')],string='Mark',Ccopy=False)
mark_avg = fields.Float(string='Mark',Ccopy=False)
item_id = fields.Many2one(comodel_name='item.item',string='Item')
employee_apprisal_id = fields.Many2one(
comodel_name='hr.employee.appraisal')
class SkillItems(models.Model):
_name = 'skill.item.employee.table'
skill_id = fields.Many2one('skill.skill', string='Skill')
skill_appraisal_id = fields.Many2one(comodel_name='skill.appraisal',ondelete='cascade')
name = fields.Char(string='Description')
level = fields.Selection([('beginner', '1'),('intermediate', '2'),('advanced', '3')],string='Level', default='beginner')
mark = fields.Selection([('1', '1'),('2', '2'),('3', '3'),('4', '4'),('5', '5')],string='Mark',Ccopy=False)
mark_avg = fields.Float(string='Mark',Ccopy=False)
item_id = fields.Many2one(comodel_name='item.item',string='Item')
employee_apprisal_id = fields.Many2one(
comodel_name='hr.employee.appraisal')
class SkillItem(models.Model):
_name = 'item.item'
name = fields.Char(string='Name')
class SkillJob(models.Model):
_inherit = 'hr.job'
item_job_ids = fields.Many2many('skill.item', 'merge_item_skill1_rel', 'merge1_id', 'item1_id', string='Skills')
# appraisal_percentage_id = fields.Many2one(comodel_name='job.class.apprisal',string='Appraisal Percentage')
appraisal_percentages_id = fields.Many2one(comodel_name='job.class.apprisal',string='Appraisal Percentage')

View File

@ -0,0 +1,141 @@
from odoo import fields, models,exceptions, api,_
from odoo.exceptions import UserError,ValidationError
from lxml import etree
import json
class SkillAppraisal(models.Model):
_name = 'skill.appraisal'
_inherit = ['mail.thread']
_rec_name = 'employee_id'
_description = 'Skill Appraisal'
name= fields.Char(string='Name',tracking=True,)
recommendations= fields.Text(string='Recommendations',tracking=True,required=False)
date_apprisal = fields.Date(default=lambda self: fields.Date.today(),string='Apprisal Date',tracking=True,)
employee_id = fields.Many2one('hr.employee', string='Employee',tracking=True,required=True)
manager_id = fields.Many2one('hr.employee', string='Manager',readonly=False,tracking=True,required=True,default=lambda item: item.get_user_id())
period = fields.Many2one('kpi.period.notes',string='Period',tracking=True,)
department_id = fields.Many2one('hr.department',readonly=True,store=True,compute='compute_depart_job', tracking=True,string='Department')
job_id = fields.Many2one('hr.job',readonly=False,store=True, string='Job Title',tracking=True,)
year_id = fields.Many2one(comodel_name='kpi.period',string='Year')
@api.constrains('employee_id', 'year_id', 'period')
def check_unique_employee_year_period_skills(self):
for record in self:
if self.search_count([
('employee_id', '=', record.employee_id.id),
('year_id', '=', record.year_id.id),
('period', '=', record.period.id),
('id', '!=', record.id),
]) > 0:
raise exceptions.ValidationError(_("Employee Skill Apprisal must be unique per Employee, Year, and Period!"))
state = fields.Selection([
('draft', 'Draft'),('dir_manager', 'Wait Employee Accept'),
('wait_dir_manager', 'Wait Manager Accept'),
('wait_hr_manager', 'Wait HR Manager Accept'),
('approve', 'Accept'),
('refuse', 'Refused')
], string='State',tracking=True,default='draft')
avarage = fields.Float(string='Result',readonly=True,store=True,tracking=True,compute='calc_avg')
items_ids = fields.One2many(comodel_name='skill.item.table',inverse_name='skill_appraisal_id',string='Items',copy=True)
@api.model
def fields_view_get(self, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
res = super(SkillAppraisal, self).fields_view_get(view_id=view_id, view_type=view_type, toolbar=toolbar,
submenu=submenu)
doc = etree.XML(res['arch'])
emp_group = self.env.ref('exp_hr_appraisal.group_appraisal_employee').id
user_group = self.env.ref('exp_hr_appraisal.group_appraisal_user').id
manager_group = self.env.ref('exp_hr_appraisal.group_appraisal_manager').id
current_user_gids = self.env.user.groups_id.mapped('id')
if ((emp_group in current_user_gids) and (user_group not in current_user_gids )and(manager_group not in current_user_gids)):
if view_type=='tree' or view_type=='form':
print('if node1.....')
# if view_type == 'tree':
for node in doc.xpath("//tree"):
print('if node.....')
node.set('create', 'false')
node.set('delete', 'false')
node.set('edit', 'false')
for node in doc.xpath("//form"):
node.set('create', 'false')
node.set('delete', 'false')
node.set('edit', 'false')
res['arch'] = etree.tostring(doc)
elif ((user_group in current_user_gids or manager_group in current_user_gids)):
if view_type=='tree' or view_type=='form':
print('if node2.....')
# if view_type == 'tree':
for node in doc.xpath("//tree"):
print('for..node')
node.set('create', 'true')
node.set('edit', 'true')
for node in doc.xpath("//form"):
node.set('create', 'true')
node.set('edit', 'true')
res['arch'] = etree.tostring(doc)
elif (user_group in current_user_gids and manager_group in current_user_gids and emp_group in current_user_gids):
if view_type=='tree' or view_type=='form':
print('if node3.....')
# if view_type == 'tree':
for node in doc.xpath("//tree"):
print('for..node')
node.set('create', 'true')
node.set('edit', 'true')
for node in doc.xpath("//form"):
node.set('create', 'true')
node.set('edit', 'true')
res['arch'] = etree.tostring(doc)
return res
def get_user_id(self):
employee_id = self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1)
if employee_id:
return employee_id.id
else:
return False
@api.depends('employee_id')
def compute_depart_job(self):
for rec in self:
if rec.employee_id:
rec.department_id = rec.employee_id.department_id.id
rec.job_id = rec.employee_id.job_id.id
@api.depends('items_ids.mark')
def calc_avg(self):
sum = 0
for rec in self.items_ids:
if rec.mark and len(self.items_ids)!=0:
sum = sum+int(rec.mark)
self.avarage = sum/len(self.items_ids)
def send(self):
self.state = 'dir_manager'
def reset_draft(self):
self.state = 'draft'
def action_approval(self):
if self.state=='dir_manager':
self.state='wait_dir_manager'
elif self.state=='wait_dir_manager':
self.state='wait_hr_manager'
else:
self.state='approve'
def action_refuse(self):
self.state = 'refuse'
@api.onchange('job_id','employee_id')
def onchange_emp(self):
item_lines=[(5,0,0)]
for line in self.job_id.item_job_ids:
line_item = {'item_id':line.item_id.id,'name':line.name,'level':line.level}
item_lines.append((0,0,line_item))
self.items_ids = item_lines
def unlink(self):
for rec in self:
if rec.state != 'draft':
raise ValidationError(_("You can't delete a Skill apprisal not in Draft State , archive it instead."))
return super().unlink()

View File

@ -0,0 +1,220 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import fields, models, api,exceptions,_
class Period(models.Model):
_name = 'period.goals'
period_goals_id = fields.Many2one('kpi.period.notes', domain=[('kpi_period_id','=',False)], string='Period Of Goals', tracking=True)
employee_goals_id = fields.Many2one('years.employee.goals')
target = fields.Float(string='Target', store=True)
done = fields.Float(string='Done')
kpi_id = fields.Many2one(comodel_name='kpi.item', string='KPI', related='employee_goals_id.kpi_id')
employee_eval_id = fields.Many2one(comodel_name='employee.performance.evaluation', string='KPI')
weight = fields.Float(string='Weight', related='employee_goals_id.weight')
mark_evaluation = fields.Integer(string='Evaluation Mark', store=True, compute='_compute_mark_evaluation')
year_id = fields.Many2one(comodel_name='kpi.period', related='employee_goals_id.year_id')
employee_id = fields.Many2one(comodel_name='hr.employee', related='employee_goals_id.employee_id')
@api.depends('done', 'target', 'kpi_id')
def _compute_mark_evaluation(self):
sum = 0
for record in self:
if record.done!=0.0 and record.target!=0.0 and record.kpi_id:
done_percentage = (record.done / record.target) * 100
marks = self.env['mark.mark'].search([('kip_id', '=', record.kpi_id.id)])
if marks:
# Finding the closest mark where the done_percentage fits into the target-to range
closest_mark = min(
marks,
key=lambda x: abs(done_percentage - ((x.target + x.to) / 2))
)
if closest_mark.target <= done_percentage <= closest_mark.to:
record.mark_evaluation = int(closest_mark.choiec)
closest_mark = None
for mark in marks:
if mark.target <= done_percentage <= mark.to:
record.mark_evaluation = mark.choiec
break
else:
record.mark_evaluation = 0 # Or any other default value if fields are empty
sum = sum+ ((record.weight*record.mark_evaluation)/100)
record.employee_eval_id.mark_apprisal = sum
class YearEmployeeGoals(models.Model):
_name = 'years.employee.goals'
_inherit = ['mail.thread']
_description = 'years employee goals'
_rec_name = 'employee_id'
employee_id = fields.Many2one('hr.employee', string='Employee',tracking=True,required=True)
year_id = fields.Many2one(comodel_name='kpi.period',string='Year')
category_id = fields.Many2one(comodel_name='kpi.category',string='Category')
kpi_id = fields.Many2one(comodel_name='kpi.item',string='KPI',)
method_of_calculate = fields.Selection(related='kpi_id.method_of_calculate')
responsible_item_id = fields.Many2one(comodel_name='hr.employee',related='kpi_id.responsible_item_id',store=True,string='Responsible')
user_id = fields.Many2one(comodel_name='res.users',related='responsible_item_id.user_id',store=True,string='Responsible')
department_id = fields.Many2one('hr.department',readonly=True,store=True,compute='compute_depart_job', tracking=True,string='Department')
job_id = fields.Many2one('hr.job',readonly=True,store=True,compute='compute_depart_job', string='Job Title',tracking=True,)
year_target = fields.Float(string='Year Target')
weight = fields.Float(string='Weight')
goals_period_ids = fields.One2many(comodel_name='period.goals',inverse_name='employee_goals_id',string='Period',copy=False)
done = fields.Float(string='Done',store=True,compute='total_done')
state = fields.Selection([('draft', 'Draft'),('apprisal', 'Apprisal'),('close', 'Close')], string='State',tracking=True,default='draft')
choiec = fields.Integer(string='Choiec',store=True,compute='compute_choice')
employee_apprisal_id = fields.Many2one(comodel_name='hr.employee.appraisal')
first_period_traget = fields.Float(compute='_compute_first_period_traget', string='First Period Traget',
inverse='_inverse_first_period_traget')
second_period_traget = fields.Float(compute='_compute_second_period_traget', string='Second Period Traget',
inverse='_inverse_second_period_traget')
third_period_traget = fields.Float(compute='_compute_third_period_traget', string='Third Period Traget',
inverse='_inverse_third_period_traget')
fourth_period_traget = fields.Float(compute='_compute_fourth_period_traget', string='Fourth Period Traget',
inverse='_inverse_fourth_period_traget')
def _compute_first_period_traget(self):
for rec in self:
rec.first_period_traget = 0.0
first_period = rec.goals_period_ids.filtered(lambda period: period.period_goals_id.sequence == '1')
if first_period:
rec.first_period_traget = first_period.target
def _inverse_first_period_traget(self):
for rec in self:
first_period = rec.goals_period_ids.filtered(lambda period: period.period_goals_id.sequence == '1')
if first_period:
first_period.sudo().target = rec.first_period_traget
else:
if rec.year_id:
first_period = rec.year_id.kpi_goals_periods_ids.filtered(lambda period: period.sequence == '1')
if first_period:
rec.goals_period_ids = [(0, 0, {'period_goals_id':first_period.id,'target':rec.first_period_traget})]
def _compute_second_period_traget(self):
for rec in self:
rec.second_period_traget = 0.0
second_period = rec.goals_period_ids.filtered(lambda period: period.period_goals_id.sequence == '2')
if second_period:
rec.second_period_traget = second_period.target
def _inverse_second_period_traget(self):
for rec in self:
second_period = rec.goals_period_ids.filtered(lambda period: period.period_goals_id.sequence == '2')
if second_period:
second_period.sudo().target = rec.second_period_traget
else:
if rec.year_id:
second_period = rec.year_id.kpi_goals_periods_ids.filtered(lambda period: period.sequence == '2')
if second_period:
rec.goals_period_ids = [(0, 0, {'period_goals_id':second_period.id,'target':rec.second_period_traget})]
def _compute_third_period_traget(self):
for rec in self:
rec.third_period_traget = 0.0
third_period = rec.goals_period_ids.filtered(lambda period: period.period_goals_id.sequence == '3')
if third_period:
rec.third_period_traget = third_period.target
def _inverse_third_period_traget(self):
for rec in self:
third_period = rec.goals_period_ids.filtered(lambda period: period.period_goals_id.sequence == '3')
if third_period:
third_period.sudo().target = rec.third_period_traget
else:
if rec.year_id:
third_period = rec.year_id.kpi_goals_periods_ids.filtered(lambda period: period.sequence == '3')
if third_period:
rec.goals_period_ids = [(0, 0, {'period_goals_id':third_period.id,'target':rec.third_period_traget})]
def _compute_fourth_period_traget(self):
for rec in self:
rec.fourth_period_traget = 0.0
fourth_period = rec.goals_period_ids.filtered(lambda period: period.period_goals_id.sequence == '4')
if fourth_period:
rec.fourth_period_traget = fourth_period.target
def _inverse_fourth_period_traget(self):
for rec in self:
fourth_period = rec.goals_period_ids.filtered(lambda period: period.period_goals_id.sequence == '4')
if fourth_period:
fourth_period.sudo().target = rec.fourth_period_traget
else:
if rec.year_id:
fourth_period = rec.year_id.kpi_goals_periods_ids.filtered(lambda period: period.sequence == '4')
if fourth_period:
rec.goals_period_ids = [(0, 0, {'period_goals_id':fourth_period.id,'target':rec.fourth_period_traget})]
@api.model
def search(self, args, offset=0, limit=None, order=None, count=False):
# add domain filter to only show records related to login responsible_item_id employee
if self.env.user.has_group("exp_hr_appraisal_kpi.group_appraisal_responsabil") and not self.env.user.has_group("exp_hr_appraisal.group_appraisal_manager") and not self.env.user.has_group("exp_hr_appraisal.group_appraisal_user") :
args += [('user_id','=',self.env.user.id)]
return super (YearEmployeeGoals,self).search(args,offset,limit,order,count)
@api.depends('goals_period_ids.done','goals_period_ids.target','method_of_calculate')
def total_done(self):
for rec in self:
if rec.method_of_calculate=='accumulative':
sum=0
for record in rec.goals_period_ids:
sum = sum+record.done
rec.done = sum
elif rec.method_of_calculate=='avrerage':
sum=0
for record in rec.goals_period_ids:
sum = (sum+record.done)
rec.done = sum/len(rec.goals_period_ids)
else:
rec.done=0.0
@api.depends('goals_period_ids.done','done','goals_period_ids.target','method_of_calculate')
def compute_choice(self):
for rec in self:
choice = 0
if rec.done!=0.0 and rec.year_target!=0.0 and rec.kpi_id:
done_percentage = (rec.done / rec.year_target) * 100
marks = self.env['mark.mark'].search([('kip_id', '=', rec.kpi_id.id),('target','<=',done_percentage),('to','>=',done_percentage)],limit=1)
if marks:
choice = marks.choiec
rec.choiec = int(choice)
def apprisal(self):
self.state='apprisal'
def action_close(self):
self.state='close'
def action_set_to_dratt(self):
self.state='draft'
@api.constrains('employee_id', 'year_id', 'kpi_id')
def check_unique_employee_year_period_goals(self):
for record in self:
if self.search_count([
('employee_id', '=', record.employee_id.id),
('year_id', '=', record.year_id.id),
('kpi_id', '=', record.kpi_id.id),
('id', '!=', record.id),
]) > 0:
raise exceptions.ValidationError(_("Employee Goals must be unique per Employee, Year, and kpi!"))
@api.depends('employee_id')
def compute_depart_job(self):
for rec in self:
if rec.employee_id:
rec.department_id = rec.employee_id.department_id.id
rec.job_id = rec.employee_id.job_id.id
@api.onchange('year_id')
def onchange_emp(self):
goals_lines=[(5,0,0)]
if self.year_id:
for line in self.year_id.kpi_goals_periods_ids:
line_item = {'period_goals_id':line.id}
goals_lines.append((0,0,line_item))
self.goals_period_ids = goals_lines

View File

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<data>
<record id="apprisal_kpi_group" model="res.groups">
<field name="name">Menu apprisal hide/show</field>
</record>
<record id="group_appraisal_responsabil" model="res.groups">
<field name="name">Goals Responsible</field>
<field name="category_id" ref="exp_hr_appraisal.module_category_hr_appraisal"/>
<field name="implied_ids" eval="[(4, ref('base.group_user')),(4, ref('exp_hr_appraisal.group_appraisal_employee'))]"/>
</record>
<record id="extended_kpi_category_rule" model="ir.rule">
<field name="name">Extended KPI Category Rule</field>
<field name="model_id" ref="kpi_scorecard.model_kpi_category"/>
<field name="domain_force">[
'|',
('company_id','=', False),
('company_id', 'in', company_ids),
]
</field>
<field name="groups"
eval="[(4, ref('base.group_user')), (4, ref('exp_hr_appraisal.group_appraisal_employee')),(4, ref('exp_hr_appraisal.group_appraisal_manager')),(4, ref('exp_hr_appraisal.group_appraisal_user'))]"/>
</record>
<record id="extended_kpi_item_rule" model="ir.rule">
<field name="name">Extended KPI Category Rule</field>
<field name="model_id" ref="kpi_scorecard.model_kpi_item"/>
<field name="domain_force">[
'|',
('company_id','=', False),
('company_id', 'in', company_ids),
]
</field>
<field name="groups"
eval="[(4, ref('base.group_user')), (4, ref('exp_hr_appraisal.group_appraisal_employee')),(4, ref('exp_hr_appraisal.group_appraisal_manager')),(4, ref('exp_hr_appraisal.group_appraisal_user'))]"/>
</record>
<!--add record rule for skill apprisal,employee apprisal -->
<record id="hr_employee_appraisal_kpi_employee_rule" model="ir.rule">
<field name="name">Employee: views its Skill appraisals only</field>
<field name="model_id" ref="model_skill_appraisal"/>
<field name="domain_force">[('employee_id.user_id','=',user.id)]</field>
<field name="groups" eval="[(4, ref('base.group_user'))]"/>
</record>
<record id="hr_employee_appraisal_goal_kpi_employee_rule" model="ir.rule">
<field name="name">Employee: views its Goal appraisals only</field>
<field name="model_id" ref="model_employee_performance_evaluation"/>
<field name="domain_force">[('employee_id.user_id','=',user.id)]</field>
<field name="groups" eval="[(4, ref('base.group_user'))]"/>
</record>
<record id="hr_employee_kpi_appraisal_manager_rule" model="ir.rule">
<field name="name">Manager: views Skill appraisals of its subordinates</field>
<field name="model_id" ref="model_skill_appraisal"/>
<field name="domain_force">['|','|',('employee_id.department_id.manager_id','=',False),
('employee_id.department_id.manager_id.user_id','in', [user.id]),
('employee_id.department_id.parent_id.manager_id.user_id','in', [user.id])]
</field>
<field name="groups"
eval="[(4, ref('hr_base.group_department_manager')),(4, ref('hr_base.group_division_manager'))]"/>
</record>
<record id="hr_employee_kpi_appraisal_goals_manager_rule" model="ir.rule">
<field name="name">Manager: views Goals appraisals of its subordinates</field>
<field name="model_id" ref="model_employee_performance_evaluation"/>
<field name="domain_force">['|','|',('employee_id.department_id.manager_id','=',False),
('employee_id.department_id.manager_id.user_id','in', [user.id]),
('employee_id.department_id.parent_id.manager_id.user_id','in', [user.id])]
</field>
<field name="groups"
eval="[(4, ref('hr_base.group_department_manager')),(4, ref('hr_base.group_division_manager'))]"/>
</record>
<record id="hr_employee_skill_appraisal_all_rule" model="ir.rule">
<field name="name"> Manager: views Skills appraisals of all subordinates </field>
<field name="model_id" ref="model_employee_performance_evaluation"/>
<field name="domain_force">[(1 ,'=', 1)]</field>
<field name="groups" eval="[(4, ref('hr_base.group_executive_manager')),
(4, ref('hr_base.group_general_manager')),
(4, ref('exp_hr_appraisal.group_appraisal_manager')),
(4, ref('hr.group_hr_user'))]"/>
</record>
<record id="hr_employee_goal_appraisal_all_rule" model="ir.rule">
<field name="name"> Manager: views Goals appraisals of all subordinates </field>
<field name="model_id" ref="model_skill_appraisal"/>
<field name="domain_force">[(1 ,'=', 1)]</field>
<field name="groups" eval="[(4, ref('hr_base.group_executive_manager')),
(4, ref('hr_base.group_general_manager')),
(4, ref('exp_hr_appraisal.group_appraisal_manager')),
(4, ref('hr.group_hr_user'))]"/>
</record>
<!--#################################################################################################################################################################-->
<!-- end -->
</data>
</odoo>

View File

@ -0,0 +1,71 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_mark2,access_marks2,model_mark_mark,base.group_user,1,1,1,1
access_mark3,access_marks3,model_mark_mark,exp_hr_appraisal.group_appraisal_employee,1,1,1,1
access_mark4,access_marks4,model_mark_mark,exp_hr_appraisal.group_appraisal_manager,1,1,1,1
access_mark5,access_marks5,model_mark_mark,exp_hr_appraisal.group_appraisal_user,1,1,1,1
access_kpi_p7,access_kpi_ps8,model_kpi_period_notes,base.group_user,1,1,1,1
access_kpi_p7,access_kpi_ps8,model_kpi_period_notes,exp_hr_appraisal.group_appraisal_manager,1,1,1,1
access_kpi_p7,access_kpi_ps8,model_kpi_period_notes,exp_hr_appraisal.group_appraisal_user,1,1,1,1
access_kpi_p7,access_kpi_ps8,model_kpi_period_notes,exp_hr_appraisal.group_appraisal_employee,1,1,1,1
access_kpi_p535,access_kpi_ps185,model_skill_skill,exp_hr_appraisal.group_appraisal_manager,1,1,1,1
access_kpi_p535,access_kpi_ps185,model_skill_skill,exp_hr_appraisal.group_appraisal_user,1,1,1,1
access_kpi_p54435,access_kpi_ps18555,model_skill_item,base.group_user,1,1,1,1
access_kpi_p544355,access_kpi_ps189555,model_skill_item_table,base.group_user,1,1,1,1
access_kpi_p544385,access_kpi_ps179555,model_skill_item_employee_table,base.group_user,1,1,1,1
access_kpi_p53577,access_kpi_ps17785,model_item_item,base.group_user,1,1,1,1
access_kpi_p53577,access_kpi_ps17785,model_item_item,exp_hr_appraisal.group_appraisal_user,1,1,1,1
access_kpi_p53577,access_kpi_ps17785,model_item_item,exp_hr_appraisal.group_appraisal_manager,1,1,1,1
access_kpi_p53577,access_kpi_ps17785,model_item_item,exp_hr_appraisal.group_appraisal_employee,1,1,1,1
access_kpi_p5357b7p,access_kpbi_ps17785p,model_skill_appraisal,base.group_user,1,1,1,1
access_kpi_p5357b7,access_kpbi_ps17785,model_skill_appraisal,exp_hr_appraisal.group_appraisal_manager,1,1,1,1
access_kpi_p5357b7,access_kpbi_ps17785,model_skill_appraisal,exp_hr_appraisal.group_appraisal_user,1,1,1,1
access_kpi_p5357b7,access_kpbi_ps17785,model_skill_appraisal,exp_hr_appraisal.group_appraisal_employee,1,0,0,1
access_kpi_p5357b7d,access_kpbi_ps1778d5,model_skill_appraisal,hr_base.group_division_manager,1,1,1,1
access_kpi_p535d7b7,access_kpbi_ps17d785,model_skill_appraisal,hr_base.group_department_manager,1,1,1,1
access_kpi_p5357bd7,access_kpbi_ps1778d5,model_skill_appraisal,hr.group_hr_user,1,1,1,0
access_kpi_emp_performansel1,access_kpbi_emp_perfomance_evalution39,model_employee_performance_evaluation,base.group_user,1,1,1,0
access_kpi_emp_performanse1,access_kpbi_emp_perfomance_evalution3,model_employee_performance_evaluation,exp_hr_appraisal.group_appraisal_manager,1,1,1,1
access_kpi_emp_performanse1,access_kpbi_emp_perfomance_evalution3,model_employee_performance_evaluation,exp_hr_appraisal.group_appraisal_user,1,1,1,1
access_kpi_emp_performanse1,access_kpbi_emp_perfomance_evalution3,model_employee_performance_evaluation,exp_hr_appraisal.group_appraisal_employee,1,0,0,1
access_kpi_emp_performanse11,access_kpbi_emp_perfomance_evalution33,model_employee_performance_evaluation,hr_base.group_division_manager,1,1,1,1
access_kpi_emp_performanse12,access_kpbi_emp_perfomance_evalutionr3,model_employee_performance_evaluation,hr_base.group_department_manager,1,1,1,1
access_kpi_emp_performanse13,access_kpbi_emp_perfomance_evalution53,model_employee_performance_evaluation,hr.group_hr_user,1,1,1,0
access_kpi_emp_goals_res,access_kpbi_emp_goals1_res,model_years_employee_goals,exp_hr_appraisal_kpi.group_appraisal_responsabil,1,1,1,0
access_kpi_emp_goals11,access_kpbi_emp_goals1,model_years_employee_goals,base.group_user,1,1,1,0
access_kpi_emp_goals1,access_kpbi_emp_goals11,model_years_employee_goals,exp_hr_appraisal.group_appraisal_manager,1,1,1,1
access_kpi_emp_goals5,access_kpbi_emp_goals151,model_years_employee_goals,exp_hr_appraisal.group_appraisal_user,1,1,1,0
access_kpi_emp_goals,access_kpbi_emp_goals1,model_years_employee_goals,hr_base.group_department_manager,1,1,0,0
access_kpi_emp_goals_period,access_kpbi_emp_period1,model_period_goals,base.group_user,1,1,1,1
access_kpi_perecentage,access_kpbi_perecentage1,model_job_class_apprisal,base.group_user,1,1,1,1
access_kpi_category,access_kpi_category,kpi_scorecard.model_kpi_category,base.group_user,1,1,1,1
access_kpi_category,access_kpbi_category1,kpi_scorecard.model_kpi_category,kpi_scorecard.group_kpi_admin,1,1,1,1
access_kpi_category,access_kpbi_category1,kpi_scorecard.model_kpi_category,exp_hr_appraisal.group_appraisal_manager,1,1,1,1
access_kpi_category1,access_kpbi_category2,kpi_scorecard.model_kpi_category,exp_hr_appraisal.group_appraisal_user,1,1,1,0
access_kpi_category21,access_kpbi_category25,kpi_scorecard.model_kpi_category,exp_hr_appraisal.group_appraisal_employee,1,0,0,0
access_kpi_period,access_kpbi_period1,kpi_scorecard.model_kpi_period,base.group_user,1,0,0,0
access_kpi_period,access_kpbi_period1,kpi_scorecard.model_kpi_period,kpi_scorecard.group_kpi_admin,1,1,1,1
access_kpi_period,access_kpbi_period1,kpi_scorecard.model_kpi_period,exp_hr_appraisal.group_appraisal_manager,1,1,1,1
access_kpi_category1,access_kpbi_period2,kpi_scorecard.model_kpi_period,exp_hr_appraisal.group_appraisal_user,1,1,1,0
access_kpi_category21,access_kpbi_period25,kpi_scorecard.model_kpi_period,exp_hr_appraisal.group_appraisal_employee,1,0,0,0
access_kpi_item,access_kpbi_item1,kpi_scorecard.model_kpi_item,base.group_user,1,0,0,0
access_kpi_item,access_kpbi_item1,kpi_scorecard.model_kpi_item,kpi_scorecard.group_kpi_admin,1,1,1,1
access_kpi_item,access_kpbi_item1,kpi_scorecard.model_kpi_item,exp_hr_appraisal.group_appraisal_manager,1,1,1,1
access_kpi_item1,access_item2,kpi_scorecard.model_kpi_item,exp_hr_appraisal.group_appraisal_user,1,1,1,0
access_kpi_item21,access_kpbi_item25,kpi_scorecard.model_kpi_item,exp_hr_appraisal.group_appraisal_employee,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_mark2 access_marks2 model_mark_mark base.group_user 1 1 1 1
3 access_mark3 access_marks3 model_mark_mark exp_hr_appraisal.group_appraisal_employee 1 1 1 1
4 access_mark4 access_marks4 model_mark_mark exp_hr_appraisal.group_appraisal_manager 1 1 1 1
5 access_mark5 access_marks5 model_mark_mark exp_hr_appraisal.group_appraisal_user 1 1 1 1
6 access_kpi_p7 access_kpi_ps8 model_kpi_period_notes base.group_user 1 1 1 1
7 access_kpi_p7 access_kpi_ps8 model_kpi_period_notes exp_hr_appraisal.group_appraisal_manager 1 1 1 1
8 access_kpi_p7 access_kpi_ps8 model_kpi_period_notes exp_hr_appraisal.group_appraisal_user 1 1 1 1
9 access_kpi_p7 access_kpi_ps8 model_kpi_period_notes exp_hr_appraisal.group_appraisal_employee 1 1 1 1
10 access_kpi_p535 access_kpi_ps185 model_skill_skill exp_hr_appraisal.group_appraisal_manager 1 1 1 1
11 access_kpi_p535 access_kpi_ps185 model_skill_skill exp_hr_appraisal.group_appraisal_user 1 1 1 1
12 access_kpi_p54435 access_kpi_ps18555 model_skill_item base.group_user 1 1 1 1
13 access_kpi_p544355 access_kpi_ps189555 model_skill_item_table base.group_user 1 1 1 1
14 access_kpi_p544385 access_kpi_ps179555 model_skill_item_employee_table base.group_user 1 1 1 1
15 access_kpi_p53577 access_kpi_ps17785 model_item_item base.group_user 1 1 1 1
16 access_kpi_p53577 access_kpi_ps17785 model_item_item exp_hr_appraisal.group_appraisal_user 1 1 1 1
17 access_kpi_p53577 access_kpi_ps17785 model_item_item exp_hr_appraisal.group_appraisal_manager 1 1 1 1
18 access_kpi_p53577 access_kpi_ps17785 model_item_item exp_hr_appraisal.group_appraisal_employee 1 1 1 1
19 access_kpi_p5357b7p access_kpbi_ps17785p model_skill_appraisal base.group_user 1 1 1 1
20 access_kpi_p5357b7 access_kpbi_ps17785 model_skill_appraisal exp_hr_appraisal.group_appraisal_manager 1 1 1 1
21 access_kpi_p5357b7 access_kpbi_ps17785 model_skill_appraisal exp_hr_appraisal.group_appraisal_user 1 1 1 1
22 access_kpi_p5357b7 access_kpbi_ps17785 model_skill_appraisal exp_hr_appraisal.group_appraisal_employee 1 0 0 1
23 access_kpi_p5357b7d access_kpbi_ps1778d5 model_skill_appraisal hr_base.group_division_manager 1 1 1 1
24 access_kpi_p535d7b7 access_kpbi_ps17d785 model_skill_appraisal hr_base.group_department_manager 1 1 1 1
25 access_kpi_p5357bd7 access_kpbi_ps1778d5 model_skill_appraisal hr.group_hr_user 1 1 1 0
26 access_kpi_emp_performansel1 access_kpbi_emp_perfomance_evalution39 model_employee_performance_evaluation base.group_user 1 1 1 0
27 access_kpi_emp_performanse1 access_kpbi_emp_perfomance_evalution3 model_employee_performance_evaluation exp_hr_appraisal.group_appraisal_manager 1 1 1 1
28 access_kpi_emp_performanse1 access_kpbi_emp_perfomance_evalution3 model_employee_performance_evaluation exp_hr_appraisal.group_appraisal_user 1 1 1 1
29 access_kpi_emp_performanse1 access_kpbi_emp_perfomance_evalution3 model_employee_performance_evaluation exp_hr_appraisal.group_appraisal_employee 1 0 0 1
30 access_kpi_emp_performanse11 access_kpbi_emp_perfomance_evalution33 model_employee_performance_evaluation hr_base.group_division_manager 1 1 1 1
31 access_kpi_emp_performanse12 access_kpbi_emp_perfomance_evalutionr3 model_employee_performance_evaluation hr_base.group_department_manager 1 1 1 1
32 access_kpi_emp_performanse13 access_kpbi_emp_perfomance_evalution53 model_employee_performance_evaluation hr.group_hr_user 1 1 1 0
33 access_kpi_emp_goals_res access_kpbi_emp_goals1_res model_years_employee_goals exp_hr_appraisal_kpi.group_appraisal_responsabil 1 1 1 0
34 access_kpi_emp_goals11 access_kpbi_emp_goals1 model_years_employee_goals base.group_user 1 1 1 0
35 access_kpi_emp_goals1 access_kpbi_emp_goals11 model_years_employee_goals exp_hr_appraisal.group_appraisal_manager 1 1 1 1
36 access_kpi_emp_goals5 access_kpbi_emp_goals151 model_years_employee_goals exp_hr_appraisal.group_appraisal_user 1 1 1 0
37 access_kpi_emp_goals access_kpbi_emp_goals1 model_years_employee_goals hr_base.group_department_manager 1 1 0 0
38 access_kpi_emp_goals_period access_kpbi_emp_period1 model_period_goals base.group_user 1 1 1 1
39 access_kpi_perecentage access_kpbi_perecentage1 model_job_class_apprisal base.group_user 1 1 1 1
40 access_kpi_category access_kpi_category kpi_scorecard.model_kpi_category base.group_user 1 1 1 1
41 access_kpi_category access_kpbi_category1 kpi_scorecard.model_kpi_category kpi_scorecard.group_kpi_admin 1 1 1 1
42 access_kpi_category access_kpbi_category1 kpi_scorecard.model_kpi_category exp_hr_appraisal.group_appraisal_manager 1 1 1 1
43 access_kpi_category1 access_kpbi_category2 kpi_scorecard.model_kpi_category exp_hr_appraisal.group_appraisal_user 1 1 1 0
44 access_kpi_category21 access_kpbi_category25 kpi_scorecard.model_kpi_category exp_hr_appraisal.group_appraisal_employee 1 0 0 0
45 access_kpi_period access_kpbi_period1 kpi_scorecard.model_kpi_period base.group_user 1 0 0 0
46 access_kpi_period access_kpbi_period1 kpi_scorecard.model_kpi_period kpi_scorecard.group_kpi_admin 1 1 1 1
47 access_kpi_period access_kpbi_period1 kpi_scorecard.model_kpi_period exp_hr_appraisal.group_appraisal_manager 1 1 1 1
48 access_kpi_category1 access_kpbi_period2 kpi_scorecard.model_kpi_period exp_hr_appraisal.group_appraisal_user 1 1 1 0
49 access_kpi_category21 access_kpbi_period25 kpi_scorecard.model_kpi_period exp_hr_appraisal.group_appraisal_employee 1 0 0 0
50 access_kpi_item access_kpbi_item1 kpi_scorecard.model_kpi_item base.group_user 1 0 0 0
51 access_kpi_item access_kpbi_item1 kpi_scorecard.model_kpi_item kpi_scorecard.group_kpi_admin 1 1 1 1
52 access_kpi_item access_kpbi_item1 kpi_scorecard.model_kpi_item exp_hr_appraisal.group_appraisal_manager 1 1 1 1
53 access_kpi_item1 access_item2 kpi_scorecard.model_kpi_item exp_hr_appraisal.group_appraisal_user 1 1 1 0
54 access_kpi_item21 access_kpbi_item25 kpi_scorecard.model_kpi_item exp_hr_appraisal.group_appraisal_employee 1 0 0 0

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -0,0 +1,22 @@
@media (min-width: 768px){
.rtl .navbar-right{
float: left !important;
}
.rtl .navbar-right .dropdown .dropdown-menu{
right: auto !important;
left: 0 !important;
}
.rtl .navbar-left{
float: right !important;
}
.rtl .navbar-left .dropdown .dropdown-menu{
left: auto !important;
right: 0 !important;
}
.navbar-nav.navbar-right:last-child{
margin-left: auto;
}
.rtl .pull-left{
float: right !important;
}
}

View File

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="apprisal_percentag_form_view" model="ir.ui.view">
<field name="name">apprisal.apprisal_percentag.form</field>
<field name="model">job.class.apprisal</field>
<field name="arch" type="xml">
<form string="Apprisal Percentag">
<sheet>
<group>
<group>
<field name="name"/>
<field name="percentage_kpi" widget="percentage" />
<field name="percentage_skills" widget="percentage" />
<field name="job_ids"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
<record id="apprisal_percentag_tree_view" model="ir.ui.view">
<field name="name">apprisal.apprisal_percentag.tree</field>
<field name="model">job.class.apprisal</field>
<field name="arch" type="xml">
<tree string="ModelTitle">
<field name="name"/>
<field name="percentage_kpi"/>
<field name="percentage_skills"/>
</tree>
</field>
</record>
<!-- <record id="apprisal_percentag_search_view" model="ir.ui.view">-->
<!-- <field name="name">ProjectName.apprisal_percentag.search</field>-->
<!-- <field name="model">ProjectName.apprisal_percentag</field>-->
<!-- <field name="arch" type="xml">-->
<!-- <search string="Apprisal Percentag">-->
<!-- <group expand="1" string="Group By">-->
<!-- <filter string="Example Field" name="example_field" domain="[]"-->
<!-- context="{'group_by':'example_field'}"/>-->
<!-- </group>-->
<!-- </search>-->
<!-- </field>-->
<!-- </record>-->
<record id="apprisal_percentag_act_window1" model="ir.actions.act_window">
<field name="name">Apprisal Percentag</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">job.class.apprisal</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
There is no examples click here to add new ModelTitle.
</p>
</field>
</record>
<menuitem name="Appraisal Percentage"
id="menu_kpi_percentage"
parent="exp_hr_appraisal.appraisal_configuration"
action="apprisal_percentag_act_window1"
sequence="1" groups="exp_hr_appraisal.group_appraisal_manager,exp_hr_appraisal.group_appraisal_user,exp_hr_appraisal.group_appraisal_employee"
/>
</data>
</odoo>

View File

@ -0,0 +1,226 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="employee_apprisal_extend" model="ir.ui.view">
<field name="name">employee.apprisal.form.extend</field>
<field name="model">hr.employee.appraisal</field>
<field name="inherit_id" ref="exp_hr_appraisal.hr_appraisal_form_view"/>
<field name="priority" eval="8"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='appraisal_result']" position="replace">
</xpath>
<xpath expr="//field[@name='appraisal_date']" position="after">
<field name="year_id"/>
<field name="goals_mark"/>
<field name="skill_mark"/>
<field name="total_score"/>
<field name="appraisal_result"/>
</xpath>
<xpath expr="//field[@name='great_level']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//field[@name='level_achieved']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//field[@name='level_achieved_percentage']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//field[@name='manager_appraisal_line_id']" position="replace">
<!-- <attribute name="invisible">1</attribute>-->
</xpath>
<xpath expr="//field[@name='appraisal_plan_id']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//field[@name='appraisal_type']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//field[@name='standard_appraisal_employee_line_ids']" position="replace">
<!-- <attribute name="invisible">1</attribute>-->
</xpath>
<xpath expr="//field[@name='is_manager']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//field[@name='date_from']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//field[@name='date_to']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//sheet/group[2]" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//button[@name='recompute_values_level_achieved']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//field[@name='employee_id']" position="after">
<field name="manager_id"/>
<field name="department_id"/>
<field name="job_id"/>
</xpath>
<xpath expr="//sheet/group[1]" position="after">
<group>
<group>
<button name="compute_apprisal" string="Compute Apprisal" type="object" class="oe_highlight"
icon="fa-cogs"/>
</group>
</group>
<notebook>
<page string="Goals">
<field name="goal_ids">
<tree create="0" delete="0" editable="bottom">
<field name="kpi_id" width="12"
options='{"no_open": False,"no_create_edit": True,"no_create":True}'/>
<field name="weight" sum="Total Weight" width="12"/>
<field name="year_target" sum="Total Target" width="12"/>
<field name="done" width="12"/>
<field name="choiec" width="12"/>
</tree>
</field>
</page>
<page string="Skills">
<field name="skill_ids">
<tree create="0" delete="0" editable="bottom">
<field readonly="1" force_save='1' name="item_id" width="12"
options='{"no_open": True,"no_create_edit": True}'/>
<field readonly="1" force_save='1' name="name" width="12"/>
<field readonly="1" force_save='1' name="level" width="12"/>
<field force_save='1' name="mark_avg" width="12"/>
</tree>
</field>
</page>
<page string="Notes">
<field widget="html" required="0" name="notes"/>
</page>
</notebook>
</xpath>
</field>
</record>
<record id="employee_apprisal_view_tree" model="ir.ui.view">
<field name="name">employee_apprisal.extend.view.tree</field>
<field name="model">hr.employee.appraisal</field>
<field name="inherit_id" ref="exp_hr_appraisal.hr_appraisal_tree_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='is_manager']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//field[@name='appraisal_plan_id']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//field[@name='employee_id']" position="after">
<field name="manager_id"/>
<field name="department_id"/>
<field name="job_id"/>
<field name="year_id"/>
</xpath>
<xpath expr="//field[@name='state']" position="before">
<field name="skill_mark"/>
<field name="goals_mark"/>
<field name="total_score"/>
<field name="apprisal_result"/>
</xpath>
</field>
</record>
<record id="employee_apprisal_view_tree2" model="ir.ui.view">
<field name="name">employee_apprisal.extend.view.tree</field>
<field name="model">hr.group.employee.appraisal</field>
<field name="inherit_id" ref="exp_hr_appraisal.employee_appraisal_tree_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='totals_great_level']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//field[@name='totals_level_achieved']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//field[@name='totals_level_achieved_percentage']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//field[@name='totals_appraisal_result']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//field[@name='appraisal_plan_id']" position="replace">
<field name="year_id"/>
</xpath>
</field>
</record>
<!-- Inherit Form View to Modify it -->
<record id="group_employee_apprisal_extend" model="ir.ui.view">
<field name="name">employee.apprisal.group.extend</field>
<field name="model">hr.group.employee.appraisal</field>
<field name="inherit_id" ref="exp_hr_appraisal.employee_appraisal_form_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='date']" position="after">
<field name="year_id"/>
</xpath>
<xpath expr="//field[@name='appraisal_plan_id']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//field[@name='appraisal_type']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//field[@name='totals_great_level']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//field[@name='totals_level_achieved']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//field[@name='totals_level_achieved_percentage']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//field[@name='totals_appraisal_result']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//field[@name='state']" position="attributes">
<attribute name="statusbar_visible">
draft,gen_appraisal,finish_appraisal,hr_approval,gm_approval,done
</attribute>
</xpath>
<xpath expr="//field[@name='appraisal_id']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//separator[2]" position="replace">
</xpath>
<xpath expr="//separator[1]" position="replace">
</xpath>
<xpath expr="//field[@name='employee_ids']" position="replace">
<notebook>
<page string="Employees">
<field name="employee_ids" string="" attrs="{'readonly':[('state','!=','draft')]}">
<tree>
<field name="name" string="Employee name"/>
<field name="department_id" string="Department"/>
<field name="job_id" string="Job title"/>
</tree>
</field>
</page>
<page string="Apprisal">
<field name="appraisal_ids" string=""
attrs="{'invisible':[('state','=','draft')],'readonly':[('state','!=','draft')]}">
<tree editable="bottom">
<field name="employee_id" width='12' string="Employee"/>
<field name="department_id" width='12' string=""/>
<field name="appraisal_date" width='12' string=""/>
<field name="year_id" width='12' string=""/>
<field name="skill_mark" width='12' string=""/>
<field name="goals_mark" width='12' string=""/>
<field name="total_score" width='12' string=""/>
<field name="apprisal_result" width='12' string=""/>
</tree>
</field>
</page>
</notebook>
</xpath>
</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Form View -->
<record id="view_emplo_evalu_form" model="ir.ui.view">
<field name="name">evalution.employee.goals.form1</field>
<field name="model">employee.performance.evaluation</field>
<field name="arch" type="xml">
<form string="Evaluation Employee Goals">
<header>
<button string="Send" groups='hr_base.group_division_manager' states="draft" class="oe_highlight" type="object" name="send"/>
<button string="Accept" states='dir_manager' class="oe_highlight" type="object" name="action_approval"/>
<button string="refuse" states='dir_manager' class="oe_highlight" type="object" name="action_refuse"/>
<button string="Accept" groups='hr_base.group_department_manager' states='wait_dir_manager' class="oe_highlight" type="object" name="action_approval"/>
<button string="refuse" groups='hr_base.group_department_manager' states='wait_dir_manager' class="oe_highlight" type="object" name="action_refuse"/>
<button string="Accept" groups='hr.group_hr_user' states='wait_hr_manager' class="oe_highlight" type="object" name="action_approval"/>
<button string="refuse" groups='hr.group_hr_user' states='wait_hr_manager' class="oe_highlight" type="object" name="action_refuse"/>
<button string="Reset To Draft" states='approve,refuse' class="oe_highlight" type="object" name="reset_draft"/>
<field name="state" required="1" statusbar_visible="draft,wait_dir_manager,wait_hr_manager,approve,refuse" widget="statusbar"/>
</header>
<sheet>
<group>
<group>
<field name="employee_id" required="1"/>
<field name="manager_id" required="1"/>
<field name="department_id" required="1"/>
<field name="job_id" required="1"/>
</group>
<group>
<field name="date_apprisal"/>
<field name="year_id" required="1" options='{"no_open": True,"no_create_edit": True,"no_create":True}'/>
<field name="period_goals_id" domain="[('kpi_goal_period_id', '=', year_id),('kpi_period_id','=',False)]" attrs="{'invisible':[('year_id','=',False)]}" required="1" options='{"no_open": False,"no_create_edit": True,"no_create":True}'/>
<field name="mark_apprisal" decoration-bf="1" required="1"/>
<!-- <field name="total" decoration-bf="1" />-->
</group>
</group>
<notebook>
<page string="Employee Goals">
<button string="Select Goals" class="oe_highlight" type="object" name="onchange_emp_goal_ids"/>
<field name="emp_goal_ids">
<tree create="0" delete="0" editable="bottom">
<field name="kpi_id" width="12" options='{"no_open": False,"no_create_edit": True,"no_create":True}'/>
<field name="weight" sum="Total Weight" width="12"/>
<field name="target" sum="Total Target" width="12"/>
<field name="done" width="12"/>
<field decoration-bf="1" name="mark_evaluation" width="12"/>
</tree>
</field>
</page>
<page string="Recommendations">
<field widget="html" required="0" name="recommendations"/>
</page>
</notebook>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers"/>
<field name="message_ids" widget="mail_thread"/>
</div>
</form>
</field>
</record>
<!-- Tree View -->
<record id="view_evalution_goals_employee_tree1" model="ir.ui.view">
<field name="name">evalution.employee.goals.tree1</field>
<field name="model">employee.performance.evaluation</field>
<field name="arch" type="xml">
<tree string="Year Employee Goals" decoration-info="state == 'draft'" decoration-danger="state == 'refuse'" decoration-success="state== 'approve'" >
<field name="employee_id"/>
<field name="department_id"/>
<field name="job_id"/>
<field name="year_id"/>
<field name="period_goals_id"/><field name="date_apprisal"/>
<field name="state" widget="badge" decoration-info="state == 'draft'" decoration-danger="state == 'refuse'" decoration-success="state== 'approve'"/>
<field name="mark_apprisal" sum='Total' decoration-bf="1"/>
</tree>
</field>
</record>
<!-- Menu Action -->
<record id="action_evalution_goal_emp" model="ir.actions.act_window">
<field name="name">Evaluation Employee Goals</field>
<field name="res_model">employee.performance.evaluation</field>
<field name="view_mode">tree,form</field>
</record>
<!-- Menu Item -->
<menuitem id="menu_evalution_employee_goals_" sequence="2" groups="exp_hr_appraisal.group_appraisal_manager,exp_hr_appraisal.group_appraisal_user,exp_hr_appraisal.group_appraisal_employee" name="Employee Goals Appraisal" parent="exp_hr_appraisal.appraisal_menu_id" action="action_evalution_goal_emp"/>
</odoo>

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="kpi_category_inherit" model="ir.ui.view">
<field name="name">kpi.category.form</field>
<field name="model">kpi.category</field>
<field name="inherit_id" ref="kpi_scorecard.kpi_category_view_form"/>
<field name="priority" eval="8"/>
<field name="arch" type="xml">
<xpath expr="//notebook/page[1]" position="attributes">
<attribute name="groups">kpi_scorecard.group_kpi_admin</attribute>
</xpath>
</field>
</record>
<menuitem name="Goals"
id="menu_kpi_categories"
parent="exp_hr_appraisal.appraisal_configuration"
action="kpi_scorecard.kpi_category_action"
sequence="1"
groups="kpi_scorecard.group_kpi_admin,exp_hr_appraisal.group_appraisal_employee,exp_hr_appraisal.group_appraisal_manager,exp_hr_appraisal.group_appraisal_user"/>
<menuitem name="KPI"
id="menu_kpi_kpi"
parent="exp_hr_appraisal.appraisal_configuration"
action="kpi_scorecard.kpi_item_action"
sequence="1"
groups="kpi_scorecard.group_kpi_admin,exp_hr_appraisal.group_appraisal_manager,exp_hr_appraisal.group_appraisal_employee,exp_hr_appraisal.group_appraisal_user"
/>
<menuitem name="Periods"
id="menu_kpi_period"
parent="exp_hr_appraisal.appraisal_configuration"
action="kpi_scorecard.kpi_period_action"
sequence="1"
groups="kpi_scorecard.group_kpi_admin,exp_hr_appraisal.group_appraisal_manager,exp_hr_appraisal.group_appraisal_user,exp_hr_appraisal.group_appraisal_employee"
/>
<menuitem name="Goals and Skills" id="menu_kpi_goal_skill" parent="exp_hr_appraisal.appraisal_menu_id" sequence="3"/>
<!-- todo start -->
<!-- hide menu -->
<record model="ir.ui.menu" id="exp_hr_appraisal.appraisal_plan_menu">
<field name="groups_id" eval="[(6,0,[ref('exp_hr_appraisal_kpi.apprisal_kpi_group')])]"/>
</record>
<record model="ir.ui.menu" id="exp_hr_appraisal.appraisal_setting_menu">
<field name="groups_id" eval="[(6,0,[ref('exp_hr_appraisal_kpi.apprisal_kpi_group')])]"/>
</record>
<record model="ir.ui.menu" id="exp_hr_appraisal.appraisal_menu">
<field name="groups_id" eval="[(6,0,[ref('exp_hr_appraisal_kpi.apprisal_kpi_group')])]"/>
</record>
<record model="ir.ui.menu" id="exp_hr_appraisal.appraisal_degree_menu">
<field name="groups_id" eval="[(6,0,[ref('exp_hr_appraisal_kpi.apprisal_kpi_group')])]"/>
</record>
<!-- todo end -->
</odoo>

View File

@ -0,0 +1,51 @@
<odoo>
<!-- Inherit Form View to Modify it -->
<record id="kpi_item_tree_extend" model="ir.ui.view">
<field name="name">kpi.item.tree.extend</field>
<field name="model">kpi.item</field>
<field name="inherit_id" ref="kpi_scorecard.kpi_item_view_tree"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='formula_warning']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
</field>
</record>
<record id="hpi_item_extend" model="ir.ui.view">
<field name="name">kpi.form.extend</field>
<field name="model">kpi.item</field>
<field name="inherit_id" ref="kpi_scorecard.kpi_item_view_form"/>
<field name="arch" type="xml">
<!-- add new tab -->
<xpath expr="//field[@name='formula_warning']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//field[@name='formula']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//h2" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//field[@name='category_id']" position="after">
<field name="department_item_id"/>
<field name="responsible_item_id"/>
<field name="method_of_calculate"/>
</xpath>
<xpath expr="//notebook" position="inside">
<page string="Marks" groups="base.group_user,exp_hr_appraisal.group_appraisal_user,exp_hr_appraisal.group_appraisal_manager,exp_hr_appraisal.group_appraisal_employee">
<field name="mark_ids">
<tree editable="bottom">
<field name="choiec" width="12"/>
<field name="target" string="From(Done)" width="12"/>
<field name="to" width="12"/>
</tree>
</field>
</page>
</xpath>
<xpath expr="//notebook/page[2]" position="attributes">
<attribute name="groups">kpi_scorecard.group_kpi_admin</attribute>
</xpath>
</field>
</record>
</odoo>

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="kpi_period_form_extend" model="ir.ui.view">
<field name="name">kpi.period.form.extend</field>
<field name="model">kpi.period</field>
<field name="inherit_id" ref="kpi_scorecard.kpi_period_view_form"/>
<field name="arch" type="xml">
<xpath expr="//page[1]" position="attributes">
<attribute name="groups">kpi_scorecard.group_kpi_admin</attribute>
</xpath>
<xpath expr="//page[2]" position="attributes">
<attribute name="groups">kpi_scorecard.group_kpi_admin</attribute>
</xpath>
<xpath expr="//button[@name='%(kpi_scorecard.kpi_copy_template_action)d']" position="attributes">
<attribute name="groups">kpi_scorecard.group_kpi_admin</attribute>
</xpath>
<xpath expr="//page[2]" position="after">
<page string="Goals Period">
<field name="kpi_goals_periods_ids">
<tree editable="bottom">
<field name="sequence" width="4"/>
<field name="name" width="8"/>
<field name="date_start_k" width="12"/>
<field name="date_end_k" width="12"/>
<button string="Create Apprisal" width="" class="oe_highlight" type="object" name="create_apprisal_goals_employee"/>
</tree>
</field>
</page>
<page string="Skills Period">
<field name="kpi_periods_ids">
<tree editable="bottom">
<field name="name" width="12"/>
<field name="date_start_k" width="12"/>
<field name="date_end_k" width="12"/>
</tree>
</field>
</page>
</xpath>
</field>
</record>
</odoo>

View File

@ -0,0 +1,112 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Skill Form View -->
<record id="view_skill_form" model="ir.ui.view">
<field name="name">skill.form</field>
<field name="model">skill.skill</field>
<field name="arch" type="xml">
<form string="Skill">
<sheet>
<group>
<field name="name"/>
<field name="description"/>
</group>
<notebook>
<page string="Items">
<field widget="section_and_note_one2many" name="items_ids">
<tree editable="bottom">
<field name="sequence" widget="handle"/>
<field name="display_type" invisible="1"/>
<field name="item_id"/>
<field widget="section_and_note_text" name="name"/>
<field name="level"/>
<control>
<create name="add_product_control" string="Add a Item "/>
<create name="add_section_control" string="Add a section " context="{'default_display_type': 'line_section'}"/>
<create name="add_note_control" string="Add a note" context="{'default_display_type': 'line_note'}"/>
</control>
</tree>
</field>
</page>
</notebook>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers"/>
<field name="message_ids" widget="mail_thread"/>
</div>
</form>
</field>
</record>
<!-- Skill Tree View -->
<record id="view_skill_tree" model="ir.ui.view">
<field name="name">skill.tree</field>
<field name="model">skill.skill</field>
<field name="arch" type="xml">
<tree string="Skills">
<field name="name"/>
<field name="description"/>
</tree>
</field>
</record>
<record id="skill_search_view" model="ir.ui.view">
<field name="name">kpi.skill.search</field>
<field name="model">skill.skill</field>
<field name="arch" type="xml">
<search string="Skill">
<field name="name"/>
</search>
</field>
</record>
<record id="skill_act_window" model="ir.actions.act_window">
<field name="name">Skills</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">skill.skill</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
There is no examples click here to add new Skill.
</p>
</field>
</record>
<!-- form inherit -->
<!-- Inherit Form View to Modify it -->
<record id="hr_job_from_extend" model="ir.ui.view">
<field name="name">hr.job.extend</field>
<field name="model">hr.job</field>
<field name="inherit_id" ref="hr.view_hr_job_form"/>
<field name="arch" type="xml">
<xpath expr="//notebook" position="inside">
<page string="Skills">
<field name="item_job_ids" domain="[('display_type','=',False)]"/>
</page>
</xpath>
</field>
</record>
<record id="item_tree_view_tree" model="ir.ui.view">
<field name="name">item.tree.view.tree</field>
<field name="model">skill.item</field>
<field name="arch" type="xml">
<tree string="item_tree_tree">
<field name="skill_id"/>
<field name="item_id"/>
<field name="name"/>
<field name="level"/>
<field name="mark" invisible="1"/>
</tree>
</field>
</record>
<!-- Inherit the menu -->
<!-- <record model="ir.ui.menu" id="hr_base_reports.appraisal_report_menu">-->
<!-- <field name="groups_id" eval="[(4, ref('exp_hr_appraisal.group_appraisal_user,exp_hr_appraisal.group_appraisal_manager'))]"/>-->
<!-- </record>-->
<!-- end from -->
<menuitem name="Skills" id="skill_menu" sequence="1" parent="exp_hr_appraisal_kpi.menu_kpi_goal_skill" groups="exp_hr_appraisal.group_appraisal_user,exp_hr_appraisal.group_appraisal_manager"
action="skill_act_window"/>
</odoo>

View File

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Form View -->
<record id="view_skill_appraisal_form" model="ir.ui.view">
<field name="name">skill.appraisal.form</field>
<field name="model">skill.appraisal</field>
<field name="arch" type="xml">
<form string="Skill Appraisal">
<header>
<button string="Send" groups='hr_base.group_division_manager' states="draft" class="oe_highlight" type="object" name="send"/>
<button string="Accept" states='dir_manager' class="oe_highlight" type="object" name="action_approval"/>
<button string="refuse" states='dir_manager' class="oe_highlight" type="object" name="action_refuse"/>
<button string="Accept" groups='hr_base.group_department_manager' states='wait_dir_manager' class="oe_highlight" type="object" name="action_approval"/>
<button string="refuse" groups='hr_base.group_department_manager' states='wait_dir_manager' class="oe_highlight" type="object" name="action_refuse"/>
<button string="Accept" groups='hr.group_hr_user' states='wait_hr_manager' class="oe_highlight" type="object" name="action_approval"/>
<button string="refuse" groups='hr.group_hr_user' states='wait_hr_manager' class="oe_highlight" type="object" name="action_refuse"/>
<button string="Reset To Draft" states='approve,refuse' class="oe_highlight" type="object" name="reset_draft"/>
<field name="state" required='1' statusbar_visible="draft,dir_manager,wait_dir_manager,wait_hr_manager,approve,refuse" widget="statusbar"/>
</header>
<sheet>
<group>
<group>
<field name="employee_id" attrs="{'readonly': [('state', 'not in', ['draft'])]}" required='1'/>
<field attrs="{'readonly': [('state', 'not in', ['draft'])]}" name="department_id" required='1'/>
<field attrs="{'readonly': [('state', 'not in', ['draft'])]}" name="job_id" required='1'/>
<field attrs="{'readonly': [('state', 'not in', ['draft'])]}" name="manager_id" required='1'/>
</group>
<group>
<field attrs="{'readonly': [('state', 'not in', ['draft'])]}" name="date_apprisal"/>
<field attrs="{'readonly': [('state', 'not in', ['draft'])]}" name="year_id" required="1" options='{"no_open": True,"no_create_edit": True,"no_create":True}'/>
<field attrs="{'readonly': [('state', 'not in', ['draft'])],'invisible':[('year_id','=',False)]}" name="period" domain="[('kpi_period_id', '=',year_id),('kpi_goal_period_id','=',False)]" required="1" options='{"no_open": True,"no_create_edit": True,"no_create":True}'/>
<field attrs="{'readonly': [('state', 'not in', ['draft'])]}" required='1' decoration-bf="1" name="avarage"/>
</group>
</group>
<notebook>
<page string="Items">
<field name="items_ids">
<tree create="0" delete='0' editable="bottom">
<field readonly="1" force_save='1' name="item_id" width="12" options='{"no_open": True,"no_create_edit": True}'/>
<field readonly="1" force_save='1' name="name" width="12" attrs="{'readonly': [('parent.state', 'not in', ['draft'])]}"/>
<field readonly="1" force_save='1' name="level" width="12"/>
<field force_save='1' attrs="{'readonly': [('parent.state', 'not in', ['wait_dir_manager','draft'])]}" name="mark" width="12"/>
</tree>
</field>
</page>
<page string="Recommendations">
<field attrs="{'readonly': [('state', 'not in', ['draft'])]}" widget="html" required="0" name="recommendations"/>
</page>
</notebook>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers"/>
<field name="message_ids" widget="mail_thread"/>
</div>
</form>
</field>
</record>
<!-- Tree View -->
<record id="view_skill_appraisal_tree" model="ir.ui.view">
<field name="name">skill.appraisal.tree</field>
<field name="model">skill.appraisal</field>
<field name="arch" type="xml">
<tree string="Skill Appraisal" decoration-info="state == 'draft'" decoration-danger="state == 'refuse'" decoration-success="state== 'approve'">
<field name="employee_id"/>
<field name="department_id"/>
<field name="job_id"/>
<field name="manager_id"/>
<field name="period"/>
<field name="date_apprisal"/>
<field name="state" widget="badge" decoration-info="state == 'draft'" decoration-danger="state == 'refuse'" decoration-success="state== 'approve'"/>
<field name="avarage" decoration-bf="1"/>
</tree>
</field>
</record>
<!-- Menu Action -->
<record id="action_skill_appraisal" model="ir.actions.act_window">
<field name="name">Skill Appraisal</field>
<field name="res_model">skill.appraisal</field>
<field name="view_mode">tree,form</field>
</record>
<!-- Menu Item -->
<menuitem id="menu_skill_appraisal_list" groups="exp_hr_appraisal.group_appraisal_manager,exp_hr_appraisal.group_appraisal_user,exp_hr_appraisal.group_appraisal_employee" sequence="2" name="Employee Skill Appraisal" parent="exp_hr_appraisal.appraisal_menu_id" action="action_skill_appraisal"/>
</odoo>

View File

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Form View -->
<record id="view_emplo_goals_form" model="ir.ui.view">
<field name="name">years.employee.goals.form1</field>
<field name="model">years.employee.goals</field>
<field name="arch" type="xml">
<form string="Year Employee Goals">
<header>
<button string="Start Apprisal" states="draft" class="oe_highlight" type="object" name="apprisal"/>
<button string="Close" states='apprisal' class="oe_highlight" type="object" name="action_close"/>
<button string="Set To Dratt" states='apprisal,close' type="object" name="action_set_to_dratt"/>
<field name="state" required="1" statusbar_visible="draft,apprisal,close" widget="statusbar"/>
</header>
<sheet>
<group>
<group>
<field name="year_id" required="1"/>
<field name="employee_id" required="1"/>
<field name="department_id" required="1"/>
<field required="1" name="job_id"/>
</group>
<group>
<field required="1" name="category_id"/>
<field required="1" name="kpi_id" domain="[('category_id', '=',category_id)]"/>
<field required="1" name="responsible_item_id"/>
<field required="1" name="year_target"/>
<field required="1" invisible='1' name="method_of_calculate"/>
<field name="done" attrs="{'readonly': [('method_of_calculate', '!=', 'undefined')],'invisible':[('state','=','draft')]}"/>
<field name="choiec" atrrs="{'invisible':[('state','=','draft')]}"/>
<field required="1" name="weight"/>
<field name="first_period_traget" invisible="1"/>
<field name="second_period_traget" invisible="1"/>
<field name="third_period_traget" invisible="1"/>
<field name="fourth_period_traget" invisible="1"/>
</group>
</group>
<notebook>
<page string="Period">
<field name="goals_period_ids" attrs="{'readonly':[('state','=','close')]}">
<tree create="0" editable="bottom">
<field name="period_goals_id" width="12" options='{"no_open": False,"no_create_edit": True,"no_create":True}'/>
<field sum='Totat Traget' name="target" width="12"/>
<field name="done" width="12" attrs="{'column_invisible': [('parent.state', 'in', ['draft'])]}"/>
<field name="mark_evaluation" width="12" attrs="{'column_invisible': [('parent.state', 'in', ['draft'])]}"/>
</tree>
</field>
</page>
</notebook>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers"/>
<field name="message_ids" widget="mail_thread"/>
</div>
</form>
</field>
</record>
<!-- Tree View -->
<record id="view_year_goals_employee_tree1" model="ir.ui.view">
<field name="name">years.employee.goals.tree1</field>
<field name="model">years.employee.goals</field>
<field name="arch" type="xml">
<tree string="Year Employee Goals">
<field name="employee_id"/>
<field name="department_id"/>
<field name="job_id"/>
<field name="year_id"/>
<field name="category_id"/>
<field name="kpi_id"/>
<field name="responsible_item_id"/>
<field name="weight"/>
<field name="done" />
<field name="year_target" sum="Total"/>
<field name="state" decoration-info="state == 'draft'" decoration-primary="state== 'apprisal'" decoration-success="state== 'close'" widget="badge"/>
</tree>
</field>
</record>
<!-- Menu Action -->
<record id="action_year_goal_emp" model="ir.actions.act_window">
<field name="name">Employee Goals</field>
<field name="res_model">years.employee.goals</field>
<field name="view_mode">tree,form</field>
</record>
<!-- Menu Item -->
<menuitem groups="exp_hr_appraisal_kpi.group_appraisal_responsabil,exp_hr_appraisal.group_appraisal_manager,exp_hr_appraisal.group_appraisal_user" id="menu_year_employee_goals_list" sequence="2" name="Employee Goals" parent="exp_hr_appraisal_kpi.menu_kpi_goal_skill" action="action_year_goal_emp"/>
</odoo>