netgescon-day0/app/Filament/Pages/Contabilita/SaldiContiArchivio.php

247 lines
9.5 KiB
PHP

<?php
namespace App\Filament\Pages\Contabilita;
use App\Models\DatiBancari;
use App\Models\User;
use App\Modules\Contabilita\Models\SaldoConto;
use App\Support\StabileContext;
use BackedEnum;
use Filament\Actions\Action;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
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\DB;
use UnitEnum;
class SaldiContiArchivio extends Page implements HasTable
{
use InteractsWithTable;
protected static ?string $navigationLabel = 'Saldi conti';
protected static ?string $title = 'Saldi conti';
protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-scale';
protected static UnitEnum|string|null $navigationGroup = 'Contabilità';
protected static ?int $navigationSort = 12;
protected static ?string $slug = 'contabilita/saldi-conti';
protected string $view = 'filament.pages.gescon.table';
public static function canAccess(): bool
{
$user = Auth::user();
if (! $user instanceof User) {
return false;
}
if ($user->hasAnyRole(['super-admin', 'admin'])) {
return true;
}
return $user->can('contabilita.casse-banche');
}
public function mount(): void
{
$this->mountInteractsWithTable();
}
protected function getTableQuery(): Builder
{
$user = Auth::user();
if (! $user instanceof User) {
return SaldoConto::query()->whereRaw('1 = 0');
}
$stabileId = StabileContext::resolveActiveStabileId($user);
if (! $stabileId) {
return SaldoConto::query()->whereRaw('1 = 0');
}
return SaldoConto::query()
->with('conto')
->where('stabile_id', $stabileId);
}
public function table(Table $table): Table
{
return $table
->striped()
->defaultSort('data_saldo', 'desc')
->columns([
TextColumn::make('conto_label')
->label('Conto')
->getStateUsing(function (SaldoConto $record): string {
$c = $record->conto;
if ($c instanceof DatiBancari) {
$iban = is_string($c->iban) ? trim((string) $c->iban) : '';
return trim((string) ($c->denominazione_banca ?: 'Conto') . ($iban !== '' ? (' · ' . $iban) : ''));
}
$iban = is_string($record->iban) ? trim((string) $record->iban) : '';
return $iban !== '' ? $iban : '—';
})
->searchable(query: function (Builder $query, string $search): Builder {
$search = trim($search);
if ($search === '') {
return $query;
}
return $query->where(function (Builder $q) use ($search): void {
$q->where('iban', 'like', '%' . $search . '%')
->orWhereHas('conto', fn(Builder $cq) => $cq->where('denominazione_banca', 'like', '%' . $search . '%'));
});
}),
TextColumn::make('data_saldo')
->label('Data')
->date('d/m/Y')
->sortable(),
TextColumn::make('saldo')
->label('Saldo')
->alignEnd()
->formatStateUsing(fn($state) => '€ ' . number_format((float) $state, 2, ',', '.')),
TextColumn::make('note')
->label('Note')
->wrap()
->toggleable(isToggledHiddenByDefault: true),
TextColumn::make('updated_at')
->label('Aggiornato')
->dateTime('d/m/Y H:i')
->toggleable(isToggledHiddenByDefault: true),
])
->headerActions([
Action::make('create')
->label('Nuovo saldo')
->icon('heroicon-o-plus')
->form([
Select::make('conto_id')
->label('Conto')
->native(false)
->searchable()
->options(fn(): array => $this->getContiOptions())
->required(),
DatePicker::make('data_saldo')->label('Data')->required(),
TextInput::make('saldo')->label('Saldo')->numeric()->required(),
Textarea::make('note')->label('Note (opzionale)')->rows(2)->maxLength(255),
])
->action(function (array $data): void {
$user = Auth::user();
if (! $user instanceof User) {
return;
}
$stabileId = StabileContext::resolveActiveStabileId($user);
if (! $stabileId) {
return;
}
$contoId = isset($data['conto_id']) && is_numeric($data['conto_id']) ? (int) $data['conto_id'] : 0;
if ($contoId <= 0) {
return;
}
$conto = DatiBancari::query()
->where('stabile_id', $stabileId)
->where('id', $contoId)
->first(['id', 'iban']);
$iban = $conto && is_string($conto->iban) ? trim((string) $conto->iban) : null;
$iban = is_string($iban) && $iban !== '' ? $iban : null;
SaldoConto::query()->create([
'stabile_id' => (int) $stabileId,
'conto_id' => $contoId,
'iban' => $iban,
'data_saldo' => $data['data_saldo'] ?? null,
'saldo' => isset($data['saldo']) ? (float) $data['saldo'] : 0.0,
'note' => isset($data['note']) && is_string($data['note']) ? trim((string) $data['note']) : null,
'created_by' => (int) ($user->id ?? 0) ?: null,
'updated_by' => (int) ($user->id ?? 0) ?: null,
]);
}),
])
->actions([
Action::make('edit')
->label('Modifica')
->icon('heroicon-o-pencil-square')
->form([
DatePicker::make('data_saldo')->label('Data')->required(),
TextInput::make('saldo')->label('Saldo')->numeric()->required(),
Textarea::make('note')->label('Note (opzionale)')->rows(2)->maxLength(255),
])
->fillForm(fn(SaldoConto $record): array => [
'data_saldo' => $record->data_saldo,
'saldo' => (float) $record->saldo,
'note' => $record->note,
])
->action(function (SaldoConto $record, array $data): void {
$user = Auth::user();
$record->fill([
'data_saldo' => $data['data_saldo'] ?? $record->data_saldo,
'saldo' => isset($data['saldo']) ? (float) $data['saldo'] : (float) $record->saldo,
'note' => isset($data['note']) && is_string($data['note']) ? trim((string) $data['note']) : null,
'updated_by' => $user instanceof User ? ((int) $user->id ?: null) : null,
]);
$record->save();
}),
Action::make('delete')
->label('Elimina')
->icon('heroicon-o-trash')
->color('danger')
->requiresConfirmation()
->action(fn(SaldoConto $record) => $record->delete()),
]);
}
/** @return array<int,string> */
protected function getContiOptions(): array
{
$user = Auth::user();
if (! $user instanceof User) {
return [];
}
$stabileId = StabileContext::resolveActiveStabileId($user);
if (! $stabileId) {
return [];
}
if (! DB::getSchemaBuilder()->hasTable('dati_bancari')) {
return [];
}
return DatiBancari::query()
->where('stabile_id', $stabileId)
->orderBy('stato_conto')
->orderBy('denominazione_banca')
->orderBy('iban')
->orderBy('id')
->get(['id', 'denominazione_banca', 'iban'])
->mapWithKeys(function (DatiBancari $r): array {
$iban = is_string($r->iban) ? trim((string) $r->iban) : '';
$label = trim((string) ($r->denominazione_banca ?: 'Conto') . ($iban !== '' ? (' · ' . $iban) : ''));
return [(int) $r->id => $label];
})
->all();
}
}