Files

80 lines
2.3 KiB
Python
Raw Permalink Normal View History

"""Working-hours helpers.
Working hours are stored per tenant as:
{"mon": [["09:00", "13:00"], ["14:00", "18:00"]], ..., "sun": []}
Multiple intervals per day model lunch breaks. Missing/empty day = closed.
All computations happen in the tenant's timezone.
"""
from __future__ import annotations
from datetime import date, datetime, time, timedelta
from zoneinfo import ZoneInfo
WEEKDAY_KEYS = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"]
# Bosnian day names (Latin) for UI / agent context
DAY_NAMES_BS = {
"mon": "ponedjeljak",
"tue": "utorak",
"wed": "srijeda",
"thu": "četvrtak",
"fri": "petak",
"sat": "subota",
"sun": "nedjelja",
}
DEFAULT_WORKING_HOURS: dict[str, list[list[str]]] = {
"mon": [["09:00", "18:00"]],
"tue": [["09:00", "18:00"]],
"wed": [["09:00", "18:00"]],
"thu": [["09:00", "18:00"]],
"fri": [["09:00", "18:00"]],
"sat": [["09:00", "14:00"]],
"sun": [],
}
def _parse_hhmm(s: str) -> time:
h, m = s.split(":")
return time(int(h), int(m))
def day_intervals(
working_hours: dict, day: date, tz: ZoneInfo
) -> list[tuple[datetime, datetime]]:
"""Open intervals for a calendar day as tz-aware datetimes."""
key = WEEKDAY_KEYS[day.weekday()]
out = []
for start_s, end_s in working_hours.get(key, []):
start = datetime.combine(day, _parse_hhmm(start_s), tzinfo=tz)
end = datetime.combine(day, _parse_hhmm(end_s), tzinfo=tz)
if end > start:
out.append((start, end))
return out
def is_open_at(working_hours: dict, at: datetime, tz: ZoneInfo) -> bool:
at = at.astimezone(tz)
return any(s <= at < e for s, e in day_intervals(working_hours, at.date(), tz))
def hours_summary_bs(working_hours: dict) -> str:
"""Human-readable Bosnian working-hours summary for prompts/emails."""
parts = []
for key in WEEKDAY_KEYS:
intervals = working_hours.get(key, [])
if not intervals:
parts.append(f"{DAY_NAMES_BS[key]}: zatvoreno")
else:
spans = ", ".join(f"{a}{b}" for a, b in intervals)
parts.append(f"{DAY_NAMES_BS[key]}: {spans}")
return "; ".join(parts)
def iter_days(start: date, end: date):
d = start
while d <= end:
yield d
d += timedelta(days=1)