feat(ticket): resolve effective event dates and handle reschedule chains

This commit is contained in:
2026-09-11 12:28:37 -03:00
parent d5fdae9a24
commit 106cf017dc
3 changed files with 62 additions and 2 deletions

View File

@@ -0,0 +1,37 @@
<?php
namespace App\Domains\Event\Services;
use App\Domains\Event\Models\EventDate;
class EffectiveEventDateResolver
{
public function resolve(EventDate $eventDate): ?EventDate
{
$current = $eventDate;
$visited = [];
while (true) {
$identity = $current->getKey() === null
? 'object:'.spl_object_id($current)
: 'key:'.$current->getKey();
if (isset($visited[$identity])) {
return null;
}
$visited[$identity] = true;
if ($current->rescheduled_to_event_date_id === null) {
return $current->cancelled_at === null ? $current : null;
}
$current->loadMissing('rescheduledTo');
$current = $current->rescheduledTo;
if ($current === null) {
return null;
}
}
}
}

View File

@@ -4,6 +4,8 @@ namespace App\Domains\Ticket\Services;
use App\Domains\Catalog\Models\Variant;
use App\Domains\Catalog\Models\VariantDefinition;
use App\Domains\Event\Models\EventDate;
use App\Domains\Event\Services\EffectiveEventDateResolver;
use App\Domains\Ticket\Models\Ticket;
use App\Domains\Ticket\Models\ValidityTime;
use Illuminate\Support\Collection;
@@ -17,6 +19,14 @@ use Illuminate\Support\Collection;
*/
class TicketValidityResolver
{
private readonly EffectiveEventDateResolver $effectiveEventDateResolver;
public function __construct(?EffectiveEventDateResolver $effectiveEventDateResolver = null)
{
$this->effectiveEventDateResolver = $effectiveEventDateResolver
?? new EffectiveEventDateResolver;
}
/** Relaciones necesarias para resolver tickets sin consultas N+1. */
public const RELATIONS = [
'sourceVariant.eventDates.validityTime',
@@ -56,7 +66,18 @@ class TicketValidityResolver
]);
$dimensions = collect();
$eventDates = $variant->selectedEventDates();
$selectedEventDates = $variant->selectedEventDates();
$eventDates = $selectedEventDates
->map(fn (EventDate $eventDate): ?EventDate => $this->effectiveEventDateResolver->resolve($eventDate))
->filter()
->unique(fn (EventDate $eventDate): int => $eventDate->getKey() ?? spl_object_id($eventDate))
->values();
if ($selectedEventDates->isNotEmpty() && $eventDates->isEmpty()) {
return ResolvedTicketValidity::unresolvable();
}
$eventDates->each->loadMissing('validityTime');
if ($eventDates->contains(fn ($eventDate): bool => $eventDate->validityTime === null)) {
return ResolvedTicketValidity::unresolvable();