From 5cfac4177fe16e6812c1c868c636f311fb4c6b6a Mon Sep 17 00:00:00 2001 From: Gregor Kleen Date: Thu, 15 Feb 2024 09:57:09 +0100 Subject: ... --- overlays/worktime/worktime/__main__.py | 46 +++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/overlays/worktime/worktime/__main__.py b/overlays/worktime/worktime/__main__.py index 14381e0c..154c1966 100755 --- a/overlays/worktime/worktime/__main__.py +++ b/overlays/worktime/worktime/__main__.py @@ -299,16 +299,34 @@ class Worktime(object): if e.errno != 2: raise e + def hours_per_week(day): + hours_per_week = float(config.get("WORKTIME", {}).get("HoursPerWeek", 40)) + + for epoch in reversed(config.get("epoch", [])): + from_date = None + to_date = None + + if "from" in epoch: + from_date = datetime.strptime(epoch["from"], date_format).replace(tzinfo=tzlocal()).date() + if day < from_date: + continue + if "to" in epoch: + to_date = datetime.strptime(epoch["to"], date_format).replace(tzinfo=tzlocal()).date() + if day >= to_date: + continue + + hours_per_week = float(epoch.get("HoursPerWeek", 40)) + + return hours_per_week - hours_per_week = float(config.get("WORKTIME", {}).get("HoursPerWeek", 40)) self.workdays = set([int(d.strip()) for d in config.get("WORKTIME", {}).get("Workdays", '1,2,3,4,5').split(',')]) - self.time_per_day = timedelta(hours = hours_per_week) / len(self.workdays) + self.time_per_day = lambda day: timedelta(hours = hours_per_week(day)) / len(self.workdays) holidays = dict() leave_per_year = int(config.get("WORKTIME", {}).get("LeavePerYear", 30)) for year in range(self.start_date.year, self.end_date.year + 1): - holidays |= {k: v * self.time_per_day for k, v in Worktime.holidays(year).items()} + holidays |= {k: v * self.time_per_day(k) for k, v in Worktime.holidays(year).items()} leave_frac = 1 if date(year, 1, 1) < self.start_date.date(): leave_frac = (date(year + 1, 1, 1) - self.start_date.date()) / (date(year + 1, 1, 1) - date(year, 1, 1)) @@ -348,7 +366,7 @@ class Worktime(object): toDay = parse_single(toDay) else: fromDay = toDay = parse_single(datestr) - time = self.time_per_day + time = None if len(splitLine) == 2: [hours, datestr] = splitLine time = timedelta(hours = float(hours)) @@ -363,9 +381,9 @@ class Worktime(object): if self.would_be_workday(day): if excused_kind == 'leave': self.leave_days.add(day) - elif time >= self.time_per_day: + elif time is not None and time >= self.time_per_day(day): self.excused_days.add(day) - holidays[day] = time + holidays[day] = time if time is not None else self.time_per_day(day) except IOError as e: if e.errno != 2: raise e @@ -398,7 +416,7 @@ class Worktime(object): if not d == datetime.strptime(c, date_format).replace(tzinfo=tzlocal()).date(): break else: if d >= self.end_date.date(): - pull_forward[d] = min(timedelta(hours = float(hours)), self.time_per_day - (holidays[d] if d in holidays else timedelta())) + pull_forward[d] = min(timedelta(hours = float(hours)), self.time_per_day(d) - (holidays[d] if d in holidays else timedelta())) except IOError as e: if e.errno != 2: raise e @@ -410,7 +428,7 @@ class Worktime(object): for day in [start_day + timedelta(days = x) for x in range(0, (end_day - start_day).days + 1)]: if day.isoweekday() in self.workdays: - time_to_work = self.time_per_day + time_to_work = self.time_per_day(day) if day in holidays.keys(): time_to_work -= holidays[day] if time_to_work > timedelta(): @@ -429,7 +447,8 @@ class Worktime(object): day = datetime.strptime(datestr, date_format).replace(tzinfo=tzlocal()).date() self.extra_days_to_work[day] = timedelta(hours = float(hours)) else: - self.extra_days_to_work[datetime.strptime(stripped_line, date_format).replace(tzinfo=tzlocal()).date()] = self.time_per_day + day = datetime.strptime(stripped_line, date_format).replace(tzinfo=tzlocal()).date() + self.extra_days_to_work[day] = self.time_per_day(day) except IOError as e: if e.errno != 2: raise e @@ -456,13 +475,13 @@ class Worktime(object): extra_day_time_left = timedelta() for extra_day in extra_days_forward: - day_time = max(timedelta(), self.time_per_day - self.extra_days_to_work[extra_day]) + day_time = max(timedelta(), self.time_per_day(extra_day) - self.extra_days_to_work[extra_day]) extra_day_time_left += day_time extra_day_time = min(extra_day_time_left, pull_forward[day]) time_forward = pull_forward[day] - extra_day_time if extra_day_time_left > timedelta(): for extra_day in extra_days_forward: - day_time = max(timedelta(), self.time_per_day - self.extra_days_to_work[extra_day]) + day_time = max(timedelta(), self.time_per_day(extra_day) - self.extra_days_to_work[extra_day]) self.extra_days_to_work[extra_day] += extra_day_time * (day_time / extra_day_time_left) hours_per_day_forward = time_forward / len(days_forward) if len(days_forward) > 0 else timedelta() @@ -577,7 +596,7 @@ def time_worked(now, **args): clockout_time = None clockout_difference = None if then.now_is_workday or now.now_is_workday: - target_time = max(then.time_per_day, now.time_per_day) if then.time_per_day and now.time_per_day else (then.time_per_day if then.time_per_day else now.time_per_day); + target_time = max(then.time_per_day(then.now.date()), now.time_per_day(now.now.date())) if then.time_per_day(then.now.date()) and now.time_per_day(now.now.date()) else (then.time_per_day(then.now.date()) if then.time_per_day(then.now.date()) else now.time_per_day(now.now.date())); difference = target_time - worked clockout_difference = 5 * ceil(difference / timedelta(minutes = 5)) clockout_time = now.now + difference @@ -627,6 +646,9 @@ def leave(year, table, table_format, **args): year_leave_budget = deepcopy(worktime.leave_budget) if year else None years = sorted(leave_budget.keys()) for day in sorted(worktime.leave_days): + if not worktime.would_be_workday(day): + continue + for iyear in years: if day > leave_expires.replace(year = iyear + 1): continue -- cgit v1.2.3