From b89b1fd6f289367fbb2a5d1dd2203398549375a7 Mon Sep 17 00:00:00 2001 From: odoo-robot Date: Thu, 23 Jan 2025 07:51:07 +0000 Subject: [PATCH] automatic update repo with commit - 'fix: holydays duration' from project hr_holidays_ru --- models/resource.py | 77 ++++++++++++++++------------------------------ 1 file changed, 27 insertions(+), 50 deletions(-) diff --git a/models/resource.py b/models/resource.py index 8bb1ee0..4416c0e 100644 --- a/models/resource.py +++ b/models/resource.py @@ -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)) -- 2.47.1