diff options
| -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 |
