48 lines
1.4 KiB
Python
48 lines
1.4 KiB
Python
"""Pure production-calendar classification shared by API and tests."""
|
|
|
|
from datetime import date
|
|
|
|
from app.merakomis_schema import DAY_TYPE_NO_WORK
|
|
|
|
PER_HOUR_DEFAULT = 8
|
|
|
|
|
|
def get_work_hours_in_date(day: date) -> float:
|
|
if day.weekday() < 5:
|
|
return float(PER_HOUR_DEFAULT)
|
|
return 0.0
|
|
|
|
|
|
def format_day_context(row: dict | None, day: date) -> dict:
|
|
"""Return the complete calendar contract for one date."""
|
|
row = row or {}
|
|
day_type = int(row.get("type") or 0)
|
|
source_text = (row.get("text") or "").strip()
|
|
explicit_hours = row.get("hours")
|
|
normal_hours = (
|
|
float(explicit_hours)
|
|
if explicit_hours is not None
|
|
else get_work_hours_in_date(day)
|
|
)
|
|
is_non_working = day_type == DAY_TYPE_NO_WORK or day.weekday() >= 5
|
|
if is_non_working:
|
|
normal_hours = 0.0
|
|
|
|
if source_text:
|
|
explanation = source_text
|
|
elif is_non_working:
|
|
explanation = "Выходной или нерабочий день"
|
|
elif normal_hours < PER_HOUR_DEFAULT:
|
|
explanation = "Сокращённый рабочий день"
|
|
else:
|
|
explanation = "Рабочий день"
|
|
|
|
return {
|
|
"date": day.isoformat(),
|
|
"type": day_type,
|
|
"text": source_text,
|
|
"normal_hours": normal_hours,
|
|
"is_non_working": is_non_working,
|
|
"source_explanation": explanation,
|
|
}
|