refactor(cart): own checkout item editing
This commit is contained in:
@@ -4,15 +4,23 @@ namespace App\Domains\Cart\Services;
|
||||
|
||||
use App\Domains\Auth\Models\User;
|
||||
use App\Domains\Cart\Models\Cart;
|
||||
use App\Domains\Catalog\Services\StockReservationService;
|
||||
use App\Domains\Purchase\Models\Purchase;
|
||||
use App\Domains\Tenant\Models\Tenant;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Symfony\Component\HttpFoundation\Cookie;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
class CartService
|
||||
{
|
||||
public function __construct(
|
||||
private readonly StockReservationService $reservations,
|
||||
) {}
|
||||
|
||||
public function show(Tenant $tenant, Request $request): Cart
|
||||
{
|
||||
$resolvedIdentity = $this->resolveIdentity($request);
|
||||
@@ -66,6 +74,139 @@ class CartService
|
||||
return $this->loadCart($cart);
|
||||
}
|
||||
|
||||
public function updateCheckoutItem(
|
||||
Tenant $tenant,
|
||||
Request $request,
|
||||
Cart $cart,
|
||||
int $cartItemId,
|
||||
int $quantity,
|
||||
?int $variantId,
|
||||
bool $updateVariant,
|
||||
): Cart {
|
||||
$user = $request->user() ?? Auth::guard('sanctum')->user();
|
||||
|
||||
if (! $user instanceof User) {
|
||||
throw new NotFoundHttpException('Checkout cart not found.');
|
||||
}
|
||||
|
||||
return DB::transaction(function () use (
|
||||
$tenant,
|
||||
$user,
|
||||
$cart,
|
||||
$cartItemId,
|
||||
$quantity,
|
||||
$variantId,
|
||||
$updateVariant,
|
||||
): Cart {
|
||||
/** @var Purchase|null $purchase */
|
||||
$purchase = Purchase::query()
|
||||
->where('cart_id', $cart->getKey())
|
||||
->where('tenant_codigo', $tenant->codigo)
|
||||
->where('user_id', $user->getKey())
|
||||
->where('status', Purchase::STATUS_CREATED)
|
||||
->whereDoesntHave('items')
|
||||
->lockForUpdate()
|
||||
->first();
|
||||
|
||||
if ($purchase === null) {
|
||||
throw new NotFoundHttpException('Checkout cart not found.');
|
||||
}
|
||||
|
||||
if ($purchase->expires_at !== null && $purchase->expires_at->isPast()) {
|
||||
throw ValidationException::withMessages([
|
||||
'cart' => __('api.purchase.not_editable'),
|
||||
]);
|
||||
}
|
||||
|
||||
/** @var Cart|null $checkoutCart */
|
||||
$checkoutCart = Cart::query()
|
||||
->whereKey($cart->getKey())
|
||||
->where('tenant_codigo', $tenant->codigo)
|
||||
->where('user_id', $user->getKey())
|
||||
->where('status', 'checkout')
|
||||
->lockForUpdate()
|
||||
->first();
|
||||
|
||||
if ($checkoutCart === null) {
|
||||
throw new NotFoundHttpException('Checkout cart not found.');
|
||||
}
|
||||
|
||||
$checkoutCart->updateItem(
|
||||
$cartItemId,
|
||||
$quantity,
|
||||
$variantId,
|
||||
$updateVariant,
|
||||
$purchase->getKey(),
|
||||
);
|
||||
$purchase->update(['total' => $checkoutCart->getTotalAmount()]);
|
||||
|
||||
return $this->loadCart($checkoutCart);
|
||||
});
|
||||
}
|
||||
|
||||
public function prepareCheckoutEditing(
|
||||
Tenant $tenant,
|
||||
Request $request,
|
||||
Cart $cart,
|
||||
): Cart {
|
||||
$user = $request->user() ?? Auth::guard('sanctum')->user();
|
||||
|
||||
if (! $user instanceof User) {
|
||||
throw new NotFoundHttpException('Checkout cart not found.');
|
||||
}
|
||||
|
||||
return DB::transaction(function () use ($tenant, $user, $cart): Cart {
|
||||
/** @var Purchase|null $purchase */
|
||||
$purchase = Purchase::query()
|
||||
->where('cart_id', $cart->getKey())
|
||||
->where('tenant_codigo', $tenant->codigo)
|
||||
->where('user_id', $user->getKey())
|
||||
->whereIn('status', [
|
||||
Purchase::STATUS_CREATED,
|
||||
Purchase::STATUS_PENDING_PAYMENT,
|
||||
])
|
||||
->whereDoesntHave('items')
|
||||
->lockForUpdate()
|
||||
->first();
|
||||
|
||||
if ($purchase === null) {
|
||||
throw new NotFoundHttpException('Checkout cart not found.');
|
||||
}
|
||||
|
||||
if ($purchase->expires_at !== null && $purchase->expires_at->isPast()) {
|
||||
throw ValidationException::withMessages([
|
||||
'cart' => __('api.purchase.not_editable'),
|
||||
]);
|
||||
}
|
||||
|
||||
/** @var Cart|null $checkoutCart */
|
||||
$checkoutCart = Cart::query()
|
||||
->whereKey($cart->getKey())
|
||||
->where('tenant_codigo', $tenant->codigo)
|
||||
->where('user_id', $user->getKey())
|
||||
->where('status', 'checkout')
|
||||
->lockForUpdate()
|
||||
->first();
|
||||
|
||||
if ($checkoutCart === null) {
|
||||
throw new NotFoundHttpException('Checkout cart not found.');
|
||||
}
|
||||
|
||||
$purchase->telepagosQr()->delete();
|
||||
$purchase->update([
|
||||
'status' => Purchase::STATUS_CREATED,
|
||||
'payment_method' => null,
|
||||
'transfer_payer_dni' => null,
|
||||
'expires_at' => now()->addMinutes(
|
||||
max(1, (int) config('purchase.checkout_expiration_minutes', 30)),
|
||||
),
|
||||
]);
|
||||
$this->reservations->syncPurchaseExpiration($purchase);
|
||||
|
||||
return $this->loadCart($checkoutCart);
|
||||
});
|
||||
}
|
||||
|
||||
public function removeItem(Tenant $tenant, Request $request, int $cartItemId): Cart
|
||||
{
|
||||
$identity = $this->requireIdentity($request);
|
||||
|
||||
Reference in New Issue
Block a user