Revert "feat(variants): implement restoration of previously suspended variants with usable dates"

This reverts commit 3a4f6b64d2.
This commit is contained in:
2026-09-16 09:08:43 -03:00
parent 3a4f6b64d2
commit 8ad9b3a4e3
5 changed files with 21 additions and 124 deletions

View File

@@ -8,9 +8,7 @@ use App\Domains\Catalog\Models\StockReservation;
use App\Domains\Catalog\Models\StockReservationLine;
use App\Domains\Catalog\Models\Variant;
use App\Domains\Event\Models\EventDate;
use App\Domains\Event\Services\EffectiveEventDateResolver;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
class VariantReplacementService
{
@@ -72,7 +70,14 @@ class VariantReplacementService
->get();
foreach ($variants as $variant) {
$remainingDateIds = $this->usableDateIds($variant);
$remainingDateIds = $variant->selectedEventDates()
->filter(fn (EventDate $date): bool => $date->suspended_at === null
&& $date->rescheduled_to_event_date_id === null)
->pluck('id')
->map(fn ($id): int => (int) $id)
->unique()
->sort()
->values();
if ($remainingDateIds->isEmpty()) {
$variant->update(['sales_disabled_at' => now()]);
@@ -80,75 +85,22 @@ class VariantReplacementService
continue;
}
$this->replaceWithUsableDates($variant, $remainingDateIds);
}
}
public function restorePreviouslySuspendedVariants(): int
{
return DB::transaction(function (): int {
$variants = Variant::query()
->whereNotNull('sales_disabled_at')
->whereNull('replaced_by_variant_id')
->with(['eventDates', 'eventDate', 'definitions', 'allAttachments'])
->orderBy('id')
->lockForUpdate()
->get();
$restored = 0;
foreach ($variants as $variant) {
if (! $variant->selectedEventDates()->contains(
fn (EventDate $date): bool => $date->suspended_at !== null,
)) {
continue;
}
$usableDateIds = $this->usableDateIds($variant);
if ($usableDateIds->isEmpty()) {
continue;
}
$this->replaceWithUsableDates($variant, $usableDateIds);
$restored++;
$replacement = $this->findEquivalent($variant, $remainingDateIds);
if ($replacement === null) {
$replacement = $this->cloneWithDates($variant, $remainingDateIds);
} else {
$this->mergeInventoryInto($variant, $replacement);
}
return $restored;
});
}
$variant->update([
'replaced_by_variant_id' => $replacement->getKey(),
'sales_disabled_at' => now(),
]);
/** @return Collection<int, int> */
private function usableDateIds(Variant $variant): Collection
{
$resolver = app(EffectiveEventDateResolver::class);
return $variant->selectedEventDates()
->map(fn (EventDate $date): ?EventDate => $resolver->resolve($date))
->filter()
->pluck('id')
->map(fn ($id): int => (int) $id)
->unique()
->sort()
->values();
}
/** @param Collection<int, int> $dateIds */
private function replaceWithUsableDates(Variant $variant, Collection $dateIds): void
{
$replacement = $this->findEquivalent($variant, $dateIds);
if ($replacement === null) {
$replacement = $this->cloneWithDates($variant, $dateIds);
} else {
$this->mergeInventoryInto($variant, $replacement);
BundleComponent::query()
->where('component_variant_id', $variant->getKey())
->update(['component_variant_id' => $replacement->getKey()]);
}
$variant->update([
'replaced_by_variant_id' => $replacement->getKey(),
'sales_disabled_at' => $variant->sales_disabled_at ?? now(),
]);
BundleComponent::query()
->where('component_variant_id', $variant->getKey())
->update(['component_variant_id' => $replacement->getKey()]);
}
/** @param Collection<int, int> $eventDateIds */

View File

@@ -12,12 +12,7 @@ class EntryResource extends JsonResource
/** @return array<string, mixed> */
public function toArray(Request $request): array
{
$variant = $this->variants
->filter(fn ($candidate): bool => $candidate->sales_disabled_at === null
&& $candidate->replaced_by_variant_id === null)
->sortByDesc('id')
->first()
?? $this->variants->sortByDesc('id')->firstOrFail();
$variant = $this->variants->sole();
return [
'id' => $this->id,

View File

@@ -97,8 +97,6 @@ class EntryService
$variants = Variant::query()
->where('catalog_item_id', $catalogItem->id)
->whereNull('sales_disabled_at')
->whereNull('replaced_by_variant_id')
->lockForUpdate()
->get();

View File

@@ -1,17 +0,0 @@
<?php
use App\Domains\Catalog\Services\VariantReplacementService;
use Illuminate\Database\Migrations\Migration;
return new class extends Migration
{
public function up(): void
{
app(VariantReplacementService::class)->restorePreviouslySuspendedVariants();
}
public function down(): void
{
// Historical variants and their purchases must remain intact.
}
};

View File

@@ -11,7 +11,6 @@ use App\Domains\Catalog\Models\Inventory;
use App\Domains\Catalog\Models\StockReservation;
use App\Domains\Catalog\Models\StockReservationLine;
use App\Domains\Catalog\Models\Variant;
use App\Domains\Catalog\Services\VariantReplacementService;
use App\Domains\Event\Events\EventDateRescheduled;
use App\Domains\Event\Events\EventDateSuspended;
use App\Domains\Purchase\Services\Checkout\CatalogSelectionResolver;
@@ -576,36 +575,6 @@ class AdminAppEventControllerTest extends TestCase
$this->assertFalse($ticket->fresh()->resolvedValidity()->isResolvable);
}
public function test_previous_suspensions_restore_variants_with_usable_dates(): void
{
$tenant = $this->createTenant('acme');
$suspendedDate = $tenant->eventDates()->create([
'date' => '2027-10-09',
'time_start' => '09:00',
'time_end' => '18:30',
'suspended_at' => now(),
]);
$usableDate = $tenant->eventDates()->create([
'date' => '2027-10-10',
'time_start' => '09:00',
'time_end' => '18:30',
]);
$variant = $this->createVariant($tenant);
$variant->eventDates()->sync([$suspendedDate->id, $usableDate->id]);
$variant->inventory->update(['real_stock' => 5]);
$variant->update(['sales_disabled_at' => now()]);
$service = app(VariantReplacementService::class);
$this->assertSame(1, $service->restorePreviouslySuspendedVariants());
$this->assertSame(0, $service->restorePreviouslySuspendedVariants());
$replacement = $variant->fresh()->replacement;
$this->assertNotNull($replacement);
$this->assertSame([$usableDate->id], $replacement->selectedEventDates()->pluck('id')->all());
$this->assertSame(5, $replacement->inventory->availableStock());
$this->assertTrue(CatalogItem::query()->whereKey($variant->catalog_item_id)->whereAvailable()->exists());
}
public function test_update_and_date_creation_validate_their_own_payloads(): void
{
$tenant = $this->createTenant('acme');