Merge branch 'feature/cart_editing_policy' into dev

This commit is contained in:
2026-08-19 16:47:30 -03:00
32 changed files with 1057 additions and 74 deletions

View File

@@ -4,6 +4,7 @@ namespace App\Domains\Cart\Resources;
use App\Domains\Cart\Models\CartItem;
use App\Domains\Catalog\Enums\InventoryPolicy;
use App\Domains\Catalog\Models\Variant;
use App\Domains\Tenant\Models\Tenant;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
@@ -22,6 +23,8 @@ class CartItemResource extends JsonResource
$imageUrl = null;
$tenant = $request->route('tenant');
$displayImage = ! $tenant instanceof Tenant || $tenant->display_cart_item_images;
$includeVariants = $tenant instanceof Tenant
&& $tenant->cart_editing_policy->allowsVariantChanges();
if ($displayImage && $selectedItem?->relationLoaded('attachments')) {
$imageUrl = $selectedItem->attachments->first()?->getTemporaryUrl(1440);
@@ -39,14 +42,27 @@ class CartItemResource extends JsonResource
'variant_id' => $this->variant_id,
'nombre' => $selectedItem?->getName(),
'imagen' => $imageUrl,
'variant' => $this->variant === null ? null : [
'id' => $this->variant->id,
'precio' => $this->formatMoney($this->variant->getPrice()),
'stock_tecnico' => $this->catalogItem->inventory_policy === InventoryPolicy::Unlimited
? null
: $this->variant->inventory->availableStock(),
'values' => $this->variant->selectorOptions($this->catalogItem->itemAttributes),
],
'variant' => $this->variant === null ? null : $this->variantData($this->variant),
'variants' => $this->when(
$includeVariants,
fn () => $this->catalogItem
->visibleVariants($this->variant_id)
->map(fn (Variant $variant): array => $this->variantData($variant))
->values(),
),
];
}
/** @return array<string, mixed> */
protected function variantData(Variant $variant): array
{
return [
'id' => $variant->id,
'precio' => $this->formatMoney($variant->precio ?? $this->catalogItem->precio),
'stock_tecnico' => $this->catalogItem->inventory_policy === InventoryPolicy::Unlimited
? null
: $variant->inventory->availableStock(),
'values' => $variant->selectorOptions($this->catalogItem->itemAttributes),
];
}

View File

@@ -36,7 +36,7 @@ class CartService
return $this->makeEmptyCart($tenant);
}
return $this->loadCart($cart);
return $this->loadCart($cart, $tenant);
}
/**
@@ -55,7 +55,7 @@ class CartService
$cart->addItem($catalogItemId, $variantId, $quantity);
return [
'cart' => $this->loadCart($cart),
'cart' => $this->loadCart($cart, $tenant),
'guest_token' => $resolvedIdentity['generated_guest_token'],
];
}
@@ -68,11 +68,23 @@ class CartService
?int $variantId,
bool $updateVariant,
): Cart {
if ($updateVariant && ! $tenant->cart_editing_policy->allowsVariantChanges()) {
throw ValidationException::withMessages([
'variant_id' => __('api.cart.variant_change_disabled'),
]);
}
if (! $updateVariant && ! $tenant->cart_editing_policy->allowsQuantityChanges()) {
throw ValidationException::withMessages([
'cantidad' => __('api.cart.editing_disabled'),
]);
}
$identity = $this->requireIdentity($request);
$cart = $this->findCartOrFail($tenant, $identity);
$cart->updateItem($cartItemId, $quantity, $variantId, $updateVariant);
return $this->loadCart($cart);
return $this->loadCart($cart, $tenant);
}
public function updateCheckoutItem(
@@ -178,11 +190,17 @@ class CartService
public function removeItem(Tenant $tenant, Request $request, int $cartItemId): Cart
{
if (! $tenant->cart_editing_policy->allowsRemoval()) {
throw ValidationException::withMessages([
'cart_item' => __('api.cart.editing_disabled'),
]);
}
$identity = $this->requireIdentity($request);
$cart = $this->findCartOrFail($tenant, $identity);
$cart->removeItem($cartItemId);
return $this->loadCart($cart);
return $this->loadCart($cart, $tenant);
}
public function makeGuestTokenCookie(string $guestToken): Cookie
@@ -212,9 +230,9 @@ class CartService
return $cart;
}
protected function loadCart(Cart $cart): Cart
protected function loadCart(Cart $cart, Tenant $tenant): Cart
{
return $cart->fresh()->load([
$relations = [
'items.catalogItem.attachments',
'items.catalogItem.inventory',
'items.catalogItem.itemAttributes.attribute',
@@ -223,7 +241,21 @@ class CartService
'items.variant.definitions.itemAttribute.attribute.options',
'items.variant.eventDates',
'items.variant.eventDate',
]);
];
if ($tenant->cart_editing_policy->allowsVariantChanges()) {
$relations = [
...$relations,
'items.catalogItem.variants' => fn ($query) => $query->orderBy('id'),
'items.catalogItem.variants.inventory',
'items.catalogItem.variants.definitions' => fn ($query) => $query->orderBy('id'),
'items.catalogItem.variants.definitions.itemAttribute.attribute.options',
'items.catalogItem.variants.eventDates',
'items.catalogItem.variants.eventDate',
];
}
return $cart->fresh()->load($relations);
}
/**