mirror of
https://github.com/bringout/oca-ocb-hr.git
synced 2026-04-27 10:51:59 +02:00
Initial commit: Hr packages
This commit is contained in:
commit
62531cd146
2820 changed files with 1432848 additions and 0 deletions
|
|
@ -0,0 +1,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import holidays_summary_report
|
||||
from . import hr_leave_report
|
||||
from . import hr_leave_report_calendar
|
||||
from . import hr_leave_employee_type_report
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,132 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import babel.dates
|
||||
import calendar
|
||||
|
||||
from datetime import timedelta
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tools.misc import format_date, get_lang
|
||||
|
||||
|
||||
class HrHolidaySummaryReport(models.AbstractModel):
|
||||
_name = 'report.hr_holidays.report_holidayssummary'
|
||||
_description = 'Holidays Summary Report'
|
||||
|
||||
def _get_header_info(self, start_date, holiday_type):
|
||||
st_date = fields.Date.from_string(start_date)
|
||||
if holiday_type == 'Confirmed':
|
||||
holiday_type = _('Confirmed')
|
||||
elif holiday_type == 'Approved':
|
||||
holiday_type = _('Approved')
|
||||
else:
|
||||
holiday_type = _('Confirmed and Approved')
|
||||
return {
|
||||
'start_date': format_date(self.env, st_date),
|
||||
'end_date': format_date(self.env, st_date + relativedelta(days=59)),
|
||||
'holiday_type': holiday_type
|
||||
}
|
||||
|
||||
def _date_is_day_off(self, date):
|
||||
return date.weekday() in (calendar.SATURDAY, calendar.SUNDAY,)
|
||||
|
||||
def _get_day(self, start_date):
|
||||
res = []
|
||||
start_date = fields.Date.from_string(start_date)
|
||||
for x in range(0, 60):
|
||||
color = '#ababab' if self._date_is_day_off(start_date) else ''
|
||||
res.append({'day_str': babel.dates.get_day_names('abbreviated', locale=get_lang(self.env).code)[start_date.weekday()], 'day': start_date.day, 'color': color})
|
||||
start_date = start_date + relativedelta(days=1)
|
||||
return res
|
||||
|
||||
def _get_months(self, start_date):
|
||||
# it works for geting month name between two dates.
|
||||
res = []
|
||||
start_date = fields.Date.from_string(start_date)
|
||||
end_date = start_date + relativedelta(days=59)
|
||||
while start_date <= end_date:
|
||||
last_date = start_date + relativedelta(day=1, months=+1, days=-1)
|
||||
if last_date > end_date:
|
||||
last_date = end_date
|
||||
month_days = (last_date - start_date).days + 1
|
||||
res.append({'month_name': babel.dates.get_month_names(locale=get_lang(self.env).code)[start_date.month], 'days': month_days})
|
||||
start_date += relativedelta(day=1, months=+1)
|
||||
return res
|
||||
|
||||
def _get_leaves_summary(self, start_date, empid, holiday_type):
|
||||
res = []
|
||||
count = 0
|
||||
start_date = fields.Date.from_string(start_date)
|
||||
end_date = start_date + relativedelta(days=59)
|
||||
for index in range(0, 60):
|
||||
current = start_date + timedelta(index)
|
||||
res.append({'day': current.day, 'color': ''})
|
||||
if self._date_is_day_off(current) :
|
||||
res[index]['color'] = '#ababab'
|
||||
# count and get leave summary details.
|
||||
holiday_type = ['confirm','validate'] if holiday_type == 'both' else ['confirm'] if holiday_type == 'Confirmed' else ['validate']
|
||||
holidays = self.env['hr.leave'].search([
|
||||
('employee_id', '=', empid), ('state', 'in', holiday_type),
|
||||
('date_from', '<=', str(end_date)),
|
||||
('date_to', '>=', str(start_date))
|
||||
])
|
||||
for holiday in holidays:
|
||||
# Convert date to user timezone, otherwise the report will not be consistent with the
|
||||
# value displayed in the interface.
|
||||
date_from = fields.Datetime.from_string(holiday.date_from)
|
||||
date_from = fields.Datetime.context_timestamp(holiday, date_from).date()
|
||||
date_to = fields.Datetime.from_string(holiday.date_to)
|
||||
date_to = fields.Datetime.context_timestamp(holiday, date_to).date()
|
||||
for index in range(0, ((date_to - date_from).days + 1)):
|
||||
if date_from >= start_date and date_from <= end_date:
|
||||
res[(date_from-start_date).days]['color'] = holiday.holiday_status_id.color_name
|
||||
date_from += timedelta(1)
|
||||
count += holiday.number_of_days
|
||||
employee = self.env['hr.employee'].browse(empid)
|
||||
return {'emp': employee.name, 'display': res, 'sum': count}
|
||||
|
||||
def _get_data_from_report(self, data):
|
||||
res = []
|
||||
Employee = self.env['hr.employee']
|
||||
if 'depts' in data:
|
||||
for department in self.env['hr.department'].browse(data['depts']):
|
||||
res.append({
|
||||
'dept': department.name,
|
||||
'data': [
|
||||
self._get_leaves_summary(data['date_from'], emp.id, data['holiday_type'])
|
||||
for emp in Employee.search([('department_id', '=', department.id)])
|
||||
],
|
||||
'color': self._get_day(data['date_from']),
|
||||
})
|
||||
elif 'emp' in data:
|
||||
res.append({'data': [
|
||||
self._get_leaves_summary(data['date_from'], emp.id, data['holiday_type'])
|
||||
for emp in Employee.browse(data['emp'])
|
||||
]})
|
||||
return res
|
||||
|
||||
def _get_holidays_status(self):
|
||||
res = []
|
||||
for holiday in self.env['hr.leave.type'].search([]):
|
||||
res.append({'color': holiday.color_name, 'name': holiday.name})
|
||||
return res
|
||||
|
||||
@api.model
|
||||
def _get_report_values(self, docids, data=None):
|
||||
if not data.get('form'):
|
||||
raise UserError(_("Form content is missing, this report cannot be printed."))
|
||||
|
||||
holidays_report = self.env['ir.actions.report']._get_report_from_name('hr_holidays.report_holidayssummary')
|
||||
holidays = self.env['hr.leave'].browse(self.ids)
|
||||
return {
|
||||
'doc_ids': self.ids,
|
||||
'doc_model': holidays_report.model,
|
||||
'docs': holidays,
|
||||
'get_header_info': self._get_header_info(data['form']['date_from'], data['form']['holiday_type']),
|
||||
'get_day': self._get_day(data['form']['date_from']),
|
||||
'get_months': self._get_months(data['form']['date_from']),
|
||||
'get_data_from_report': self._get_data_from_report(data['form']),
|
||||
'get_holidays_status': self._get_holidays_status(),
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0"?>
|
||||
<odoo>
|
||||
|
||||
<record id="action_report_holidayssummary" model="ir.actions.report">
|
||||
<field name="name">Time Off Summary</field>
|
||||
<field name="model">hr.holidays.summary.dept</field>
|
||||
<field name="report_type">qweb-pdf</field>
|
||||
<field name="report_name">hr_holidays.report_holidayssummary</field>
|
||||
<field name="report_file">hr_holidays.report_holidayssummary</field>
|
||||
</record>
|
||||
|
||||
<record id="action_report_holidayssummary" model="ir.actions.report">
|
||||
<field name="paperformat_id" ref="hr_holidays.paperformat_hrsummary"/>
|
||||
</record>
|
||||
|
||||
<record id="action_report_holidayssummary2" model="ir.actions.report">
|
||||
<field name="name">Time Off Summary</field>
|
||||
<field name="model">hr.leave.allocation</field>
|
||||
<field name="report_type">qweb-pdf</field>
|
||||
<field name="report_name">hr_holidays.report_holidayssummary</field>
|
||||
<field name="report_file">hr_holidays.report_holidayssummary</field>
|
||||
</record>
|
||||
|
||||
<record id="action_report_holidayssummary" model="ir.actions.report">
|
||||
<field name="paperformat_id" ref="hr_holidays.paperformat_hrsummary"/>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<template id="report_holidayssummary">
|
||||
<t t-call="web.html_container">
|
||||
<t t-call="web.internal_layout">
|
||||
<div class="page">
|
||||
<h3 class="mb32">Time Off Summary</h3>
|
||||
<t t-set="info" t-value="get_header_info"/>
|
||||
<h3 class="text-center mb32">
|
||||
Analyze from <u><t t-esc="info['start_date']"/></u> to <u><t t-esc="info['end_date']"/></u> of the <u><t t-esc="info['holiday_type']"/></u> Time Off.
|
||||
</h3>
|
||||
|
||||
<table class="table table-bordered mb32" style="table-layout:auto">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Month</th>
|
||||
<t t-foreach="get_months" t-as="month">
|
||||
<th class="text-center" colspan=<t t-esc="month['days']"/>><t t-esc="month['month_name']"/></th>
|
||||
</t>
|
||||
<th/>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan="2">
|
||||
<strong>Departments and Employees</strong>
|
||||
</td>
|
||||
<t t-foreach="get_day" t-as="day">
|
||||
<td class="text-center oe_leftfit oe_rightfit" style="background-color:<t t-esc="day['color']"/>!important; font-size: 8px; min-width: 18px"> <t t-esc="day['day_str']"/></td>
|
||||
</t>
|
||||
<td/>
|
||||
</tr>
|
||||
<tr>
|
||||
<t t-foreach="get_day" t-as="day">
|
||||
<td class="text-center oe_leftfit oe_rightfit" style="background-color:<t t-esc="day['color']"/>!important; font-size: 10px" > <t t-esc="day['day']"/></td>
|
||||
</t>
|
||||
<td class="text-center">Sum</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<t t-foreach="get_data_from_report" t-as="obj">
|
||||
<tr t-if="'dept' in obj">
|
||||
<td style="background-color:#ababab">
|
||||
<strong><t t-esc="obj['dept']"/></strong>
|
||||
</td>
|
||||
<t t-foreach="obj['color']" t-as="c">
|
||||
<td style=background-color:<t t-esc="c['color']"/> !important/>
|
||||
</t>
|
||||
<td/>
|
||||
</tr>
|
||||
<tr t-foreach="obj['data']" t-as="emp">
|
||||
<td><t t-esc="emp['emp']"/></td>
|
||||
<t t-foreach="emp['display']" t-as="details">
|
||||
<td style=background-color:<t t-esc="details['color']"/> !important />
|
||||
</t>
|
||||
<td class="text-center"><strong><t t-esc="emp['sum']"/></strong></td>
|
||||
</tr>
|
||||
</t>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="col-3 offset-5 mt32">
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-1">Color</th>
|
||||
<th class="text-center">Time Off Type</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr t-foreach="get_holidays_status" t-as="status">
|
||||
<td style=background-color:<t t-esc="status['color']"/>!important ></td>
|
||||
<td><t t-esc="status['name']"/></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models, tools, _
|
||||
|
||||
|
||||
class LeaveReport(models.Model):
|
||||
_name = "hr.leave.employee.type.report"
|
||||
_description = 'Time Off Summary / Report'
|
||||
_auto = False
|
||||
_order = "date_from DESC, employee_id"
|
||||
|
||||
employee_id = fields.Many2one('hr.employee', string="Employee", readonly=True)
|
||||
active_employee = fields.Boolean(readonly=True)
|
||||
number_of_days = fields.Float('Number of Days', readonly=True, group_operator="sum")
|
||||
department_id = fields.Many2one('hr.department', string='Department', readonly=True)
|
||||
leave_type = fields.Many2one("hr.leave.type", string="Leave Type", readonly=True)
|
||||
holiday_status = fields.Selection([
|
||||
('taken', 'Taken'), #taken = validated
|
||||
('left', 'Left'),
|
||||
('planned', 'Planned')
|
||||
])
|
||||
state = fields.Selection([
|
||||
('draft', 'To Submit'),
|
||||
('cancel', 'Cancelled'),
|
||||
('confirm', 'To Approve'),
|
||||
('refuse', 'Refused'),
|
||||
('validate1', 'Second Approval'),
|
||||
('validate', 'Approved')
|
||||
], string='Status', readonly=True)
|
||||
date_from = fields.Datetime('Start Date', readonly=True)
|
||||
date_to = fields.Datetime('End Date', readonly=True)
|
||||
company_id = fields.Many2one('res.company', string="Company", readonly=True)
|
||||
|
||||
def init(self):
|
||||
tools.drop_view_if_exists(self._cr, 'hr_leave_employee_type_report')
|
||||
|
||||
self._cr.execute("""
|
||||
CREATE or REPLACE view hr_leave_employee_type_report as (
|
||||
SELECT row_number() over(ORDER BY leaves.employee_id) as id,
|
||||
leaves.employee_id as employee_id,
|
||||
leaves.active_employee as active_employee,
|
||||
leaves.number_of_days as number_of_days,
|
||||
leaves.department_id as department_id,
|
||||
leaves.leave_type as leave_type,
|
||||
leaves.holiday_status as holiday_status,
|
||||
leaves.state as state,
|
||||
leaves.date_from as date_from,
|
||||
leaves.date_to as date_to,
|
||||
leaves.company_id as company_id
|
||||
FROM (SELECT
|
||||
allocation.employee_id as employee_id,
|
||||
employee.active as active_employee,
|
||||
CASE
|
||||
WHEN allocation.id = min_allocation_id.min_id
|
||||
THEN aggregate_allocation.number_of_days - COALESCE(aggregate_leave.number_of_days, 0)
|
||||
ELSE 0
|
||||
END as number_of_days,
|
||||
allocation.department_id as department_id,
|
||||
allocation.holiday_status_id as leave_type,
|
||||
allocation.state as state,
|
||||
allocation.date_from as date_from,
|
||||
allocation.date_to as date_to,
|
||||
'left' as holiday_status,
|
||||
allocation.employee_company_id as company_id
|
||||
FROM hr_leave_allocation as allocation
|
||||
INNER JOIN hr_employee as employee ON (allocation.employee_id = employee.id)
|
||||
|
||||
/* Obtain the minimum id for a given employee and type of leave */
|
||||
LEFT JOIN
|
||||
(SELECT employee_id, holiday_status_id, min(id) as min_id
|
||||
FROM hr_leave_allocation GROUP BY employee_id, holiday_status_id) min_allocation_id
|
||||
on (allocation.employee_id=min_allocation_id.employee_id and allocation.holiday_status_id=min_allocation_id.holiday_status_id)
|
||||
|
||||
/* Obtain the sum of allocations (validated) */
|
||||
LEFT JOIN
|
||||
(SELECT employee_id, holiday_status_id,
|
||||
sum(CASE WHEN state = 'validate' and active = True THEN number_of_days ELSE 0 END) as number_of_days
|
||||
FROM hr_leave_allocation
|
||||
GROUP BY employee_id, holiday_status_id) aggregate_allocation
|
||||
on (allocation.employee_id=aggregate_allocation.employee_id and allocation.holiday_status_id=aggregate_allocation.holiday_status_id)
|
||||
|
||||
/* Obtain the sum of requested leaves (validated) */
|
||||
LEFT JOIN
|
||||
(SELECT employee_id, holiday_status_id,
|
||||
sum(CASE WHEN state IN ('validate', 'validate1') THEN number_of_days ELSE 0 END) as number_of_days
|
||||
FROM hr_leave
|
||||
|
||||
GROUP BY employee_id, holiday_status_id) aggregate_leave
|
||||
on (allocation.employee_id=aggregate_leave.employee_id and allocation.holiday_status_id = aggregate_leave.holiday_status_id)
|
||||
|
||||
UNION ALL SELECT
|
||||
request.employee_id as employee_id,
|
||||
employee.active as active_employee,
|
||||
request.number_of_days as number_of_days,
|
||||
request.department_id as department_id,
|
||||
request.holiday_status_id as leave_type,
|
||||
request.state as state,
|
||||
request.date_from as date_from,
|
||||
request.date_to as date_to,
|
||||
CASE
|
||||
WHEN request.state IN ('validate1', 'validate') THEN 'taken'
|
||||
WHEN request.state = 'confirm' THEN 'planned'
|
||||
END as holiday_status,
|
||||
request.employee_company_id as company_id
|
||||
FROM hr_leave as request
|
||||
INNER JOIN hr_employee as employee ON (request.employee_id = employee.id)
|
||||
WHERE request.state IN ('confirm', 'validate', 'validate1')) leaves
|
||||
);
|
||||
""")
|
||||
|
||||
@api.model
|
||||
def action_time_off_analysis(self):
|
||||
domain = []
|
||||
if self.env.context.get('active_ids'):
|
||||
domain = [('employee_id', 'in', self.env.context.get('active_ids', []))]
|
||||
|
||||
return {
|
||||
'name': _('Time Off Analysis'),
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'hr.leave.employee.type.report',
|
||||
'view_mode': 'pivot',
|
||||
'search_view_id': [self.env.ref('hr_holidays.view_search_hr_holidays_employee_type_report').id],
|
||||
'domain': domain,
|
||||
'context': {
|
||||
'search_default_year': True,
|
||||
'search_default_company': True,
|
||||
'search_default_employee': True,
|
||||
'group_expand': True,
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0"?>
|
||||
<odoo>
|
||||
<record id="view_search_hr_holidays_employee_type_report" model="ir.ui.view">
|
||||
<field name="name">hr.holidays.filter</field>
|
||||
<field name="model">hr.leave.employee.type.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Time Off">
|
||||
<field name="employee_id"/>
|
||||
<field name="date_from"/>
|
||||
<filter name="year" date="date_from" default_period="this_year" string="Period"/>
|
||||
<filter string="Company" name="company" context="{'group_by':'company_id'}" groups="base.group_multi_company"/>
|
||||
<filter string="Employee" name="employee" context="{'group_by':'employee_id'}"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="hr_leave_employee_type_report" model="ir.ui.view">
|
||||
<field name="name">hr.leave.employee.type.report.view.pivot</field>
|
||||
<field name="model">hr.leave.employee.type.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<pivot sample="1" disable_linking="1">
|
||||
<field name="employee_id" type="row"/>
|
||||
<field name="number_of_days" type="measure"/>
|
||||
<field name="leave_type" type="col"/>
|
||||
<field name="holiday_status" type="col"/>
|
||||
</pivot>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_hr_holidays_by_employee_and_type_report" model="ir.actions.server">
|
||||
<field name="name">Time off Analysis by Employee and Time Off Type</field>
|
||||
<field name="model_id" ref="hr_holidays.model_hr_leave_employee_type_report"/>
|
||||
<field name="binding_model_id" ref="hr.model_hr_employee"/>
|
||||
<field name="state">code</field>
|
||||
<field name="groups_id" eval="[(4, ref('base.group_no_one'))]"/>
|
||||
<field name="code">
|
||||
action = model.action_time_off_analysis()
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models, tools, _
|
||||
from odoo.osv import expression
|
||||
|
||||
|
||||
class LeaveReport(models.Model):
|
||||
_name = "hr.leave.report"
|
||||
_description = 'Time Off Summary / Report'
|
||||
_auto = False
|
||||
_order = "date_from DESC, employee_id"
|
||||
|
||||
active = fields.Boolean(readonly=True)
|
||||
employee_id = fields.Many2one('hr.employee', string="Employee", readonly=True)
|
||||
leave_id = fields.Many2one('hr.leave', string="Leave Request", readonly=True)
|
||||
allocation_id = fields.Many2one('hr.leave.allocation', string="Allocation Request", readonly=True)
|
||||
active_employee = fields.Boolean(readonly=True)
|
||||
name = fields.Char('Description', readonly=True)
|
||||
number_of_days = fields.Float('Number of Days', readonly=True)
|
||||
leave_type = fields.Selection([
|
||||
('allocation', 'Allocation'),
|
||||
('request', 'Time Off')
|
||||
], string='Request Type', readonly=True)
|
||||
department_id = fields.Many2one('hr.department', string='Department', readonly=True)
|
||||
category_id = fields.Many2one('hr.employee.category', string='Employee Tag', readonly=True)
|
||||
holiday_status_id = fields.Many2one("hr.leave.type", string="Leave Type", readonly=True)
|
||||
state = fields.Selection([
|
||||
('draft', 'To Submit'),
|
||||
('cancel', 'Cancelled'),
|
||||
('confirm', 'To Approve'),
|
||||
('refuse', 'Refused'),
|
||||
('validate1', 'Second Approval'),
|
||||
('validate', 'Approved')
|
||||
], string='Status', readonly=True)
|
||||
holiday_type = fields.Selection([
|
||||
('employee', 'By Employee'),
|
||||
('category', 'By Employee Tag')
|
||||
], string='Allocation Mode', readonly=True)
|
||||
date_from = fields.Datetime('Start Date', readonly=True)
|
||||
date_to = fields.Datetime('End Date', readonly=True)
|
||||
company_id = fields.Many2one('res.company', string="Company", readonly=True)
|
||||
|
||||
def init(self):
|
||||
tools.drop_view_if_exists(self._cr, 'hr_leave_report')
|
||||
|
||||
self._cr.execute("""
|
||||
CREATE or REPLACE view hr_leave_report as (
|
||||
SELECT row_number() over(ORDER BY leaves.employee_id) as id,
|
||||
leaves.allocation_id as allocation_id, leaves.leave_id as leave_id,
|
||||
leaves.employee_id as employee_id, leaves.name as name,
|
||||
leaves.active_employee as active_employee, leaves.active as active,
|
||||
leaves.number_of_days as number_of_days, leaves.leave_type as leave_type,
|
||||
leaves.category_id as category_id, leaves.department_id as department_id,
|
||||
leaves.holiday_status_id as holiday_status_id, leaves.state as state,
|
||||
leaves.holiday_type as holiday_type, leaves.date_from as date_from,
|
||||
leaves.date_to as date_to, leaves.company_id
|
||||
from (select
|
||||
allocation.active as active,
|
||||
allocation.id as allocation_id,
|
||||
null as leave_id,
|
||||
allocation.employee_id as employee_id,
|
||||
employee.active as active_employee,
|
||||
allocation.private_name as name,
|
||||
allocation.number_of_days as number_of_days,
|
||||
allocation.category_id as category_id,
|
||||
allocation.department_id as department_id,
|
||||
allocation.holiday_status_id as holiday_status_id,
|
||||
allocation.state as state,
|
||||
allocation.holiday_type,
|
||||
allocation.date_from as date_from,
|
||||
allocation.date_to as date_to,
|
||||
'allocation' as leave_type,
|
||||
allocation.employee_company_id as company_id
|
||||
from hr_leave_allocation as allocation
|
||||
inner join hr_employee as employee on (allocation.employee_id = employee.id)
|
||||
union all select
|
||||
request.active as active,
|
||||
null as allocation_id,
|
||||
request.id as leave_id,
|
||||
request.employee_id as employee_id,
|
||||
employee.active as active_employee,
|
||||
request.private_name as name,
|
||||
(request.number_of_days * -1) as number_of_days,
|
||||
request.category_id as category_id,
|
||||
request.department_id as department_id,
|
||||
request.holiday_status_id as holiday_status_id,
|
||||
request.state as state,
|
||||
request.holiday_type,
|
||||
request.date_from as date_from,
|
||||
request.date_to as date_to,
|
||||
'request' as leave_type,
|
||||
request.employee_company_id as company_id
|
||||
from hr_leave as request
|
||||
inner join hr_employee as employee on (request.employee_id = employee.id)
|
||||
) leaves
|
||||
);
|
||||
""")
|
||||
|
||||
@api.model
|
||||
def action_time_off_analysis(self):
|
||||
domain = [('holiday_type', '=', 'employee')]
|
||||
|
||||
if self.env.context.get('active_ids'):
|
||||
domain = expression.AND([
|
||||
domain,
|
||||
[('employee_id', 'in', self.env.context.get('active_ids', []))]
|
||||
])
|
||||
|
||||
return {
|
||||
'name': _('Time Off Analysis'),
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'hr.leave.report',
|
||||
'view_mode': 'tree,pivot,form',
|
||||
'search_view_id': [self.env.ref('hr_holidays.view_hr_holidays_filter_report').id],
|
||||
'domain': domain,
|
||||
'context': {
|
||||
'search_default_group_type': True,
|
||||
'search_default_year': True,
|
||||
'search_default_validated': True,
|
||||
'search_default_active_employee': True,
|
||||
}
|
||||
}
|
||||
|
||||
def action_open_record(self):
|
||||
self.ensure_one()
|
||||
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_mode': 'form',
|
||||
'res_id': self.leave_id.id if self.leave_id else self.allocation_id.id,
|
||||
'res_model': 'hr.leave' if self.leave_id else 'hr.leave.allocation',
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models, tools, SUPERUSER_ID
|
||||
|
||||
from odoo.addons.base.models.res_partner import _tz_get
|
||||
|
||||
|
||||
class LeaveReportCalendar(models.Model):
|
||||
_name = "hr.leave.report.calendar"
|
||||
_description = 'Time Off Calendar'
|
||||
_auto = False
|
||||
_order = "start_datetime DESC, employee_id"
|
||||
|
||||
name = fields.Char(string='Name', readonly=True)
|
||||
start_datetime = fields.Datetime(string='From', readonly=True)
|
||||
stop_datetime = fields.Datetime(string='To', readonly=True)
|
||||
tz = fields.Selection(_tz_get, string="Timezone", readonly=True)
|
||||
duration = fields.Float(string='Duration', readonly=True)
|
||||
employee_id = fields.Many2one('hr.employee', readonly=True)
|
||||
department_id = fields.Many2one('hr.department', readonly=True)
|
||||
job_id = fields.Many2one('hr.job', readonly=True)
|
||||
company_id = fields.Many2one('res.company', readonly=True)
|
||||
state = fields.Selection([
|
||||
('draft', 'To Submit'),
|
||||
('cancel', 'Cancelled'), # YTI This state seems to be unused. To remove
|
||||
('confirm', 'To Approve'),
|
||||
('refuse', 'Refused'),
|
||||
('validate1', 'Second Approval'),
|
||||
('validate', 'Approved')
|
||||
], readonly=True)
|
||||
|
||||
is_hatched = fields.Boolean('Hatched', readonly=True)
|
||||
is_striked = fields.Boolean('Striked', readonly=True)
|
||||
|
||||
def init(self):
|
||||
tools.drop_view_if_exists(self._cr, 'hr_leave_report_calendar')
|
||||
self._cr.execute("""CREATE OR REPLACE VIEW hr_leave_report_calendar AS
|
||||
(SELECT
|
||||
hl.id AS id,
|
||||
CONCAT(em.name, ': ', hl.duration_display) AS name,
|
||||
hl.date_from AS start_datetime,
|
||||
hl.date_to AS stop_datetime,
|
||||
hl.employee_id AS employee_id,
|
||||
hl.state AS state,
|
||||
hl.department_id AS department_id,
|
||||
hl.number_of_days as duration,
|
||||
em.company_id AS company_id,
|
||||
em.job_id AS job_id,
|
||||
COALESCE(
|
||||
CASE WHEN hl.holiday_type = 'employee' THEN COALESCE(rr.tz, rc.tz) END,
|
||||
cc.tz,
|
||||
'UTC'
|
||||
) AS tz,
|
||||
hl.state = 'refuse' as is_striked,
|
||||
hl.state not in ('validate', 'refuse') as is_hatched
|
||||
FROM hr_leave hl
|
||||
LEFT JOIN hr_employee em
|
||||
ON em.id = hl.employee_id
|
||||
LEFT JOIN resource_resource rr
|
||||
ON rr.id = em.resource_id
|
||||
LEFT JOIN resource_calendar rc
|
||||
ON rc.id = em.resource_calendar_id
|
||||
LEFT JOIN res_company co
|
||||
ON co.id = em.company_id
|
||||
LEFT JOIN resource_calendar cc
|
||||
ON cc.id = co.resource_calendar_id
|
||||
WHERE
|
||||
hl.state IN ('confirm', 'validate', 'validate1')
|
||||
AND hl.active IS TRUE
|
||||
);
|
||||
""")
|
||||
|
||||
def _read(self, fields):
|
||||
res = super()._read(fields)
|
||||
if self.env.context.get('hide_employee_name') and 'employee_id' in self.env.context.get('group_by', []):
|
||||
name_field = self._fields['name']
|
||||
for record in self.with_user(SUPERUSER_ID):
|
||||
self.env.cache.set(record, name_field, record.name.split(':')[-1].strip())
|
||||
return res
|
||||
|
||||
@api.model
|
||||
def get_unusual_days(self, date_from, date_to=None):
|
||||
return self.env.user.employee_id._get_unusual_days(date_from, date_to)
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
<?xml version='1.0' encoding='UTF-8' ?>
|
||||
<odoo>
|
||||
<record id="hr_leave_report_calendar_view" model="ir.ui.view">
|
||||
<field name="name">hr.leave.report.calendar.view</field>
|
||||
<field name="model">hr.leave.report.calendar</field>
|
||||
<field name="arch" type="xml">
|
||||
<calendar
|
||||
string="Time Off"
|
||||
date_start="start_datetime"
|
||||
date_stop="stop_datetime"
|
||||
mode="month"
|
||||
quick_add="False"
|
||||
color="employee_id"
|
||||
event_open_popup="True"
|
||||
js_class="time_off_calendar"
|
||||
show_unusual_days="True">
|
||||
<field name="name"/>
|
||||
<field name="employee_id" filters="1" invisible="1"/>
|
||||
<field name="is_hatched" invisible="1"/>
|
||||
</calendar>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="hr_leave_report_calendar_view_form" model="ir.ui.view">
|
||||
<field name="name">hr.leave.report.calendar.view.form</field>
|
||||
<field name="model">hr.leave.report.calendar</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Time Off">
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="start_datetime"/>
|
||||
<field name="stop_datetime"/>
|
||||
<field name="employee_id" />
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="hr_leave_report_calendar_view_search" model="ir.ui.view">
|
||||
<field name="name">hr.leave.report.calendar.view.search</field>
|
||||
<field name="model">hr.leave.report.calendar</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Department search">
|
||||
<field name="name"/>
|
||||
<field name="employee_id"/>
|
||||
<field name="department_id"/>
|
||||
<field name="job_id"/>
|
||||
<filter name="my_team" string="My Team" domain="['|', ('employee_id.user_id', '=', uid), ('employee_id.parent_id.user_id', '=', uid)]"/>
|
||||
<filter string="My Department" name="department"
|
||||
domain="[('employee_id.member_of_department', '=', True)]"
|
||||
help="My Department"/>
|
||||
<separator/>
|
||||
<filter string="Off Today" name="off_today" domain="[('start_datetime', '<=', context_today().strftime('%Y-%m-%d')), ('stop_datetime', '>=', context_today().strftime('%Y-%m-%d'))]" help="My Department"/>
|
||||
<separator/>
|
||||
<filter string="Approved" name="validate" domain="[('state', '=', 'validate')]" help="validate"/>
|
||||
<filter string="Waiting for Approval" name="approve" domain="[('state','in',('confirm','validate1'))]"/>
|
||||
<filter name="groupby_job_id" string="Job Position" context="{'group_by': 'job_id'}"/>
|
||||
<filter name="groupby_company_id" string="Company" context="{'group_by': 'company_id'}" groups="base.group_multi_company"/>
|
||||
<filter name="groupby_department_id" context="{'group_by': 'department_id'}"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_hr_holidays_dashboard" model="ir.actions.act_window">
|
||||
<field name="name">All Time Off</field>
|
||||
<field name="res_model">hr.leave.report.calendar</field>
|
||||
<field name="view_mode">calendar</field>
|
||||
<field name="search_view_id" ref="hr_leave_report_calendar_view_search"/>
|
||||
<field name="domain">[('employee_id.active','=',True)]</field>
|
||||
<field name="context">{'hide_employee_name': 1, 'search_default_my_team': 1}</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
<?xml version="1.0"?>
|
||||
<odoo>
|
||||
|
||||
<record id="view_hr_holidays_filter_report" model="ir.ui.view">
|
||||
<field name="name">hr.holidays.filter</field>
|
||||
<field name="model">hr.leave.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Time Off">
|
||||
<field name="employee_id"/>
|
||||
<field name="name"/>
|
||||
<filter domain="[('state','in',('confirm','validate1'))]" string="To Approve" name="approve"/>
|
||||
<filter string="Approved Requests" domain="[('state', '=', 'validate')]" name="validated"/>
|
||||
<separator/>
|
||||
<filter name="active_types" string="Active Types" domain="[('holiday_status_id.active', '=', True)]" help="Filters only on requests that belong to an time off type that is 'active' (active field is True)"/>
|
||||
<separator/>
|
||||
<filter string="My Department" name="department" domain="[('department_id.manager_id.user_id', '=', uid)]" help="My Department"/>
|
||||
<separator/>
|
||||
<filter string="Active Employee" name="active_employee" domain="[('active_employee','=',True)]"/>
|
||||
<separator/>
|
||||
<filter name="year" date="date_from" default_period="this_year" string="Current Year"/>
|
||||
<separator/>
|
||||
<filter string="My Requests" name="my_leaves" domain="[('employee_id.user_id', '=', uid)]"/>
|
||||
<filter string="Archived" name="archived" domain="[('active', '=', False)]"/>
|
||||
<separator/>
|
||||
<field name="department_id" operator="child_of"/>
|
||||
<field name="holiday_status_id"/>
|
||||
<group expand="0" string="Group By">
|
||||
<filter name="group_employee" string="Employee" context="{'group_by':'employee_id'}"/>
|
||||
<filter name="group_type" string="Type" context="{'group_by':'holiday_status_id'}"/>
|
||||
<filter name="group_company" string="Company" context="{'group_by':'company_id'}" groups="base.group_multi_company"/>
|
||||
<separator/>
|
||||
<filter name="group_date_from" string="Start Date" context="{'group_by':'date_from'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="hr_leave_report_tree" model="ir.ui.view">
|
||||
<field name="name">report.hr.holidays.report.leave_all.tree</field>
|
||||
<field name="model">hr.leave.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree create="0" edit="0" delete="0">
|
||||
<button name="action_open_record" type="object" icon="fa-external-link" title="Open" />
|
||||
<field name="employee_id" decoration-muted="not active_employee"/>
|
||||
<field name="number_of_days" string="Number of Days" sum="Remaining Days"/>
|
||||
<field name="leave_type"/>
|
||||
<field name="date_from"/>
|
||||
<field name="date_to"/>
|
||||
<field name="state"/>
|
||||
<field name="name"/>
|
||||
<field name="active_employee" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="hr_leave_report_pivot" model="ir.ui.view">
|
||||
<field name="name">report.hr.holidays.report.leave_all.pivot</field>
|
||||
<field name="model">hr.leave.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<pivot>
|
||||
<field name="employee_id" decoration-muted="not active_employee"/>
|
||||
<field name="number_of_days" type="measure"/>
|
||||
<field name="leave_type"/>
|
||||
<field name="date_from"/>
|
||||
<field name="date_to"/>
|
||||
<field name="state"/>
|
||||
<field name="name"/>
|
||||
<field name="active_employee" invisible="1"/>
|
||||
</pivot>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="hr_leave_report_view_form" model="ir.ui.view">
|
||||
<field name="name">hr.leave.report.view.form</field>
|
||||
<field name="model">hr.leave.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<sheet>
|
||||
<group>
|
||||
<group>
|
||||
<field name="employee_id"/>
|
||||
<field name="name"/>
|
||||
<field name="allocation_id" attrs="{'invisible': [('allocation_id', '=', False)]}"/>
|
||||
<field name="leave_id" attrs="{'invisible': [('leave_id', '=', False)]}"/>
|
||||
<field name="leave_type" />
|
||||
<field name="category_id"/>
|
||||
<field name="state"/>
|
||||
<field name="date_from"/>
|
||||
<field name="date_to"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="active_employee"/>
|
||||
<field name="number_of_days"/>
|
||||
<field name="department_id"/>
|
||||
<field name="holiday_status_id"/>
|
||||
<field name="holiday_type"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="act_hr_employee_holiday_request" model="ir.actions.server">
|
||||
<field name="name">Time off Analysis</field>
|
||||
<field name="model_id" ref="hr_holidays.model_hr_leave_report"/>
|
||||
<field name="binding_model_id" ref="hr.model_hr_employee"/>
|
||||
<field name="state">code</field>
|
||||
<field name="groups_id" eval="[(4, ref('hr_holidays.group_hr_holidays_user'))]"/>
|
||||
<field name="code">
|
||||
action = model.action_time_off_analysis()
|
||||
</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_empty_folder">
|
||||
No data to display
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
Loading…
Add table
Add a link
Reference in a new issue