refactor(stock): propagate reservation expiration
This commit is contained in:
@@ -4,6 +4,7 @@ namespace App\Domains\Cart\Services;
|
|||||||
|
|
||||||
use App\Domains\Auth\Models\User;
|
use App\Domains\Auth\Models\User;
|
||||||
use App\Domains\Cart\Models\Cart;
|
use App\Domains\Cart\Models\Cart;
|
||||||
|
use App\Domains\Catalog\Exceptions\StockReservationExpiredException;
|
||||||
use App\Domains\Catalog\Models\StockReservation;
|
use App\Domains\Catalog\Models\StockReservation;
|
||||||
use App\Domains\Catalog\Services\ExpireStockReservationsService;
|
use App\Domains\Catalog\Services\ExpireStockReservationsService;
|
||||||
use App\Domains\Tenant\Models\Tenant;
|
use App\Domains\Tenant\Models\Tenant;
|
||||||
@@ -126,7 +127,7 @@ class CartService
|
|||||||
}
|
}
|
||||||
|
|
||||||
$cart->update([
|
$cart->update([
|
||||||
'status' => 'abandoned',
|
'status' => Cart::STATUS_ABANDONED,
|
||||||
'current_purchase_id' => null,
|
'current_purchase_id' => null,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -292,68 +293,14 @@ class CartService
|
|||||||
*/
|
*/
|
||||||
protected function findOrCreateCart(Tenant $tenant, array $identity): Cart
|
protected function findOrCreateCart(Tenant $tenant, array $identity): Cart
|
||||||
{
|
{
|
||||||
return $this->resolveCart($tenant, $identity)
|
|
||||||
?? $this->createCart($tenant, $identity);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array{user_id: ?int, guest_token: ?string} $identity
|
|
||||||
*/
|
|
||||||
protected function resolveCart(
|
|
||||||
Tenant $tenant,
|
|
||||||
array $identity,
|
|
||||||
bool $replaceExpired = true,
|
|
||||||
): ?Cart {
|
|
||||||
$cart = $this->findCart($tenant, $identity);
|
$cart = $this->findCart($tenant, $identity);
|
||||||
|
|
||||||
if ($cart?->status === Cart::STATUS_ACTIVE
|
|
||||||
&& $cart->current_stock_reservation_id !== null
|
|
||||||
&& app(ExpireStockReservationsService::class)
|
|
||||||
->expireIfOverdue($cart->current_stock_reservation_id)) {
|
|
||||||
$cart = $this->findCart($tenant, $identity);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($cart?->status === Cart::STATUS_EXPIRED) {
|
if ($cart?->status === Cart::STATUS_EXPIRED) {
|
||||||
if (! $replaceExpired) {
|
throw new StockReservationExpiredException;
|
||||||
throw new StockReservationExpiredException;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->replaceExpiredCart($cart, $tenant, $identity);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($cart !== null) {
|
if ($cart !== null) {
|
||||||
return $cart;
|
return $cart;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array{user_id: ?int, guest_token: ?string} $identity
|
|
||||||
*/
|
|
||||||
protected function replaceExpiredCart(Cart $expiredCart, Tenant $tenant, array $identity): Cart
|
|
||||||
{
|
|
||||||
return DB::transaction(function () use ($expiredCart, $tenant, $identity): Cart {
|
|
||||||
/** @var Cart|null $lockedCart */
|
|
||||||
$lockedCart = Cart::query()->lockForUpdate()->find($expiredCart->getKey());
|
|
||||||
|
|
||||||
if ($lockedCart?->status === Cart::STATUS_EXPIRED) {
|
|
||||||
$lockedCart->update([
|
|
||||||
'status' => Cart::STATUS_ABANDONED,
|
|
||||||
'current_purchase_id' => null,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->findCart($tenant, $identity)
|
|
||||||
?? $this->createCart($tenant, $identity);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array{user_id: ?int, guest_token: ?string} $identity
|
|
||||||
*/
|
|
||||||
protected function createCart(Tenant $tenant, array $identity): Cart
|
|
||||||
{
|
|
||||||
$attributes = [
|
$attributes = [
|
||||||
'tenant_codigo' => $tenant->codigo,
|
'tenant_codigo' => $tenant->codigo,
|
||||||
'status' => Cart::STATUS_ACTIVE,
|
'status' => Cart::STATUS_ACTIVE,
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ class ExpireStockReservationsService
|
|||||||
$cart = Cart::query()
|
$cart = Cart::query()
|
||||||
->whereKey($cartId)
|
->whereKey($cartId)
|
||||||
->where('current_stock_reservation_id', $reservationId)
|
->where('current_stock_reservation_id', $reservationId)
|
||||||
->where('status', 'active')
|
->where('status', Cart::STATUS_ACTIVE)
|
||||||
->lockForUpdate()
|
->lockForUpdate()
|
||||||
->first();
|
->first();
|
||||||
if ($cart === null) {
|
if ($cart === null) {
|
||||||
@@ -155,6 +155,7 @@ class ExpireStockReservationsService
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->reservations->expire($reservation);
|
$this->reservations->expire($reservation);
|
||||||
|
$cart->update(['status' => Cart::STATUS_EXPIRED]);
|
||||||
|
|
||||||
return 'cart_reservations';
|
return 'cart_reservations';
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -129,13 +129,25 @@ class ReleaseCheckoutService
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($cart->status === 'active') {
|
if ($targetStatus === Purchase::STATUS_EXPIRED
|
||||||
|
&& in_array($cart->status, [Cart::STATUS_ACTIVE, Cart::STATUS_CHECKOUT], true)) {
|
||||||
|
Cart::query()
|
||||||
|
->whereKey($cart->getKey())
|
||||||
|
->where('current_purchase_id', $purchase->getKey())
|
||||||
|
->where('current_stock_reservation_id', $purchase->stock_reservation_id)
|
||||||
|
->update([
|
||||||
|
'status' => Cart::STATUS_EXPIRED,
|
||||||
|
'current_purchase_id' => null,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($cart->status === Cart::STATUS_ACTIVE) {
|
||||||
$cartUpdate = [
|
$cartUpdate = [
|
||||||
'current_purchase_id' => null,
|
'current_purchase_id' => null,
|
||||||
|
'current_stock_reservation_id' => null,
|
||||||
];
|
];
|
||||||
if ($targetStatus !== Purchase::STATUS_EXPIRED) {
|
|
||||||
$cartUpdate['current_stock_reservation_id'] = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Cart::query()
|
Cart::query()
|
||||||
->whereKey($cart->getKey())
|
->whereKey($cart->getKey())
|
||||||
@@ -145,7 +157,7 @@ class ReleaseCheckoutService
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($cart->status !== 'checkout') {
|
if ($cart->status !== Cart::STATUS_CHECKOUT) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user