sistema; // Finiture del profilo attive nel modello, divise per lato (interno / esterno). $finiture = $modello->haModulo('modello') ? Finitura::delProfiloPerModello($modello) : collect(); $interne = $finiture->filter(fn (Finitura $f) => $f->disponibileSu('interno'))->map($this->finitura(...))->values(); $esterne = $modello->haModulo('finitura_esterna') ? $finiture->filter(fn (Finitura $f) => $f->disponibileSu('esterno'))->map($this->finitura(...))->values() : collect(); $maniglie = $modello->haModulo('maniglia') ? $sistema->finiture()->where('tipo', 'maniglia')->attive()->get()->map($this->finitura(...))->values() : collect(); $vetri = $modello->haModulo('vetro') ? $sistema->vetri()->attivi()->get()->map($this->vetro(...))->values() : collect(); return [ 'nome' => $modello->titolo ?: ($modello->descrizione ?: $modello->nome), 'form' => $this->form($modello, $interne->isNotEmpty(), $esterne->isNotEmpty(), $maniglie->isNotEmpty(), $vetri->isNotEmpty()), 'finiture' => $finiture->map($this->finitura(...))->values(), 'finiture_interne' => $interne, 'finiture_esterne' => $esterne, 'maniglie' => $maniglie, 'vetri' => $vetri, 'misure' => $modello->listino() ->orderBy('altezza') ->orderBy('larghezza') ->get(['altezza', 'larghezza', 'prezzo']) ->map(fn ($p) => ['altezza' => $p->altezza, 'larghezza' => $p->larghezza, 'prezzo' => $p->prezzo]) ->values(), ]; } /** Stessa struttura del vecchio form.json (radios, select, finiture) letta dal MenuBuilder. */ private function form(Modello $modello, bool $interne, bool $esterne, bool $maniglie, bool $vetri): array { $radios = []; $select = []; $multiple = []; $gruppi = []; $definizioni = GruppoOpzioni::perCodice(); $opzioni = Opzione::perModello($modello); // Nell'ordine dei gruppi: il configuratore li presenta così. foreach ($definizioni as $gruppo => $definizione) { $righe = $opzioni->get($gruppo); if (! $righe || ! $definizione->haControllo() || ! $modello->haModulo($definizione->modulo)) { continue; } $gruppi[$gruppo] = ['etichetta' => $definizione->etichetta, 'ui' => $definizione->ui, 'sezione' => $definizione->sezione]; $voci = $righe->map(fn (Opzione $o) => ($o->parametri ?? []) + [ 'valore' => $o->valore, 'label' => $o->etichetta, 'icon' => Media::url($o->icona), 'alternativa' => $o->alternativa, ])->values(); match ($definizione->ui) { 'radio' => $radios[$gruppo] = $voci, 'multipla' => $multiple[$gruppo] = $voci, default => $select[$gruppo] = $voci, }; } $menu = []; if ($interne) { $menu[] = ['nome' => 'finitura_interna', 'categorie' => ['interno'], 'data' => 'data_finiture_interne']; } if ($esterne) { $menu[] = ['nome' => 'finitura_esterna', 'categorie' => ['esterno'], 'data' => 'data_finiture_esterne']; } if ($maniglie) { $menu[] = ['nome' => 'maniglia', 'categorie' => ['maniglia', 'cerniere'], 'data' => 'data_maniglie']; } if ($vetri) { $menu[] = ['nome' => 'vetro', 'categorie' => ['vetro'], 'data' => 'data_vetri']; } return [ 'nome' => $modello->titolo ?: ($modello->descrizione ?: $modello->nome), 'radios' => (object) $radios, 'select' => (object) $select, // Pulsanti selezionabili insieme (es. profili extra), anche nessuno. 'multiple' => (object) $multiple, // Titolo, controllo e sezione del menu dei gruppi sopra, nell'ordine del backoffice. 'gruppi' => (object) $gruppi, 'finiture' => $menu, ]; } /** Campi con i nomi letti da APP.Player.changeTexture/changeColor. */ private function finitura(Finitura $f): array { return [ 'id' => $f->codice, 'descrizione' => $f->descrizione, 'anteprima' => Media::url($f->anteprima), 'texture_map' => Media::url($f->texture), 'texture_bump' => Media::url($f->texture_bump), 'bump_valore' => $f->bump_scala, 'color_valore' => $f->colore, 'color_valore_corpo_base' => $f->colore_corpo_base, 'roughness_valore' => $f->roughness, 'metalness_valore' => $f->metalness, 'predefinito' => $f->predefinita, ]; } private function vetro(Vetro $v): array { return [ 'id' => $v->codice, 'descrizione' => $v->descrizione, 'anteprima' => Media::url($v->anteprima), 'pop_up' => Media::url($v->popup), 'texture_map' => Media::url($v->texture), 'texture_bump' => Media::url($v->texture_bump), 'bump_valore' => $v->bump_scala, 'color_valore' => $v->colore, 'roughness_valore' => $v->roughness, 'metalness_valore' => $v->metalness, 'opacity_valore' => $v->opacita, 'predefinito' => $v->predefinito, ]; } }