netgescon-day0/app/Filament/Pages/SuperAdmin/CodiciFatturaElettronicaXsd.php

200 lines
6.3 KiB
PHP

<?php
namespace App\Filament\Pages\SuperAdmin;
use App\Models\FeXsdCode;
use App\Models\FeXsdCodeDomain;
use App\Models\FeXsdVersion;
use App\Models\User;
use App\Services\FattureElettroniche\FeXsdCodesDiff;
use App\Services\FattureElettroniche\FeXsdCodesImporter;
use BackedEnum;
use Filament\Actions\Action;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Textarea;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Schema;
use UnitEnum;
class CodiciFatturaElettronicaXsd extends Page
{
protected static ?string $navigationLabel = 'Codici FE (XSD)';
protected static ?string $title = 'Codici Fattura Elettronica (da XSD)';
protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-code-bracket-square';
protected static UnitEnum|string|null $navigationGroup = 'Super Admin';
protected static ?int $navigationSort = 25;
protected static ?string $slug = 'superadmin/codici-fe-xsd';
protected string $view = 'filament.pages.super-admin.codici-fe-xsd';
public static function canAccess(): bool
{
$user = Auth::user();
return $user instanceof User
&& $user->hasRole('super-admin')
&& Schema::hasTable('fe_xsd_versions');
}
protected function getHeaderActions(): array
{
return [
Action::make('importa_xsd')
->label('Importa XSD')
->icon('heroicon-o-arrow-up-tray')
->modalWidth('7xl')
->form([
TextInput::make('version_label')
->label('Versione (etichetta)')
->helperText('Es: VFPR12 1.2.3')
->maxLength(100),
Textarea::make('note')
->label('Note')
->rows(3),
FileUpload::make('xsd_file')
->label('File XSD')
->disk('local')
->directory('tmp/fe-xsd')
->required(),
])
->action(function (array $data): void {
$user = Auth::user();
$createdBy = $user instanceof User ? $user : null;
$path = (string) ($data['xsd_file'] ?? '');
if ($path === '') {
Notification::make()->title('Seleziona un file XSD')->danger()->send();
return;
}
try {
$importer = app(FeXsdCodesImporter::class);
$res = $importer->importFromUploadedXsd(
$path,
isset($data['version_label']) ? (string) $data['version_label'] : null,
isset($data['note']) ? (string) $data['note'] : null,
$createdBy,
);
$already = (bool) ($res['summary']['already_imported'] ?? false);
$title = $already ? 'XSD già importato' : 'Import XSD completato';
$body = 'SHA256: ' . ($res['summary']['sha256'] ?? '')
. ($already ? '' : (' · Domini: ' . ($res['summary']['domains'] ?? 0) . ' · Codici: ' . ($res['summary']['codes'] ?? 0)));
Notification::make()->title($title)->body($body)->success()->send();
} catch (\Throwable $e) {
Notification::make()->title('Errore import XSD')->body($e->getMessage())->danger()->send();
}
}),
];
}
public function getVersions()
{
return FeXsdVersion::query()
->orderByDesc('imported_at')
->orderByDesc('id')
->get(['id', 'version_label', 'original_filename', 'sha256', 'imported_at']);
}
public function getLatestVersion(): ?FeXsdVersion
{
return FeXsdVersion::query()->orderByDesc('imported_at')->orderByDesc('id')->first();
}
public function getLatestDomains()
{
$latest = $this->getLatestVersion();
if (!$latest) {
return collect();
}
return FeXsdCodeDomain::query()
->where('version_id', $latest->id)
->orderBy('type_name')
->get(['type_name', 'codes_count']);
}
public function getSelectedDomainTypeName(): ?string
{
$domain = request()->query('domain');
if (! is_string($domain)) {
return null;
}
$domain = trim($domain);
if ($domain === '' || strlen($domain) > 190) {
return null;
}
// Keep it simple: only allow characters that can appear in XSD type names.
if (! preg_match('/^[A-Za-z0-9_\-\.]+$/', $domain)) {
return null;
}
return $domain;
}
public function getSelectedDomainCodes()
{
$latest = $this->getLatestVersion();
if (! $latest) {
return collect();
}
$domain = $this->getSelectedDomainTypeName();
if (! $domain) {
return collect();
}
$domainId = FeXsdCodeDomain::query()
->where('version_id', $latest->id)
->where('type_name', $domain)
->value('id');
$domainId = is_numeric($domainId) ? (int) $domainId : null;
if (! $domainId) {
return collect();
}
return FeXsdCode::query()
->where('domain_id', $domainId)
->orderBy('code')
->get(['code', 'documentation']);
}
public function getPreviousVersion(?FeXsdVersion $latest): ?FeXsdVersion
{
if (!$latest) {
return null;
}
return FeXsdVersion::query()
->where('id', '<', $latest->id)
->orderByDesc('imported_at')
->orderByDesc('id')
->first();
}
public function getDiffSummary(): ?array
{
$latest = $this->getLatestVersion();
if (!$latest) {
return null;
}
$prev = $this->getPreviousVersion($latest);
$diff = app(FeXsdCodesDiff::class);
return $diff->diff($prev, $latest);
}
}