refactor(ticket): implement fixed validity time generation for event date and time windows in TicketGeneratorService
This commit is contained in:
@@ -5,6 +5,7 @@ namespace App\Domains\Ticket\Services;
|
||||
use App\Domains\Auth\Models\User;
|
||||
use App\Domains\Catalog\Models\CatalogItem;
|
||||
use App\Domains\Catalog\Models\Variant;
|
||||
use App\Domains\Ticket\Enums\ValidityTimeType;
|
||||
use App\Domains\Ticket\Exceptions\TicketGenerationException;
|
||||
use App\Domains\Ticket\Models\Ticket;
|
||||
use App\Domains\Ticket\Models\ValidityTime;
|
||||
@@ -34,14 +35,21 @@ class TicketGeneratorService
|
||||
$quantity,
|
||||
$sourceVariantId,
|
||||
);
|
||||
$fixedValidityTimes = [];
|
||||
|
||||
return $targets->map(function (array $target) use (
|
||||
&$fixedValidityTimes,
|
||||
$sourcePurchaseId,
|
||||
$user,
|
||||
): Ticket {
|
||||
$item = $target['catalog_item'];
|
||||
$variant = $target['variant'];
|
||||
$validityTime = $this->resolveValidityTime($item, $variant);
|
||||
$validityTime = $this->materializeEventDateValidityTime(
|
||||
$variant,
|
||||
$validityTime,
|
||||
$fixedValidityTimes,
|
||||
);
|
||||
|
||||
return Ticket::query()->create([
|
||||
'tenant_code' => $item->tenant_code,
|
||||
@@ -168,4 +176,56 @@ class TicketGeneratorService
|
||||
|
||||
return $validityTimes->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a recurring time window into the fixed date and time purchased by
|
||||
* the customer. Equal tickets generated together share the same snapshot.
|
||||
*
|
||||
* @param array<string, ValidityTime> $fixedValidityTimes
|
||||
*/
|
||||
private function materializeEventDateValidityTime(
|
||||
?Variant $variant,
|
||||
?ValidityTime $validityTime,
|
||||
array &$fixedValidityTimes,
|
||||
): ?ValidityTime {
|
||||
if (
|
||||
$variant === null
|
||||
|| $validityTime === null
|
||||
|| $validityTime->type !== ValidityTimeType::TimeWindow
|
||||
) {
|
||||
return $validityTime;
|
||||
}
|
||||
|
||||
$variant->loadMissing('eventDate');
|
||||
$eventDate = $variant->eventDate;
|
||||
|
||||
if ($eventDate === null) {
|
||||
return $validityTime;
|
||||
}
|
||||
|
||||
$cacheKey = $eventDate->getKey().':'.$validityTime->getKey();
|
||||
|
||||
if (isset($fixedValidityTimes[$cacheKey])) {
|
||||
return $fixedValidityTimes[$cacheKey];
|
||||
}
|
||||
|
||||
$startsAt = $validityTime->startsAt($eventDate->date);
|
||||
$expiresAt = $validityTime->expiresAt($eventDate->date);
|
||||
|
||||
if (
|
||||
$startsAt !== null
|
||||
&& $expiresAt !== null
|
||||
&& $expiresAt->lessThanOrEqualTo($startsAt)
|
||||
) {
|
||||
$expiresAt = $expiresAt->addDay();
|
||||
}
|
||||
|
||||
return $fixedValidityTimes[$cacheKey] = ValidityTime::query()->create([
|
||||
'type' => ValidityTimeType::FixedWindow,
|
||||
'start_time' => null,
|
||||
'end_time' => null,
|
||||
'fixed_starts_at' => $startsAt,
|
||||
'fixed_expires_at' => $expiresAt,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user