settings = new CompanySettingManager($settingsPdo, $company_id); } public function assertOpenDate(?string $posting_date, string $context = 'GL posting'): void { $date = $this->normalizeDate($posting_date); if ($date === '') { throw new Exception("{$context} date is required for posting-window validation."); } $window = $this->getWindow(); $from = $window['open_from']; $to = $window['open_to']; if ($from !== '' && $date < $from) { throw new Exception("{$context} date {$date} is before the open posting window ({$from} to " . ($to ?: 'no upper limit') . ")."); } if ($to !== '' && $date > $to) { throw new Exception("{$context} date {$date} is after the open posting window (" . ($from ?: 'no lower limit') . " to {$to})."); } } private function getWindow(): array { if ($this->window === null) { $open_from = $this->settings->get('posting_open_from'); if ($open_from === null || $open_from === '') { $open_from = $this->settings->get('gl_open_from') ?: ''; } $open_to = $this->settings->get('posting_open_to'); if ($open_to === null || $open_to === '') { $open_to = $this->settings->get('gl_open_to') ?: ''; } $this->window = [ 'open_from' => $this->normalizeDate($open_from ?: ''), 'open_to' => $this->normalizeDate($open_to ?: ''), ]; } return $this->window; } private function normalizeDate(?string $date): string { $date = trim((string)$date); if ($date === '') { return ''; } if (preg_match('#^(\d{2})/(\d{2})/(\d{4})$#', $date, $m)) { $date = "{$m[3]}-{$m[2]}-{$m[1]}"; } if (preg_match("#^([0-9]{4}-[0-9]{2}-[0-9]{2})[ T]#", $date, $m)) { $date = $m[1]; } if (!preg_match("#^[0-9]{4}-[0-9]{2}-[0-9]{2}$#", $date)) { throw new Exception("Invalid posting date {$date}. Use YYYY-MM-DD."); } return $date; } }