228 lines
7.7 KiB
PHP
228 lines
7.7 KiB
PHP
<?php
|
|
|
|
namespace App\Filament\Pages\Contabilita;
|
|
|
|
use App\Models\GestioneContabile;
|
|
use App\Models\User;
|
|
use App\Models\DatiBancari;
|
|
use App\Services\Contabilita\IntesaCsvParser;
|
|
use App\Services\Contabilita\ExcelMovimentiParser;
|
|
use App\Services\Contabilita\MovimentiBancaImporter;
|
|
use App\Services\Contabilita\UnicreditWriParser;
|
|
use App\Support\StabileContext;
|
|
use BackedEnum;
|
|
use Filament\Actions\Action;
|
|
use Filament\Forms\Components\FileUpload;
|
|
use Filament\Forms\Components\Select;
|
|
use Filament\Forms\Components\Toggle;
|
|
use Filament\Notifications\Notification;
|
|
use Filament\Pages\Page;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use UnitEnum;
|
|
|
|
class CaricamentoDatiBanca extends Page
|
|
{
|
|
protected static ?string $navigationLabel = 'Caricamento dati banca';
|
|
|
|
protected static ?string $title = 'Caricamento dati banca';
|
|
|
|
protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-arrow-up-tray';
|
|
|
|
protected static UnitEnum|string|null $navigationGroup = 'Contabilità';
|
|
|
|
protected static ?int $navigationSort = 15;
|
|
|
|
protected static ?string $slug = 'contabilita/caricamento-dati-banca';
|
|
|
|
protected string $view = 'filament.pages.contabilita.caricamento-dati-banca';
|
|
|
|
protected function getHeaderActions(): array
|
|
{
|
|
return [
|
|
Action::make('importa_unicredit_wri')
|
|
->label('Importa estratto (Unicredit WRI)')
|
|
->icon('heroicon-o-arrow-up-tray')
|
|
->modalWidth('7xl')
|
|
->form($this->getImportFormSchema())
|
|
->action(function (array $data): void {
|
|
$this->runImport('unicredit', $data);
|
|
}),
|
|
|
|
Action::make('importa_intesa_csv')
|
|
->label('Importa estratto (Intesa CSV)')
|
|
->icon('heroicon-o-arrow-up-tray')
|
|
->modalWidth('7xl')
|
|
->form($this->getImportFormSchema())
|
|
->action(function (array $data): void {
|
|
$this->runImport('intesa', $data);
|
|
}),
|
|
];
|
|
}
|
|
|
|
private function getImportFormSchema(): array
|
|
{
|
|
return [
|
|
Select::make('iban')
|
|
->label('Conto (IBAN)')
|
|
->native(false)
|
|
->searchable()
|
|
->options(fn(): array => $this->getIbanOptions())
|
|
->helperText('Consigliato: seleziona il conto per associare i movimenti.'),
|
|
|
|
Select::make('gestione_id')
|
|
->label('Gestione (opzionale)')
|
|
->native(false)
|
|
->searchable()
|
|
->options(fn(): array => $this->getGestioneOptions())
|
|
->default(fn(): ?string => $this->resolveDefaultGestioneId()),
|
|
|
|
FileUpload::make('file')
|
|
->label('File estratto')
|
|
->directory('tmp/banca')
|
|
->disk('local')
|
|
->required(),
|
|
|
|
Toggle::make('replace')
|
|
->label('Sostituisci import nel periodo')
|
|
->helperText('Elimina SOLO i movimenti importati e NON riconciliati (registrazione vuota) per lo stesso conto e per l\'intervallo date del file, poi reimporta.')
|
|
->default(false),
|
|
];
|
|
}
|
|
|
|
private function runImport(string $tipo, array $data): void
|
|
{
|
|
$user = Auth::user();
|
|
if (! $user instanceof User) {
|
|
Notification::make()->title('Utente non valido')->danger()->send();
|
|
return;
|
|
}
|
|
|
|
$stabileId = StabileContext::resolveActiveStabileId($user);
|
|
if (! $stabileId) {
|
|
Notification::make()->title('Seleziona uno stabile')->danger()->send();
|
|
return;
|
|
}
|
|
|
|
$path = (string) ($data['file'] ?? '');
|
|
if ($path === '') {
|
|
Notification::make()->title('Seleziona un file')->danger()->send();
|
|
return;
|
|
}
|
|
|
|
try {
|
|
$content = Storage::disk('local')->get($path);
|
|
$importer = new MovimentiBancaImporter(new UnicreditWriParser(), new IntesaCsvParser(), new ExcelMovimentiParser());
|
|
|
|
$iban = isset($data['iban']) && is_string($data['iban']) && trim($data['iban']) !== '' ? trim((string) $data['iban']) : null;
|
|
$gestioneId = isset($data['gestione_id']) && is_numeric($data['gestione_id']) ? (int) $data['gestione_id'] : null;
|
|
$replace = isset($data['replace']) ? (bool) $data['replace'] : false;
|
|
|
|
if ($tipo === 'intesa') {
|
|
$res = $importer->importIntesaCsv($content, $stabileId, basename($path), $iban, $gestioneId, $replace);
|
|
} else {
|
|
$res = $importer->importUnicreditWri($content, $stabileId, basename($path), $iban, $gestioneId, $replace);
|
|
}
|
|
|
|
Notification::make()
|
|
->title('Import completato')
|
|
->body('Importati: ' . ($res['imported'] ?? 0) . ' · Duplicati: ' . ($res['duplicates'] ?? 0))
|
|
->success()
|
|
->send();
|
|
} catch (\Throwable $e) {
|
|
Notification::make()->title('Errore import')->body($e->getMessage())->danger()->send();
|
|
} finally {
|
|
try {
|
|
Storage::disk('local')->delete($path);
|
|
} catch (\Throwable) {
|
|
// ignore
|
|
}
|
|
}
|
|
}
|
|
|
|
private function getIbanOptions(): array
|
|
{
|
|
$user = Auth::user();
|
|
if (! $user instanceof User) {
|
|
return [];
|
|
}
|
|
|
|
$stabileId = StabileContext::resolveActiveStabileId($user);
|
|
if (! $stabileId) {
|
|
return [];
|
|
}
|
|
|
|
$opts = [];
|
|
foreach (
|
|
DatiBancari::query()
|
|
->where('stabile_id', $stabileId)
|
|
->orderBy('denominazione_banca')
|
|
->orderBy('iban')
|
|
->get(['iban', 'denominazione_banca']) as $c
|
|
) {
|
|
$iban = is_string($c->iban) ? trim($c->iban) : '';
|
|
if ($iban === '') {
|
|
continue;
|
|
}
|
|
$label = trim(($c->denominazione_banca ?: 'Banca') . ' · ' . $iban);
|
|
$opts[$iban] = $label;
|
|
}
|
|
|
|
return $opts;
|
|
}
|
|
|
|
private function getGestioneOptions(): array
|
|
{
|
|
$user = Auth::user();
|
|
if (! $user instanceof User) {
|
|
return [];
|
|
}
|
|
|
|
$stabileId = StabileContext::resolveActiveStabileId($user);
|
|
if (! $stabileId) {
|
|
return [];
|
|
}
|
|
|
|
if (! DB::getSchemaBuilder()->hasTable('gestioni_contabili')) {
|
|
return [];
|
|
}
|
|
|
|
return GestioneContabile::query()
|
|
->where('stabile_id', $stabileId)
|
|
->orderByDesc('anno_gestione')
|
|
->orderBy('tipo_gestione')
|
|
->orderByDesc('id')
|
|
->get(['id', 'denominazione', 'protocollo_prefix', 'stato'])
|
|
->mapWithKeys(fn(GestioneContabile $g) => [
|
|
(string) $g->id => trim(($g->protocollo_prefix ? $g->protocollo_prefix . ' · ' : '') . $g->denominazione) . ($g->stato !== 'aperta' ? (' (' . $g->stato . ')') : ''),
|
|
])
|
|
->all();
|
|
}
|
|
|
|
private function resolveDefaultGestioneId(): ?string
|
|
{
|
|
$user = Auth::user();
|
|
if (! $user instanceof User) {
|
|
return null;
|
|
}
|
|
|
|
$stabileId = StabileContext::resolveActiveStabileId($user);
|
|
if (! $stabileId) {
|
|
return null;
|
|
}
|
|
|
|
if (! DB::getSchemaBuilder()->hasTable('gestioni_contabili')) {
|
|
return null;
|
|
}
|
|
|
|
$g = GestioneContabile::query()
|
|
->where('stabile_id', $stabileId)
|
|
->orderByDesc('anno_gestione')
|
|
->orderByDesc('id')
|
|
->first(['id']);
|
|
|
|
return $g ? (string) $g->id : null;
|
|
}
|
|
}
|