Initial commit: Hr packages

This commit is contained in:
Ernad Husremovic 2025-08-29 15:20:50 +02:00
commit 62531cd146
2820 changed files with 1432848 additions and 0 deletions

View file

@ -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

View file

@ -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(),
}

View file

@ -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>

View file

@ -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">
&lt;th class="text-center" colspan=<t t-esc="month['days']"/>&gt;<t t-esc="month['month_name']"/>&lt;/th&gt;
</t>
<th/>
</tr>
<tr>
<td rowspan="2">
<strong>Departments and Employees</strong>
</td>
<t t-foreach="get_day" t-as="day">
&lt;td class="text-center oe_leftfit oe_rightfit" style="background-color:<t t-esc="day['color']"/>!important; font-size: 8px; min-width: 18px"&gt; <t t-esc="day['day_str']"/>&lt;/td&gt;
</t>
<td/>
</tr>
<tr>
<t t-foreach="get_day" t-as="day">
&lt;td class="text-center oe_leftfit oe_rightfit" style="background-color:<t t-esc="day['color']"/>!important; font-size: 10px" &gt; <t t-esc="day['day']"/>&lt;/td&gt;
</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">
&lt;td style=background-color:<t t-esc="c['color']"/> !important/&gt;
</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">
&lt;td style=background-color:<t t-esc="details['color']"/> !important /&gt;
</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">
&lt;td style=background-color:<t t-esc="status['color']"/>!important &gt;&lt;/td&gt;
<td><t t-esc="status['name']"/></td>
</tr>
</tbody>
</table>
</div>
</div>
</t>
</t>
</template>
</odoo>

View file

@ -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,
}
}

View file

@ -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>

View file

@ -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',
}

View file

@ -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)

View file

@ -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', '&lt;=', context_today().strftime('%Y-%m-%d')), ('stop_datetime', '&gt;=', 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>

View file

@ -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>