refactor(backend): reorganize domains into Core, Commerce, Ticketing and Shared
This commit is contained in:
@@ -0,0 +1,216 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Ticket\Services;
|
||||
|
||||
use App\Domains\Catalog\Models\ItemAttribute;
|
||||
use App\Domains\Event\Models\EventDate;
|
||||
use App\Domains\Ticket\Models\Ticket;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class AdminAppTicketRowService
|
||||
{
|
||||
private const FIESTA_FUTBOL_INFANTIL = 'fiesta_futbol_infantil';
|
||||
|
||||
private const CATEGORY_PRESENTATIONS = [
|
||||
'alojamientos' => ['category' => 'Camping', 'product' => 'tipo_alojamiento', 'type' => null, 'size' => null],
|
||||
'camping' => ['category' => null, 'product' => 'tipo_alojamiento', 'type' => null, 'size' => null],
|
||||
'entradas' => ['category' => null, 'product' => 'product', 'type' => null, 'size' => null],
|
||||
'comidas' => ['category' => 'Comida', 'product' => 'horario', 'type' => 'servicio', 'size' => null],
|
||||
'comida' => ['category' => null, 'product' => 'horario', 'type' => 'servicio', 'size' => null],
|
||||
'merchandising' => ['category' => null, 'product' => 'product', 'type' => 'color', 'size' => 'talle'],
|
||||
];
|
||||
|
||||
/** @return array<string, mixed> */
|
||||
public function details(Ticket $ticket): array
|
||||
{
|
||||
$purchaseItem = $ticket->sourcePurchaseItem;
|
||||
$refund = $ticket->refund;
|
||||
|
||||
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,
|
||||
'refund_type' => $refund?->type,
|
||||
'refund_type_label' => $refund?->typeLabel(),
|
||||
'client' => $purchaseItem?->purchase?->nombre_apellido ?? $ticket->user?->nombre_apellido,
|
||||
'status' => $ticket->status,
|
||||
'scanned_by' => $ticket->scannerUser?->nombre_apellido,
|
||||
'variant_properties' => $this->variantProperties($ticket),
|
||||
'allow_refund' => $ticket->allow_refund(),
|
||||
];
|
||||
}
|
||||
|
||||
/** @param array<string, mixed>|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'],
|
||||
'status_label' => $ticket->status_label,
|
||||
'scanned_by' => $details['scanned_by'] ?? '-',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection<int, Ticket> $tickets
|
||||
* @return Collection<int, array<string, mixed>>
|
||||
*/
|
||||
public function rows(Collection $tickets): Collection
|
||||
{
|
||||
return $tickets->values()->map(fn (Ticket $ticket): array => $this->values($ticket));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection<int, array<string, mixed>> $rows
|
||||
* @param list<array<string, mixed>> $columns
|
||||
* @return Collection<int, array<string, string>>
|
||||
*/
|
||||
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(
|
||||
$column['type'] === 'status'
|
||||
? ($row['status_label'] ?? $row[$column['key']] ?? null)
|
||||
: ($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' => Ticket::statusLabel((string) $value),
|
||||
default => (string) $value,
|
||||
};
|
||||
}
|
||||
|
||||
/** @param array<string, mixed> $details */
|
||||
private function presentation(Ticket $ticket, array $details): array
|
||||
{
|
||||
$sourceCategory = trim((string) ($ticket->sourceCatalogItem?->category?->nombre ?? '')) ?: '-';
|
||||
$effectiveDates = $this->effectiveEventDateLabels($ticket) ?: '-';
|
||||
|
||||
if ($ticket->tenant_code !== self::FIESTA_FUTBOL_INFANTIL) {
|
||||
return [
|
||||
'category' => $sourceCategory,
|
||||
'product' => (string) ($details['product'] ?: $ticket->name ?: '-'),
|
||||
'type' => $this->allPropertyLabels($details) ?: '-',
|
||||
'date' => $effectiveDates,
|
||||
'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' => $effectiveDates,
|
||||
'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' => $effectiveDates,
|
||||
'size' => $configuration['size'] === null
|
||||
? '-'
|
||||
: ($this->propertyLabels($details, $configuration['size']) ?: '-'),
|
||||
];
|
||||
}
|
||||
|
||||
private function effectiveEventDateLabels(Ticket $ticket): string
|
||||
{
|
||||
return $ticket->sourceVariant?->selectedEventDates()
|
||||
->map(fn (EventDate $date): ?EventDate => $date->effectiveDate())
|
||||
->filter()
|
||||
->unique(fn (EventDate $date): int => $date->getKey())
|
||||
->sortBy(fn (EventDate $date): string => $date->date->format('Y-m-d'))
|
||||
->map(fn (EventDate $date): string => $date->date->format('d/m'))
|
||||
->implode(', ') ?? '';
|
||||
}
|
||||
|
||||
/** @param array<string, mixed> $details */
|
||||
private function propertyLabels(array $details, string $code): string
|
||||
{
|
||||
$property = collect($details['variant_properties'] ?? [])->firstWhere('code', $code);
|
||||
$labels = collect($property['values'] ?? [])->pluck('label')->filter();
|
||||
|
||||
return $labels->implode(', ');
|
||||
}
|
||||
|
||||
/** @param array<string, mixed> $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<array{code: string, label: string, values: list<array{value: string, label: string}>}> */
|
||||
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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user