* }> */ public function attributes(Tenant $tenant): array { if ($tenant->codigo !== self::DESFILE_PURA_TENDENCIA) { return []; } $items = CatalogItem::withTrashed() ->where('tenant_code', $tenant->codigo) ->where(function (Builder $query): void { $query ->where(function (Builder $activeQuery): void { $activeQuery ->whereNull('catalog_items.deleted_at') ->where('has_tickets', true); }) ->orWhereHas('sourceTickets'); }) ->with([ 'itemAttributes' => fn ($query) => $query->orderBy('sort_order')->orderBy('id'), 'itemAttributes.attribute.options', 'variants' => fn ($query) => $query ->withTrashed() ->where(fn (Builder $variantQuery): Builder => $variantQuery ->whereNull('variantes.deleted_at') ->orWhereHas('sourceTickets')) ->orderBy('id'), 'variants.definitions.itemAttribute.attribute.options', ]) ->get(); $attributes = []; foreach ($items as $item) { foreach ($item->itemAttributes as $itemAttribute) { $attribute = $itemAttribute->attribute; if ($attribute === null) { continue; } $code = $attribute->codigo; $attributes[$code] ??= [ 'code' => $code, 'label' => $itemAttribute->ticket_label ?: $attribute->nombre, 'sort_order' => $itemAttribute->sort_order, 'options' => [], ]; foreach ($item->variants as $variant) { $definition = $variant->definitions->firstWhere('item_attribute_id', $itemAttribute->id); if ($definition === null) { continue; } $value = (string) $definition->value; $option = $attribute->options->firstWhere('value', $value); $attributes[$code]['options'][$value] = [ 'value' => $value, 'label' => (string) ($option?->label ?: $value), ]; } } } uasort($attributes, fn (array $left, array $right): int => $left['sort_order'] <=> $right['sort_order'] ?: $left['label'] <=> $right['label']); return array_values(array_map(fn (array $attribute): array => [ 'code' => $attribute['code'], 'label' => $attribute['label'], 'options' => array_values($attribute['options']), ], $attributes)); } }