60 lines
2.3 KiB
PHP
60 lines
2.3 KiB
PHP
<?php
|
|
|
|
namespace App\Domains\Cart\Services;
|
|
|
|
use App\Domains\Cart\Models\Cart;
|
|
use App\Domains\Catalog\Models\StockReservation;
|
|
use App\Domains\Catalog\Services\StockReservationService;
|
|
use App\Domains\Purchase\Models\Purchase;
|
|
use App\Domains\Tenant\Models\Tenant;
|
|
use Illuminate\Support\Collection;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class InvalidateEventDateCartsService
|
|
{
|
|
public function __construct(private readonly StockReservationService $reservations) {}
|
|
|
|
/** @param Collection<int, int> $eventDateIds */
|
|
public function invalidate(
|
|
Tenant $tenant,
|
|
Collection $eventDateIds,
|
|
string $reason = StockReservationService::REASON_EVENT_DATE_RESCHEDULED,
|
|
): void {
|
|
DB::transaction(function () use ($tenant, $eventDateIds, $reason): void {
|
|
$carts = Cart::query()
|
|
->where('tenant_codigo', $tenant->codigo)
|
|
->where('status', Cart::STATUS_ACTIVE)
|
|
->whereNull('current_purchase_id')
|
|
->whereHas('currentStockReservation', fn ($reservation) => $reservation
|
|
->where('status', StockReservation::STATUS_ACTIVE))
|
|
->whereHas('items.variant', fn ($variant) => $variant
|
|
->withTrashed()
|
|
->where(fn ($dates) => $dates
|
|
->whereIn('event_date_id', $eventDateIds)
|
|
->orWhereHas('eventDates', fn ($date) => $date
|
|
->whereIn('event_dates.id', $eventDateIds))))
|
|
->orderBy('id')
|
|
->lockForUpdate()
|
|
->get();
|
|
|
|
foreach ($carts as $cart) {
|
|
// Checkout keeps the cart and purchase attached to the same reservation.
|
|
if (Purchase::query()
|
|
->where('stock_reservation_id', $cart->current_stock_reservation_id)
|
|
->exists()) {
|
|
continue;
|
|
}
|
|
|
|
$this->reservations->releaseCurrentCartReservation(
|
|
$cart,
|
|
$reason,
|
|
);
|
|
|
|
// Reuse the existing expired-cart flow: stale mutations receive the
|
|
// expiration response and the next GET replaces the whole cart.
|
|
$cart->update(['status' => Cart::STATUS_EXPIRED]);
|
|
}
|
|
});
|
|
}
|
|
}
|