['category' => 'Camping', 'product' => 'tipo_alojamiento', 'type' => null, 'date' => null, 'size' => null], 'camping' => ['category' => null, 'product' => 'tipo_alojamiento', 'type' => null, 'date' => null, 'size' => null], 'entradas' => ['category' => null, 'product' => 'product', 'type' => null, 'date' => null, 'size' => null], 'comidas' => ['category' => 'Comida', 'product' => 'horario', 'type' => 'servicio', 'date' => 'event_date', 'size' => null], 'comida' => ['category' => null, 'product' => 'horario', 'type' => 'servicio', 'date' => 'event_date', 'size' => null], 'merchandising' => ['category' => null, 'product' => 'product', 'type' => 'color', 'date' => null, 'size' => 'talle'], ]; /** @return array */ public function details(Ticket $ticket): array { $purchaseItem = $ticket->sourcePurchaseItem; return [ 'source_purchase_item_id' => $ticket->source_purchase_item_id, 'order_number' => $purchaseItem?->compra_id, 'product' => $purchaseItem?->item_nombre ?? $ticket->sourceCatalogItem?->nombre ?? $ticket->name, 'amount' => $purchaseItem?->precio_unitario, 'client' => $purchaseItem?->purchase?->nombre_apellido ?? $ticket->user?->nombre_apellido, 'status' => $ticket->status, 'scanned_by' => $ticket->scannerUser?->nombre_apellido, 'variant_properties' => $this->variantProperties($ticket), ]; } /** @param array|null $details */ public function values(Ticket $ticket, ?array $details = null): array { $details ??= $this->details($ticket); $presentation = $this->presentation($ticket, $details); return [ 'order_number' => $details['order_number'], 'category' => $presentation['category'], 'product' => $presentation['product'], 'type' => $presentation['type'], 'date' => $presentation['date'], 'size' => $presentation['size'], 'amount' => $details['amount'] === null ? null : (float) $details['amount'], 'client' => $details['client'] ?? 'Sin nombre', 'id' => $ticket->id, 'status' => $details['status'], 'scanned_by' => $details['scanned_by'] ?? '-', ]; } /** * @param Collection $tickets * @return Collection> */ public function rows(Collection $tickets): Collection { return $tickets->values()->map(fn (Ticket $ticket): array => $this->values($ticket)); } /** * @param Collection> $rows * @param list> $columns * @return Collection> */ public function displayRows(Collection $rows, array $columns, string $timeZone): Collection { return $rows->map(fn (array $row): array => collect($columns) ->mapWithKeys(fn (array $column): array => [ $column['key'] => $this->displayValue( $row[$column['key']] ?? null, $column['type'], $timeZone, ), ]) ->all()); } public function displayValue(mixed $value, string $type, string $timeZone): string { if ($value === null || $value === '') { return '-'; } return match ($type) { 'order_number' => '#'.$value, 'currency' => '$'.number_format((float) $value, 2, ',', '.'), 'status' => match ((string) $value) { Ticket::STATUS_USED => 'Usado', Ticket::STATUS_EXPIRED => 'Vencido', default => 'Activo', }, default => (string) $value, }; } /** @param array $details */ private function presentation(Ticket $ticket, array $details): array { $sourceCategory = trim((string) ($ticket->sourceCatalogItem?->category?->nombre ?? '')) ?: '-'; if ($ticket->tenant_code !== self::FIESTA_FUTBOL_INFANTIL) { return [ 'category' => $sourceCategory, 'product' => (string) ($details['product'] ?: $ticket->name ?: '-'), 'type' => $this->allPropertyLabels($details) ?: '-', 'date' => '-', 'size' => '-', ]; } $configuration = self::CATEGORY_PRESENTATIONS[mb_strtolower($sourceCategory)] ?? null; if ($configuration === null) { return [ 'category' => $sourceCategory, 'product' => (string) ($details['product'] ?: $ticket->name ?: '-'), 'type' => $this->allPropertyLabels($details) ?: '-', 'date' => '-', 'size' => '-', ]; } return [ 'category' => $configuration['category'] ?? $sourceCategory, 'product' => $configuration['product'] === 'product' ? (string) ($details['product'] ?: $ticket->name ?: '-') : ($this->propertyLabels($details, $configuration['product']) ?: '-'), 'type' => $configuration['type'] === null ? '-' : ($this->propertyLabels($details, $configuration['type']) ?: '-'), 'date' => $configuration['date'] === null ? '-' : ($this->propertyLabels($details, $configuration['date']) ?: '-'), 'size' => $configuration['size'] === null ? '-' : ($this->propertyLabels($details, $configuration['size']) ?: '-'), ]; } /** @param array $details */ private function propertyLabels(array $details, string $code): string { $property = collect($details['variant_properties'] ?? [])->firstWhere('code', $code); $labels = collect($property['values'] ?? [])->pluck('label')->filter(); if ($code === 'event_date') { $labels = $labels->map(function (string $label): string { [$day, $month] = array_pad(explode('/', $label), 2, null); return $day !== null && $month !== null ? "{$day}/{$month}" : $label; }); } return $labels->implode(', '); } /** @param array $details */ private function allPropertyLabels(array $details): string { return collect($details['variant_properties'] ?? []) ->flatMap(fn (array $property): array => $property['values'] ?? []) ->pluck('label') ->filter() ->implode(', '); } /** @return list}> */ private function variantProperties(Ticket $ticket): array { $variant = $ticket->sourceVariant; if ($variant === null) { return []; } $itemAttributes = $variant->definitions ->map(fn ($definition) => $definition->itemAttribute) ->filter() ->merge($variant->catalogItem?->itemAttributes ?? collect()) ->unique('id') ->values(); return $variant->selectionOptions($itemAttributes) ->map(function (array $selection, string $attributeCode) use ($itemAttributes): array { $itemAttribute = $itemAttributes->first( fn (ItemAttribute $itemAttribute): bool => $itemAttribute->attribute?->codigo === $attributeCode, ); $values = array_is_list($selection) ? $selection : [$selection]; return [ 'code' => $attributeCode, 'label' => $itemAttribute?->attribute?->nombre ?? ($attributeCode === 'event_date' ? 'Fecha' : $attributeCode), 'values' => array_values($values), ]; }) ->values() ->all(); } }