Employee event alerts to hr
This commit is contained in:
parent
2be841e823
commit
e4b45574fe
|
|
@ -24,6 +24,9 @@
|
||||||
'data': [
|
'data': [
|
||||||
'security/security.xml',
|
'security/security.xml',
|
||||||
'security/ir.model.access.csv',
|
'security/ir.model.access.csv',
|
||||||
|
'data/cron.xml',
|
||||||
|
'data/mail.xml',
|
||||||
|
'views/res_config_settings.xml',
|
||||||
'views/hr_employee.xml',
|
'views/hr_employee.xml',
|
||||||
'views/bank_details.xml',
|
'views/bank_details.xml',
|
||||||
'wizards/work_location_wizard.xml'
|
'wizards/work_location_wizard.xml'
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<odoo>
|
||||||
|
<data noupdate="1">
|
||||||
|
<record model="ir.cron" id="hr_employee_event_remainder_trigger">
|
||||||
|
<field name="name">Employee: Event Remainder</field>
|
||||||
|
<field name="model_id" ref="hr.model_hr_employee"/>
|
||||||
|
<field name="state">code</field>
|
||||||
|
<field name="code">model.hr_employee_event_remainder()</field>
|
||||||
|
<field name="interval_number">1</field>
|
||||||
|
<field name="interval_type">days</field>
|
||||||
|
<field name="nextcall" eval="(DateTime.now().replace(hour=9, minute=15, second=0, microsecond=0) + timedelta(days=1)).strftime('%Y-%m-%d %H:%M:%S')"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<record id="hr_employee_event_reminder_template" model="mail.template">
|
||||||
|
<field name="name">Employee Birthday & Anniversary Reminder</field>
|
||||||
|
<field name="model_id" ref="hr.model_hr_employee"/>
|
||||||
|
<field name="email_from">{{ user.email_formatted }}</field>
|
||||||
|
<field name="email_to">hr@ftprotech.com</field> <!-- Replace with real HR email -->
|
||||||
|
<field name="subject">Upcoming Employee Events: Birthdays & Anniversaries</field>
|
||||||
|
<field name="description">Notify HR of employees with upcoming birthdays or anniversaries.</field>
|
||||||
|
<field name="body_html" type="html">
|
||||||
|
<t t-set="birthday_list" t-value="ctx.get('birthday_list')"/>
|
||||||
|
<t t-set="anniversary_list" t-value="ctx.get('anniversary_list')"/>
|
||||||
|
<p style="margin: 0px; padding: 0px; font-size: 13px;">
|
||||||
|
Dear HR Team,
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
Here are the upcoming Employee Events:
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
|
<t t-if="birthday_list">
|
||||||
|
<strong>🎂 Birthdays:</strong>
|
||||||
|
<br/>
|
||||||
|
<ul>
|
||||||
|
<t t-foreach="birthday_list" t-as="emp">
|
||||||
|
<li>
|
||||||
|
<t t-esc="emp['name']"/>
|
||||||
|
—
|
||||||
|
<t t-esc="emp['birthday']"/>
|
||||||
|
</li>
|
||||||
|
</t>
|
||||||
|
</ul>
|
||||||
|
</t>
|
||||||
|
|
||||||
|
<t t-if="anniversary_list">
|
||||||
|
<strong>💍 Marriage Anniversaries:</strong><br/>
|
||||||
|
<ul>
|
||||||
|
<t t-foreach="anniversary_list" t-as="emp">
|
||||||
|
<li>
|
||||||
|
<t t-esc="emp['name']"/> —
|
||||||
|
<t t-esc="emp['marriage_anniversary_date']"/>
|
||||||
|
</li>
|
||||||
|
</t>
|
||||||
|
</ul>
|
||||||
|
</t>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
Regards,
|
||||||
|
<br/>
|
||||||
|
<t t-out="user.name or 'Odoo Reminder Bot'"/>
|
||||||
|
</p>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
from . import res_config_settings
|
||||||
from . import hr_employee
|
from . import hr_employee
|
||||||
from . import work_location_history
|
from . import work_location_history
|
||||||
from . import education_history
|
from . import education_history
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ class HrEmployeeBase(models.AbstractModel):
|
||||||
@api.constrains('identification_id')
|
@api.constrains('identification_id')
|
||||||
def _check_identification_id(self):
|
def _check_identification_id(self):
|
||||||
for record in self:
|
for record in self:
|
||||||
if not record.identification_id.isdigit():
|
if record.identification_id and not record.identification_id.isdigit():
|
||||||
raise ValidationError("Identification ID should only contain numbers.")
|
raise ValidationError("Identification ID should only contain numbers.")
|
||||||
|
|
||||||
@api.depends('doj')
|
@api.depends('doj')
|
||||||
|
|
@ -156,4 +156,67 @@ class HrEmployee(models.Model):
|
||||||
passport_issued_location = fields.Char(string='Passport Issued Location')
|
passport_issued_location = fields.Char(string='Passport Issued Location')
|
||||||
|
|
||||||
previous_company_pf_no = fields.Char(string='Previous Company PF No')
|
previous_company_pf_no = fields.Char(string='Previous Company PF No')
|
||||||
previous_company_uan_no = fields.Char(string='Previous Company UAN No')
|
previous_company_uan_no = fields.Char(string='Previous Company UAN No')
|
||||||
|
|
||||||
|
def hr_employee_event_remainder(self):
|
||||||
|
self.send_birthday_reminders()
|
||||||
|
today = fields.Date.today()
|
||||||
|
tomorrow = today + timedelta(days=1)
|
||||||
|
day_after = today + timedelta(days=2)
|
||||||
|
|
||||||
|
tomorrow_md = tomorrow.strftime('-%m-%d')
|
||||||
|
day_after_md = day_after.strftime('-%m-%d')
|
||||||
|
|
||||||
|
if today.weekday() == 4: # Friday
|
||||||
|
birthday_domain = ['|', ('birthday', 'like', f'%{tomorrow_md}'), ('birthday', 'like', f'%{day_after_md}')]
|
||||||
|
anniversary_domain = [('marital', '=', 'married'), '|',
|
||||||
|
('marriage_anniversary_date','like', f'%{tomorrow_md}'),
|
||||||
|
('marriage_anniversary_date', 'like', f'%{day_after_md}')]
|
||||||
|
else:
|
||||||
|
birthday_domain = [('birthday','like', f'%{tomorrow_md}')]
|
||||||
|
anniversary_domain = [('marital', '=', 'married'),
|
||||||
|
('marriage_anniversary_date','like', f'%{tomorrow_md}')]
|
||||||
|
|
||||||
|
birthday_emps = self.search(birthday_domain)
|
||||||
|
anniversary_emps = self.search(anniversary_domain)
|
||||||
|
|
||||||
|
birthday_list = [{'name': emp.name, 'birthday': emp.birthday} for emp in birthday_emps]
|
||||||
|
anniversary_list = [{'name': emp.name, 'marriage_anniversary_date': emp.marriage_anniversary_date} for emp in anniversary_emps]
|
||||||
|
context = {
|
||||||
|
'birthday_list': birthday_list,
|
||||||
|
'anniversary_list': anniversary_list,
|
||||||
|
}
|
||||||
|
email_values = {'auto_delete': True}
|
||||||
|
template = self.env.ref('hr_employee_extended.hr_employee_event_reminder_template')
|
||||||
|
if template and (birthday_list or anniversary_list):
|
||||||
|
hr_id = self.env['ir.config_parameter'].sudo().get_param('hr_employee_extended.emp_hr_id')
|
||||||
|
if hr_id:
|
||||||
|
emp_hr = self.env['res.users'].sudo().browse(int(hr_id)) if hr_id else False
|
||||||
|
email_values['email_to'] = emp_hr.email
|
||||||
|
else:
|
||||||
|
emp_hr = self.env['res.users'].sudo().search([('groups_id', 'in', self.env.ref('hr.group_hr_manager').id)],limit=1)
|
||||||
|
|
||||||
|
# Use `self[0]` as dummy record for sending
|
||||||
|
template.with_context(**context).send_mail(
|
||||||
|
emp_hr.employee_id.id, force_send=True, email_values=email_values,
|
||||||
|
)
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def send_birthday_reminders(self):
|
||||||
|
today = datetime.today().strftime('%m-%d')
|
||||||
|
employees = self.search([('birthday', '!=', False)])
|
||||||
|
|
||||||
|
birthday_emps = employees.filtered(
|
||||||
|
lambda emp: emp.birthday.strftime('%m-%d') == today
|
||||||
|
)
|
||||||
|
|
||||||
|
if birthday_emps:
|
||||||
|
channel = self.env['discuss.channel'].search([('name', 'ilike', 'General')], limit=1)
|
||||||
|
if channel:
|
||||||
|
for emp in birthday_emps:
|
||||||
|
message = f"🎉 Happy Birthday {emp.name}! 🎂 Wishing you a fantastic day! 🥳"
|
||||||
|
channel.message_post(
|
||||||
|
body=message,
|
||||||
|
message_type='comment',
|
||||||
|
subtype_xmlid='mail.mt_comment'
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from odoo import fields, models, api, _
|
||||||
|
|
||||||
|
|
||||||
|
class ResConfigSettings(models.TransientModel):
|
||||||
|
_inherit = 'res.config.settings'
|
||||||
|
|
||||||
|
emp_hr_id = fields.Many2one('res.users',config_parameter='hr_employee_extended.emp_hr_id', string='Employee HR',
|
||||||
|
domain=lambda self: [
|
||||||
|
('groups_id', 'in', self.env.ref('hr.group_hr_manager').id)])
|
||||||
|
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<record id="res_config_settings_view_form" model="ir.ui.view">
|
||||||
|
<field name="name">res.config.settings.view.form.inherit.employee</field>
|
||||||
|
<field name="model">res.config.settings</field>
|
||||||
|
<field name="priority" eval="75"/>
|
||||||
|
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//block[@name='employees_setting_container']" position="after">
|
||||||
|
<block title="Employee Management" name="employee_rights_setting_container">
|
||||||
|
<setting string="HR Employee Access"
|
||||||
|
help="Select the HR responsible for employees"
|
||||||
|
id="employee_hr_access_control">
|
||||||
|
<field name="emp_hr_id"
|
||||||
|
options="{'no_quick_create': True, 'no_create_edit': True, 'no_open': True}"/>
|
||||||
|
</setting>
|
||||||
|
</block>
|
||||||
|
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
<record id="action_hr_employee_appraisal_configuration" model="ir.actions.act_window">
|
||||||
|
<field name="name">Settings</field>
|
||||||
|
<field name="res_model">res.config.settings</field>
|
||||||
|
<field name="view_mode">form</field>
|
||||||
|
<field name="target">inline</field>
|
||||||
|
<field name="context">{'module' : 'hr_appraisal', 'bin_size': False}</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<menuitem
|
||||||
|
id="menu_hr_appraisal_global_settings"
|
||||||
|
name="Settings"
|
||||||
|
parent="hr_employee_appraisal.menu_configurations"
|
||||||
|
sequence="0"
|
||||||
|
action="hr_employee_appraisal.action_hr_employee_appraisal_configuration"
|
||||||
|
groups="base.group_system"/>
|
||||||
|
|
||||||
|
|
||||||
|
</odoo>
|
||||||
|
|
@ -69,22 +69,4 @@ class HrEmployee(models.Model):
|
||||||
|
|
||||||
return self.env.cr.dictfetchall()
|
return self.env.cr.dictfetchall()
|
||||||
|
|
||||||
@api.model
|
|
||||||
def send_birthday_reminders(self):
|
|
||||||
today = datetime.today().strftime('%m-%d')
|
|
||||||
employees = self.search([('birthday', '!=', False)])
|
|
||||||
|
|
||||||
birthday_emps = employees.filtered(
|
|
||||||
lambda emp: emp.birthday.strftime('%m-%d') == today
|
|
||||||
)
|
|
||||||
|
|
||||||
if birthday_emps:
|
|
||||||
channel = self.env['discuss.channel'].search([('name', 'ilike', 'General')], limit=1)
|
|
||||||
if channel:
|
|
||||||
for emp in birthday_emps:
|
|
||||||
message = f"🎉 Happy Birthday {emp.name}! 🎂 Wishing you a fantastic day! 🥳"
|
|
||||||
channel.message_post(
|
|
||||||
body=message,
|
|
||||||
message_type='comment',
|
|
||||||
subtype_xmlid='mail.mt_comment'
|
|
||||||
)
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue