netgescon-day0/resources/views/filament/print/etichetta-documento.blade.php

261 lines
10 KiB
PHP

<!doctype html>
<html lang="it">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Etichetta Documento</title>
@php($fmt = in_array(($format ?? '11354'), ['11354','99014'], true) ? $format : '11354')
@php($dymoFix = isset($dymoFix) ? (bool) $dymoFix : false)
@php($dymoRot = isset($dymoRot) && in_array((int) $dymoRot, [-90, 90], true) ? (int) $dymoRot : -90)
@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($showMarks = request()->has('marks') && filter_var(request()->query('marks'), FILTER_VALIDATE_BOOL))
<style>
/*
* IMPORTANT: senza una @page size esplicita, molti browser/stampanti
* “adattano” l'etichetta a un foglio (A4/Letter) e la stampano minuscola.
*/
@page {
margin: 0;
size: {{ $fmt === '99014' ? '54mm 101mm' : '57mm 32mm' }};
}
html, body {
margin: 0;
padding: 0;
width: {{ $fmt === '99014' ? '54mm' : '57mm' }};
height: {{ $fmt === '99014' ? '101mm' : '32mm' }};
font-family: Arial, Helvetica, sans-serif;
overflow: hidden;
}
/*
* Formati:
* - 11354: 57x32mm
* - 99014: 54x101mm
*/
.label {
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: space-between;
overflow: hidden;
position: relative;
break-inside: avoid;
break-after: avoid-page;
page-break-inside: avoid;
page-break-after: avoid;
}
.label.format-11354 { width: 57mm; height: 32mm; padding: 0; }
.label.format-99014 { width: 54mm; height: 101mm; padding: 4mm; }
.label-content {
box-sizing: border-box;
width: 100%;
height: 100%;
padding: {{ $fmt === '99014' ? '2.8mm' : '2.0mm' }};
display: flex;
flex-direction: column;
justify-content: space-between;
position: relative;
z-index: 2;
}
/* Segnalini calibrazione (opzionali): attiva con ?marks=1 */
.marks {
position: absolute;
inset: 0;
pointer-events: none;
z-index: 1;
opacity: 0.28;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
.marks .border {
position: absolute;
inset: 0;
border: 0.35mm solid #000;
box-sizing: border-box;
}
.marks .corner {
position: absolute;
width: 6mm;
height: 6mm;
box-sizing: border-box;
border: 0.55mm solid #000;
}
.marks .corner.tl { left: 0; top: 0; border-right: 0; border-bottom: 0; }
.marks .corner.tr { right: 0; top: 0; border-left: 0; border-bottom: 0; }
.marks .corner.bl { left: 0; bottom: 0; border-right: 0; border-top: 0; }
.marks .corner.br { right: 0; bottom: 0; border-left: 0; border-top: 0; }
.marks .cross {
position: absolute;
left: 50%;
top: 50%;
width: 0;
height: 0;
}
.marks .cross::before,
.marks .cross::after {
content: '';
position: absolute;
background: #000;
}
.marks .cross::before { width: 18mm; height: 0.6mm; left: -9mm; top: -0.3mm; }
.marks .cross::after { width: 0.6mm; height: 18mm; left: -0.3mm; top: -9mm; }
.marks .grid {
position: absolute;
inset: 0;
background-image:
repeating-linear-gradient(0deg, rgba(0,0,0,0.08), rgba(0,0,0,0.08) 0.2mm, transparent 0.2mm, transparent 1mm),
repeating-linear-gradient(90deg, rgba(0,0,0,0.08), rgba(0,0,0,0.08) 0.2mm, transparent 0.2mm, transparent 1mm),
repeating-linear-gradient(0deg, rgba(0,0,0,0.18), rgba(0,0,0,0.18) 0.35mm, transparent 0.35mm, transparent 5mm),
repeating-linear-gradient(90deg, rgba(0,0,0,0.18), rgba(0,0,0,0.18) 0.35mm, transparent 0.35mm, transparent 5mm);
}
.marks .legend {
position: absolute;
left: 1.2mm;
top: 1.2mm;
font-size: 8px;
line-height: 1.1;
background: rgba(255,255,255,0.85);
border: 0.2mm solid rgba(0,0,0,0.35);
padding: 0.6mm 0.8mm;
color: #000;
max-width: calc(100% - 2.4mm);
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.row { display: flex; justify-content: space-between; gap: 8px; }
.title { font-size: 12px; font-weight: 800; line-height: 1.1; }
.meta { font-size: 9px; color: #222; line-height: 1.15; }
.code { font-size: 10px; font-weight: 800; letter-spacing: .4px; }
.small { font-size: 8px; color: #444; }
.divider { border-top: 1px solid #000; margin: 1.5mm 0; }
.format-99014 .title { font-size: 18px; }
.format-99014 .meta { font-size: 12px; }
.format-99014 .code { font-size: 14px; }
.format-99014 .small { font-size: 10px; }
@media print {
.no-print { display: none; }
/* Evita "seconda pagina" dovuta a arrotondamenti mm->px in alcuni browser */
html, body { width: 100%; height: 100%; overflow: hidden; }
.label { position: fixed; left: 0; top: 0; }
/* Default calibration offsets (works for 99014 and for 11354 when DYMO workaround is OFF) */
@if(!($fmt === '11354' && $dymoFix) && (abs($dymoDx) > 0.001 || abs($dymoDy) > 0.001))
.label-content {
transform: translateX({{ $dymoDx }}mm) translateY({{ $dymoDy }}mm);
transform-origin: top left;
}
@endif
/*
* DYMO 11354 workaround:
* alcuni driver ruotano automaticamente il job. Per ottenere una stampa
* orizzontale a piena larghezza, impostiamo la pagina a 32x57 e ruotiamo
* dentro una grafica 57x32.
*/
@if($fmt === '11354' && $dymoFix)
@page { size: 32mm 57mm; }
html, body { width: 32mm; height: 57mm; }
.label.format-11354 { width: 32mm; height: 57mm; }
.label.format-11354 .label-content {
width: 57mm;
height: 32mm;
transform-origin: top left;
@if($dymoRot === -90)
/* Offsets in page coords (mm) to correct DYMO driver shifts */
transform: translateX({{ $dymoDx }}mm) translateY({{ $dymoDy }}mm) translateY(57mm) rotate(-90deg);
@else
transform: translateX({{ $dymoDx }}mm) translateY({{ $dymoDy }}mm) translateX(32mm) rotate(90deg);
@endif
}
@endif
}
</style>
@if($autoPrint)
<script>
window.addEventListener('load', () => {
setTimeout(() => {
try { window.print(); } catch (e) {}
}, 80);
});
window.onafterprint = () => {
// Return to Filament page without opening a new window.
try { window.history.back(); } catch (e) {}
};
</script>
@endif
</head>
<body>
<div class="label format-{{ $fmt }}">
@if($showMarks)
<div class="marks">
<div class="grid"></div>
<div class="border"></div>
<div class="corner tl"></div>
<div class="corner tr"></div>
<div class="corner bl"></div>
<div class="corner br"></div>
<div class="cross"></div>
<div class="legend">
{{ $fmt }} · fix={{ $dymoFix ? '1' : '0' }} · rot={{ (int) $dymoRot }} · dx={{ number_format($dymoDx, 2, '.', '') }} · dy={{ number_format($dymoDy, 2, '.', '') }}
</div>
</div>
@endif
<div class="label-content">
<div>
<div class="row">
<div class="title">{{ $codiceUnico ?? ($protocollo ?? '') }}</div>
<div class="meta" style="text-align:right;">
<div>{{ strtoupper((string) ($documento->tipologia ?? 'DOC')) }}</div>
<div>{{ $anno ?? now()->format('Y') }}</div>
</div>
</div>
<div class="meta" style="margin-top: 1mm;">
<div><strong>Protocollo:</strong> {{ $protocollo ?? ($documento->numero_protocollo ?: '—') }}</div>
@if(!empty($documento->nome))
<div><strong>Titolo:</strong> {{ $documento->nome }}</div>
@endif
@if(!empty($faldone))
<div><strong>Faldone:</strong> {{ $faldone }}</div>
@endif
</div>
<div class="divider"></div>
<div class="row">
<div class="code">DOC-{{ (int) $documento->id }}</div>
@if($documento->data_scadenza)
<div class="small" style="text-align:right;">
<div><strong>Scad.:</strong> {{ \Carbon\Carbon::parse($documento->data_scadenza)->format('d-m-Y') }}</div>
</div>
@endif
</div>
<div class="small">Apri PDF: {{ $openUrl ?? '' }}</div>
</div>
@if(! $autoPrint)
<div class="no-print" style="padding-top: 6px;">
<button onclick="window.print()">Stampa</button>
<button onclick="window.close()">Chiudi</button>
</div>
@endif
</div>
</body>
</html>