135 lines
5.6 KiB
PHP
135 lines
5.6 KiB
PHP
<?php
|
|
|
|
namespace App\Filament\Resources\ModelloResource\RelationManagers;
|
|
|
|
use App\Models\ListinoPrezzo;
|
|
use Filament\Forms;
|
|
use Filament\Forms\Form;
|
|
use Filament\Notifications\Notification;
|
|
use Filament\Resources\RelationManagers\RelationManager;
|
|
use Filament\Tables;
|
|
use Filament\Tables\Table;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Validation\Rules\Unique;
|
|
|
|
class ListinoRelationManager extends RelationManager
|
|
{
|
|
protected static string $relationship = 'listino';
|
|
|
|
protected static ?string $title = 'Listino';
|
|
|
|
protected static ?string $modelLabel = 'prezzo';
|
|
|
|
protected static ?string $pluralModelLabel = 'prezzi';
|
|
|
|
public function form(Form $form): Form
|
|
{
|
|
return $form->columns(3)->schema([
|
|
Forms\Components\TextInput::make('larghezza')
|
|
->label('Larghezza (mm)')
|
|
->integer()
|
|
->minValue(1)
|
|
->required()
|
|
->unique(
|
|
ignoreRecord: true,
|
|
modifyRuleUsing: fn (Unique $rule, Forms\Get $get) => $rule
|
|
->where('modello_id', $this->getOwnerRecord()->getKey())
|
|
->where('altezza', $get('altezza')),
|
|
)
|
|
->validationMessages(['unique' => 'Esiste già un prezzo per questa misura.']),
|
|
Forms\Components\TextInput::make('altezza')
|
|
->label('Altezza (mm)')
|
|
->integer()
|
|
->minValue(1)
|
|
->required(),
|
|
Forms\Components\TextInput::make('prezzo')
|
|
->label('Prezzo')
|
|
->numeric()
|
|
->minValue(0)
|
|
->prefix('€')
|
|
->required(),
|
|
]);
|
|
}
|
|
|
|
public function table(Table $table): Table
|
|
{
|
|
$misure = fn (string $colonna) => fn () => ListinoPrezzo::query()
|
|
->where('modello_id', $this->getOwnerRecord()->getKey())
|
|
->orderBy($colonna)
|
|
->distinct()
|
|
->pluck($colonna)
|
|
->mapWithKeys(fn ($v) => [$v => $this->mm($v)])
|
|
->all();
|
|
|
|
return $table
|
|
->description(fn () => ($data = $this->getOwnerRecord()->listino_aggiornato_at)
|
|
? 'Ultimo aggiornamento: '.$data->format('d/m/Y H:i').'. Il configuratore usa la prima misura del listino uguale o superiore a quella richiesta.'
|
|
: 'Nessun listino caricato: importalo dalla lista Sistemi o aggiungi i prezzi a mano.')
|
|
->modifyQueryUsing(fn (Builder $query) => $query->orderBy('altezza')->orderBy('larghezza'))
|
|
->defaultPaginationPageOption(25)
|
|
->columns([
|
|
Tables\Columns\TextColumn::make('altezza')
|
|
->label('Altezza')
|
|
->formatStateUsing(fn ($state) => $this->mm($state))
|
|
->sortable(),
|
|
Tables\Columns\TextColumn::make('larghezza')
|
|
->label('Larghezza')
|
|
->formatStateUsing(fn ($state) => $this->mm($state))
|
|
->sortable(),
|
|
Tables\Columns\TextInputColumn::make('prezzo')
|
|
->label('Prezzo (€)')
|
|
->type('number')
|
|
->step('0.01')
|
|
->rules(['required', 'numeric', 'min:0'])
|
|
->sortable(),
|
|
Tables\Columns\IconColumn::make('personalizzato')
|
|
->label('Personalizzato')
|
|
->icon(fn (bool $state) => $state ? 'heroicon-o-pencil-square' : null)
|
|
->color('warning')
|
|
->tooltip(fn (ListinoPrezzo $record) => $record->personalizzato ? 'Aggiunto a mano: può essere preservato alla prossima importazione' : null),
|
|
])
|
|
->filters([
|
|
Tables\Filters\SelectFilter::make('altezza')->label('Altezza')->options($misure('altezza')),
|
|
Tables\Filters\SelectFilter::make('larghezza')->label('Larghezza')->options($misure('larghezza')),
|
|
Tables\Filters\TernaryFilter::make('personalizzato')->label('Personalizzato'),
|
|
])
|
|
->headerActions([
|
|
Tables\Actions\CreateAction::make()
|
|
->mutateFormDataUsing(fn (array $data) => $data + ['personalizzato' => true]),
|
|
Tables\Actions\Action::make('svuota')
|
|
->label('Svuota listino')
|
|
->icon('heroicon-o-trash')
|
|
->color('danger')
|
|
->requiresConfirmation()
|
|
->modalDescription('Verranno eliminati tutti i prezzi del modello. Il configuratore non potrà calcolare il prezzo finché non sarà caricato un nuovo listino.')
|
|
->visible(fn () => $this->getOwnerRecord()->listino()->exists())
|
|
->action(function () {
|
|
$modello = $this->getOwnerRecord();
|
|
$modello->listino()->delete();
|
|
$modello->update(['listino_aggiornato_at' => null]);
|
|
|
|
Notification::make()->title('Listino svuotato')->success()->send();
|
|
}),
|
|
])
|
|
->actions([
|
|
Tables\Actions\EditAction::make(),
|
|
Tables\Actions\DeleteAction::make(),
|
|
])
|
|
->bulkActions([
|
|
Tables\Actions\BulkActionGroup::make([
|
|
Tables\Actions\DeleteBulkAction::make(),
|
|
]),
|
|
]);
|
|
}
|
|
|
|
public function isReadOnly(): bool
|
|
{
|
|
return false;
|
|
}
|
|
|
|
private function mm(mixed $valore): string
|
|
{
|
|
return number_format((int) $valore, 0, ',', '.').' mm';
|
|
}
|
|
}
|