249 lines
10 KiB
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();
|
|
}
|
|
}),
|
|
]);
|
|
}
|
|
}
|