Files
kreios/backoffice/app/Support/Configuratore/ConfigurazioneModello.php
T
carmine.savino 06617a985a feat: add previous configuration handling for user selections in quotes
- Implemented session storage management for the last configuration choices made by the user.
- Added functionality to prompt users when changing models to retain their previous selections.
- Introduced methods to apply previous choices to the newly loaded model, including finishes, handles, glass types, and options.
- Enhanced user experience by ensuring selections are automatically applied where applicable.
2026-10-19 19:49:44 +02:00

149 lines
6.0 KiB
PHP

<?php
namespace App\Support\Configuratore;
use App\Models\Finitura;
use App\Models\GruppoOpzioni;
use App\Models\Modello;
use App\Models\Opzione;
use App\Models\Vetro;
/**
* Dati del configuratore per un modello: struttura del menu, finiture, vetri, opzioni e
* misure del listino, con le immagini servite dal backoffice. Sostituisce i vecchi
* form.json / modello.json / maniglia.json / vetro.json e la cartella immagini.
*
* Non espone supplementi e maggiorazioni: il prezzo lo calcola CalcolatorePrezzo.
*/
class ConfigurazioneModello
{
public function perModello(Modello $modello): array
{
$sistema = $modello->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,
];
}
}