Files
kreios/backoffice/app/Http/Controllers/Api/CatalogoController.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

133 lines
5.0 KiB
PHP

<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\Modello;
use App\Models\Sistema;
use App\Support\Configuratore\CalcolatorePrezzo;
use App\Support\Configuratore\ConfigurazioneModello;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class CatalogoController extends Controller
{
/**
* GET /api/sistemi
* Sistemi attivi con i rispettivi modelli attivi e con listino, nell'ordine del menu.
*/
public function sistemi(): JsonResponse
{
$sistemi = Sistema::attivi()
->with(['modelli' => fn ($q) => $q->nelConfiguratore()])
->get();
return response()->json($sistemi->map(fn (Sistema $s) => $this->sistema($s))->values());
}
/**
* GET /api/sistemi/{codice}
*/
public function sistemaPerCodice(string $codice): JsonResponse
{
$sistema = Sistema::attivi()
->where('codice', $codice)
->with(['modelli' => fn ($q) => $q->nelConfiguratore()])
->firstOrFail();
return response()->json($this->sistema($sistema));
}
/**
* GET /api/sistemi/{codice}/modelli/{modello}/listino
* Griglia prezzi del modello (misure in mm), ordinata per altezza e larghezza.
*/
public function listino(string $codice, string $modello): JsonResponse
{
$prezzi = $this->trovaModello($codice, $modello)->listino()
->orderBy('altezza')
->orderBy('larghezza')
->get(['altezza', 'larghezza', 'prezzo'])
->map(fn ($p) => ['altezza' => $p->altezza, 'larghezza' => $p->larghezza, 'prezzo' => $p->prezzo]);
return response()->json($prezzi);
}
/**
* GET /api/sistemi/{codice}/modelli/{modello}/configurazione
* Menu, finiture, vetri, opzioni e misure del modello per il configuratore.
*/
public function configurazione(string $codice, string $modello, ConfigurazioneModello $configurazione): JsonResponse
{
return response()->json($configurazione->perModello($this->trovaModello($codice, $modello)));
}
/**
* POST /api/sistemi/{codice}/modelli/{modello}/prezzo
* Prezzo (IVA esclusa) della configurazione scelta; 422 se la misura è fuori listino.
*/
public function prezzo(Request $request, string $codice, string $modello, CalcolatorePrezzo $calcolatore): JsonResponse
{
$scelte = $request->validate(self::regoleScelte());
return response()->json($calcolatore->calcola($this->trovaModello($codice, $modello), $scelte));
}
/** Validazione delle scelte del configuratore, condivisa con il carrello. */
public static function regoleScelte(string $prefisso = ''): array
{
return [
"{$prefisso}larghezza" => ['required', 'integer', 'min:1', 'max:100000'],
"{$prefisso}altezza" => ['required', 'integer', 'min:1', 'max:100000'],
"{$prefisso}finitura_interna" => ['nullable', 'string', 'max:50'],
"{$prefisso}finitura_esterna" => ['nullable', 'string', 'max:50'],
"{$prefisso}maniglia" => ['nullable', 'string', 'max:50'],
"{$prefisso}vetro" => ['nullable', 'string', 'max:50'],
"{$prefisso}opzioni" => ['nullable', 'array'],
// Un codice per i gruppi a scelta singola, una lista di codici per quelli multipli.
"{$prefisso}opzioni.*" => ['nullable', function (string $campo, mixed $valore, \Closure $errore) {
$codici = is_array($valore) ? $valore : [$valore];
if (count($codici) > 50 || collect($codici)->contains(fn ($c) => ! is_string($c) || mb_strlen($c) > 100)) {
$errore('Scelta non valida.');
}
}],
];
}
/** Modello attivo e con listino di un sistema attivo, cercato per codici (404 altrimenti). */
public static function trovaModello(string $codice, string $modello): Modello
{
return Modello::nelConfiguratore()
->where('codice', $modello)
->whereHas('sistema', fn ($q) => $q->where('codice', $codice)->where('attivo', true))
->with('sistema', 'regolaVetro')
->firstOrFail();
}
private function sistema(Sistema $sistema): array
{
return [
'codice' => $sistema->codice,
'nome' => $sistema->nome,
'modelli' => $sistema->modelli->map(fn (Modello $m) => $this->modello($m))->values(),
];
}
// Stessa forma del vecchio modelli.json (id, nome, cartella, modello, ...) più descrizione e icona.
private function modello(Modello $modello): array
{
return [
'id' => $modello->codice,
'nome' => $modello->nome,
'descrizione' => $modello->descrizione,
'icona' => $modello->icona_url,
'cartella' => $modello->cartella,
'modello' => $modello->file_modello,
'categoria' => $modello->categoria,
'cartella_texture' => $modello->cartella_texture,
'moduli' => $modello->moduli ?? [],
'enabled' => true,
];
}
}