"""Request context — the single object that carries the GLOBAL filters through a page render. Instead of threading date_from / date_to / team_id / ... through every function, a page builds one `Ctx` from the sidebar controls and passes it (or its primitives) down. Modules read only what they need. Add a new global filter once here and every module can opt into it. The DBA (doing-business-as) brand filter lives here as `team_id`: None -> All / consolidated (Fisch + Royal) 5 -> Fisch 6 -> Royal HQ / company-level modules (cash flow, balance sheet, AR/AP, consolidated P&L) ignore brand and call `ctx.consolidated()`; operational modules (sales, customers, products, margins) honour it. """ from dataclasses import dataclass, replace import core.odoo as O import core.periods as P # label -> team_id used by the sidebar Brand (DBA) selector BRANDS = {'All': None, 'Fisch': 5, 'Royal': 6} @dataclass(frozen=True) class Ctx: date_from: str date_to: str period_label: str = 'Year to date' team_id: int | None = None # None = All DBAs (consolidated); 5 = Fisch; 6 = Royal doc_mode: str = 'order' # reserved: 'order' vs 'invoice' recognition basis @property def brand(self) -> str: return O.TEAM_NAMES.get(self.team_id, 'All') if self.team_id else 'All' @property def teams(self) -> list: """Team ids in scope (single brand, or both when consolidated).""" return [self.team_id] if self.team_id else list(O.TEAM_IDS) @property def window(self) -> tuple: return self.date_from, self.date_to def consolidated(self) -> 'Ctx': """All-DBA copy — HQ modules use this so the brand filter never scopes company numbers.""" return replace(self, team_id=None) def with_period(self, date_from, date_to, label=None) -> 'Ctx': return replace(self, date_from=date_from, date_to=date_to, period_label=label or self.period_label) def from_ui(period_label, period_window, brand_label='All', doc_mode='order') -> Ctx: df, dt = period_window return Ctx(df, dt, period_label, BRANDS.get(brand_label), doc_mode) def default(t=None) -> Ctx: df, dt = P.ytd(t) return Ctx(df, dt, 'Year to date', None)