270 lines
10 KiB
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 [];
|
|
}
|
|
}
|