automatic update repo with commit - 'fix: holydays duration' from project hr_holidays_ru #2

Merged
vladislav.kostrov merged 1 commits from rydlab-17.0 into 17.0 2025-01-23 10:57:12 +03:00

View File

@ -1,11 +1,8 @@
# -*- coding: utf-8 -*-
import logging
from datetime import datetime
from datetime import timedelta
from datetime import datetime, timedelta, time
from pytz import timezone, utc
from datetime import datetime, time
from collections import defaultdict
from dateutil.relativedelta import relativedelta
import pytz
from odoo import models, fields
@ -335,56 +332,36 @@ class ResourceCalendar(models.Model):
def get_holidays_duration(self, start_dt, end_dt):
"""
Returns timedelta object which is duration of all holidays included into
specified period.
Returns the number of holiday days in the specified datetime range.
Converts datetime objects to date and calculates overlapping holiday days.
"""
start_date = start_dt.date()
end_date = end_dt.date()
days = set()
holidays_ids = self.env["holidays.calendar.leaves"].search(
# Find all holidays that are marked as "is_holiday"
holidays = self.env["holidays.calendar.leaves"].search(
[("type_transfer_day", "=", "is_holiday")]
)
for holiday in holidays_ids:
# Transformation date to datetime
date_from = datetime(
year=holiday.date_from.year,
month=holiday.date_from.month,
day=holiday.date_from.day,
hour=0,
minute=0,
second=0,
)
date_to = datetime(
year=holiday.date_to.year,
month=holiday.date_to.month,
day=holiday.date_to.day,
hour=23,
minute=59,
second=59,
)
# Dates in database are without timezones, and time in fact for UTC timezone,
# so it should be added explicitly.
holiday_date_from = utc.localize(date_from) if date_from else None
holiday_date_to = utc.localize(date_to) if date_to else None
# Bring booth dates to the holiday timezone
if holiday_date_from and start_dt.tzinfo != holiday_date_from.tzinfo:
start_dt = start_dt.astimezone(holiday_date_from.tzinfo)
if holiday_date_to and end_dt.tzinfo != holiday_date_to.tzinfo:
end_dt = end_dt.astimezone(holiday_date_to.tzinfo)
# Check periods intersection
if (
holiday_date_from
and end_dt < holiday_date_from
or holiday_date_to
and start_dt > holiday_date_to
):
for holiday in holidays:
holiday_start = holiday.date_from
holiday_end = holiday.date_to
# Ensure both dates are valid
if not holiday_start or not holiday_end:
continue
# Handle this holiday
start = start_dt.date()
if holiday_date_from:
start = max(start, holiday_date_from.date())
until = end_dt.date()
if holiday_date_to:
until = min(until, holiday_date_to.date())
for i in range((until - start + timedelta(1)).days):
days.add(start + timedelta(i))
# Check if the holiday range overlaps with the input range
if holiday_end < start_date or holiday_start > end_date:
continue
overlap_start = max(start_date, holiday_start)
overlap_end = min(end_date, holiday_end)
for i in range((overlap_end - overlap_start).days + 1):
days.add(overlap_start + timedelta(days=i))
return timedelta(len(days))