dodil/erp-brick-sales-order

DODIL ERP brick: sales order

src/brick_sales_order/infrastructure/business_time.py

"""'Today' is the date in business_timezone — ONE value per bucket (shared.yaml conventions.business_timezone).

The read sits behind this one small function so it can move to the platform later without touching a use case. Until
the platform holds the single value, the dated setting `business_timezone` in so_settings is where this brick reads it.
Business time is `work.now()` (a demo may move the clock); audit stamps use real time.

Which row is in force is decided in BUSINESS time, not UTC: walking the dated rows in order, a row takes over once the
business date in the zone BEFORE it has reached the row's valid_from. (By the UTC date a row dated tomorrow could be
accepted as future and be in force at once, at 18:00 in Pago_Pago.)
"""
from datetime import date
from zoneinfo import ZoneInfo

from erp_platform import work

KEY = "business_timezone"
EPOCH = date(1970, 1, 1)


def timezone_name(settings) -> str:
    now = work.now()
    name = settings.value_on(KEY, EPOCH) or "Europe/London"
    for row in settings.rows(KEY):
        if row["valid_from"] <= EPOCH:
            continue
        if row["valid_from"] <= now.astimezone(ZoneInfo(name)).date():
            name = row["value"] or name
        else:
            break
    return name


def today(settings) -> date:
    return work.now().astimezone(ZoneInfo(timezone_name(settings))).date()