netgescon-day0/app/Filament/Pages/Condomini/FornitoriStabileImpostazioniArchivio.php

270 lines
10 KiB
PHP

<?php
namespace App\Filament\Pages\Condomini;
use App\Models\Fornitore;
use App\Models\FornitoreStabileImpostazione;
use App\Models\User;
use App\Models\VoceSpesa;
use App\Modules\Contabilita\Models\PianoConti;
use App\Support\StabileContext;
use BackedEnum;
use Filament\Actions\Action;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Textarea;
use Filament\Pages\Page;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Concerns\InteractsWithTable;
use Filament\Tables\Contracts\HasTable;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Schema;
use UnitEnum;
class FornitoriStabileImpostazioniArchivio extends Page implements HasTable
{
use InteractsWithTable;
protected static ?string $navigationLabel = 'Impostazioni fornitori';
protected static ?string $title = 'Impostazioni fornitori (per stabile)';
protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-adjustments-horizontal';
protected static UnitEnum|string|null $navigationGroup = 'Stabile';
protected static ?int $navigationSort = 35;
protected static ?string $slug = 'condomini/fornitori-impostazioni';
protected string $view = 'filament.pages.gescon.table';
public static function canAccess(): bool
{
$user = Auth::user();
return $user instanceof User
&& $user->hasAnyRole(['super-admin', 'admin', 'amministratore', 'collaboratore'])
&& Schema::hasTable('fornitore_stabile_impostazioni');
}
public function mount(): void
{
$this->mountInteractsWithTable();
}
protected function getTableQuery(): Builder
{
$user = Auth::user();
if (! $user instanceof User) {
return FornitoreStabileImpostazione::query()->whereRaw('1 = 0');
}
$stabileId = StabileContext::resolveActiveStabileId($user);
if (! $stabileId) {
return FornitoreStabileImpostazione::query()->whereRaw('1 = 0');
}
return FornitoreStabileImpostazione::query()
->where('stabile_id', (int) $stabileId)
->with([
'fornitore:id,ragione_sociale',
'voceSpesaDefault:id,descrizione,tipo_gestione',
])
->orderByDesc('updated_at')
->orderByDesc('id');
}
public function table(Table $table): Table
{
return $table
->striped()
->columns([
TextColumn::make('fornitore.ragione_sociale')->label('Fornitore')->searchable()->wrap(),
TextColumn::make('voceSpesaDefault.descrizione')->label('Voce spesa default')->wrap()->toggleable(),
TextColumn::make('conto_costo_default_id')->label('Conto costo (ID)')->toggleable(isToggledHiddenByDefault: true),
TextColumn::make('updated_at')->label('Aggiornato')->dateTime('d/m/Y H:i')->toggleable(isToggledHiddenByDefault: true),
])
->headerActions([
Action::make('create')
->label('Nuova')
->icon('heroicon-o-plus')
->form([
Select::make('fornitore_id')
->label('Fornitore')
->options(fn() => $this->getFornitoriOptions())
->searchable()
->required(),
Select::make('voce_spesa_default_id')
->label('Voce spesa default')
->options(fn() => $this->getVociSpesaOptions())
->searchable(),
Select::make('conto_costo_default_id')
->label('Conto costo default')
->options(fn() => $this->getPianoContiOptions())
->searchable(),
Textarea::make('meta_json')
->label('Meta (JSON)')
->rows(6)
->rules(['nullable', 'json'])
->placeholder("{\n \"fe_features\": {\n \"acqua\": {\n \"enabled\": true\n }\n }\n}"),
])
->action(function (array $data): void {
$user = Auth::user();
if (! $user instanceof User) {
return;
}
$stabileId = StabileContext::resolveActiveStabileId($user);
if (! $stabileId) {
return;
}
$meta = null;
$metaJson = trim((string) ($data['meta_json'] ?? ''));
if ($metaJson !== '') {
$decoded = json_decode($metaJson, true);
$meta = is_array($decoded) ? $decoded : null;
}
FornitoreStabileImpostazione::query()->updateOrCreate(
[
'stabile_id' => (int) $stabileId,
'fornitore_id' => (int) ($data['fornitore_id'] ?? 0),
],
[
'voce_spesa_default_id' => (int) ($data['voce_spesa_default_id'] ?? 0) ?: null,
'conto_costo_default_id' => (int) ($data['conto_costo_default_id'] ?? 0) ?: null,
'meta' => $meta,
]
);
}),
])
->actions([
Action::make('edit')
->label('Modifica')
->icon('heroicon-o-pencil-square')
->form([
Select::make('voce_spesa_default_id')
->label('Voce spesa default')
->options(fn() => $this->getVociSpesaOptions())
->searchable(),
Select::make('conto_costo_default_id')
->label('Conto costo default')
->options(fn() => $this->getPianoContiOptions())
->searchable(),
Textarea::make('meta_json')
->label('Meta (JSON)')
->rows(6)
->rules(['nullable', 'json']),
])
->fillForm(fn(FornitoreStabileImpostazione $record): array => [
'voce_spesa_default_id' => $record->voce_spesa_default_id,
'conto_costo_default_id' => $record->conto_costo_default_id,
'meta_json' => $record->meta ? json_encode($record->meta, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) : '',
])
->action(function (FornitoreStabileImpostazione $record, array $data): void {
$meta = null;
$metaJson = trim((string) ($data['meta_json'] ?? ''));
if ($metaJson !== '') {
$decoded = json_decode($metaJson, true);
$meta = is_array($decoded) ? $decoded : null;
}
$record->fill([
'voce_spesa_default_id' => (int) ($data['voce_spesa_default_id'] ?? 0) ?: null,
'conto_costo_default_id' => (int) ($data['conto_costo_default_id'] ?? 0) ?: null,
'meta' => $meta,
]);
$record->save();
}),
Action::make('delete')
->label('Elimina')
->icon('heroicon-o-trash')
->color('danger')
->requiresConfirmation()
->action(fn(FornitoreStabileImpostazione $record) => $record->delete()),
]);
}
/**
* @return array<int, string>
*/
private function getFornitoriOptions(): array
{
$user = Auth::user();
if (! $user instanceof User) {
return [];
}
$query = Fornitore::query();
if (! $user->hasAnyRole(['super-admin', 'admin'])) {
$activeStabile = StabileContext::getActiveStabile($user);
$adminId = (int) ($activeStabile?->amministratore_id ?: 0);
if ($adminId > 0) {
$query->where('amministratore_id', $adminId);
}
}
return $query
->orderBy('ragione_sociale')
->get(['id', 'ragione_sociale'])
->mapWithKeys(fn(Fornitore $f) => [(int) $f->id => (string) ($f->ragione_sociale ?? ('Fornitore #' . $f->id))])
->all();
}
/**
* @return array<int, string>
*/
private function getVociSpesaOptions(): array
{
$user = Auth::user();
if (! $user instanceof User) {
return [];
}
$stabileId = StabileContext::resolveActiveStabileId($user);
if (! $stabileId) {
return [];
}
return VoceSpesa::query()
->where('stabile_id', (int) $stabileId)
->orderBy('tipo_gestione')
->orderBy('descrizione')
->get(['id', 'descrizione', 'tipo_gestione'])
->mapWithKeys(function (VoceSpesa $v): array {
$tipo = strtolower(trim((string) ($v->tipo_gestione ?? '')));
$prefix = $tipo !== '' ? strtoupper(substr($tipo, 0, 1)) . ' - ' : '';
return [(int) $v->id => $prefix . (string) ($v->descrizione ?? ('Voce #' . $v->id))];
})
->all();
}
/**
* @return array<int, string>
*/
private function getPianoContiOptions(): array
{
if (! Schema::hasTable('contabilita_piano_conti') && ! Schema::hasTable('piano_conti')) {
return [];
}
// Model standard nel modulo Contabilità: contabilita_piano_conti
if (Schema::hasTable('contabilita_piano_conti')) {
return PianoConti::query()
->orderBy('codice')
->orderBy('descrizione')
->get(['id', 'codice', 'descrizione'])
->mapWithKeys(fn(PianoConti $c) => [(int) $c->id => trim((string) $c->codice . ' - ' . (string) $c->descrizione)])
->all();
}
// Fallback best-effort: se esiste una tabella alternativa, mostriamo solo gli ID.
return [];
}
}