Odoo18-Base/addons/l10n_in_hr_holidays/models/hr_leave.py
2025-01-06 10:57:38 +07:00

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