Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.
import re
from typing import List, Optional, Sequence
from .dates_add_business_days import add_business_days ← from dates.add-business-days ^1.0.0 · built alongside by fune
from .dates_bank_holidays import UkRegion, bank_holidays ← from dates.bank-holidays ^1.0.0 · built alongside by fune
from .dates_day_of_week import day_of_week ← from dates.day-of-week ^1.0.0 · built alongside by fune
from .logistics_delivery_date_types import DeliveryEstimate
_TIME = re.compile(r"([01][0-9]|2[0-3]):[0-5][0-9]")
def _estimate(
order_date: str, order_time: str, cut_off: str, service_days: int, holidays: Sequence[str]
) -> DeliveryEstimate:
working = day_of_week(order_date) <= 5 and order_date not in holidays
# HH:MM compares correctly as text. Strictly before: 15:00 misses a 15:00 cut-off.
same_day = working and order_time < cut_off
dispatch = order_date if same_day else add_business_days(order_date, 1, holidays)
return DeliveryEstimate(
dispatch_date=dispatch,
delivery_date=add_business_days(dispatch, service_days, holidays),
same_day_dispatch=same_day,
)
def delivery_date(
order_date: str,
order_time: str,
cut_off: str,
service_days: int,
region: Optional[UkRegion],
closures: Sequence[str],
) -> DeliveryEstimate:
"""When an order leaves the warehouse and when it should arrive: same
working day if placed before the cut-off, then service_days working days in
transit, skipping weekends, the region's bank holidays and the caller's
closures."""
if not isinstance(order_time, str) or not _TIME.fullmatch(order_time):
raise ValueError('orderTime must be a 24-hour time HH:MM, received "%s"' % (order_time,))
if not isinstance(cut_off, str) or not _TIME.fullmatch(cut_off):
raise ValueError('cutOff must be a 24-hour time HH:MM, received "%s"' % (cut_off,))
if isinstance(service_days, bool) or not isinstance(service_days, int):
raise TypeError("serviceDays must be an integer, received %r" % (service_days,))
if service_days < 0:
raise ValueError("serviceDays must not be negative, received %d" % service_days)
day_of_week(order_date) # validates the date before its year is used
holidays: List[str] = list(closures)
last_year = int(order_date[0:4])
if region is not None:
holidays.extend(h.date for h in bank_holidays(region, last_year))
# Load each later year the estimate reaches: an order on 31 December must
# skip next year's New Year's Day. More holidays only move the answer later,
# so this settles.
while True:
result = _estimate(order_date, order_time, cut_off, service_days, holidays)
reached = int(result.delivery_date[0:4])
if region is None or reached <= last_year:
return result
for year in range(last_year + 1, reached + 1):
holidays.extend(h.date for h in bank_holidays(region, year))
last_year = reached