*/ public function toArray(Request $request): array { $tenant = $request->route('tenant'); $displayImage = ! $tenant instanceof Tenant || $tenant->display_cart_item_images; if ($this->resource instanceof PurchaseItem) { $imageUrl = $displayImage ? $this->imageAttachment?->getTemporaryUrl(1440) : null; $attributes = $this->variant_attributes ?? []; $catalogItem = $this->relationLoaded('sourceCatalogItem') ? $this->sourceCatalogItem : null; $includeVariants = $tenant instanceof Tenant && $tenant->checkout_editing_policy->allowsVariantChanges() && $catalogItem !== null && $catalogItem->relationLoaded('variants'); return [ 'id' => $this->id, 'quantity' => (int) $this->cantidad, 'unit_price' => $this->formatMoney($this->precio_unitario), 'line_total' => $this->formatMoney($this->total), 'source_catalog_item_id' => $this->source_catalog_item_id, 'source_variant_id' => $this->source_variant_id, 'item_details' => [ 'nombre' => $this->item_nombre, 'descripcion' => $this->descripcion, 'slug' => $this->slug, 'imagen' => $imageUrl, 'attributes' => $attributes, ], 'variants' => $this->when( $includeVariants, fn () => $catalogItem ->visibleVariants($this->source_variant_id) ->map(fn (Variant $variant): array => $this->variantData($catalogItem, $variant)) ->values(), ), ]; } $selectedItem = $this->selectedItem(); $catalogItem = $this->catalogItem; $variant = $this->variant; $quantity = (int) ($this->cantidad ?? 0); $unitPrice = $this->resolveUnitPrice($selectedItem); $lineTotal = $unitPrice * $quantity; $imageUrl = $displayImage ? $this->resolveImageUrl($selectedItem, $catalogItem) : null; $includeVariants = $tenant instanceof Tenant && $tenant->checkout_editing_policy->allowsVariantChanges() && $catalogItem?->relationLoaded('variants'); return [ 'id' => $this->id, 'quantity' => $quantity, 'unit_price' => $this->formatMoney($unitPrice), 'line_total' => $this->formatMoney($lineTotal), 'source_catalog_item_id' => $this->catalog_item_id, 'source_variant_id' => $this->variant_id, 'item_details' => $selectedItem === null ? null : [ 'nombre' => $selectedItem->getName(), 'descripcion' => $selectedItem->getDescription(), 'slug' => $catalogItem?->slug, 'imagen' => $imageUrl, 'attributes' => $variant === null ? [] : $this->resolveAttributes($variant), ], 'variants' => $this->when( $includeVariants, fn () => $catalogItem ->visibleVariants($this->variant_id) ->map(fn (Variant $availableVariant): array => $this->variantData( $catalogItem, $availableVariant, )) ->values(), ), ]; } private function resolveUnitPrice(CatalogItem|Variant|null $selectedItem): float { return (float) ($selectedItem?->getPrice() ?? 0); } private function resolveImageUrl( CatalogItem|Variant|null $selectedItem, ?CatalogItem $catalogItem, ): ?string { $attachment = $selectedItem?->relationLoaded('attachments') ? $selectedItem->attachments->first() : null; if ($attachment === null && $catalogItem?->relationLoaded('attachments')) { $attachment = $catalogItem->attachments->first(); } return $attachment?->getTemporaryUrl(1440); } /** @return array */ private function resolveAttributes(Variant $variant): array { if (! $variant->relationLoaded('definitions')) { return []; } $attributes = $variant->definitions ->groupBy('item_attribute_id') ->map(function ($definitions): array { $itemAttribute = $definitions->first()?->itemAttribute; $values = $definitions->pluck('value')->values(); return [ 'name' => (string) ($itemAttribute?->attribute?->nombre ?? ''), 'value' => $itemAttribute?->allow_multi_select ? $values->all() : $values->first(), ]; }) ->filter(fn (array $attribute): bool => $attribute['name'] !== '' || $attribute['value'] !== null) ->values(); $eventDates = $variant->relationLoaded('eventDates') ? $variant->selectedEventDates() : collect(); if ($eventDates->isNotEmpty()) { $attributes->prepend([ 'name' => 'Fecha', 'value' => $eventDates ->map(fn ($eventDate): string => $eventDate->date->format('Y-m-d')) ->values() ->all(), ]); } return $attributes->all(); } private function formatMoney(float|int|string|null $amount): string { return number_format((float) ($amount ?? 0), 2, '.', ''); } /** @return array */ private function variantData(CatalogItem $catalogItem, Variant $variant): array { return [ 'id' => $variant->id, 'precio' => $this->formatMoney($variant->precio ?? $catalogItem->precio), 'stock_tecnico' => $catalogItem->inventory_policy === InventoryPolicy::Unlimited ? null : $variant->inventory->availableStock(), 'values' => $variant->selectorOptions($catalogItem->itemAttributes), ]; } }