#fix:PERformancemanagement

This commit is contained in:
seshikanth 2026-07-03 10:54:28 +05:30
parent 5e617d3ff8
commit ea58c69ed8
13 changed files with 290 additions and 86 deletions

View File

@ -10,7 +10,7 @@
'company': 'FTPROTECH',
'website': 'https://www.ftprotech.in',
'depends': ['base', 'hr','hr_employee_extended'],
'depends': ['base', 'hr','hr_employee_extended','mail'],
'data': [
# 'data/reminder_corn.xml',

View File

@ -90,6 +90,7 @@ class AppraisalTemplate(models.Model):
name = fields.Char(string="Name")
employee_evaluator_name_id = fields.Many2one('employee.appraisal.evaluator', string="Employee Appraisal Evaluator")
employee_eva_id = fields.Many2one('hr.employee',string="Manager")
hr_head_employee_id = fields.Many2one('hr.employee',string="Head HR")
image_template = fields.Image(related='employee_eva_id.image_1920', string="Image")
hr_employee_id = fields.Many2one('hr.employee',string="Employee HR Employee")
employee_department_id = fields.Many2one('hr.department',string="Department")
@ -124,6 +125,10 @@ class AppraisalTemplate(models.Model):
def action_sent_employee(self):
for rec in self:
if not rec.kra_ids.name:
raise ValidationError('Please create KRA')
if not rec.kra_ids.mapped('kpi_line_ids'):
raise ValidationError('Please create KPI')
# appraisal_config_obj = self.env['employee.appraisal.template.config']
# for rec in self:
# first_stage = rec.stage_config_ids.sorted(
@ -160,6 +165,8 @@ class AppraisalTemplate(models.Model):
employee_emails = rec.employee_ids.mapped('work_email')
manager_emails = rec.manager_ids.mapped('work_email')
all_emails = employee_emails + manager_emails
partner_ids = (
self.employee_ids.mapped('user_id.partner_id'))
email_to = ",".join(filter(None, all_emails))
body_html = f"""
<div>
@ -204,6 +211,7 @@ class AppraisalTemplate(models.Model):
'default_res_ids': [rec.id],
'default_composition_mode': 'comment',
'default_email_to': email_to,
'default_partner_ids': [(6, 0, partner_ids.ids)],
'default_subject': f'Employee Appraisal - {rec.seq}',
'default_body': body_html,
'mark_appraisal_sent_appraisal': True,

View File

@ -20,6 +20,7 @@ class EmployeeAppraisal(models.Model):
name = fields.Char(string="Reference", copy=False)
employee_evaluator_name_id = fields.Many2one('employee.appraisal.evaluator', string="Employee Appraisal Evaluator")
hr_apprai_id = fields.Many2one('hr.employee')
hr_head_apprai_id = fields.Many2one('hr.employee')
managerapp_id = fields.Many2one('hr.employee', string='Manager')
# managerapp_id = fields.Many2one('hr.employee', compute='_compute_managerapp_id', string='Manager')
performance_evaluator = fields.Selection([('manager', 'Manager'), ('colleague', 'Colleague'), ('own', 'Own')])
@ -376,20 +377,20 @@ class EmployeeAppraisal(models.Model):
rec.overall_rating = '0'
rec.overall_rating_star = '0'
rec.overall_rating_value = False
@api.onchange('overall_rating_value')
def _onchange_overall_rating_value(self):
for rec in self:
if rec.overall_rating_value == 'outstanding':
rec.appraisal_percentage = 20
elif rec.overall_rating_value == 'exceed_expectation':
rec.appraisal_percentage = 15
elif rec.overall_rating_value == 'meet_expectation':
rec.appraisal_percentage = 10
elif rec.overall_rating_value == 'needs_improvements':
rec.appraisal_percentage = 5
else:
rec.appraisal_percentage = 0
#
# @api.onchange('overall_rating_value')
# def _onchange_overall_rating_value(self):
# for rec in self:
# if rec.overall_rating_value == 'outstanding':
# rec.appraisal_percentage = 20
# elif rec.overall_rating_value == 'exceed_expectation':
# rec.appraisal_percentage = 15
# elif rec.overall_rating_value == 'meet_expectation':
# rec.appraisal_percentage = 10
# elif rec.overall_rating_value == 'needs_improvements':
# rec.appraisal_percentage = 5
# else:
# rec.appraisal_percentage = 0
# @api.depends('manager_ids')
# def _compute_manager_email(self):
@ -532,86 +533,74 @@ class EmployeeAppraisal(models.Model):
raise ValidationError(
_('Please provide Finance Remarks.')
)
if not self.current_salary:
raise ValidationError(
_('Please enter Current Salary.')
)
if not self.appraisal_percentage:
raise ValidationError(
_('Please enter Appraisal Percentage.')
)
email_to = ",".join(
filter(None, [
self.employee_appraisal_id.work_email,
self.managerapp_id.work_email,
self.creator_email
])
)
# email_to = ",".join(
# filter(None, [
# self.employee_appraisal_id.work_email,
# self.managerapp_id.work_email,
# self.creator_email
# ])
# )
finance_head_group = self.env.ref('hrms_employee_appraisal.group_appraisal_finance_head')
email_list = []
partner_ids = []
for user in finance_head_group.users:
if user.partner_id.email:
email_list.append(user.partner_id.email)
if user.partner_id:
partner_ids.append(user.partner_id.id)
body_html = f"""
<div>
<p>Hello,</p>
<p>
Finance review has been completed for the appraisal of
<b>{self.employee_appraisal_id.name}</b>.
</p>
<p>
The salary revision details are given below for further approval.
</p>
<br/>
<table border="1" cellpadding="5" cellspacing="0">
<tr>
<td><b>Employee</b></td>
<td>{self.employee_appraisal_id.name or ''}</td>
</tr>
<tr>
<td><b>Department</b></td>
<td>{self.department_appraisal_id.name or ''}</td>
</tr>
<tr>
<td><b>Current Salary</b></td>
<td>{self.current_salary or 0}</td>
</tr>
<tr>
<td><b>Appraisal Percentage</b></td>
<td>{self.appraisal_percentage or 0}%</td>
</tr>
<tr>
<td><b>Appraisal Amount</b></td>
<td>{self.appraisal_amount or 0}</td>
</tr>
<tr>
<td><b>Revised Salary</b></td>
<td>{self.new_salary or 0}</td>
</tr>
<tr>
<td><b>Finance Remarks</b></td>
<td>{self.finance_remarks or ''}</td>
</tr>
</table>
<br/>
<p>
Kindly review and proceed with the next level approval.
</p>
<br/>
<p>Regards,</p>
@ -624,7 +613,8 @@ class EmployeeAppraisal(models.Model):
'default_model': 'employee.appraisal.template.config',
'default_res_ids': [self.id],
'default_composition_mode': 'comment',
'default_email_to': email_to,
'default_email_to': ",".join(email_list),
'default_partner_ids': [(6, 0, list(set(partner_ids)))],
'default_subject': f'Finance Approval - {self.employee_appraisal_id.name}',
'default_body': body_html,
'move_next_stage': True,
@ -647,13 +637,21 @@ class EmployeeAppraisal(models.Model):
_('Please provide Finance Head Remarks.')
)
email_to = ",".join(
filter(None, [
self.employee_appraisal_id.work_email,
self.managerapp_id.work_email,
self.creator_email
])
)
# email_to = ",".join(
# filter(None, [
# self.employee_appraisal_id.work_email,
# self.managerapp_id.work_email,
# self.creator_email
# ])
# )
management_group = self.env.ref('hrms_employee_appraisal.group_appraisal_management')
email_list = []
partner_ids = []
for user in management_group.users:
if user.partner_id.email:
email_list.append(user.partner_id.email)
if user.partner_id:
partner_ids.append(user.partner_id.id)
body_html = f"""
<div>
@ -728,7 +726,8 @@ class EmployeeAppraisal(models.Model):
'default_model': 'employee.appraisal.template.config',
'default_res_ids': [self.id],
'default_composition_mode': 'comment',
'default_email_to': email_to,
'default_email_to': ",".join(email_list),
'default_partner_ids': [(6, 0, list(set(partner_ids)))],
'default_subject': f'Finance Head Approval - {self.employee_appraisal_id.name}',
'default_body': body_html,
'move_next_stage': True,
@ -809,6 +808,20 @@ class EmployeeAppraisal(models.Model):
def action_sent_employee_appraisal(self):
self.ensure_one()
missing = []
for kra in self.kra_line_ids:
for kpi in kra.kpi_line_ids:
if self.template_empl_rating_bool and not kpi.manager_rating_star:
missing.append(_("Please give the Star rating for KPI '%s'.") % (kpi.question or ''))
if self.template_empl_point_bool and kpi.manager_score <= 0:
missing.append(_("Please enter the score for KPI '%s'.") % (kpi.question or ''))
if missing:
raise ValidationError("\n".join(missing))
if not self.manager_remarks:
raise ValidationError("Please give the Manager Remarks")
@ -823,6 +836,22 @@ class EmployeeAppraisal(models.Model):
creator_email
])
)
partner_ids = []
# if self.managerapp_id.user_id.partner_id:
# partner_ids.append(self.managerapp_id.user_id.partner_id.id)
# if self.employee_appraisal_id.user_id.partner_id:
# partner_ids.append(self.employee_appraisal_id.user_id.partner_id.id)
if self.hr_apprai_id.user_id.partner_id:
partner_ids.append(self.hr_apprai_id.user_id.partner_id.id)
# creator = self.env['res.users'].search(
# [('email', '=', self.creator_email)],
# limit=1
# )
# if creator.partner_id:
# partner_ids.append(creator.partner_id.id)
body_html = f"""
<div>
@ -881,6 +910,7 @@ class EmployeeAppraisal(models.Model):
'default_res_ids': [self.id],
'default_composition_mode': 'comment',
'default_email_to': emails,
'default_partner_ids': [(6, 0, list(set(partner_ids)))],
'default_subject': 'Employee Appraisal Notification',
'default_body': body_html,
'mark_appraisal_sent': True,
@ -896,12 +926,29 @@ class EmployeeAppraisal(models.Model):
def action_confirm_hr(self):
self.ensure_one()
missing = []
for kra in self.kra_line_ids:
for kpi in kra.kpi_line_ids:
if self.template_empl_rating_bool and not kpi.hr_rating_star:
missing.append(_("Please give the Star rating for KPI '%s'.") % (kpi.question or ''))
if self.template_empl_point_bool and kpi.hr_score <= 0:
missing.append(_("Please enter the score for KPI '%s'.") % (kpi.question or ''))
if missing:
raise ValidationError("\n".join(missing))
if not self.hr_remarks:
raise ValidationError ('Please Provide the Remarks')
email_to = self.managerapp_id.work_email or ''
partner_ids = []
if self.hr_head_apprai_id.user_id.partner_id:
partner_ids.append(self.hr_head_apprai_id.user_id.partner_id.id)
body_html = f"""
<div>
<p>Hello,</p>
@ -945,6 +992,7 @@ class EmployeeAppraisal(models.Model):
'default_res_ids': [self.id],
'default_composition_mode': 'comment',
'default_email_to': email_to,
'default_partner_ids': [(6, 0, list(set(partner_ids)))],
'default_subject': f'HR Evaluation Completed - {self.employee_appraisal_id.name}',
'default_body': body_html,
'move_hr_next_stage': True,
@ -966,7 +1014,18 @@ class EmployeeAppraisal(models.Model):
_('Please provide HR Head Remarks.')
)
email_to = self.created_by_id.work_email or ''
# email_to = self.created_by_id.work_email or ''
# partner_ids = []
# if self.created_by_id.user_id.partner_id:
# partner_ids.append(self.created_by_id.user_id.partner_id.id)
finance_group = self.env.ref('hrms_employee_appraisal.group_appraisal_finance')
email_list = []
partner_ids = []
for user in finance_group.users:
if user.partner_id.email:
email_list.append(user.partner_id.email)
if user.partner_id:
partner_ids.append(user.partner_id.id)
body_html = f"""
<div>
@ -1007,7 +1066,8 @@ class EmployeeAppraisal(models.Model):
'default_model': 'employee.appraisal.template.config',
'default_res_ids': [self.id],
'default_composition_mode': 'comment',
'default_email_to': email_to,
'default_email_to': ",".join(email_list),
'default_partner_ids': [(6, 0, list(set(partner_ids)))],
'default_subject': f'HR Head Approval - {self.employee_appraisal_id.name}',
'default_body': body_html,
'move_hr_head_next_stage': True,
@ -1023,12 +1083,35 @@ class EmployeeAppraisal(models.Model):
def action_send_colleague_feedback(self):
for rec in self:
# for kra in rec.kra_line_ids:
# for kpi in kra.kpi_line_ids:
# if rec.template_empl_rating_bool and not kpi.rating_star:
# raise ValidationError(_(
# "Please give the self rating for the KPI '%s' before sending the colleague feedback."
# ) % (kpi.question or ''))
# if rec.template_empl_point_bool and not kpi.employee_score <= 0:
# raise ValidationError(_("Please enter the self score for the KPI '%s' before sending the colleague feedback."
# ) % (kpi.question or ''))
missing = []
for kra in rec.kra_line_ids:
for kpi in kra.kpi_line_ids:
if rec.template_empl_rating_bool and not kpi.rating_star:
missing.append(_("Please give the self rating for KPI '%s'.") % (kpi.question or ''))
if rec.template_empl_point_bool and kpi.employee_score <= 0:
missing.append(_("Please enter the self score for KPI '%s'.") % (kpi.question or ''))
if missing:
raise ValidationError("\n".join(missing))
employees = self.env['hr.employee'].search([
('department_id', '=', rec.department_appraisal_id.id),
('id', '!=', rec.employee_appraisal_id.id)
])
vals = []
email_list = []
for emp in employees:
already_exists = self.env['colleague.feedback'].search([
('employee_appraisal_feed_id', '=', rec.id),
@ -1039,9 +1122,13 @@ class EmployeeAppraisal(models.Model):
'colleague_feed_id': emp.id,
}))
rec.colleague_feed_ids = vals
if self.managerapp_id and self.managerapp_id.work_email:
email_list.append(self.managerapp_id.work_email)
email_to = ",".join(filter(None, email_list))
email_list = []
partner_ids = []
if rec.managerapp_id:
if rec.managerapp_id.work_email:
email_list.append(rec.managerapp_id.work_email)
if rec.managerapp_id.user_id.partner_id:
partner_ids.append(rec.managerapp_id.user_id.partner_id.id)
body_html = f"""
<div>
@ -1067,7 +1154,8 @@ class EmployeeAppraisal(models.Model):
'default_model': 'employee.appraisal.template.config',
'default_res_ids': [self.id],
'default_composition_mode': 'comment',
'default_email_to': email_to,
'default_email_to': ",".join(email_list),
'default_partner_ids': [(6, 0, partner_ids)],
'default_subject': f'Colleague Feedback Request - {self.employee_appraisal_id.name}',
'default_body': body_html,
'mark_colleague_feedback_sent': True,

View File

@ -1,4 +1,5 @@
from odoo import api, fields, models
from odoo.exceptions import ValidationError
class HrHeadNofication(models.Model):
@ -37,6 +38,13 @@ class HrHeadNofication(models.Model):
hr_users_ids = fields.Many2many('res.users', string="HR Team", copy=False, domain=_get_hr_users_domain)
@api.constrains('start_date','end_date')
def check_dates(self):
for rec in self:
if rec.start_date and rec.end_date and rec.end_date <= rec.start_date:
raise ValidationError("End date must be before start date.")
@api.model
def create(self, vals):
if vals.get('seq', 'New') == 'New':
@ -68,6 +76,9 @@ class HrHeadNofication(models.Model):
hr_emails = self.hr_users_ids.mapped('email')
email_to = ",".join(filter(None, hr_emails))
partner_ids = []
if self.hr_users_ids.partner_id:
partner_ids = self.hr_users_ids.partner_id.ids
body_html = f"""
<div>
@ -108,6 +119,7 @@ class HrHeadNofication(models.Model):
'default_res_ids': [self.id],
'default_composition_mode': 'comment',
'default_email_to': email_to,
'default_partner_ids':[(6,0,list(set(partner_ids)))],
'default_subject': self.name,
'default_body': body_html,
'mark_hr_notification_sent': True,

View File

@ -17,6 +17,7 @@ class HrNoticeAppraisal(models.Model):
return self.env.user.employee_id
hr_employee_id = fields.Many2one('hr.employee', string='Employee', default=_default_employee_get)
hr_head_employe_id = fields.Many2one('hr.employee', string='HR Head')
notification_id = fields.Many2one('hr.head.notification','HR')
subject = fields.Char(string="Subject", required=True, tracking=True)
body = fields.Html(string="Notice Body", required=True)
@ -35,7 +36,7 @@ class HrNoticeAppraisal(models.Model):
appraisal_notice_id = fields.Many2one('employee.appraisal.year',string="Appraisal Name",domain="[('appraisal_type_id', '=', appraisal_type_id)]")
template_appraisal_id = fields.Many2one('employee.appraisal.template', string="Template")
seq = fields.Char( string="Reference",readonly=True,copy=False,default="New")
employee_rating = fields.Boolean(string="Employee Rating")
employee_rating = fields.Boolean(string="Employee star Rating")
employee_points = fields.Boolean(string="Employee Points")
cancel_reason = fields.Text(string="Cancel Reason",tracking=True)
cancelled_date = fields.Datetime(string="Cancelled On",tracking=True)
@ -137,6 +138,10 @@ class HrNoticeAppraisal(models.Model):
employee_emails = self.employee_ids.mapped('work_email')
manager_emails = self.manager_ids.mapped('work_email')
all_emails = employee_emails + manager_emails
partner_ids = (
self.employee_ids.mapped('user_id.partner_id') |
self.manager_ids.mapped('user_id.partner_id')
)
email_to = ",".join(filter(None, all_emails))
body_html = f"""
<div>
@ -187,7 +192,9 @@ class HrNoticeAppraisal(models.Model):
'default_model': 'hr.notice.appraisal',
'default_res_ids': [self.id],
'default_composition_mode': 'comment',
'default_partner_ids': [(6, 0, partner_ids.ids)],
'default_email_to': email_to,
'default_email_from': self.env.user.email_formatted,
'default_subject': self.subject,
'default_body': body_html,
'mark_notice_sent': True,
@ -277,6 +284,7 @@ class MailComposeMessage(models.TransientModel):
'name': rec.subject,
'seq': rec.seq,
'employee_eva_id': manager_id,
'hr_head_employee_id': rec.hr_head_employe_id.id,
'employee_department_id': department_id,
'employee_ids': [(6, 0, employees.ids)],
'manager_ids': [(6, 0, [manager_id])] if manager_id else [(5, 0, 0)],
@ -345,6 +353,7 @@ class MailComposeMessage(models.TransientModel):
'employee_ids': [(6, 0, rec.employee_ids.ids)],
'manager_ids': [(6, 0, rec.manager_ids.ids)],
'notice_id': rec.notice_id.id,
'hr_head_apprai_id': rec.hr_head_employee_id.id,
'start_date': rec.start_date,
'end_date': rec.end_date,
'appraisal_period_id': rec.appraisal_period_id.id,
@ -385,6 +394,7 @@ class MailComposeMessage(models.TransientModel):
'notification_id': record.id,
'hr_employee_id': employee.id,
'subject': record.name,
'hr_head_employe_id':record.hr_employee_id.id,
'appraisal_type_id':
record.appraisal_type_id.id,
'appraisal_notice_id':

View File

@ -148,47 +148,36 @@ class EmployeeAppraisalKRALine(models.Model):
manager_kra_stars = fields.Float(compute='_compute_kra_scores', store=True)
hr_kra_stars = fields.Float(compute='_compute_kra_scores', store=True)
kra_line_star_display = fields.Char(compute='_compute_kra_line_star_display', string='Rating')
kra_line_rating = fields.Char(compute="_compute_kra_line_star_display",string="Rating")
@api.depends(
'kpi_line_ids.rating_star',
'kpi_line_ids.manager_rating_star',
'kpi_line_ids.hr_rating_star'
)
@api.depends('kpi_line_ids.rating_star','kpi_line_ids.manager_rating_star','kpi_line_ids.hr_rating_star')
def _compute_kra_line_star_display(self):
for rec in self:
ratings = []
ratings += [
int(kpi.rating_star)
for kpi in rec.kpi_line_ids
if kpi.rating_star
]
ratings += [
int(kpi.manager_rating_star)
for kpi in rec.kpi_line_ids
if kpi.manager_rating_star
]
ratings += [
int(kpi.hr_rating_star)
for kpi in rec.kpi_line_ids
if kpi.hr_rating_star
]
if ratings:
avg = round(sum(ratings) / len(ratings))
stars = '' * avg + '' * (5 - avg)
rec.kra_line_star_display = f"{stars} ({avg})"
rec.kra_line_star_display = "" * avg + "" * (5 - avg)
rec.kra_line_rating = f"({avg})"
else:
rec.kra_line_star_display = "☆☆☆☆☆ (0)"
rec.kra_line_star_display = "☆☆☆☆☆"
rec.kra_line_rating = "(0)"
@api.depends(
'kpi_line_ids.employee_score',
'kpi_line_ids.manager_score',
'kpi_line_ids.hr_score'
)
@api.depends('kpi_line_ids.employee_score','kpi_line_ids.manager_score','kpi_line_ids.hr_score')
def _compute_kra_line_weightage(self):
for rec in self:
employee_total = sum(

View File

@ -5,8 +5,16 @@
}
.kra_star_display {
font-size: 22px !important;
font-weight: bold !important;
color: #FFD700 !important;
font-size: 22px !important;
font-weight: 700 !important;
text-align: center;
}
.kra_rating_display {
color: #2563EB !important; /* Blue */
font-size: 18px !important;
font-weight: 700 !important;
text-align: center;
}

View File

@ -70,12 +70,15 @@
groups="hrms_employee_appraisal.group_appraisal_hr"
class="btn-primary" invisible="stage_name != 'HR'"/>
<button name="action_head_hr"
string="HR Head Approval" type="object" class="btn-primary"
string="HR Head Approval"
groups="hrms_employee_appraisal.group_appraisal_hr_head"
type="object" class="btn-primary"
invisible="stage_name != 'HR HEAD'"/>
<!-- invisible="state != 'hr_evaluation'"/>-->
<button name="action_finance_approve" string="Finance Appraisal"
type="object" class="btn-primary" invisible="stage_name != 'FINANCE'"/>
<button name="action_finance_head" string="Finance Head Approval" type="object"
type="object" class="btn-primary"
groups="hrms_employee_appraisal.group_appraisal_finance" invisible="stage_name != 'FINANCE'"/>
<button name="action_finance_head" string="Finance Head Approval" type="object" groups="hrms_employee_appraisal.group_appraisal_finance_head"
class="btn-primary" invisible="stage_name != 'FINANCE HEAD'"/>
<button name="action_create_pip"
string="Create PIP"
@ -129,6 +132,7 @@
<field name="is_manager_reviewer" invisible="1"/>
<field name="manager_remarks" readonly="not is_manager_reviewer"/>
<field name="hr_apprai_id" string="HR" readonly="1" options="{'no_open': True}"/>
<field name="hr_head_apprai_id" string="Head HR" readonly="1" options="{'no_open': True}"/>
<field name="is_hr_reviewer" invisible="1"/>
<field name="hr_remarks" readonly="not is_hr_reviewer"/>
@ -190,6 +194,10 @@
<field name="kra_line_star_display" class="kra_star_display"
readonly="1" sum="Total stars"
column_invisible="parent.template_empl_rating_bool == False"/>
<field name="kra_line_rating"
class="kra_rating_display"
readonly="1"
column_invisible="parent.template_empl_rating_bool == False"/>
<!-- <field name="kra_line_star_demo_weightage" widget="priority"-->
<!-- sum="Total Weightage" readonly="1" column_invisible="1"/>-->
<!-- <field name="kra_line_star_display" readonly="1" class="kra_star_display"/>-->

View File

@ -26,6 +26,7 @@
<field name="manager_ids" widget="many2many_tags" string="Performance Evaluator"
invisible="1"/>
<field name="employee_eva_id" readonly="1" options="{'no_open': True}"/>
<field name="hr_head_employee_id" readonly="1" options="{'no_open': True}"/>
<field name="employee_department_id" readonly="1" options="{'no_open': True}"/>
<field name="appraisal_period_type_id" string="Appraisal Type" readonly="1" options="{'no_open' : True}"/>
<field name="appraisal_period_id" string="Appraisal Period" readonly="1" options="{'no_open' : True}"/>
@ -66,7 +67,7 @@
</list>
</field>
</page>
<page string="Assigned Employees">
<page string="KRA Assigned Employees">
<field name="employee_ids" widget="many2many_tags"/>
<field name="mail_sent_employee_ids" widget="many2many_tags"/>
</page>

View File

@ -43,6 +43,7 @@
<field name="subject" readonly="1"/>
<field name="start_date" readonly="1" force_save="1"/>
<field name="end_date" readonly="1" force_save="1"/>
<field name="hr_head_employe_id" readonly="1" options="{'no_open': True}"/>
</group>
<group>
<field name="employee_ids" widget="many2many_tags" required="1"
@ -51,8 +52,8 @@
<field name="hr_department_ids" widget="many2many_tags" readonly="state != 'draft'"/>
<field name="stage_config" widget="many2many_tags" required="1"
readonly="1"/>
<field name="employee_rating" readonly="state != 'draft'"/>
<field name="employee_points" readonly="state != 'draft'"/>
<field name="employee_rating" readonly="state != 'draft' or employee_points"/>
<field name="employee_points" readonly="state != 'draft' or employee_rating"/>
</group>
</group>
<group>
@ -169,7 +170,7 @@
</group>
</group>
<notebook>
<page string="Notification Message">
<page string="Notice Body">
<field name="body" widget="html" readonly="state != 'draft'"/>
</page>
<page string="Audit">
@ -220,5 +221,19 @@
groups="group_appraisal_hr_head,group_appraisal_management"
sequence="01"/>
<record id="mail_compose_message_form_inherit_from" model="ir.ui.view">
<field name="name">mail.compose.message.form.inherit.from</field>
<field name="model">mail.compose.message</field>
<field name="inherit_id" ref="mail.email_compose_message_wizard_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='partner_ids']" position="before">
<field name="email_from"/>
</xpath>
</field>
</record>
</odoo>

View File

@ -14,6 +14,7 @@
'data': [
'data/project_task_data.xml',
'reports/draft_leave_template.xml',
'views/hr_leave_views.xml',
'views/hr_leave_type.xml',
'views/hr_leave_allocation.xml',

View File

@ -26,6 +26,10 @@ class HrLeave(models.Model):
def action_draft(self):
res = super().action_draft()
template = self.env.ref(
"leaves_timesheets_extended.email_template_leave_draft_notification"
)
default_project = self.env.ref(
'leaves_timesheets_extended.project_internal_leave'
)
@ -69,6 +73,11 @@ class HrLeave(models.Model):
leave.timesheet_line_id = analytic_line.id
template.send_mail(
leave.id,
force_send=True,
)
return res
def action_refuse(self):

View File

@ -0,0 +1,55 @@
<odoo>
<record id="email_template_leave_draft_notification" model="mail.template">
<field name="name">Leave Draft Notification</field>
<field name="model_id" ref="hr_holidays.model_hr_leave"/>
<field name="subject">Leave Request from ${object.employee_id.name}</field>
<field name="email_from">${user.email_formatted}</field>
<field name="email_to">${object._get_responsible_for_approval()[:1].email}</field>
<field name="body_html" type="html">
<div>
<p>Dear Manager,</p>
<p>
A leave request has been submitted by
<strong>${object.employee_id.name}</strong>.
</p>
<table border="1" cellpadding="6" cellspacing="0">
<tr>
<td>
<b>Employee</b>
</td>
<td>${object.employee_id.name}</td>
</tr>
<tr>
<td>
<b>Leave Type</b>
</td>
<td>${object.holiday_status_id.name}</td>
</tr>
<tr>
<td>
<b>From</b>
</td>
<td>${object.request_date_from}</td>
</tr>
<tr>
<td>
<b>To</b>
</td>
<td>${object.request_date_to}</td>
</tr>
<tr>
<td>
<b>Reason</b>
</td>
<td>${object.name or ''}</td>
</tr>
</table>
<br/>
<p>Please log in to Odoo and review this leave request.</p>
<br/>
<p>Regards,</p>
<p>${user.name}</p>
</div>
</field>
</record>
</odoo>