feat(checkout): enforce editing policy on items
This commit is contained in:
@@ -161,7 +161,26 @@ class CartService
|
||||
|| ($updateVariant && $cartItem->variant_id !== $variantId);
|
||||
|
||||
if (! $hasChanges) {
|
||||
return $this->loadCart($checkoutCart);
|
||||
return $this->loadCart($checkoutCart, $tenant, true);
|
||||
}
|
||||
|
||||
if (
|
||||
(int) $cartItem->cantidad !== $quantity
|
||||
&& ! $tenant->checkout_editing_policy->allowsQuantityChanges()
|
||||
) {
|
||||
throw ValidationException::withMessages([
|
||||
'cantidad' => __('api.cart.editing_disabled'),
|
||||
]);
|
||||
}
|
||||
|
||||
if (
|
||||
$updateVariant
|
||||
&& $cartItem->variant_id !== $variantId
|
||||
&& ! $tenant->checkout_editing_policy->allowsVariantChanges()
|
||||
) {
|
||||
throw ValidationException::withMessages([
|
||||
'variant_id' => __('api.cart.variant_change_disabled'),
|
||||
]);
|
||||
}
|
||||
|
||||
$checkoutCart->updateItem(
|
||||
@@ -184,7 +203,7 @@ class CartService
|
||||
]);
|
||||
$this->reservations->syncPurchaseExpiration($purchase);
|
||||
|
||||
return $this->loadCart($checkoutCart);
|
||||
return $this->loadCart($checkoutCart, $tenant, true);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -203,6 +222,78 @@ class CartService
|
||||
return $this->loadCart($cart, $tenant);
|
||||
}
|
||||
|
||||
public function removeCheckoutItem(
|
||||
Tenant $tenant,
|
||||
Request $request,
|
||||
Cart $cart,
|
||||
int $cartItemId,
|
||||
): Cart {
|
||||
if (! $tenant->checkout_editing_policy->allowsRemoval()) {
|
||||
throw ValidationException::withMessages([
|
||||
'cart_item' => __('api.cart.editing_disabled'),
|
||||
]);
|
||||
}
|
||||
|
||||
$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): 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.');
|
||||
}
|
||||
|
||||
$checkoutCart->removeItem($cartItemId);
|
||||
$purchase->telepagosQr()->delete();
|
||||
$purchase->update([
|
||||
'status' => Purchase::STATUS_CREATED,
|
||||
'payment_method' => null,
|
||||
'transfer_payer_dni' => null,
|
||||
'total' => $checkoutCart->getTotalAmount(),
|
||||
'expires_at' => now()->addMinutes(
|
||||
max(1, (int) config('purchase.checkout_expiration_minutes', 30)),
|
||||
),
|
||||
]);
|
||||
$this->reservations->syncPurchaseExpiration($purchase);
|
||||
|
||||
return $this->loadCart($checkoutCart, $tenant, true);
|
||||
});
|
||||
}
|
||||
|
||||
public function makeGuestTokenCookie(string $guestToken): Cookie
|
||||
{
|
||||
return cookie(
|
||||
@@ -230,7 +321,7 @@ class CartService
|
||||
return $cart;
|
||||
}
|
||||
|
||||
protected function loadCart(Cart $cart, Tenant $tenant): Cart
|
||||
protected function loadCart(Cart $cart, Tenant $tenant, bool $isCheckout = false): Cart
|
||||
{
|
||||
$relations = [
|
||||
'items.catalogItem.attachments',
|
||||
@@ -243,7 +334,11 @@ class CartService
|
||||
'items.variant.eventDate',
|
||||
];
|
||||
|
||||
if ($tenant->cart_editing_policy->allowsVariantChanges()) {
|
||||
$editingPolicy = $isCheckout
|
||||
? $tenant->checkout_editing_policy
|
||||
: $tenant->cart_editing_policy;
|
||||
|
||||
if ($editingPolicy->allowsVariantChanges()) {
|
||||
$relations = [
|
||||
...$relations,
|
||||
'items.catalogItem.variants' => fn ($query) => $query->orderBy('id'),
|
||||
|
||||
Reference in New Issue
Block a user