79 lines
3.3 KiB
Python
79 lines
3.3 KiB
Python
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
from datetime import datetime, timedelta
|
|
|
|
from odoo import models, fields
|
|
|
|
|
|
class HolidaysRequest(models.Model):
|
|
_inherit = "hr.leave"
|
|
|
|
l10n_in_contains_sandwich_leaves = fields.Boolean()
|
|
|
|
def _l10n_in_apply_sandwich_rule(self, public_holidays, employee_leaves):
|
|
self.ensure_one()
|
|
if not self.request_date_from or not self.request_date_to:
|
|
return
|
|
date_from = self.request_date_from
|
|
date_to = self.request_date_to
|
|
total_leaves = (self.request_date_to - self.request_date_from).days + 1
|
|
|
|
def is_non_working_day(calendar, date):
|
|
return not calendar._works_on_date(date) or any(
|
|
datetime.date(holiday['date_from']) <= date <= datetime.date(holiday['date_to']) for holiday in public_holidays
|
|
)
|
|
|
|
def count_sandwich_days(calendar, date, direction):
|
|
current_date = date + timedelta(days=direction)
|
|
days_count = 0
|
|
while is_non_working_day(calendar, current_date):
|
|
days_count += 1
|
|
current_date += timedelta(days=direction)
|
|
for leave in employee_leaves:
|
|
if leave['request_date_from'] <= current_date <= leave['request_date_to']:
|
|
return days_count
|
|
return 0
|
|
|
|
calendar = self.resource_calendar_id
|
|
total_leaves += count_sandwich_days(calendar, date_from, -1) + count_sandwich_days(calendar, date_to, 1)
|
|
if is_non_working_day(calendar, date_from):
|
|
total_leaves -= 1
|
|
if is_non_working_day(calendar, date_from + timedelta(days=+1)):
|
|
total_leaves -= 1
|
|
if is_non_working_day(calendar, date_to):
|
|
total_leaves -= 1
|
|
if is_non_working_day(calendar, date_to + timedelta(days=-1)):
|
|
total_leaves -= 1
|
|
return total_leaves
|
|
|
|
def _get_durations(self, check_leave_type=True, resource_calendar=None):
|
|
result = super()._get_durations(check_leave_type, resource_calendar)
|
|
indian_leaves = self.filtered(lambda c: c.company_id.country_id.code == 'IN')
|
|
if not indian_leaves:
|
|
return result
|
|
|
|
public_holidays = self.env['resource.calendar.leaves'].search([
|
|
('resource_id', '=', False),
|
|
('company_id', 'in', indian_leaves.company_id.ids),
|
|
])
|
|
leaves_by_employee = dict(self._read_group(
|
|
domain=[
|
|
('id', 'not in', self.ids),
|
|
('employee_id', 'in', self.employee_id.ids),
|
|
('state', 'not in', ['cancel', 'refuse']),
|
|
('leave_type_request_unit', '=', 'day'),
|
|
],
|
|
groupby=['employee_id'],
|
|
aggregates=['id:recordset'],
|
|
))
|
|
for leave in indian_leaves:
|
|
if leave.holiday_status_id.l10n_in_is_sandwich_leave:
|
|
days, hours = result[leave.id]
|
|
updated_days = leave._l10n_in_apply_sandwich_rule(public_holidays, leaves_by_employee.get(leave.employee_id, []))
|
|
result[leave.id] = (updated_days, hours)
|
|
if updated_days:
|
|
leave.l10n_in_contains_sandwich_leaves = updated_days != days
|
|
else:
|
|
leave.l10n_in_contains_sandwich_leaves = False
|
|
return result
|