200 lines
6.3 KiB
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);
|
|
}
|
|
}
|