fix(settings): honor per-day trading hours and refresh SuperAdmin overlay
Use trading_hours_by_day for close_price gates, prefer public SuperAdmin fetch, and add refresh endpoint/command so stale last-good cache no longer keeps switches like enable_automation off. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -638,6 +638,86 @@ class ConfigService
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{mode: 'uniform'|'per_day', days: array<string, array{enabled: bool, start: string, end: string}>}|null
|
||||
*/
|
||||
public function tradingHoursByDay(): ?array
|
||||
{
|
||||
$raw = $this->getString('trading_hours_by_day', '');
|
||||
if ($raw === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
$parsed = json_decode($raw, true, 512, JSON_THROW_ON_ERROR);
|
||||
} catch (\Throwable) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! is_array($parsed) || ! isset($parsed['days']) || ! is_array($parsed['days'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$mode = ($parsed['mode'] ?? 'uniform') === 'per_day' ? 'per_day' : 'uniform';
|
||||
$defaults = $this->tradingHourBounds();
|
||||
$dayKeys = ['sat', 'sun', 'mon', 'tue', 'wed', 'thu', 'fri'];
|
||||
$days = [];
|
||||
|
||||
foreach ($dayKeys as $key) {
|
||||
$row = is_array($parsed['days'][$key] ?? null) ? $parsed['days'][$key] : [];
|
||||
$days[$key] = [
|
||||
'enabled' => ($row['enabled'] ?? true) !== false,
|
||||
'start' => $this->normalizeTradingTime((string) ($row['start'] ?? $defaults['start']), $defaults['start']),
|
||||
'end' => $this->normalizeTradingTime((string) ($row['end'] ?? $defaults['end']), $defaults['end']),
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'mode' => $mode,
|
||||
'days' => $days,
|
||||
];
|
||||
}
|
||||
|
||||
private function weekdayKey(Carbon $now): string
|
||||
{
|
||||
return match ($now->dayOfWeek) {
|
||||
Carbon::SATURDAY => 'sat',
|
||||
Carbon::SUNDAY => 'sun',
|
||||
Carbon::MONDAY => 'mon',
|
||||
Carbon::TUESDAY => 'tue',
|
||||
Carbon::WEDNESDAY => 'wed',
|
||||
Carbon::THURSDAY => 'thu',
|
||||
Carbon::FRIDAY => 'fri',
|
||||
default => 'sat',
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* بازهٔ مؤثر ساعت کاری برای لحظهٔ فعلی.
|
||||
*
|
||||
* @return array{enabled: bool, start: string, end: string}
|
||||
*/
|
||||
public function effectiveTradingBounds(?Carbon $now = null): array
|
||||
{
|
||||
$now = $now ?? Carbon::now();
|
||||
$weekly = $this->tradingHoursByDay();
|
||||
|
||||
if ($weekly !== null && $weekly['mode'] === 'per_day') {
|
||||
$day = $weekly['days'][$this->weekdayKey($now)] ?? null;
|
||||
if ($day !== null) {
|
||||
return $day;
|
||||
}
|
||||
}
|
||||
|
||||
$bounds = $this->tradingHourBounds();
|
||||
|
||||
return [
|
||||
'enabled' => true,
|
||||
'start' => $bounds['start'],
|
||||
'end' => $bounds['end'],
|
||||
];
|
||||
}
|
||||
|
||||
private function normalizeTradingTime(string $value, string $default): string
|
||||
{
|
||||
$value = trim($value);
|
||||
@@ -659,7 +739,12 @@ class ConfigService
|
||||
}
|
||||
|
||||
$now = $now ?? Carbon::now();
|
||||
$bounds = $this->tradingHourBounds();
|
||||
$bounds = $this->effectiveTradingBounds($now);
|
||||
|
||||
if (!$bounds['enabled']) {
|
||||
return true;
|
||||
}
|
||||
|
||||
[$startHour, $startMinute] = array_map('intval', explode(':', $bounds['start']));
|
||||
[$endHour, $endMinute] = array_map('intval', explode(':', $bounds['end']));
|
||||
|
||||
@@ -669,6 +754,39 @@ class ConfigService
|
||||
return !$now->between($start, $end);
|
||||
}
|
||||
|
||||
/**
|
||||
* گیت ساعت کاری روی payload کش/SSE — وقتی close_price روشن است.
|
||||
*
|
||||
* @param array<string, mixed> $payload
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function applyGlobalTradingHoursToPayload(array $payload): array
|
||||
{
|
||||
if (!$this->isClosePriceEnabled() || !$this->isOutsideTradingHours()) {
|
||||
return $payload;
|
||||
}
|
||||
|
||||
if ($this->shouldShowHomePriceWhenClosed()) {
|
||||
$payload['closed'] = true;
|
||||
$payload['status'] = 'closed';
|
||||
|
||||
return $payload;
|
||||
}
|
||||
|
||||
return [
|
||||
'sell' => 0,
|
||||
'buy' => 0,
|
||||
'price_last' => 0,
|
||||
'price' => 0,
|
||||
'main_product' => (int) ($payload['main_product'] ?? 0),
|
||||
'montzar' => (int) ($payload['montzar'] ?? 0),
|
||||
'zaarbox' => (int) ($payload['zaarbox'] ?? 0),
|
||||
'closed' => true,
|
||||
'status' => 'closed',
|
||||
'time' => now(),
|
||||
];
|
||||
}
|
||||
|
||||
public function syncAppClosedFlag(?Carbon $now = null): bool
|
||||
{
|
||||
$closed = $this->isOutsideTradingHours($now);
|
||||
@@ -710,7 +828,13 @@ class ConfigService
|
||||
|
||||
public function tradingClosedMessage(?Carbon $now = null): string
|
||||
{
|
||||
$bounds = $this->tradingHourBounds();
|
||||
$now = $now ?? Carbon::now();
|
||||
$bounds = $this->effectiveTradingBounds($now);
|
||||
|
||||
if (!$bounds['enabled']) {
|
||||
return 'فروشگاه امروز تعطیل است.';
|
||||
}
|
||||
|
||||
$start = $this->formatTradingTimeForDisplay($bounds['start']);
|
||||
$end = $this->formatTradingTimeForDisplay($bounds['end']);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user