diff options
Diffstat (limited to 'overlays/worktime')
-rwxr-xr-x | overlays/worktime/worktime/__main__.py | 46 |
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 |