- Deleted the `vetro.json` file containing glass configurations. - Introduced `ImportaTitoliAction` to facilitate importing model titles from Excel. - Created `TitoliModelliImporter` for handling title import logic and updating existing models. - Updated `SistemaResource` to include the new title import action. - Modified `ConfigurazioneModello` to adjust the model name retrieval logic. - Changed `ListinoImporter` to make the alias constant public. - Added tests for title import functionality, ensuring correct updates and creation of new models.
149 lines
6.0 KiB
PHP
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->descrizione ?: ($modello->titolo ?: $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->descrizione ?: ($modello->titolo ?: $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,
|
|
];
|
|
}
|
|
}
|