diff --git a/README.md b/README.md
index 79527b9..a1abbc0 100644
--- a/README.md
+++ b/README.md
@@ -40,7 +40,8 @@ ## Struttura documentazione
## Stato operativo recente
- Strumenti > Documenti apre ora una dashboard `Protocollo comunicazioni` con ricerca, filtri e anteprima PDF.
-- Le etichette archivio fisico generano il QR in locale e supportano i formati DYMO `11354` e `99014`.
+- Le etichette archivio fisico generano il QR in locale, supportano i formati DYMO `11354` e `99014` e usano un URL pubblico configurabile tramite `APP_PUBLIC_URL`.
+- La vista `Archivio digitale` usa ora una tabella a tutta larghezza con riepilogo rapido della cartella corrente.
- La topbar contestuale Filament usa layout a capo, senza scrollbar orizzontale.
## Contribuire
diff --git a/app/Filament/Pages/Strumenti/DocumentiArchivio.php b/app/Filament/Pages/Strumenti/DocumentiArchivio.php
index cf9cc02..89007d6 100644
--- a/app/Filament/Pages/Strumenti/DocumentiArchivio.php
+++ b/app/Filament/Pages/Strumenti/DocumentiArchivio.php
@@ -49,7 +49,7 @@ class DocumentiArchivio extends Page implements HasTable
public string $protocolloView = 'cards';
- #[Url(as: 'folder')]
+ #[Url( as : 'folder')]
public ?int $currentFolderId = null;
public array $physicalArchiveForm = [];
@@ -292,15 +292,15 @@ public function table(Table $table): Table
->hiddenLabel()
->icon('heroicon-o-archive-box')
->tooltip('Collega archivio fisico')
- ->fillForm(fn(Documento $record): array => [
- 'supporto_fisico' => data_get($record->metadati_archivio ?? [], 'supporto_fisico'),
- 'modello_etichetta' => data_get($record->metadati_archivio ?? [], 'modello_etichetta', '11354'),
- 'busta_numero' => data_get($record->metadati_archivio ?? [], 'busta_numero'),
- 'fascicolo_numero' => data_get($record->metadati_archivio ?? [], 'fascicolo_numero'),
- 'contenitore_numero' => data_get($record->metadati_archivio ?? [], 'contenitore_numero'),
+ ->fillForm(fn(Documento $record): array=> [
+ 'supporto_fisico' => data_get($record->metadati_archivio ?? [], 'supporto_fisico'),
+ 'modello_etichetta' => data_get($record->metadati_archivio ?? [], 'modello_etichetta', '11354'),
+ 'busta_numero' => data_get($record->metadati_archivio ?? [], 'busta_numero'),
+ 'fascicolo_numero' => data_get($record->metadati_archivio ?? [], 'fascicolo_numero'),
+ 'contenitore_numero' => data_get($record->metadati_archivio ?? [], 'contenitore_numero'),
'periodo_riferimento_da' => data_get($record->metadati_archivio ?? [], 'periodo_da'),
- 'periodo_riferimento_a' => data_get($record->metadati_archivio ?? [], 'periodo_a'),
- 'watermark_predefinito' => (bool) data_get($record->metadati_archivio ?? [], 'watermark_predefinito', false),
+ 'periodo_riferimento_a' => data_get($record->metadati_archivio ?? [], 'periodo_a'),
+ 'watermark_predefinito' => (bool) data_get($record->metadati_archivio ?? [], 'watermark_predefinito', false),
])
->form([
Select::make('supporto_fisico')
@@ -327,16 +327,16 @@ public function table(Table $table): Table
->default(false),
])
->action(function (Documento $record, array $data): void {
- $meta = is_array($record->metadati_archivio ?? null) ? $record->metadati_archivio : [];
- $meta['supporto_fisico'] = $this->normalizeNullableText($data['supporto_fisico'] ?? null);
- $meta['modello_etichetta'] = $this->normalizeNullableText($data['modello_etichetta'] ?? null);
- $meta['contenitore_numero'] = $this->normalizeNullableText($data['contenitore_numero'] ?? null);
- $meta['busta_numero'] = $this->normalizeNullableText($data['busta_numero'] ?? null);
- $meta['fascicolo_numero'] = $this->normalizeNullableText($data['fascicolo_numero'] ?? null);
- $meta['periodo_da'] = $data['periodo_riferimento_da'] ?? null;
- $meta['periodo_a'] = $data['periodo_riferimento_a'] ?? null;
+ $meta = is_array($record->metadati_archivio ?? null) ? $record->metadati_archivio : [];
+ $meta['supporto_fisico'] = $this->normalizeNullableText($data['supporto_fisico'] ?? null);
+ $meta['modello_etichetta'] = $this->normalizeNullableText($data['modello_etichetta'] ?? null);
+ $meta['contenitore_numero'] = $this->normalizeNullableText($data['contenitore_numero'] ?? null);
+ $meta['busta_numero'] = $this->normalizeNullableText($data['busta_numero'] ?? null);
+ $meta['fascicolo_numero'] = $this->normalizeNullableText($data['fascicolo_numero'] ?? null);
+ $meta['periodo_da'] = $data['periodo_riferimento_da'] ?? null;
+ $meta['periodo_a'] = $data['periodo_riferimento_a'] ?? null;
$meta['watermark_predefinito'] = (bool) ($data['watermark_predefinito'] ?? false);
- $record->metadati_archivio = $meta;
+ $record->metadati_archivio = $meta;
$record->save();
Notification::make()
@@ -434,6 +434,30 @@ public function getDigitalArchiveCurrentFolderProperty(): ?DocumentoArchivioCart
return DocumentoArchivioCartella::query()->find($this->currentFolderId);
}
+ public function getDigitalArchiveCurrentFolderDocumentCountProperty(): int
+ {
+ $stabileId = (int) ($this->resolveActiveStabile()?->id ?? 0);
+ if ($stabileId <= 0 || ! $this->currentFolderId) {
+ return 0;
+ }
+
+ return (int) Documento::query()
+ ->where('stabile_id', $stabileId)
+ ->where('tipo_documento', 'fattura')
+ ->where('cartella_archivio_id', $this->currentFolderId)
+ ->count();
+ }
+
+ public function getDigitalArchiveCurrentFolderHintProperty(): string
+ {
+ $folder = $this->digitalArchiveCurrentFolder;
+ if (! $folder instanceof DocumentoArchivioCartella) {
+ return 'Seleziona la cartella annuale per vedere l’elenco dei PDF già ordinati per protocollo e data.';
+ }
+
+ return trim((string) ($folder->percorso_logico ?: $folder->nome));
+ }
+
public function getDigitalArchiveFoldersProperty(): array
{
$stabile = $this->resolveActiveStabile();
@@ -448,10 +472,10 @@ public function getDigitalArchiveFoldersProperty(): array
if (! $this->currentFolderId) {
return [[
- 'id' => (int) $root->id,
- 'nome' => (string) $root->nome,
+ 'id' => (int) $root->id,
+ 'nome' => (string) $root->nome,
'descrizione' => 'Cartella fatture PDF',
- 'conteggio' => (int) Documento::query()
+ 'conteggio' => (int) Documento::query()
->where('stabile_id', $stabile->id)
->where('tipo_documento', 'fattura')
->count(),
@@ -464,11 +488,11 @@ public function getDigitalArchiveFoldersProperty(): array
->orderBy('sort_order')
->orderBy('nome')
->get()
- ->map(fn(DocumentoArchivioCartella $folder): array => [
- 'id' => (int) $folder->id,
- 'nome' => (string) $folder->nome,
+ ->map(fn(DocumentoArchivioCartella $folder): array=> [
+ 'id' => (int) $folder->id,
+ 'nome' => (string) $folder->nome,
'descrizione' => (string) ($folder->percorso_logico ?: $folder->nome),
- 'conteggio' => (int) $folder->documenti()->count(),
+ 'conteggio' => (int) $folder->documenti()->count(),
])
->all();
}
@@ -476,7 +500,7 @@ public function getDigitalArchiveFoldersProperty(): array
public function getDigitalArchiveBreadcrumbsProperty(): array
{
$items = [[
- 'label' => $this->digitalArchiveRootLabel,
+ 'label' => $this->digitalArchiveRootLabel,
'folder_id' => null,
]];
@@ -488,7 +512,7 @@ public function getDigitalArchiveBreadcrumbsProperty(): array
$chain = collect();
while ($current instanceof DocumentoArchivioCartella) {
$chain->prepend([
- 'label' => (string) $current->nome,
+ 'label' => (string) $current->nome,
'folder_id' => (int) $current->id,
]);
$current = $current->parent;
@@ -546,26 +570,26 @@ public function getArchivioFisicoTypesProperty(): array
public function getArchivioClasseOptions(): array
{
return [
- 'libro_verbali' => 'Libro verbali',
- 'planimetria_stabile' => 'Planimetria stabile',
- 'elaborato_planimetrico' => 'Elaborato planimetrico',
+ 'libro_verbali' => 'Libro verbali',
+ 'planimetria_stabile' => 'Planimetria stabile',
+ 'elaborato_planimetrico' => 'Elaborato planimetrico',
'scheda_anagrafica_condominiale' => 'Scheda anagrafica condominiale',
- 'fascicolo_fabbricato' => 'Fascicolo fabbricato',
- 'polizza_fabbricato' => 'Polizza global fabbricato',
- 'certificazioni_impianti' => 'Certificazioni e conformita impianti',
- 'decreti_vincolo' => 'Decreti di vincolo',
- 'tabelle_millesimali' => 'Tabelle millesimali',
- 'regolamento_condominio' => 'Regolamento di condominio',
- 'rendiconti_approvati' => 'Rendiconti approvati',
- 'raccolta_contratti' => 'Raccolta contratti stipulati',
- 'servitu_diritti_terzi' => 'Servitu e diritti di terzi',
- 'giustificativi_spesa' => 'Giustificativi di spesa',
- 'scritture_contabili' => 'Scritture contabili e sostituto imposta',
- 'codice_fiscale' => 'Codice fiscale',
- 'partita_iva_amministratore' => 'Partita IVA amministratore',
- 'chiavi_stabile' => 'Chiavi stabile',
- 'timbri_stabile' => 'Timbri stabile',
- 'altro' => 'Altro contenuto archivio',
+ 'fascicolo_fabbricato' => 'Fascicolo fabbricato',
+ 'polizza_fabbricato' => 'Polizza global fabbricato',
+ 'certificazioni_impianti' => 'Certificazioni e conformita impianti',
+ 'decreti_vincolo' => 'Decreti di vincolo',
+ 'tabelle_millesimali' => 'Tabelle millesimali',
+ 'regolamento_condominio' => 'Regolamento di condominio',
+ 'rendiconti_approvati' => 'Rendiconti approvati',
+ 'raccolta_contratti' => 'Raccolta contratti stipulati',
+ 'servitu_diritti_terzi' => 'Servitu e diritti di terzi',
+ 'giustificativi_spesa' => 'Giustificativi di spesa',
+ 'scritture_contabili' => 'Scritture contabili e sostituto imposta',
+ 'codice_fiscale' => 'Codice fiscale',
+ 'partita_iva_amministratore' => 'Partita IVA amministratore',
+ 'chiavi_stabile' => 'Chiavi stabile',
+ 'timbri_stabile' => 'Timbri stabile',
+ 'altro' => 'Altro contenuto archivio',
];
}
@@ -620,7 +644,7 @@ public function getPhysicalArchiveParentOptionsProperty(): array
->whereIn('tipo_item', ['busta_trasparente', 'cartella_tre_lembi', 'faldone_anelli', 'faldone_lacci', 'scatola'])
->orderBy('codice_univoco')
->get(['id', 'codice_univoco', 'titolo'])
- ->mapWithKeys(fn(DocumentoArchivioFisicoItem $item): array => [
+ ->mapWithKeys(fn(DocumentoArchivioFisicoItem $item): array=> [
(string) $item->id => trim($item->codice_univoco . ' · ' . $item->titolo),
])
->all();
@@ -682,17 +706,17 @@ public function getPhysicalArchiveRowsProperty(): array
->get()
->map(function (DocumentoArchivioFisicoItem $item): array {
return [
- 'id' => (int) $item->id,
- 'codice_univoco' => (string) $item->codice_univoco,
- 'tipo' => (string) $item->tipo_label,
- 'titolo' => (string) $item->titolo,
- 'voce' => trim(collect([$item->voce_numero ? ('Voce ' . $item->voce_numero) : null, $item->voce_titolo])->filter()->implode(' · ')),
+ 'id' => (int) $item->id,
+ 'codice_univoco' => (string) $item->codice_univoco,
+ 'tipo' => (string) $item->tipo_label,
+ 'titolo' => (string) $item->titolo,
+ 'voce' => trim(collect([$item->voce_numero ? ('Voce ' . $item->voce_numero) : null, $item->voce_titolo])->filter()->implode(' · ')),
'data_archiviazione' => $item->data_archiviazione?->format('d-m-Y') ?: '—',
- 'parent' => $item->parent ? trim($item->parent->codice_univoco . ' · ' . $item->parent->titolo) : 'Radice',
- 'percorso' => (string) $item->percorso_fisico,
- 'documento' => $item->documento ? trim((string) ($item->documento->nome_file ?: $item->documento->nome ?: ('Documento #' . $item->documento->id))) : null,
- 'ubicazione' => collect([$item->magazzino, $item->scaffale, $item->ripiano, $item->ubicazione_dettaglio])->filter()->implode(' · '),
- 'modello_etichetta' => (string) ($item->modello_etichetta ?: '11354'),
+ 'parent' => $item->parent ? trim($item->parent->codice_univoco . ' · ' . $item->parent->titolo) : 'Radice',
+ 'percorso' => (string) $item->percorso_fisico,
+ 'documento' => $item->documento ? trim((string) ($item->documento->nome_file ?: $item->documento->nome ?: ('Documento #' . $item->documento->id))): null,
+ 'ubicazione' => collect([$item->magazzino, $item->scaffale, $item->ripiano, $item->ubicazione_dettaglio])->filter()->implode(' · '),
+ 'modello_etichetta' => (string) ($item->modello_etichetta ?: '11354'),
];
})
->all();
@@ -712,10 +736,10 @@ public function getPhysicalArchiveContainerTreeProperty(): array
->get()
->map(function (DocumentoArchivioFisicoItem $item): array {
return [
- 'id' => (int) $item->id,
+ 'id' => (int) $item->id,
'codice_univoco' => (string) $item->codice_univoco,
- 'titolo' => (string) $item->titolo,
- 'tipo' => (string) $item->tipo_label,
+ 'titolo' => (string) $item->titolo,
+ 'tipo' => (string) $item->tipo_label,
'children_count' => (int) $item->children()->count(),
];
})
@@ -736,7 +760,7 @@ public function savePhysicalArchiveEntry(): void
return;
}
- $titolo = trim((string) ($this->physicalArchiveForm['titolo'] ?? ''));
+ $titolo = trim((string) ($this->physicalArchiveForm['titolo'] ?? ''));
$tipoItem = trim((string) ($this->physicalArchiveForm['tipo_item'] ?? 'documento'));
if ($titolo === '' || ! array_key_exists($tipoItem, DocumentoArchivioFisicoItem::TIPI)) {
Notification::make()->title('Titolo e tipologia sono obbligatori')->danger()->send();
@@ -744,7 +768,7 @@ public function savePhysicalArchiveEntry(): void
}
$parentId = is_numeric($this->physicalArchiveForm['parent_id'] ?? null) ? (int) $this->physicalArchiveForm['parent_id'] : null;
- $parent = $parentId
+ $parent = $parentId
? DocumentoArchivioFisicoItem::query()->where('stabile_id', $stabileId)->find($parentId)
: null;
@@ -756,34 +780,34 @@ public function savePhysicalArchiveEntry(): void
}
$item = DocumentoArchivioFisicoItem::query()->create([
- 'stabile_id' => $stabileId,
- 'parent_id' => $parent?->id,
- 'documento_id' => is_numeric($this->physicalArchiveForm['documento_id'] ?? null) ? (int) $this->physicalArchiveForm['documento_id'] : null,
- 'voce_numero' => $voceNumero,
- 'voce_titolo' => $voceTitolo !== '' ? $voceTitolo : null,
- 'tipo_item' => $tipoItem,
- 'titolo' => $titolo,
- 'note' => $this->normalizeNullableText($this->physicalArchiveForm['note'] ?? null),
- 'data_archiviazione' => $this->physicalArchiveForm['data_archiviazione'] ?? now()->toDateString(),
- 'supporto_fisico' => $this->normalizeNullableText($this->physicalArchiveForm['supporto_fisico'] ?? null),
- 'modello_etichetta' => $this->normalizeNullableText($this->physicalArchiveForm['modello_etichetta'] ?? null) ?: '11354',
- 'magazzino' => $this->normalizeNullableText($this->physicalArchiveForm['magazzino'] ?? null),
- 'scaffale' => $this->normalizeNullableText($this->physicalArchiveForm['scaffale'] ?? null),
- 'ripiano' => $this->normalizeNullableText($this->physicalArchiveForm['ripiano'] ?? null),
+ 'stabile_id' => $stabileId,
+ 'parent_id' => $parent?->id,
+ 'documento_id' => is_numeric($this->physicalArchiveForm['documento_id'] ?? null) ? (int) $this->physicalArchiveForm['documento_id'] : null,
+ 'voce_numero' => $voceNumero,
+ 'voce_titolo' => $voceTitolo !== '' ? $voceTitolo : null,
+ 'tipo_item' => $tipoItem,
+ 'titolo' => $titolo,
+ 'note' => $this->normalizeNullableText($this->physicalArchiveForm['note'] ?? null),
+ 'data_archiviazione' => $this->physicalArchiveForm['data_archiviazione'] ?? now()->toDateString(),
+ 'supporto_fisico' => $this->normalizeNullableText($this->physicalArchiveForm['supporto_fisico'] ?? null),
+ 'modello_etichetta' => $this->normalizeNullableText($this->physicalArchiveForm['modello_etichetta'] ?? null) ?: '11354',
+ 'magazzino' => $this->normalizeNullableText($this->physicalArchiveForm['magazzino'] ?? null),
+ 'scaffale' => $this->normalizeNullableText($this->physicalArchiveForm['scaffale'] ?? null),
+ 'ripiano' => $this->normalizeNullableText($this->physicalArchiveForm['ripiano'] ?? null),
'ubicazione_dettaglio' => $this->normalizeNullableText($this->physicalArchiveForm['ubicazione_dettaglio'] ?? null),
- 'created_by' => (int) $user->id,
- 'updated_by' => (int) $user->id,
- 'metadati' => [
+ 'created_by' => (int) $user->id,
+ 'updated_by' => (int) $user->id,
+ 'metadati' => [
'origine_digitale' => is_numeric($this->physicalArchiveForm['documento_id'] ?? null),
],
]);
if ($item->documento instanceof Documento) {
- $meta = is_array($item->documento->metadati_archivio ?? null) ? $item->documento->metadati_archivio : [];
+ $meta = is_array($item->documento->metadati_archivio ?? null) ? $item->documento->metadati_archivio : [];
$meta['physical_archive_item_id'] = (int) $item->id;
- $meta['physical_archive_code'] = (string) $item->codice_univoco;
- $meta['contenitore_numero'] = $parent?->codice_univoco;
- $meta['supporto_fisico'] = $item->supporto_fisico;
+ $meta['physical_archive_code'] = (string) $item->codice_univoco;
+ $meta['contenitore_numero'] = $parent?->codice_univoco;
+ $meta['supporto_fisico'] = $item->supporto_fisico;
$item->documento->forceFill([
'metadati_archivio' => $meta,
])->save();
@@ -827,7 +851,7 @@ public function movePhysicalArchiveItem(): void
}
$source->forceFill([
- 'parent_id' => (int) $target->id,
+ 'parent_id' => (int) $target->id,
'updated_by' => Auth::id(),
])->save();
@@ -902,8 +926,8 @@ public function getProtocolloComunicazioniStatsProperty(): array
$query = $this->getProtocolloComunicazioniQuery();
return [
- 'totale' => (clone $query)->count(),
- 'con_pdf' => (clone $query)
+ 'totale' => (clone $query)->count(),
+ 'con_pdf' => (clone $query)
->where(function (Builder $builder): void {
$builder->whereNotNull('percorso_file')
->orWhereNotNull('path_file');
@@ -912,7 +936,7 @@ public function getProtocolloComunicazioniStatsProperty(): array
'questo_mese' => (clone $query)
->whereDate('created_at', '>=', now()->startOfMonth()->toDateString())
->count(),
- 'categorie' => (clone $query)
+ 'categorie' => (clone $query)
->reorder()
->select('tipo_documento')
->distinct()
@@ -935,13 +959,13 @@ public function getProtocolloComunicazioniCategoryOptionsProperty(): array
$labels = $this->getCategorieOptions();
return collect($visibleCategories)
- ->mapWithKeys(fn(string $value): array => [$value => $labels[$value] ?? Str::headline($value)])
+ ->mapWithKeys(fn(string $value): array=> [$value => $labels[$value] ?? Str::headline($value)])
->all();
}
public function getProtocolloComunicazioniRowsProperty(): array
{
- $limit = $this->protocolloView === 'list' ? 80 : 18;
+ $limit = $this->protocolloView === 'list' ? 80 : 18;
$labels = $this->getCategorieOptions();
return $this->getProtocolloComunicazioniQuery()
@@ -950,23 +974,23 @@ public function getProtocolloComunicazioniRowsProperty(): array
->get()
->map(function (Documento $documento) use ($labels): array {
$openUrl = route('filament.documenti.download', $documento) . '?inline=1';
- $tipo = trim((string) ($documento->tipo_documento ?? ''));
+ $tipo = trim((string) ($documento->tipo_documento ?? ''));
return [
- 'id' => (int) $documento->id,
- 'protocollo' => trim((string) ($documento->numero_protocollo ?: 'DOC-' . $documento->id)),
- 'titolo' => trim((string) ($documento->nome ?: $documento->nome_file ?: ('Documento #' . $documento->id))),
- 'descrizione' => trim((string) ($documento->descrizione ?: Str::limit((string) ($documento->contenuto_ocr ?? ''), 140, '...'))),
- 'categoria' => $labels[$tipo] ?? ($tipo !== '' ? Str::headline($tipo) : 'Protocollo generale'),
- 'fornitore' => trim((string) ($documento->fornitore ?? '')),
- 'data' => $documento->data_documento?->format('d/m/Y')
+ 'id' => (int) $documento->id,
+ 'protocollo' => trim((string) ($documento->numero_protocollo ?: 'DOC-' . $documento->id)),
+ 'titolo' => trim((string) ($documento->nome ?: $documento->nome_file ?: ('Documento #' . $documento->id))),
+ 'descrizione' => trim((string) ($documento->descrizione ?: Str::limit((string) ($documento->contenuto_ocr ?? ''), 140, '...'))),
+ 'categoria' => $labels[$tipo] ?? ($tipo !== '' ? Str::headline($tipo) : 'Protocollo generale'),
+ 'fornitore' => trim((string) ($documento->fornitore ?? '')),
+ 'data' => $documento->data_documento?->format('d/m/Y')
?: ($documento->created_at?->format('d/m/Y') ?: '—'),
- 'cartella' => trim((string) ($documento->cartellaArchivio?->nome ?? 'Protocollo generale')),
+ 'cartella' => trim((string) ($documento->cartellaArchivio?->nome ?? 'Protocollo generale')),
'archive_reference' => trim((string) ($documento->archive_reference ?? '')),
- 'has_pdf' => $this->hasPdf($documento),
- 'preview_url' => $openUrl,
- 'download_url' => route('filament.documenti.download', $documento),
- 'print_url' => $openUrl,
+ 'has_pdf' => $this->hasPdf($documento),
+ 'preview_url' => $openUrl,
+ 'download_url' => route('filament.documenti.download', $documento),
+ 'print_url' => $openUrl,
];
})
->all();
@@ -1160,20 +1184,20 @@ private function getStabiliOptions(): array
private function initializePhysicalArchiveForms(): void
{
$this->physicalArchiveForm = [
- 'data_archiviazione' => now()->toDateString(),
- 'voce_numero' => null,
- 'voce_titolo' => '',
- 'titolo' => '',
- 'note' => '',
- 'tipo_item' => 'documento',
- 'supporto_fisico' => 'Busta trasparente con anelli da archiviare',
- 'parent_id' => null,
- 'documento_id' => null,
- 'magazzino' => '',
- 'scaffale' => '',
- 'ripiano' => '',
+ 'data_archiviazione' => now()->toDateString(),
+ 'voce_numero' => null,
+ 'voce_titolo' => '',
+ 'titolo' => '',
+ 'note' => '',
+ 'tipo_item' => 'documento',
+ 'supporto_fisico' => 'Busta trasparente con anelli da archiviare',
+ 'parent_id' => null,
+ 'documento_id' => null,
+ 'magazzino' => '',
+ 'scaffale' => '',
+ 'ripiano' => '',
'ubicazione_dettaglio' => '',
- 'modello_etichetta' => '11354',
+ 'modello_etichetta' => '11354',
];
$this->physicalArchiveMoveForm = [
@@ -1279,7 +1303,7 @@ private function syncInvoiceFolders(): void
->orderBy('id')
->get(['id', 'data_documento', 'cartella_archivio_id'])
->each(function (Documento $documento) use ($stabile, $root): void {
- $year = (int) (($documento->data_documento?->format('Y')) ?: now()->format('Y'));
+ $year = (int) (($documento->data_documento?->format('Y')) ?: now()->format('Y'));
$yearFolder = $this->ensureInvoiceYearFolder((int) $stabile->id, $root, $year);
if (! $yearFolder instanceof DocumentoArchivioCartella) {
return;
@@ -1313,16 +1337,16 @@ private function ensureInvoiceRootFolder(int $stabileId): ?DocumentoArchivioCart
return DocumentoArchivioCartella::query()->firstOrCreate(
[
'stabile_id' => $stabileId,
- 'parent_id' => null,
- 'slug' => 'fatture-pdf',
+ 'parent_id' => null,
+ 'slug' => 'fatture-pdf',
],
[
- 'nome' => 'fatture_PDF',
- 'codice' => 'FATTURE',
- 'percorso_logico' => 'fatture_PDF',
+ 'nome' => 'fatture_PDF',
+ 'codice' => 'FATTURE',
+ 'percorso_logico' => 'fatture_PDF',
'visibility_scope' => 'interno',
- 'created_by' => Auth::id(),
- 'updated_by' => Auth::id(),
+ 'created_by' => Auth::id(),
+ 'updated_by' => Auth::id(),
]
);
}
@@ -1336,16 +1360,16 @@ private function ensureInvoiceYearFolder(int $stabileId, DocumentoArchivioCartel
return DocumentoArchivioCartella::query()->firstOrCreate(
[
'stabile_id' => $stabileId,
- 'parent_id' => (int) $root->id,
- 'slug' => (string) $year,
+ 'parent_id' => (int) $root->id,
+ 'slug' => (string) $year,
],
[
- 'nome' => (string) $year,
- 'codice' => 'FATT-' . $year,
- 'percorso_logico' => trim((string) $root->nome) . '/' . $year,
+ 'nome' => (string) $year,
+ 'codice' => 'FATT-' . $year,
+ 'percorso_logico' => trim((string) $root->nome) . '/' . $year,
'visibility_scope' => 'interno',
- 'created_by' => Auth::id(),
- 'updated_by' => Auth::id(),
+ 'created_by' => Auth::id(),
+ 'updated_by' => Auth::id(),
]
);
}
@@ -1604,8 +1628,8 @@ private function createDocumentoFromForm(array $data, bool $isDemo): void
$note = 'Faldone: ' . $faldone;
}
- $tipologia = $this->mapCategoriaToTipologia($categoria);
- $archivioClasse = trim((string) ($data['archivio_classe'] ?? ''));
+ $tipologia = $this->mapCategoriaToTipologia($categoria);
+ $archivioClasse = trim((string) ($data['archivio_classe'] ?? ''));
$archiveReference = $this->buildArchiveReference($stabileId, $categoria, $year, $data);
$doc = Documento::query()->create([
@@ -1632,18 +1656,18 @@ private function createDocumentoFromForm(array $data, bool $isDemo): void
'estensione' => 'pdf',
'dimensione_file' => $size,
'metadati_archivio' => [
- 'classe' => $archivioClasse !== '' ? $archivioClasse : null,
- 'classe_label' => $this->getArchivioClasseOptions()[$archivioClasse] ?? null,
- 'supporto_fisico' => $this->normalizeNullableText($data['supporto_fisico'] ?? null),
- 'modello_etichetta' => $this->normalizeNullableText($data['modello_etichetta'] ?? null),
- 'busta_numero' => $this->normalizeNullableText($data['busta_numero'] ?? null),
- 'fascicolo_numero' => $this->normalizeNullableText($data['fascicolo_numero'] ?? null),
+ 'classe' => $archivioClasse !== '' ? $archivioClasse : null,
+ 'classe_label' => $this->getArchivioClasseOptions()[$archivioClasse] ?? null,
+ 'supporto_fisico' => $this->normalizeNullableText($data['supporto_fisico'] ?? null),
+ 'modello_etichetta' => $this->normalizeNullableText($data['modello_etichetta'] ?? null),
+ 'busta_numero' => $this->normalizeNullableText($data['busta_numero'] ?? null),
+ 'fascicolo_numero' => $this->normalizeNullableText($data['fascicolo_numero'] ?? null),
'contenitore_numero' => $this->normalizeNullableText($data['contenitore_numero'] ?? null),
- 'periodo_da' => $data['periodo_riferimento_da'] ?? null,
- 'periodo_a' => $data['periodo_riferimento_a'] ?? null,
- 'codice_etichetta' => $archiveReference,
- 'qr_ready' => true,
- 'nfc_ready' => true,
+ 'periodo_da' => $data['periodo_riferimento_da'] ?? null,
+ 'periodo_a' => $data['periodo_riferimento_a'] ?? null,
+ 'codice_etichetta' => $archiveReference,
+ 'qr_ready' => true,
+ 'nfc_ready' => true,
],
'visibility_scope' => (string) ($data['visibility_scope'] ?? 'interno'),
'visibility_roles' => $this->normalizeStringArray($data['visibility_roles'] ?? []),
@@ -1807,18 +1831,18 @@ private function generateProtocollo(string $categoria, int $year): string
private function buildArchiveReference(int $stabileId, string $categoria, int $year, array $data): string
{
- $stabile = Stabile::query()->find($stabileId);
+ $stabile = Stabile::query()->find($stabileId);
$mnemonic = $this->mnemonicCodeHint;
if (! $mnemonic && $stabile instanceof Stabile) {
- $label = Str::upper((string) ($stabile->denominazione ?? 'STABILE'));
- $letters = preg_replace('/[^A-Z]/', '', Str::ascii($label)) ?: 'STB';
- $digits = preg_replace('/\D/', '', $label);
+ $label = Str::upper((string) ($stabile->denominazione ?? 'STABILE'));
+ $letters = preg_replace('/[^A-Z]/', '', Str::ascii($label)) ?: 'STB';
+ $digits = preg_replace('/\D/', '', $label);
$mnemonic = str_pad(substr($letters, 0, 3), 3, 'X') . str_pad(substr($digits !== '' ? $digits : (string) $stabile->id, -5), 5, '0', STR_PAD_LEFT);
}
$contenitore = $this->normalizeNullableText($data['contenitore_numero'] ?? $data['faldone'] ?? null) ?: '00';
- $fascicolo = $this->normalizeNullableText($data['fascicolo_numero'] ?? null) ?: '00/' . $year;
+ $fascicolo = $this->normalizeNullableText($data['fascicolo_numero'] ?? null) ?: '00/' . $year;
return implode(' · ', array_filter([
$mnemonic ?: 'STB00000',
@@ -1846,8 +1870,8 @@ private function buildDocumentStorageFilename(string $categoria, mixed $dataDocu
? ($fornitore !== '' ? $fornitore : $titolo)
: $titolo;
- $safeLabel = trim((string) Str::of($sourceLabel)->ascii()->replaceMatches('/[^A-Za-z0-9]+/', ' ')->squish());
- $safeLabel = str_replace(' ', '_', Str::limit($safeLabel !== '' ? $safeLabel : 'documento', 60, ''));
+ $safeLabel = trim((string) Str::of($sourceLabel)->ascii()->replaceMatches('/[^A-Za-z0-9]+/', ' ')->squish());
+ $safeLabel = str_replace(' ', '_', Str::limit($safeLabel !== '' ? $safeLabel : 'documento', 60, ''));
$safeProtocollo = str_replace(['/', ' '], '-', trim($protocollo));
if ($categoria === 'fattura') {
diff --git a/app/Http/Controllers/Filament/DocumentiPrintController.php b/app/Http/Controllers/Filament/DocumentiPrintController.php
index ce50381..676fb0d 100644
--- a/app/Http/Controllers/Filament/DocumentiPrintController.php
+++ b/app/Http/Controllers/Filament/DocumentiPrintController.php
@@ -164,9 +164,19 @@ public function etichettaArchivioFisico(Request $request, DocumentoArchivioFisic
abort(403);
}
- $format = $request->query('format', '11354');
- $format = in_array($format, ['11354', '99014'], true) ? $format : '11354';
- $defaults = $this->getDymoDefaultsForUser($format);
+ $format = $request->query('format', '11354');
+ $format = in_array($format, ['11354', '99014'], true) ? $format : '11354';
+ $labelPrinterMode = $request->boolean('autoprint')
+ || $request->has('dymo_fix')
+ || $request->has('dymo_rot')
+ || $request->has('dymo_dx')
+ || $request->has('dymo_dy');
+ $defaults = $labelPrinterMode ? $this->getDymoDefaultsForUser($format) : [
+ 'fix' => false,
+ 'rot' => 0,
+ 'dx' => 0.0,
+ 'dy' => 0.0,
+ ];
$dymoFix = $request->query('dymo_fix');
if ($dymoFix === null) {
@@ -181,24 +191,38 @@ public function etichettaArchivioFisico(Request $request, DocumentoArchivioFisic
$dymoDx = $request->has('dymo_dx') ? (float) $request->query('dymo_dx') : (float) ($defaults['dx'] ?? 0);
$dymoDy = $request->has('dymo_dy') ? (float) $request->query('dymo_dy') : (float) ($defaults['dy'] ?? 0);
+ if ($format === '11354' && $dymoFix) {
+ if (! in_array($dymoRot, [-90, 90], true)) {
+ $dymoRot = -90;
+ }
+ } else {
+ if (! in_array($dymoRot, [-180, -90, 0, 90, 180], true)) {
+ $dymoRot = 0;
+ }
+ }
+
+ $dymoDx = max(-15.0, min(15.0, $dymoDx));
+ $dymoDy = max(-15.0, min(15.0, $dymoDy));
+
return view('filament.print.etichetta-archivio-fisico', [
- 'item' => $item->load(['parent', 'children', 'stabile', 'documento']),
- 'format' => $format,
- 'dymoFix' => $dymoFix,
- 'dymoRot' => $dymoRot,
- 'dymoDx' => $dymoDx,
- 'dymoDy' => $dymoDy,
- 'publicUrl' => $item->qr_code_data,
+ 'item' => $item->load(['parent', 'children', 'stabile', 'documento']),
+ 'format' => $format,
+ 'labelPrinterMode' => $labelPrinterMode,
+ 'dymoFix' => $dymoFix,
+ 'dymoRot' => $dymoRot,
+ 'dymoDx' => $dymoDx,
+ 'dymoDy' => $dymoDy,
+ 'publicUrl' => $item->buildPublicQrUrl(),
]);
}
public function showPublicArchivioFisicoItem(Request $request, DocumentoArchivioFisicoItem $item)
{
- if (! $request->hasValidSignature()) {
+ if (! $request->hasValidSignature(false)) {
abort(403);
}
- $chain = collect();
+ $chain = collect();
$current = $item;
while ($current instanceof DocumentoArchivioFisicoItem) {
$chain->prepend($current);
@@ -206,7 +230,7 @@ public function showPublicArchivioFisicoItem(Request $request, DocumentoArchivio
}
return view('filament.pages.strumenti.archivio-fisico-show', [
- 'item' => $item->load(['children.children', 'stabile', 'documento', 'parent']),
+ 'item' => $item->load(['children.children', 'stabile', 'documento', 'parent']),
'chain' => $chain,
]);
}
@@ -301,7 +325,7 @@ private function buildWatermarkedPdf(string $inputPath, Documento $documento): ?
@unlink($outputPath);
$postScript = '<< /BeginPage { gsave 0.90 setgray /Helvetica-Bold findfont 14 scalefont setfont 140 90 translate 38 rotate 0 0 moveto ('
- . $this->escapePostScriptString($watermarkText)
+ . $this->escapePostScriptString($watermarkText)
. ') show grestore } >> setpagedevice';
$process = new Process([
@@ -332,7 +356,7 @@ private function buildWatermarkedPdf(string $inputPath, Documento $documento): ?
private function buildWatermarkText(Documento $documento): string
{
$archiveReference = trim((string) ($documento->archive_reference ?? ''));
- $meta = is_array($documento->metadati_archivio ?? null) ? $documento->metadati_archivio : [];
+ $meta = is_array($documento->metadati_archivio ?? null) ? $documento->metadati_archivio : [];
$physicalParts = array_filter([
trim((string) ($meta['supporto_fisico'] ?? '')),
diff --git a/app/Models/DocumentoArchivioFisicoItem.php b/app/Models/DocumentoArchivioFisicoItem.php
index 6771b34..35b9f91 100644
--- a/app/Models/DocumentoArchivioFisicoItem.php
+++ b/app/Models/DocumentoArchivioFisicoItem.php
@@ -1,5 +1,4 @@
'date',
- 'sort_order' => 'integer',
- 'metadati' => 'array',
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
+ 'sort_order' => 'integer',
+ 'metadati' => 'array',
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
];
public const TIPI = [
- 'documento' => 'Documento cartaceo',
- 'busta_trasparente' => 'Busta trasparente con anelli da archiviare',
+ 'documento' => 'Documento cartaceo',
+ 'busta_trasparente' => 'Busta trasparente con anelli da archiviare',
'cartella_tre_lembi' => 'Cartella a tre lembi',
- 'faldone_anelli' => 'Faldone con anelli',
- 'faldone_lacci' => 'Faldone con lacci',
- 'scatola' => 'Scatola',
+ 'faldone_anelli' => 'Faldone con anelli',
+ 'faldone_lacci' => 'Faldone con lacci',
+ 'scatola' => 'Scatola',
];
public function stabile(): BelongsTo
@@ -94,7 +93,7 @@ public function getTipoLabelAttribute(): string
public function getPercorsoFisicoAttribute(): string
{
- $parts = [];
+ $parts = [];
$current = $this;
while ($current instanceof self) {
@@ -107,15 +106,15 @@ public function getPercorsoFisicoAttribute(): string
public function getQrCodeImageAttribute(): string
{
- $data = trim((string) $this->qr_code_data);
+ $data = $this->buildPublicQrUrl();
if ($data !== '' && class_exists(\chillerlan\QRCode\QROptions::class) && class_exists(\chillerlan\QRCode\QRCode::class)) {
$options = new \chillerlan\QRCode\QROptions([
- 'outputType' => \chillerlan\QRCode\QRCode::OUTPUT_MARKUP_SVG,
- 'eccLevel' => \chillerlan\QRCode\QRCode::ECC_M,
- 'addQuietzone' => true,
+ 'outputType' => \chillerlan\QRCode\QRCode::OUTPUT_MARKUP_SVG,
+ 'eccLevel' => \chillerlan\QRCode\QRCode::ECC_M,
+ 'addQuietzone' => true,
'quietzoneSize' => 1,
- 'connectPaths' => true,
+ 'connectPaths' => true,
]);
$svg = (new \chillerlan\QRCode\QRCode($options))->render($data);
@@ -142,11 +141,11 @@ public function getQrCodeImageAttribute(): string
public static function generateCodice(int $stabileId): string
{
- $prefix = 'AF-' . $stabileId . '-';
+ $prefix = 'AF-' . $stabileId . '-';
$sequence = 1;
do {
- $code = $prefix . str_pad((string) $sequence, 4, '0', STR_PAD_LEFT);
+ $code = $prefix . str_pad((string) $sequence, 4, '0', STR_PAD_LEFT);
$exists = self::query()->where('codice_univoco', $code)->exists();
$sequence++;
} while ($exists);
@@ -156,15 +155,26 @@ public static function generateCodice(int $stabileId): string
public function refreshQrCodeData(): void
{
- $url = URL::temporarySignedRoute(
+ $this->forceFill([
+ 'qr_code_data' => $this->buildPublicQrUrl(),
+ ])->saveQuietly();
+ }
+
+ public function buildPublicQrUrl(): string
+ {
+ $relativeSignedPath = URL::temporarySignedRoute(
'public.archivio-fisico.show',
now()->addYears(5),
- ['item' => $this->id]
+ ['item' => $this->id],
+ false,
);
- $this->forceFill([
- 'qr_code_data' => $url,
- ])->saveQuietly();
+ $baseUrl = rtrim((string) config('app.public_url', config('app.url')), '/');
+ if ($baseUrl === '') {
+ return $relativeSignedPath;
+ }
+
+ return $baseUrl . '/' . ltrim($relativeSignedPath, '/');
}
protected static function booted(): void
diff --git a/app/Providers/Filament/AdminFilamentPanelProvider.php b/app/Providers/Filament/AdminFilamentPanelProvider.php
index 8288869..85c42dc 100644
--- a/app/Providers/Filament/AdminFilamentPanelProvider.php
+++ b/app/Providers/Filament/AdminFilamentPanelProvider.php
@@ -60,7 +60,7 @@ public function panel(Panel $panel): Panel
$user = Auth::user();
return $user instanceof User
- && $user->hasAnyRole(['super-admin', 'admin', 'amministratore', 'collaboratore']);
+ && $user->hasAnyRole(['super-admin', 'admin', 'amministratore', 'collaboratore']);
}),
NavigationItem::make('Cellulare / WebApp')
->group('NetGescon')
@@ -70,7 +70,7 @@ public function panel(Panel $panel): Panel
$user = Auth::user();
return $user instanceof User
- && $user->hasAnyRole(['super-admin', 'admin', 'amministratore', 'collaboratore']);
+ && $user->hasAnyRole(['super-admin', 'admin', 'amministratore', 'collaboratore']);
}),
NavigationItem::make('Ticket Mobile')
->group('NetGescon')
@@ -80,7 +80,7 @@ public function panel(Panel $panel): Panel
$user = Auth::user();
return $user instanceof User
- && $user->hasAnyRole(['super-admin', 'admin', 'amministratore', 'collaboratore']);
+ && $user->hasAnyRole(['super-admin', 'admin', 'amministratore', 'collaboratore']);
}),
NavigationItem::make('Scheda Stabile')
->group('NetGescon')
@@ -90,7 +90,7 @@ public function panel(Panel $panel): Panel
$user = Auth::user();
return $user instanceof User
- && $user->hasAnyRole(['super-admin', 'admin', 'amministratore', 'collaboratore']);
+ && $user->hasAnyRole(['super-admin', 'admin', 'amministratore', 'collaboratore']);
}),
NavigationItem::make('Catalogo Fornitore')
->group('Fornitore')
@@ -102,8 +102,8 @@ public function panel(Panel $panel): Panel
return $user instanceof User && $user->hasRole('fornitore');
}),
])
- ->discoverResources(in: app_path('Filament/Resources'), for : 'App\\Filament\\Resources')
- ->discoverPages(in: app_path('Filament/Pages'), for : 'App\\Filament\\Pages')
+ ->discoverResources(in: app_path('Filament/Resources'), for: 'App\\Filament\\Resources')
+ ->discoverPages(in: app_path('Filament/Pages'), for: 'App\\Filament\\Pages')
->pages([
Dashboard::class,
SupportoDashboard::class,
@@ -111,7 +111,7 @@ public function panel(Panel $panel): Panel
PrimaNotaModifica::class,
ContoMastrino::class,
])
- ->discoverWidgets(in: app_path('Filament/Widgets'), for : 'App\\Filament\\Widgets')
+ ->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\\Filament\\Widgets')
->widgets([
AccountWidget::class,
TicketMobileOverview::class,
@@ -171,4 +171,4 @@ protected function resolveSupplierCatalogUrl(): string
return TicketOperativi::getUrl(panel: 'admin-filament');
}
-}
\ No newline at end of file
+}
diff --git a/config/app.php b/config/app.php
index 3423674..49335df 100755
--- a/config/app.php
+++ b/config/app.php
@@ -37,6 +37,8 @@
'url' => env('APP_URL', 'http://localhost'),
+ 'public_url' => env('APP_PUBLIC_URL', env('APP_URL', 'http://localhost')),
+
'asset_url' => env('ASSET_URL'),
/*
diff --git a/docs/DOCUMENTI-NFC-E-ACQUISIZIONE.md b/docs/DOCUMENTI-NFC-E-ACQUISIZIONE.md
index 5f80e60..2bf2af6 100644
--- a/docs/DOCUMENTI-NFC-E-ACQUISIZIONE.md
+++ b/docs/DOCUMENTI-NFC-E-ACQUISIZIONE.md
@@ -53,6 +53,12 @@ ## Archivio fisico ed etichette
- stampa etichette nei formati `DYMO 11354` e `DYMO 99014`;
- pagina pubblica firmata per dettaglio contenitore o documento tramite QR.
+Taratura operativa corrente:
+
+- `11354`: layout orizzontale principale con correzione verticale leggera verso l'alto;
+- `11354 verticale`: variante dedicata ai driver che ruotano l'etichetta, ora con rotazione corretta lato stampa;
+- `99014`: QR spostato in basso a destra per liberare spazio scrivibile nella parte alta.
+
Per i documenti digitali resta disponibile anche l'assegnazione dei metadati fisici principali:
- supporto fisico;
@@ -75,6 +81,26 @@ ## QR locale sulle etichette
Questo elimina la dipendenza da URL esterni per il QR e rende piu stabile il preview di stampa.
+## QR pubblico e dominio esterno
+
+Il QR dell'archivio fisico non deve piu dipendere dall'IP interno del server.
+
+Implementazione attuale:
+
+- la firma della route pubblica viene generata in forma relativa;
+- il link finale viene costruito usando `APP_PUBLIC_URL`, con fallback su `APP_URL`;
+- la validazione avviene lato controller con firma relativa, cosi il QR resta valido anche dietro dominio pubblico o reverse proxy.
+
+Configurazione richiesta in ambiente:
+
+1. impostare `APP_PUBLIC_URL` con il dominio realmente raggiungibile dall'esterno;
+2. lasciare `APP_URL` per il contesto applicativo interno se serve;
+3. rigenerare o aggiornare i QR gia salvati solo se si vuole riallineare anche il dato persistito nel database.
+
+Esempio:
+
+- `APP_PUBLIC_URL=https://netgescon.example.it`
+
## Stampa PDF e watermark archivio
Per i documenti PDF sono ora previste due aperture distinte dalla tab archivio:
@@ -208,6 +234,24 @@ ## Scanner Epson da pagina web
2. upload/ingestione rapida in NetGescon;
3. OCR e archiviazione automatica.
+Per il modello Epson WF-C5710 la direzione pratica da testare non e il browser puro, ma una di queste due:
+
+- scansione verso cartella di rete osservata da NetGescon;
+- piccolo bridge locale o di rete che espone una chiamata HTTP interna e usa il canale scanner disponibile sul dispositivo.
+
+Questo evita il vincolo dei browser su TWAIN/WIA e mantiene il flusso pilotabile dalla pagina archivio.
+
+## Archivio digitale
+
+La vista `Strumenti > Documenti > Archivio digitale` e stata alleggerita per lavorare meglio dentro la cartella corrente.
+
+Stato attuale:
+
+- breadcrumb e cartelle restano in alto;
+- la tabella documenti ora usa tutta la larghezza utile;
+- le informazioni laterali sono state compattate in tre card sintetiche sopra la tabella;
+- la pagina mostra nome cartella attiva, numero documenti del livello e stato operativo digitale/fisico.
+
## Dymo LAN 11354
Domani si puo provare una stampa etichetta su rete con formato `11354` usando:
diff --git a/resources/views/filament/pages/strumenti/documenti-archivio.blade.php b/resources/views/filament/pages/strumenti/documenti-archivio.blade.php
index dec6724..aabd210 100644
--- a/resources/views/filament/pages/strumenti/documenti-archivio.blade.php
+++ b/resources/views/filament/pages/strumenti/documenti-archivio.blade.php
@@ -283,24 +283,26 @@ class="rounded-2xl border border-slate-200 bg-white p-4 text-left shadow-sm tran
@endforelse
-
-
- {{ $this->table }}
+
+
+
Cartella attiva
+
{{ $this->digitalArchiveCurrentFolder?->nome ?? 'Nessuna cartella selezionata' }}
+
{{ $this->digitalArchiveCurrentFolderHint }}
-
-
-
Flusso digitale e fisico
-
Usa l'icona archivio per assegnare contenitore, busta, fascicolo ed etichetta del documento cartaceo. La posizione verra poi richiamata anche nel watermark PDF.
-
-
-
Stampa
-
Icona stampante: PDF senza timbro. Icona duplicato: PDF con watermark archivio digitale e fisico, se la codifica e presente.
-
-
-
Scanner
-
La struttura attuale e pronta per il prossimo aggancio scanner: acquisizione PDF, naming ordinato, assegnazione immediata a cartella digitale e posizione fisica.
-
+
+
Documenti nel livello
+
{{ $this->digitalArchiveCurrentFolderDocumentCount }}
+
Solo fatture PDF collegate alla cartella corrente.
+
+
Operatività
+
Archivio digitale e fisico allineati
+
Da qui puoi aprire, stampare, watermarkare e assegnare subito la collocazione cartacea.
+
+
+
+
+ {{ $this->table }}
@@ -509,8 +511,9 @@ class="rounded-2xl border border-slate-200 bg-white p-4 text-left shadow-sm tran
@endif
diff --git a/resources/views/filament/print/etichetta-archivio-fisico.blade.php b/resources/views/filament/print/etichetta-archivio-fisico.blade.php
index 26cd11d..6a91d9a 100644
--- a/resources/views/filament/print/etichetta-archivio-fisico.blade.php
+++ b/resources/views/filament/print/etichetta-archivio-fisico.blade.php
@@ -10,17 +10,60 @@
@php($dymoDx = isset($dymoDx) ? (float) $dymoDx : 0.0)
@php($dymoDy = isset($dymoDy) ? (float) $dymoDy : 0.0)
@php($autoPrint = request()->has('autoprint') && filter_var(request()->query('autoprint'), FILTER_VALIDATE_BOOL))
+ @php($labelPrinterMode = isset($labelPrinterMode) ? (bool) $labelPrinterMode : false)
+ @php($pageWidth = $fmt === '99014' ? '54mm' : '57mm')
+ @php($pageHeight = $fmt === '99014' ? '101mm' : '32mm')
@@ -76,27 +184,39 @@
@endif
-
-
-
-
{{ $item->codice_univoco }}
-
{{ $item->titolo }}
-