Merge pull request 'automatic update repo with commit - 'fix: holydays duration' from project hr_holidays_ru' (#2) from rydlab-17.0 into 17.0
Reviewed-on: #2
This commit is contained in:
commit
2a8a1af32c
@ -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))
|
||||
|
Loading…
x
Reference in New Issue
Block a user