meraproject/services/user-reader/app/labor_time_logic.py

93 lines
2.3 KiB
Python
Raw Permalink Normal View History

"""Алгоритмы записи часов — порт addFromCalendar."""
from __future__ import annotations
from datetime import date
from typing import Any
def normalize_time_value(time: float) -> float:
x = (time - int(time)) * 100
if x <= 25:
frac = 0
elif x >= 75:
frac = 100
else:
frac = 50
t = int(time) + frac / 100
if t < 0:
t = 0
if t > 24:
t = 24
return float(t)
def apply_daily_limits(
time: float,
is_over: bool,
total_work: float,
total_over: float,
project_hours: float,
project_over: float,
max_work_hours: float,
max_over_hours: float,
) -> tuple[float, dict[str, float]]:
tw = total_work - project_hours
to = total_over - project_over
new_work = tw + time
new_over = to + time
left_work = max_work_hours - tw
left_over = max_over_hours - to
clamped = False
if is_over:
if new_over > max_over_hours:
time = left_over
clamped = True
else:
if new_work > max_work_hours:
time = left_work
clamped = True
if time < 0:
time = 0
clamped = True
limits = {
"max_work_hours": max_work_hours,
"max_over_hours": max_over_hours,
"left_work_hours": left_work,
"left_over_hours": left_over,
"new_work_hours": tw + (time if not is_over else 0),
"new_over_hours": to + (time if is_over else 0),
"clamped": clamped,
}
return time, limits
def sum_day_totals(rows: list[dict[str, Any]]) -> tuple[float, float]:
total_work = 0.0
total_over = 0.0
for row in rows:
dur = float(row.get("cc") or row.get("duration") or 0)
if int(row.get("is_over") or 0):
total_over += dur
else:
total_work += dur
return total_work, total_over
def project_day_info(rows: list[dict[str, Any]]) -> dict[str, float]:
hours = 0.0
over = 0.0
for row in rows:
dur = float(row.get("cc") or row.get("duration") or 0)
if int(row.get("is_over") or 0):
over += dur
else:
hours += dur
return {
"hours": hours,
"over": over,
"over1": 0.0,
"over2": 0.0,
"total": hours + over,
}