training course appraisal

This commit is contained in:
Esraa-Exp 2025-02-24 11:24:51 +02:00
parent f29cccc626
commit 35d56421c5
12 changed files with 376 additions and 23 deletions

View File

@ -27,6 +27,7 @@
'views/appraisal_view.xml',
'views/training_menus.xml',
'wizard/employee_selection_wizard.xml',
'wizard/training_appraisal.xml',
],
'installable': True,

View File

@ -2599,6 +2599,36 @@ msgstr "المدرب"
msgid "Training Details"
msgstr "تفاصيل الدورة التدريبية"
#. module: exp_official_mission
#: code:addons/exp_official_mission/models/hr_official_mission.py:0
#: model:ir.actions.act_window,name:exp_official_mission.action_training_appraisal_wizard
#: model_terms:ir.ui.view,arch_db:exp_official_mission.employee_training_form_view
#: model_terms:ir.ui.view,arch_db:exp_official_mission.view_training_appraisal_wizard_form
#, python-format
msgid "Training Course Appraisal"
msgstr "تقييم الدورة التدريبية"
#. module: exp_official_mission
#: model:ir.model.fields,field_description:exp_official_mission.field_appraisal_result__appraisal_plan_ids
#: model:ir.model.fields,field_description:exp_official_mission.field_training_appraisal_wizard__appraisal_plan_id
msgid "Appraisal Plan"
msgstr "خطة التقييم"
#. module: exp_official_mission
#: model:ir.model.fields,field_description:exp_official_mission.field_hr_employee_appraisal__mission_id
msgid "Training Course"
msgstr "الدورة التدريبية"
#. module: exp_official_mission
#: model:ir.model,name:exp_official_mission.model_appraisal_result
#: model:ir.model.fields,field_description:exp_official_mission.field_appraisal_plan__appraisal_result_ids
#: model:ir.model.fields,field_description:exp_official_mission.field_hr_official_mission_employee__appraisal_result
#: model_terms:ir.ui.view,arch_db:exp_official_mission.employee_official_mission_form_view
#: model_terms:ir.ui.view,arch_db:exp_official_mission.employee_training_form_view
msgid "Appraisal Result"
msgstr "نتيجة التقييم"

View File

@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
from . import hr_official_mission
from . import attendance
from . import attendance
from . import employee_appraisal

View File

@ -0,0 +1,70 @@
# -*- coding: utf-8 -*-
from odoo import api, fields, models, _, exceptions
class EmployeeAppraisal(models.Model):
_inherit= 'hr.employee.appraisal'
mission_id = fields.Many2one('hr.official.mission', string="Training Course",domain=[("mission_type.work_state", "=", "training")])
@api.onchange('department_id', 'mission_id', 'appraisal_type')
def employee_ids_domain(self):
self.employee_id = False
if self.mission_id and self.appraisal_type == 'training':
employee_list = self.mission_id.employee_ids.mapped('employee_id').ids
return {'domain': {'employee_id': [('id', 'in', employee_list)]}}
@api.onchange('standard_appraisal_employee_line_ids', 'appraisal_plan_id')
def onchange_appraisal_lines(self):
if self.appraisal_type == 'training' and self.mission_id:
for item in self:
# Initialize
total_greed, total_great_level, item.level_achieved, item.great_level, item.level_achieved_percentage = \
0.0, 0.0, 0.0, 0.0, 0.0
appraisal_result_list = []
if not item.is_manager:
for line in item.standard_appraisal_employee_line_ids:
# Update level achieved values when changed in lines
total_greed += line.greed
total_great_level += line.great_level
item.great_level = total_great_level
item.level_achieved = total_greed
# Update level achieved percentage when changed in lines
if item.level_achieved > 0.0 and item.great_level > 0.0:
item.level_achieved_percentage = (item.level_achieved * 100) / item.great_level
if item.level_achieved_percentage > 100:
raise exceptions.Warning(
_('There is No percentage result for employee appraisal Greater than 100%'))
# Determine which appraisal result from appraisal percentage
appraisal_result = self.appraisal_plan_id.mapped('appraisal_result_ids').filtered(lambda r: r.result_from <= item.level_achieved_percentage and r.result_to >= item.level_achieved_percentage)
if 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(item.level_achieved_percentage, 2), appraisal_result_list))
else:
item.appraisal_result = appraisal_result.id
else:
res = super(EmployeeAppraisal, self).onchange_appraisal_lines()
return res
class AppraisalResult(models.Model):
_inherit = 'appraisal.result'
appraisal_plan_ids = fields.Many2many("appraisal.plan", string="Appraisal Plan")
class AppraisalPlan(models.Model):
_inherit = 'appraisal.plan'
appraisal_result_ids = fields.Many2many("appraisal.result", string="Appraisal Result", required=True)

View File

@ -76,6 +76,7 @@ class HrOfficialMission(models.Model):
# to link with the account invoice entry
Training_cost = fields.Float()
appraisal_check = fields.Boolean()
appraisal_found = fields.Boolean(compute="check_appraisal")
Tra_cost_invo_id = fields.Many2one('account.move', string="Training Cost Invoice", readonly=True)
max_of_employee = fields.Integer()
@ -156,8 +157,6 @@ class HrOfficialMission(models.Model):
else:
ctx['default_official_mission_id'] = self.id
# if self.percentage:
# ctx['default_percentage'] = self.percentage
ctx['default_employee_id'] = self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1)
@ -170,6 +169,26 @@ class HrOfficialMission(models.Model):
'context': ctx,
}
def action_training_appraisal(self):
self.ensure_one()
ctx = dict(self.env.context)
return {
'name': _('Training Course Appraisal'),
'view_mode': 'form',
'res_model': 'training.appraisal.wizard',
'type': 'ir.actions.act_window',
'target': 'new',
'context': ctx,
}
def check_appraisal(self):
if any(self.employee_ids.mapped('appraisal_id')):
self.appraisal_found = True
else:
self.appraisal_found = False
def get_user_id(self):
employee_id = self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1)
if employee_id:
@ -336,6 +355,7 @@ class HrOfficialMission(models.Model):
'You can not re-draft official mission because account move with ID "%s" in state '
'Posted') % line.account_move_id.name)
elif item.move_type == 'payroll':
for record in item.employee_ids:
@ -364,6 +384,18 @@ class HrOfficialMission(models.Model):
raise exceptions.Warning(_(
'You can not re-draft official mission because account Invoice with ID "%s" in state Not Draft') % item.Tra_cost_invo_id.number)
if item.mission_type.work_state == 'training' and item.appraisal_found == True:
for line in item.employee_ids:
if line.appraisal_id:
if line.appraisal_id.state == 'draft':
line.appraisal_id.unlink()
line.appraisal_id = False
line.appraisal_result = 0.0
else:
raise exceptions.Warning(_(
'You can not re-draft official mission because Appraisal with ID "%s" in not draft state ') % line.appraisal_id.employee_id.name)
item.state = 'draft'
self.reset_emp_work_state()
self.call_cron_function()
@ -786,7 +818,7 @@ class HrAppraisal(models.Model):
def set_state_done(self):
res = super(HrAppraisal, self).set_state_done()
if self.appraisal_type in ['mission', 'training'] and self.employee_appraisal.mission_id:
if self.appraisal_type == 'mission' and self.employee_appraisal.mission_id:
mission = self.employee_appraisal.mission_id.employee_ids.sudo().filtered(
lambda r: r.employee_id == self.employee_id)
self.employee_appraisal.mission_id.appraisal_check = True
@ -795,6 +827,16 @@ class HrAppraisal(models.Model):
'appraisal_id': self.id,
'appraisal_result': self.appraisal_result.id if self.appraisal_result else False
})
elif self.appraisal_type == 'training' and self.mission_id:
mission = self.mission_id
if mission:
mission_employee = mission.employee_ids.sudo().filtered(
lambda r: r.employee_id == self.employee_id)
mission.appraisal_check = True
mission_employee.sudo().write({
'appraisal_id': self.id,
'appraisal_result': self.appraisal_result.id if self.appraisal_result else False
})
return res

View File

@ -11,3 +11,6 @@ access_employee_course_name_emp,access_employee_course_name_emp,model_employee_c
access_employee_course_name_hr,access_employee_course_name_hr,model_employee_course_name,hr.group_hr_user,1,1,1,1
access_ticket_class_user,access_ticket_class_user,model_ticket_class,hr.group_hr_user,1,1,1,0
access_employee_mission_selection_wizard,employee.mission.selection.wizard,model_employee_mission_selection_wizard,base.group_user,1,1,1,1
access_training_appraisal_wizard,training_appraisal_wizard,model_training_appraisal_wizard,base.group_user,1,1,1,1

1 id name model_id:id group_id/id perm_read perm_write perm_create perm_unlink
11 access_employee_course_name_hr access_employee_course_name_hr model_employee_course_name hr.group_hr_user 1 1 1 1
12 access_ticket_class_user access_ticket_class_user model_ticket_class hr.group_hr_user 1 1 1 0
13 access_employee_mission_selection_wizard employee.mission.selection.wizard model_employee_mission_selection_wizard base.group_user 1 1 1 1
14 access_training_appraisal_wizard training_appraisal_wizard model_training_appraisal_wizard base.group_user 1 1 1 1
15
16

View File

@ -11,5 +11,63 @@
</xpath>
</field>
</record>
<record id="employee_appraisal_inherit" model="ir.ui.view">
<field name="name">employee.appraisal.form.inherit</field>
<field name="model">hr.employee.appraisal</field>
<field name="inherit_id" ref="exp_hr_appraisal.hr_appraisal_form_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='appraisal_type']" position="after">
<field name="mission_id" attrs="{'invisible':[('appraisal_type','!=', 'training')]}"/>
</xpath>
</field>
</record>
<record id="employee_appraisal_result_inherit" model="ir.ui.view">
<field name="name">appraisal.result.form.inherit</field>
<field name="model">appraisal.result</field>
<field name="inherit_id" ref="exp_hr_appraisal.appraisal_result_form_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='result_to']" position="after">
<field name="appraisal_plan_ids" widget="many2many_tags"/>
</xpath>
</field>
</record>
<record id="employee_appraisal_result_inherit" model="ir.ui.view">
<field name="name">appraisal.result.form.inherit</field>
<field name="model">appraisal.result</field>
<field name="inherit_id" ref="exp_hr_appraisal.appraisal_result_form_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='result_to']" position="after">
<field name="appraisal_plan_ids" widget="many2many_tags"/>
</xpath>
</field>
</record>
<record id="employee_appraisal_plan_inherit" model="ir.ui.view">
<field name="name">appraisal.plan.form.inherit</field>
<field name="model">appraisal.plan</field>
<field name="inherit_id" ref="exp_hr_appraisal.appraisal_plan_form_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='department_id']" position="after">
<field name="appraisal_result_ids" widget="many2many_tags"/>
</xpath>
</field>
</record>
</data>
</odoo>

View File

@ -34,20 +34,22 @@
<button name="hr_aaproval" string="HR Approval" class="oe_highlight" type="object"
states="depart_manager"
groups="group_hr_training_user"/>
groups="exp_official_mission.group_hr_training_user"/>
<button name="refused" string="Refused" class="oe_highlight" type="object"
states="depart_manager"
groups="group_hr_training_user"/>
groups="exp_official_mission.group_hr_training_user"/>
<button name="approve" string="Approve" class="oe_highlight" type="object"
states="hr_aaproval" groups="group_hr_training_manager"/>
states="hr_aaproval" groups="exp_official_mission.group_hr_training_manager"/>
<button name="refused" string="Refused" class="oe_highlight" type="object"
states="hr_aaproval"
groups="group_hr_training_manager"/>
groups="exp_official_mission.group_hr_training_manager"/>
<button name="draft_state" string="RE-Draft" class="oe_highlight" type="object"
states="approve,refused" groups="hr.group_hr_user"
confirm="Are you sure to Reset To Draft This Record?"/>
<button name="action_training_appraisal" string="Training Course Appraisal" type="object" class="oe_highlight"
icon="fa-users" attrs="{'invisible':['|',('state','!=','approve'),('appraisal_found','=',True)]}"/>
<field name="state" widget="statusbar"
statusbar_visible="draft,depart_manager,hr_aaproval,approve,refused"/>
</header>
@ -127,6 +129,8 @@
<field name="max_of_employee" string="Max Trainees" attrs="{'readonly':[('state','=','approve')]}"
groups="hr_base.group_account_manager,hr.group_hr_user,hr_base.group_division_manager"/>
<field name="appraisal_check" invisible="1"/>
<field name="appraisal_found" invisible="1"/>
</group>
</group>
<!--group string="Mission Purpose">
@ -177,7 +181,7 @@
<field name="train_cost_emp" string="Training Cost"
groups="hr_base.group_account_manager,hr.group_hr_user,hr_base.group_division_manager"/>
<field name="appraisal_id" string="Appraisal" readonly="1" force_save="1"
attrs="{'column_invisible':[('parent.appraisal_check','=',False)]}"/>
attrs="{'column_invisible':[('parent.appraisal_found','=',False)]}"/>
<field name="appraisal_result" string="Appraisal Result" readonly="1"
force_save="1"
attrs="{'column_invisible':[('parent.appraisal_check','=',False)]}"/>
@ -196,6 +200,85 @@
icon="fa-paperclip" attrs="{'invisible': [('attachment_count', '=', 0)]}"/>
</tree>
<form string="Employee Training Course Day">
<header>
<button name="approve" string="Approve" class="oe_highlight" type="object"
attrs="{'invisible':[('status','!=','draft')]}"
groups="hr_base.group_division_manager"/>
<button name="refuse" string="Refuse" class="oe_highlight" type="object"
attrs="{'invisible':[('status','!=','draft')]}"
groups="hr_base.group_division_manager"/>
<button name="done" string="Done" class="oe_highlight" type="object"
attrs="{'invisible':[('status','!=','approved')]}"/>
<button name="set_to_draft" string="Set to Draft" class="oe_highlight"
type="object"
attrs="{'invisible':[('status','not in', ('done','refused'))]}"/>
<field name="status" widget="statusbar"
statusbar_visible="draft,approved,approved2,done,refused"/>
</header>
<sheet>
<div class="oe_button_box" name="button_box">
<button name="action_get_attachment_view" class="oe_stat_button"
icon="fa-file-text-o"
type="object">
<field name="attachment_count" widget="statinfo"
string="Attachments"
options="{'reload_on_button': true}"/>
</button>
</div>
<group col="4">
<field name="employee_id" string="Employee" required="1"/>
<field name="date_from" string="Date from"/>
<field name="date_to" string="Date to"/>
<field name="days" string="Days" readonly="0"/>
<field name="day_price" string="Day price"
groups="hr_base.group_account_manager,hr.group_hr_user"
attrs="{'column_invisible':['|',('parent.duration_type','!=','days'),
('parent.related_with_financial','=',False)]}"
readonly="1" force_save="1"/>
<field name="hour_from" string="Hour from" widget="float_time"
/>
<field name="hour_to" string="Hour to" widget="float_time"
/>
<field name="hours" string="Hours" readonly="0" widget="float_time"/>
<field name="total_hours" string="Total Hours" readonly="0"
widget="float_time"/>
<field name="hour_price" string="Hour price"
groups="hr_base.group_account_manager,hr.group_hr_user"
attrs="{'column_invisible':['|',('parent.duration_type','!=','hours'),
('parent.related_with_financial','=',False)]}"
readonly="1" force_save="1"/>
<field name="fees_amount" string="Fees Amount"
attrs="{'column_invisible':[('parent.related_with_financial','=',False)]}"
readonly="0"/>
<field name="train_cost_emp" string="Training Cost"
groups="hr_base.group_account_manager,hr.group_hr_user,hr_base.group_division_manager"/>
<field name="appraisal_id" string="Appraisal" readonly="1"
force_save="1"
attrs="{'column_invisible':[('parent.appraisal_check','=',False)]}"/>
<field name="appraisal_result" string="Appraisal Result" readonly="1"
force_save="1"
attrs="{'column_invisible':[('parent.appraisal_check','=',False)]}"/>
<field name="amount" string="Amount"
groups="hr_base.group_account_manager,hr.group_hr_user"
attrs="{'column_invisible':[('parent.related_with_financial','=',False)]}"
readonly="1" force_save="1"/>
<field name="account_move_id" string="Account move" readonly="1"
force_save="1"
groups="hr_base.group_account_manager,hr.group_hr_user"
attrs="{'column_invisible':['|',('parent.related_with_financial','=',False),
('parent.move_type','!=','accounting')]}"/>
</group>
</sheet>
</form>
</field>
</page>

View File

@ -7,3 +7,4 @@
##############################################################################
from . import employee_selection_wizard
from . import training_appraisal

View File

@ -18,19 +18,6 @@ class EmployeeMissionSelectionWizard(models.TransientModel):
employee_mission_id = fields.Many2one(comodel_name='hr.official.mission',string='Employee Mission')
# @api.onchange('employee_ids')
# def _onchange_employee_ids(self):
# return {
# 'domain': {
# 'employee_ids': [
# ('id', 'not in', self.employee_ids.ids),
# ('active', '=', True)
# ]
# }
# }
def _get_active_employee_mission(self):
mission_id = self.env.context.get('default_employee_mission_id')
if not mission_id and self.env.context.get('active_model') == 'hr.official.mission':
@ -107,7 +94,7 @@ class EmployeeMissionSelectionWizard(models.TransientModel):
if duplicate_employees:
duplicate_names = self.env['hr.employee'].browse(list(duplicate_employees)).mapped('name')
raise ValidationError(_(
"The following employees are already in reward lines: %s" % ', '.join(duplicate_names)
"The following employees are already in training lines: %s" % ', '.join(duplicate_names)
))
# Create all records in a single operation

View File

@ -0,0 +1,44 @@
from odoo import api, fields, models, _
from datetime import datetime, date, timedelta
from odoo.exceptions import ValidationError
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT, DEFAULT_SERVER_DATE_FORMAT
class TrainingAppraisalWizard(models.TransientModel):
_name = 'training.appraisal.wizard'
_description = 'Training Appraisal Wizard'
appraisal_plan_id = fields.Many2one('appraisal.plan', string="Appraisal Plan", required=True)
def _get_active_employee_mission(self):
if self.env.context.get('active_model') == 'hr.official.mission':
mission_id = self.env.context.get('active_id')
return mission_id
def create_employee_appraisal(self):
mission = self.env['hr.official.mission'].browse(self._get_active_employee_mission())
if not mission.exists():
# Get values from context
mission_vals = self.env.context.get('default_mission_vals', {})
mission = self.env['hr.official.mission'].create(mission_vals)
for employee in mission.employee_ids:
vals_list = {
'employee_id': employee.employee_id.id,
'date_from': employee.date_from,
'date_to': employee.date_to,
'appraisal_plan_id': self.appraisal_plan_id.id,
'appraisal_type': 'training',
'appraisal_date': date.today(),
'mission_id': mission.id,
}
appraisal = self.env['hr.employee.appraisal'].sudo().create(vals_list)
employee.appraisal_id = appraisal.id
return {'type': 'ir.actions.act_window_close'}

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_training_appraisal_wizard_form" model="ir.ui.view">
<field name="name">training.appraisal.wizard.form</field>
<field name="model">training.appraisal.wizard</field>
<field name="arch" type="xml">
<form string="Training Course Appraisal">
<sheet>
<group>
<field name="appraisal_plan_id"/>
</group>
</sheet>
<footer>
<button name="create_employee_appraisal"
string="Send"
type="object"
class="btn-primary"/>
<button string="Cancel"
class="btn-secondary"
special="cancel"/>
</footer>
</form>
</field>
</record>
<record id="action_training_appraisal_wizard" model="ir.actions.act_window">
<field name="name">Training Course Appraisal</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">training.appraisal.wizard</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</odoo>