This commit is contained in:
2026-06-14 22:00:21 +03:30
parent 0c4cbd7c12
commit b021acde56
7 changed files with 119 additions and 15 deletions
+94 -1
View File
@@ -457,10 +457,103 @@ class ConfigService
return $closed;
}
public function formatTradingTimeForDisplay(string $time): string
{
$normalized = $this->normalizeTradingTime($time, '00:00');
return $normalized . ':00';
}
public function tradingClosedMessage(?Carbon $now = null): string
{
$bounds = $this->tradingHourBounds();
$start = $this->formatTradingTimeForDisplay($bounds['start']);
$end = $this->formatTradingTimeForDisplay($bounds['end']);
return "فروشگاه در حال حاضر بسته است. ساعت کاری از {$start} تا {$end} می‌باشد.";
}
public function assertTradingOpen(?Carbon $now = null): void
{
if ($this->isOutsideTradingHours($now)) {
throw new UnprocessableEntityHttpException('فروشگاه در حال حاضر بسته است.');
throw new UnprocessableEntityHttpException($this->tradingClosedMessage($now));
}
}
public function hasProductTradingWindow(?string $open, ?string $close): bool
{
if ($open === null || $close === null || trim($open) === '' || trim($close) === '') {
return false;
}
return $this->formatProductTime($open) !== $this->formatProductTime($close);
}
public function formatProductTime(?string $time): string
{
if ($time === null || trim($time) === '') {
return '00:00:00';
}
$time = trim($time);
if (preg_match('/(\d{1,2}:\d{2}(?::\d{2})?)/', $time, $matches)) {
$parts = explode(':', $matches[1]);
return sprintf(
'%02d:%02d:%02d',
(int) ($parts[0] ?? 0),
(int) ($parts[1] ?? 0),
(int) ($parts[2] ?? 0)
);
}
return '00:00:00';
}
public function isWithinTimeWindow(?string $open, ?string $close, ?Carbon $now = null): bool
{
if (!$this->hasProductTradingWindow($open, $close)) {
return true;
}
$now = $now ?? Carbon::now();
$current = $now->format('H:i:s');
$openStr = $this->formatProductTime($open);
$closeStr = $this->formatProductTime($close);
return $current >= $openStr && $current <= $closeStr;
}
/** ساعت کاری سراسری (close_price) + بازه auto_open_at/auto_close_at هر محصول */
public function isProductWithinTradingHours(Product $product, ?Carbon $now = null): bool
{
if ($this->isClosePriceEnabled() && $this->isOutsideTradingHours($now)) {
return false;
}
return $this->isWithinTimeWindow($product->auto_open_at, $product->auto_close_at, $now);
}
public function productTradingClosedMessage(Product $product): string
{
$title = trim((string) ($product->title ?? 'محصول'));
if ($this->hasProductTradingWindow($product->auto_open_at, $product->auto_close_at)) {
$open = $this->formatProductTime($product->auto_open_at);
$close = $this->formatProductTime($product->auto_close_at);
return "محصول «{$title}» در حال حاضر بسته است. ساعت فعال‌سازی از {$open} تا {$close} می‌باشد.";
}
return $this->tradingClosedMessage();
}
public function assertProductTradingOpen(Product $product, ?Carbon $now = null): void
{
$this->assertTradingOpen($now);
if (!$this->isProductWithinTradingHours($product, $now)) {
throw new UnprocessableEntityHttpException($this->productTradingClosedMessage($product));
}
}
}