summaryrefslogtreecommitdiff
path: root/overlays/worktime
diff options
context:
space:
mode:
authorGregor Kleen <gkleen@yggdrasil.li>2024-02-15 09:57:09 +0100
committerGregor Kleen <gkleen@yggdrasil.li>2024-02-15 09:57:09 +0100
commit5cfac4177fe16e6812c1c868c636f311fb4c6b6a (patch)
tree12594254f7fdba7e49207f10ed3a767fd3ee04cd /overlays/worktime
parent7b8d1bdc62c5fc3feacfe23fd1eefe85f05b878d (diff)
downloadnixos-5cfac4177fe16e6812c1c868c636f311fb4c6b6a.tar
nixos-5cfac4177fe16e6812c1c868c636f311fb4c6b6a.tar.gz
nixos-5cfac4177fe16e6812c1c868c636f311fb4c6b6a.tar.bz2
nixos-5cfac4177fe16e6812c1c868c636f311fb4c6b6a.tar.xz
nixos-5cfac4177fe16e6812c1c868c636f311fb4c6b6a.zip
...
Diffstat (limited to 'overlays/worktime')
-rwxr-xr-xoverlays/worktime/worktime/__main__.py46
1 files 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):
299 if e.errno != 2: 299 if e.errno != 2:
300 raise e 300 raise e
301 301
302 def hours_per_week(day):
303 hours_per_week = float(config.get("WORKTIME", {}).get("HoursPerWeek", 40))
304
305 for epoch in reversed(config.get("epoch", [])):
306 from_date = None
307 to_date = None
308
309 if "from" in epoch:
310 from_date = datetime.strptime(epoch["from"], date_format).replace(tzinfo=tzlocal()).date()
311 if day < from_date:
312 continue
313 if "to" in epoch:
314 to_date = datetime.strptime(epoch["to"], date_format).replace(tzinfo=tzlocal()).date()
315 if day >= to_date:
316 continue
317
318 hours_per_week = float(epoch.get("HoursPerWeek", 40))
319
320 return hours_per_week
302 321
303 hours_per_week = float(config.get("WORKTIME", {}).get("HoursPerWeek", 40))
304 self.workdays = set([int(d.strip()) for d in config.get("WORKTIME", {}).get("Workdays", '1,2,3,4,5').split(',')]) 322 self.workdays = set([int(d.strip()) for d in config.get("WORKTIME", {}).get("Workdays", '1,2,3,4,5').split(',')])
305 self.time_per_day = timedelta(hours = hours_per_week) / len(self.workdays) 323 self.time_per_day = lambda day: timedelta(hours = hours_per_week(day)) / len(self.workdays)
306 324
307 holidays = dict() 325 holidays = dict()
308 326
309 leave_per_year = int(config.get("WORKTIME", {}).get("LeavePerYear", 30)) 327 leave_per_year = int(config.get("WORKTIME", {}).get("LeavePerYear", 30))
310 for year in range(self.start_date.year, self.end_date.year + 1): 328 for year in range(self.start_date.year, self.end_date.year + 1):
311 holidays |= {k: v * self.time_per_day for k, v in Worktime.holidays(year).items()} 329 holidays |= {k: v * self.time_per_day(k) for k, v in Worktime.holidays(year).items()}
312 leave_frac = 1 330 leave_frac = 1
313 if date(year, 1, 1) < self.start_date.date(): 331 if date(year, 1, 1) < self.start_date.date():
314 leave_frac = (date(year + 1, 1, 1) - self.start_date.date()) / (date(year + 1, 1, 1) - date(year, 1, 1)) 332 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):
348 toDay = parse_single(toDay) 366 toDay = parse_single(toDay)
349 else: 367 else:
350 fromDay = toDay = parse_single(datestr) 368 fromDay = toDay = parse_single(datestr)
351 time = self.time_per_day 369 time = None
352 if len(splitLine) == 2: 370 if len(splitLine) == 2:
353 [hours, datestr] = splitLine 371 [hours, datestr] = splitLine
354 time = timedelta(hours = float(hours)) 372 time = timedelta(hours = float(hours))
@@ -363,9 +381,9 @@ class Worktime(object):
363 if self.would_be_workday(day): 381 if self.would_be_workday(day):
364 if excused_kind == 'leave': 382 if excused_kind == 'leave':
365 self.leave_days.add(day) 383 self.leave_days.add(day)
366 elif time >= self.time_per_day: 384 elif time is not None and time >= self.time_per_day(day):
367 self.excused_days.add(day) 385 self.excused_days.add(day)
368 holidays[day] = time 386 holidays[day] = time if time is not None else self.time_per_day(day)
369 except IOError as e: 387 except IOError as e:
370 if e.errno != 2: 388 if e.errno != 2:
371 raise e 389 raise e
@@ -398,7 +416,7 @@ class Worktime(object):
398 if not d == datetime.strptime(c, date_format).replace(tzinfo=tzlocal()).date(): break 416 if not d == datetime.strptime(c, date_format).replace(tzinfo=tzlocal()).date(): break
399 else: 417 else:
400 if d >= self.end_date.date(): 418 if d >= self.end_date.date():
401 pull_forward[d] = min(timedelta(hours = float(hours)), self.time_per_day - (holidays[d] if d in holidays else timedelta())) 419 pull_forward[d] = min(timedelta(hours = float(hours)), self.time_per_day(d) - (holidays[d] if d in holidays else timedelta()))
402 except IOError as e: 420 except IOError as e:
403 if e.errno != 2: 421 if e.errno != 2:
404 raise e 422 raise e
@@ -410,7 +428,7 @@ class Worktime(object):
410 428
411 for day in [start_day + timedelta(days = x) for x in range(0, (end_day - start_day).days + 1)]: 429 for day in [start_day + timedelta(days = x) for x in range(0, (end_day - start_day).days + 1)]:
412 if day.isoweekday() in self.workdays: 430 if day.isoweekday() in self.workdays:
413 time_to_work = self.time_per_day 431 time_to_work = self.time_per_day(day)
414 if day in holidays.keys(): 432 if day in holidays.keys():
415 time_to_work -= holidays[day] 433 time_to_work -= holidays[day]
416 if time_to_work > timedelta(): 434 if time_to_work > timedelta():
@@ -429,7 +447,8 @@ class Worktime(object):
429 day = datetime.strptime(datestr, date_format).replace(tzinfo=tzlocal()).date() 447 day = datetime.strptime(datestr, date_format).replace(tzinfo=tzlocal()).date()
430 self.extra_days_to_work[day] = timedelta(hours = float(hours)) 448 self.extra_days_to_work[day] = timedelta(hours = float(hours))
431 else: 449 else:
432 self.extra_days_to_work[datetime.strptime(stripped_line, date_format).replace(tzinfo=tzlocal()).date()] = self.time_per_day 450 day = datetime.strptime(stripped_line, date_format).replace(tzinfo=tzlocal()).date()
451 self.extra_days_to_work[day] = self.time_per_day(day)
433 except IOError as e: 452 except IOError as e:
434 if e.errno != 2: 453 if e.errno != 2:
435 raise e 454 raise e
@@ -456,13 +475,13 @@ class Worktime(object):
456 475
457 extra_day_time_left = timedelta() 476 extra_day_time_left = timedelta()
458 for extra_day in extra_days_forward: 477 for extra_day in extra_days_forward:
459 day_time = max(timedelta(), self.time_per_day - self.extra_days_to_work[extra_day]) 478 day_time = max(timedelta(), self.time_per_day(extra_day) - self.extra_days_to_work[extra_day])
460 extra_day_time_left += day_time 479 extra_day_time_left += day_time
461 extra_day_time = min(extra_day_time_left, pull_forward[day]) 480 extra_day_time = min(extra_day_time_left, pull_forward[day])
462 time_forward = pull_forward[day] - extra_day_time 481 time_forward = pull_forward[day] - extra_day_time
463 if extra_day_time_left > timedelta(): 482 if extra_day_time_left > timedelta():
464 for extra_day in extra_days_forward: 483 for extra_day in extra_days_forward:
465 day_time = max(timedelta(), self.time_per_day - self.extra_days_to_work[extra_day]) 484 day_time = max(timedelta(), self.time_per_day(extra_day) - self.extra_days_to_work[extra_day])
466 self.extra_days_to_work[extra_day] += extra_day_time * (day_time / extra_day_time_left) 485 self.extra_days_to_work[extra_day] += extra_day_time * (day_time / extra_day_time_left)
467 486
468 hours_per_day_forward = time_forward / len(days_forward) if len(days_forward) > 0 else timedelta() 487 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):
577 clockout_time = None 596 clockout_time = None
578 clockout_difference = None 597 clockout_difference = None
579 if then.now_is_workday or now.now_is_workday: 598 if then.now_is_workday or now.now_is_workday:
580 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); 599 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()));
581 difference = target_time - worked 600 difference = target_time - worked
582 clockout_difference = 5 * ceil(difference / timedelta(minutes = 5)) 601 clockout_difference = 5 * ceil(difference / timedelta(minutes = 5))
583 clockout_time = now.now + difference 602 clockout_time = now.now + difference
@@ -627,6 +646,9 @@ def leave(year, table, table_format, **args):
627 year_leave_budget = deepcopy(worktime.leave_budget) if year else None 646 year_leave_budget = deepcopy(worktime.leave_budget) if year else None
628 years = sorted(leave_budget.keys()) 647 years = sorted(leave_budget.keys())
629 for day in sorted(worktime.leave_days): 648 for day in sorted(worktime.leave_days):
649 if not worktime.would_be_workday(day):
650 continue
651
630 for iyear in years: 652 for iyear in years:
631 if day > leave_expires.replace(year = iyear + 1): 653 if day > leave_expires.replace(year = iyear + 1):
632 continue 654 continue