refactor(stock): make expired reservations terminal

This commit is contained in:
2026-08-25 15:58:41 -03:00
parent 8545fbc645
commit 896fb81bcf
12 changed files with 205 additions and 30 deletions

View File

@@ -5,6 +5,7 @@ namespace App\Domains\Purchase\Services\Checkout;
use App\Domains\Cart\Models\Cart;
use App\Domains\Catalog\Models\StockReservation;
use App\Domains\Catalog\Services\StockReservationService;
use App\Domains\Purchase\Exceptions\PurchaseExpiredException;
use App\Domains\Purchase\Models\Purchase;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\ValidationException;
@@ -42,6 +43,11 @@ class ReleaseCheckoutService
): Purchase {
$purchase = $this->lockPurchase($purchase);
if ($purchase->status === Purchase::STATUS_EXPIRED
&& $targetStatus !== Purchase::STATUS_EXPIRED) {
throw new PurchaseExpiredException;
}
if ($purchase->status === Purchase::STATUS_PAID) {
if ($targetStatus === Purchase::STATUS_EXPIRED) {
return $this->loadPurchase($purchase);
@@ -66,6 +72,18 @@ class ReleaseCheckoutService
$cart = $purchase->cart()->withTrashed()->lockForUpdate()->first();
if ($targetStatus === Purchase::STATUS_CANCELLED
&& $cart?->status === 'active'
&& in_array($purchase->status, [
Purchase::STATUS_CREATED,
Purchase::STATUS_PENDING_PAYMENT,
], true)) {
$this->reservations->returnToCart($purchase, $cart);
$purchase->update(['status' => Purchase::STATUS_CANCELLED]);
return $this->loadPurchase($purchase);
}
if (
$targetStatus === Purchase::STATUS_EXPIRED
&& (! in_array($purchase->status, [
@@ -112,17 +130,17 @@ class ReleaseCheckoutService
}
if ($cart->status === 'active') {
$cartUpdate = [
'current_purchase_id' => null,
];
if ($targetStatus !== Purchase::STATUS_EXPIRED) {
$cartUpdate['current_stock_reservation_id'] = null;
}
Cart::query()
->whereKey($cart->getKey())
->where('current_purchase_id', $purchase->getKey())
->update([
'current_purchase_id' => null,
'current_stock_reservation_id' => null,
]);
if ($targetStatus === Purchase::STATUS_CANCELLED) {
$this->reservations->syncCart($cart);
}
->update($cartUpdate);
return;
}