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

249 lines
10 KiB
PHP

<?php
namespace App\Filament\Pages\Contabilita;
use App\Models\User;
use App\Modules\Contabilita\Models\FatturaFornitore;
use App\Modules\Contabilita\Services\FatturaFornitorePrimaNotaService;
use App\Support\StabileContext;
use BackedEnum;
use Filament\Actions\Action;
use Filament\Forms\Components\DatePicker;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Filament\Tables\Columns\BadgeColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Concerns\InteractsWithTable;
use Filament\Tables\Contracts\HasTable;
use Filament\Tables\Filters\Filter;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Schema;
use Illuminate\Contracts\Pagination\Paginator;
use Illuminate\Pagination\LengthAwarePaginator;
use UnitEnum;
class FattureFornitoriArchivio extends Page implements HasTable
{
use InteractsWithTable;
public function getArchivioRigheVisteCount(): int
{
$records = $this->getTableRecords();
if ($records instanceof LengthAwarePaginator) {
return (int) $records->total();
}
if ($records instanceof Paginator) {
return (int) $records->count();
}
return is_countable($records) ? count($records) : 0;
}
protected static ?string $navigationLabel = 'Fatture fornitori';
protected static ?string $title = 'Fatture fornitori';
protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-receipt-percent';
protected static UnitEnum|string|null $navigationGroup = 'Contabilità';
protected static ?int $navigationSort = 34;
protected static ?string $slug = 'contabilita/fatture-fornitori';
protected string $view = 'filament.pages.contabilita.fatture-fornitori-archivio';
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.fatture-fornitori');
}
public function mount(): void
{
$this->mountInteractsWithTable();
}
protected function getHeaderActions(): array
{
return [
Action::make('nuova')
->label('Nuova fattura')
->icon('heroicon-o-plus')
->url(fn() => FatturaFornitoreScheda::getUrl(panel: 'admin-filament')),
];
}
protected function getTableQuery(): Builder
{
$user = Auth::user();
if (! $user instanceof User) {
return FatturaFornitore::query()->whereRaw('1 = 0');
}
$activeStabileId = StabileContext::resolveActiveStabileId($user);
if (! $activeStabileId) {
return FatturaFornitore::query()->whereRaw('1 = 0');
}
return FatturaFornitore::query()
->with(['fornitore', 'fornitore.rubrica'])
->where('stabile_id', $activeStabileId);
}
public function table(Table $table): Table
{
return $table
->striped()
->defaultSort('data_documento', 'desc')
->filters([
SelectFilter::make('ordine')
->label('Ordine')
->options([
'data_desc' => 'Data doc. (più recenti)',
'data_asc' => 'Data doc. (più vecchie)',
'numero_asc' => 'Numero (A → Z)',
'numero_desc' => 'Numero (Z → A)',
'totale_desc' => 'Totale (più alto)',
'totale_asc' => 'Totale (più basso)',
])
->default('data_desc')
->query(function (Builder $query, array $data): Builder {
$v = (string) ($data['value'] ?? 'data_desc');
return match ($v) {
'data_asc' => $query->reorder('data_documento', 'asc')->orderBy('id', 'asc'),
'numero_asc' => $query->reorder('numero_documento', 'asc')->orderBy('id', 'asc'),
'numero_desc' => $query->reorder('numero_documento', 'desc')->orderBy('id', 'desc'),
'totale_asc' => $query->reorder('totale', 'asc')->orderBy('id', 'asc'),
'totale_desc' => $query->reorder('totale', 'desc')->orderBy('id', 'desc'),
default => $query->reorder('data_documento', 'desc')->orderBy('id', 'desc'),
};
}),
Filter::make('data_documento')
->label('Data documento')
->form([
DatePicker::make('from')->label('Da')->native(false),
DatePicker::make('until')->label('A')->native(false),
])
->query(function (Builder $query, array $data): Builder {
if (! empty($data['from'])) {
$query->whereDate('data_documento', '>=', $data['from']);
}
if (! empty($data['until'])) {
$query->whereDate('data_documento', '<=', $data['until']);
}
return $query;
}),
SelectFilter::make('stato')
->label('Stato')
->options([
'inserito' => 'Inserito',
'contabilizzato' => 'Contabilizzato',
'pagato' => 'Pagato',
]),
])
->columns([
TextColumn::make('data_documento')->label('Data doc.')->date('d/m/Y')->sortable(),
TextColumn::make('numero_documento')->label('Numero')->searchable()->sortable(),
TextColumn::make('fornitore_nome')
->label('Fornitore')
->wrap()
->getStateUsing(function (FatturaFornitore $record): string {
$fornitore = $record->fornitore;
if (! $fornitore) {
$fallback = trim((string) ($record->descrizione ?? ''));
return $fallback !== '' ? $fallback : '—';
}
$fromRubrica = $fornitore?->rubrica?->nome_completo;
if (is_string($fromRubrica) && trim($fromRubrica) !== '') {
return $fromRubrica;
}
$rs = $fornitore?->ragione_sociale;
if (is_string($rs) && trim($rs) !== '') {
return $rs;
}
$nome = trim((string) ($fornitore?->nome ?? ''));
$cognome = trim((string) ($fornitore?->cognome ?? ''));
$full = trim($nome . ' ' . $cognome);
return $full !== '' ? $full : '—';
})
->searchable(query: function (Builder $query, string $search): Builder {
$search = trim($search);
if ($search === '') {
return $query;
}
return $query->whereHas('fornitore', function (Builder $q) use ($search) {
$q->where('ragione_sociale', 'like', "%{$search}%")
->orWhere('nome', 'like', "%{$search}%")
->orWhere('cognome', 'like', "%{$search}%")
->orWhereHas('rubrica', function (Builder $qr) use ($search) {
$qr->where('ragione_sociale', 'like', "%{$search}%")
->orWhere('nome', 'like', "%{$search}%")
->orWhere('cognome', 'like', "%{$search}%")
->orWhere('codice_fiscale', 'like', "%{$search}%")
->orWhere('partita_iva', 'like', "%{$search}%");
});
});
}),
TextColumn::make('totale')->label('Totale')->money('EUR')->sortable(),
TextColumn::make('ritenuta_importo')->label('RA')->money('EUR')->toggleable(isToggledHiddenByDefault: true),
BadgeColumn::make('stato')->label('Stato')->colors([
'warning' => 'inserito',
'primary' => 'contabilizzato',
'success' => 'pagato',
]),
])
->actions([
Action::make('apri')
->label('Apri')
->icon('heroicon-o-eye')
->url(fn(FatturaFornitore $record) => FatturaFornitoreScheda::getUrl(['record' => $record->id], panel: 'admin-filament')),
Action::make('genera_prima_nota')
->label('Genera prima nota')
->icon('heroicon-o-book-open')
->visible(function (FatturaFornitore $record): bool {
if (! Schema::hasTable('contabilita_registrazioni') || ! Schema::hasTable('contabilita_movimenti')) {
return false;
}
return empty($record->registrazione_id);
})
->action(function (FatturaFornitore $record): void {
$user = Auth::user();
if (! $user instanceof User) {
Notification::make()->title('Utente non valido')->danger()->send();
return;
}
try {
$service = app(FatturaFornitorePrimaNotaService::class);
$service->generaRegistrazioneDaFattura($user, $record);
Notification::make()->title('Prima nota generata')->success()->send();
$this->resetTable();
} catch (\Throwable $e) {
Notification::make()->title('Errore')->body($e->getMessage())->danger()->send();
}
}),
]);
}
}