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.
This commit is contained in:
2026-10-19 19:49:44 +02:00
parent 863e6ca920
commit 06617a985a
197 changed files with 4892 additions and 400 deletions
@@ -0,0 +1,197 @@
<?php
namespace Tests\Feature;
use App\Filament\Resources\FinituraResource\Pages\ManageFiniture;
use App\Filament\Resources\GruppoOpzioniResource\Pages\ManageGruppiOpzioni;
use App\Filament\Resources\ModelloResource\Pages\EditModello;
use App\Filament\Resources\ModelloResource\RelationManagers\FinitureRelationManager;
use App\Filament\Resources\ModelloResource\RelationManagers\OpzioniRelationManager;
use App\Filament\Resources\OpzioneResource;
use App\Filament\Resources\OpzioneResource\Pages\ManageOpzioni;
use App\Filament\Resources\RegolaVetroResource\Pages\ManageRegoleVetro;
use App\Filament\Resources\VetroResource\Pages\ManageVetri;
use App\Models\Finitura;
use App\Models\Modello;
use App\Models\Opzione;
use App\Models\RegolaVetro;
use App\Models\User;
use App\Models\Vetro;
use Database\Seeders\CatalogoSeeder;
use Database\Seeders\ConfiguratoreSeeder;
use Database\Seeders\NuoveOpzioniSeeder;
use Database\Seeders\ProfiliExtraSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Livewire\Livewire;
use Tests\TestCase;
class ConfiguratoreAdminTest extends TestCase
{
use RefreshDatabase;
protected function setUp(): void
{
parent::setUp();
Storage::fake('public');
$this->seed([CatalogoSeeder::class, ConfiguratoreSeeder::class, ProfiliExtraSeeder::class, NuoveOpzioniSeeder::class]);
$this->actingAs(User::factory()->create());
}
public function test_le_pagine_del_configuratore_si_aprono(): void
{
Livewire::test(ManageFiniture::class)->assertOk()->assertSee('Noce Rivestito');
Livewire::test(ManageVetri::class)->assertOk()->assertSee('Acustico base');
Livewire::test(ManageRegoleVetro::class)->assertOk()->assertSee('ALZ_AF')->assertSee('(L − 312) ÷ 2');
// Solo le opzioni del sistema: le personalizzazioni stanno nel modello.
Livewire::test(ManageOpzioni::class)
->assertOk()
->set('tableRecordsPerPage', 50)
->assertCanSeeTableRecords(Opzione::whereNull('modello_id')->where('gruppo', 'telaio')->get())
->assertCanNotSeeTableRecords(Opzione::whereNotNull('modello_id')->get());
$modello = Modello::where('codice', 'finestra_2_ante')->firstOrFail();
Livewire::test(EditModello::class, ['record' => $modello->getRouteKey()])
->assertOk()
->assertFormSet(['regola_vetro_id' => $modello->regola_vetro_id]);
}
public function test_modifica_maggiorazione_di_un_vetro(): void
{
$vetro = Vetro::where('codice', 'V2')->firstOrFail();
Livewire::test(ManageVetri::class)
->callTableAction('edit', $vetro, ['maggiorazione_mq' => 55, 'minimo_mq' => 0.6])
->assertHasNoTableActionErrors();
$this->assertEquals(55, $vetro->fresh()->maggiorazione_mq);
$this->assertEquals(0.6, $vetro->fresh()->minimo_mq);
}
public function test_personalizza_gruppo_copia_le_opzioni_del_sistema_nel_modello(): void
{
$modello = Modello::where('codice', 'bilico')->firstOrFail();
Livewire::test(OpzioniRelationManager::class, ['ownerRecord' => $modello, 'pageClass' => EditModello::class])
->assertOk()
->callTableAction('personalizza', data: ['gruppo' => 'tipo_finitura'])
->assertHasNoTableActionErrors();
$copiate = $modello->opzioni()->where('gruppo', 'tipo_finitura')->orderBy('ordine')->get();
$this->assertSame(['bianco', 'uniforme', 'bicolore'], $copiate->pluck('valore')->all());
$this->assertEquals(27, $copiate[1]->supplemento);
}
public function test_opzione_personalizzata_con_valore_del_sistema_ne_copia_i_dati(): void
{
$modello = Modello::where('codice', 'bilico')->firstOrFail();
Livewire::test(OpzioniRelationManager::class, ['ownerRecord' => $modello, 'pageClass' => EditModello::class])
->mountTableAction('create')
->setTableActionData(['gruppo' => 'profili_extra'])
->set('mountedTableActionsData.0.valore', '50811')
->assertTableActionDataSet(['etichetta' => '50811_GUIDA 34', 'supplemento_tipo' => 'metro_lineare', 'alternativa' => 'guida'])
->setTableActionData(['supplemento' => 18])
->callMountedTableAction()
->assertHasNoTableActionErrors();
$opzione = $modello->opzioni()->where('gruppo', 'profili_extra')->sole();
$this->assertSame('50811', $opzione->valore);
$this->assertEquals(18, $opzione->supplemento);
$this->assertEquals(2, $opzione->ml_per_altezza);
$this->assertNotNull($opzione->icona);
}
public function test_opzione_personalizzata_con_valore_altro(): void
{
$modello = Modello::where('codice', 'bilico')->firstOrFail();
$manager = fn () => Livewire::test(OpzioniRelationManager::class, ['ownerRecord' => $modello, 'pageClass' => EditModello::class]);
$manager()
->callTableAction('create', data: ['gruppo' => 'profili_extra', 'valore' => OpzioneResource::ALTRO, 'valore_altro' => 'non valido!', 'etichetta' => 'X'])
->assertHasTableActionErrors(['valore_altro']);
$manager()
->callTableAction('create', data: ['gruppo' => 'profili_extra', 'valore' => OpzioneResource::ALTRO, 'valore_altro' => 'nuovo_profilo', 'etichetta' => 'Nuovo profilo'])
->assertHasNoTableActionErrors();
$opzione = $modello->opzioni()->where('valore', 'nuovo_profilo')->sole();
// In modifica un valore che il sistema non ha compare come "Altro".
$manager()
->mountTableAction('edit', $opzione)
->assertTableActionDataSet(['valore' => OpzioneResource::ALTRO, 'valore_altro' => 'nuovo_profilo']);
}
public function test_la_prova_della_regola_vetro_mostra_le_lastre(): void
{
$regola = RegolaVetro::where('codice', 'F2')->firstOrFail();
Livewire::test(ManageRegoleVetro::class)
->mountTableAction('edit', $regola)
->setTableActionData(['prova_larghezza' => 1200, 'prova_altezza' => 1400])
->assertSee('2 × 444,0 × 1.211,0 mm');
}
public function test_scelta_delle_finiture_nel_modello(): void
{
$modello = Modello::where('codice', 'finestra_2_ante')->firstOrFail();
$noce = Finitura::where('tipo', 'profilo')->where('codice', '2')->firstOrFail();
$altre = Finitura::where('tipo', 'profilo')->whereIn('codice', ['3', '4'])->get();
$tabella = fn () => Livewire::test(FinitureRelationManager::class, ['ownerRecord' => $modello, 'pageClass' => EditModello::class]);
$tabella()->assertOk()
->assertCanSeeTableRecords([$noce])
->call('updateTableColumnState', 'scelta_modello', $noce->getKey(), 'interno');
$this->assertSame('interno', DB::table('finiture_modelli')->where('finitura_id', $noce->id)->value('lato'));
$tabella()->callTableBulkAction('imposta', $altre, ['lato' => 'nessuno']);
$this->assertSame(3, DB::table('finiture_modelli')->where('modello_id', $modello->id)->count());
// "Come il sistema" rimuove la scelta del modello.
$tabella()->call('updateTableColumnState', 'scelta_modello', $noce->getKey(), '');
$this->assertFalse(DB::table('finiture_modelli')->where('finitura_id', $noce->id)->exists());
$tabella()->callTableAction('ripristina');
$this->assertFalse(DB::table('finiture_modelli')->where('modello_id', $modello->id)->exists());
}
public function test_imposta_lato_sulle_finiture_del_sistema(): void
{
$finiture = Finitura::where('tipo', 'profilo')->whereIn('codice', ['2', '3'])->get();
Livewire::test(ManageFiniture::class)->callTableBulkAction('lato', $finiture, ['lato' => 'esterno']);
$this->assertSame(['esterno'], Finitura::whereIn('id', $finiture->modelKeys())->distinct()->pluck('lato')->all());
}
public function test_profilo_extra_al_metro_lineare_dal_pannello(): void
{
$guida = Opzione::whereNull('modello_id')->where('valore', '50811')->firstOrFail();
Livewire::test(ManageOpzioni::class)
->callTableAction('edit', $guida, ['supplemento' => 18, 'ml_per_altezza' => 2, 'ml_aggiunta_mm' => 300, 'alternativa' => 'guida'])
->assertHasNoTableActionErrors();
$guida->refresh();
$this->assertEquals(18, $guida->supplemento);
$this->assertEquals(3.1, $guida->metriLineari(1200, 1400));
$this->assertSame('€ 18,00/ml × (H × 2 + 300 mm)', $guida->descriviSupplemento());
}
public function test_gruppi_di_opzioni_dal_pannello(): void
{
Livewire::test(ManageGruppiOpzioni::class)
->assertOk()
->assertSee('Soglia ribassata')
->callAction('create', ['codice' => 'zanzariera', 'etichetta' => 'Zanzariera', 'ui' => 'select', 'sezione' => 'accessori', 'modulo' => 'zanzariera'])
->assertHasNoActionErrors()
// I moduli base non si possono usare per un gruppo.
->callAction('create', ['codice' => 'altro', 'etichetta' => 'Altro', 'ui' => 'select', 'sezione' => 'accessori', 'modulo' => 'vetro'])
->assertHasActionErrors(['modulo' => 'not_in']);
$this->assertArrayHasKey('zanzariera', Modello::moduliDisponibili());
}
}