feat: implement discount and transport features in the quote system

- Added maximum discount settings configurable by the administrator.
- Implemented discount calculations in the quote confirmation process.
- Introduced transport options with associated costs, including handling for exceeding maximum piece limits.
- Updated frontend to display discounts and transport information in the quote summary.
- Created new database migrations for storing discount and transport settings.
- Developed a new Filament page for managing global discount settings.
- Enhanced email templates to include discount and transport details.
- Added tests to ensure proper functionality of discounts and transport calculations.
This commit is contained in:
2026-10-20 17:45:50 +02:00
parent 06617a985a
commit 8bef57b64b
27 changed files with 875 additions and 26 deletions
@@ -145,7 +145,28 @@ class PreventivoResource extends Resource
->label('Stato')
->badge()
->formatStateUsing(fn (string $state) => Preventivo::STATI[$state] ?? $state),
Infolists\Components\TextEntry::make('totale')->label('Totale')->money('EUR'),
Infolists\Components\TextEntry::make('subtotale')
->label('Totale parziale')
->money('EUR')
->visible(fn (Preventivo $record) => $record->haSconti()),
Infolists\Components\TextEntry::make('sconti')
->label('Sconti applicati')
->visible(fn (Preventivo $record) => $record->haSconti())
->state(function (Preventivo $record): string {
$importi = $record->importiSconto();
$euro = fn (float $v) => '€ '.number_format($v, 2, ',', '.');
return sprintf('1° sconto %s%% (−%s) · extra %s%% (−%s)',
(float) $record->sconto_1, $euro($importi['sconto_1']),
(float) $record->sconto_2, $euro($importi['sconto_2']));
}),
Infolists\Components\TextEntry::make('trasporto_etichetta')
->label('Trasporto')
->visible(fn (Preventivo $record) => $record->trasporto !== null)
->formatStateUsing(fn (string $state, Preventivo $record) => $record->trasportoDaQuantificare()
? "{$state} — da quantificare"
: $state.' — € '.number_format($record->trasporto_importo, 2, ',', '.')),
Infolists\Components\TextEntry::make('totale')->label('Totale (IVA esclusa)')->money('EUR'),
Infolists\Components\TextEntry::make('confirmed_at')->label('Confermato il')->dateTime('d/m/Y H:i')->placeholder('—'),
Infolists\Components\TextEntry::make('created_at')->label('Creato il')->dateTime('d/m/Y H:i'),
]),