Files
termanager2/resources/views/pdf/registro-s13.blade.php
2026-07-28 17:31:00 +02:00

198 lines
7.7 KiB
PHP

{{--
Modulo S-13-I — Registrazione delle assegnazioni del territorio.
Ricostruzione fedele del modulo ufficiale, la cui copia è in
resources/pdf/S-13_I.pdf e va usata come matrice per qualsiasi modifica
alla griglia. Il modulo originale è un PDF 1.7 con font CID embeddati:
sovrapporvi testo richiederebbe il parser a pagamento di FPDI, mentre
dompdf è già in uso per gli altri export del progetto.
Struttura per pagina: 21 blocchi-territorio, ognuno su due righe — quella
alta ospita i nomi dei proclamatori, quella bassa le date. Le colonne
"Terr. N." e "Restituito l'ultima volta il" occupano entrambe le righe.
Il motore CSS di dompdf non è un browser: le larghezze stanno in <colgroup>
(con i soli colspan sarebbero ripartite a caso) e l'interruzione di pagina è
decisa dall'indice del ciclo, perché il supporto a :last-child non è
garantito e un foglio bianco in coda sarebbe visibile.
--}}
@php
/**
* Il nome del proclamatore deve stare su una riga: le righe hanno altezza
* fissa e la cella è nowrap, quindi mandare a capo sfonderebbe la griglia.
* Invece di andare a capo si scala il corpo.
*
* Larghezza utile della cella ~34.8mm (due colonne meno il padding).
* DejaVu Sans occupa in media 0.52em per carattere, cioè ~0.1835mm per
* carattere per punto di corpo: da lì il corpo massimo che entra.
*
* Sotto i 4.5pt il testo non sarebbe più leggibile, quindi oltre i 42
* caratteri si tronca — l'ellissi rende visibile l'accorciamento, mentre
* un nome che deborda corromperebbe la griglia in silenzio.
*/
$LARGHEZZA_CELLA_MM = 34.8;
$MM_PER_CARATTERE_PER_PUNTO = 0.1835;
$CORPO_MAX_PT = 8.0;
$CORPO_MIN_PT = 4.5;
$maxCaratteri = (int) floor($LARGHEZZA_CELLA_MM / ($CORPO_MIN_PT * $MM_PER_CARATTERE_PER_PUNTO));
$nomeTroncato = static fn (string $nome): string => mb_strlen($nome) > $maxCaratteri
? mb_substr($nome, 0, $maxCaratteri - 1) . '…'
: $nome;
$nomeFontSize = static function (string $nome) use ($LARGHEZZA_CELLA_MM, $MM_PER_CARATTERE_PER_PUNTO, $CORPO_MAX_PT, $CORPO_MIN_PT): string {
$len = mb_strlen($nome);
if ($len === 0) {
return $CORPO_MAX_PT . 'pt';
}
$pt = $LARGHEZZA_CELLA_MM / ($len * $MM_PER_CARATTERE_PER_PUNTO);
return round(max($CORPO_MIN_PT, min($CORPO_MAX_PT, $pt)), 1) . 'pt';
};
$ultimaPagina = $pagine->count() - 1;
@endphp
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="utf-8">
<title>S-13 — Registrazione delle assegnazioni del territorio</title>
<style>
/* dompdf riporta i margini di @page sull'elemento body, quindi il
reset universale qui sotto li azzererebbe: vanno ridichiarati su
body, che per specificità vince su "*". Tenere i due valori
allineati — è @page a definire l'area utile, body a farla
sopravvivere al reset.
I margini laterali sono i più larghi perché sono quelli che si
vedono; in verticale si sta stretti, il foglio pieno misura ~266mm
e ne restano 273. Alzando questi valori, o gli spazi sotto il
titolo e sopra il codice, il piè di pagina scivola su una pagina
nuova e ogni foglio ne occupa due: rimisurare dopo ogni modifica. */
@page { margin: 14mm 16mm 10mm 16mm; }
* { margin: 0; padding: 0; }
body {
margin: 14mm 16mm 10mm 16mm;
font-family: "DejaVu Sans", sans-serif;
color: #000;
}
.interrompi { page-break-after: always; }
h1 {
font-size: 13pt;
font-weight: bold;
text-align: center;
letter-spacing: 0.2pt;
margin-bottom: 6mm;
}
.anno {
font-size: 10pt;
font-weight: bold;
margin-bottom: 3mm;
}
.anno .valore {
display: inline-block;
width: 32mm;
border-bottom: 1px solid #000;
text-align: center;
font-weight: normal;
padding-bottom: 0.4mm;
}
table {
width: 100%;
border-collapse: collapse;
border: 1.6pt solid #000;
}
td, th {
border: 0.5pt solid #000;
text-align: center;
vertical-align: middle;
}
/* Intestazione */
thead th { font-weight: normal; padding: 0.5mm 0.5mm; }
th.terr { font-size: 7.5pt; line-height: 1.15; }
/* 6.2pt e non di più: a 6.6pt "l'ultima volta il*" non entra nei
~21mm utili della colonna e l'intestazione passa da due righe a tre,
allontanandosi dal modulo originale. */
th.restituito { font-size: 6.2pt; line-height: 1.15; white-space: nowrap; }
th.assegnato-a { font-size: 8pt; }
th.sotto { font-size: 6.4pt; }
/* Corpo */
tr.riga-nome td { height: 6mm; }
tr.riga-date td { height: 4mm; }
td.numero { font-size: 9.5pt; font-weight: bold; }
td.rientro-prec { font-size: 7.5pt; }
td.data { font-size: 7.5pt; }
td.nome { line-height: 1.1; padding: 0 0.6mm; white-space: nowrap; }
.nota { font-size: 7.4pt; margin-top: 1.6mm; }
.codice { font-size: 8pt; margin-top: 3mm; }
</style>
</head>
<body>
@foreach($pagine as $indice => $righe)
<div @if($indice < $ultimaPagina) class="interrompi" @endif>
<h1>REGISTRAZIONE DELLE ASSEGNAZIONI DEL TERRITORIO</h1>
<div class="anno">Anno di servizio: <span class="valore">{{ $annoLabel }}</span></div>
<table>
<colgroup>
<col style="width:6.5%">
<col style="width:12.5%">
@for($c = 0; $c < 8; $c++)
<col style="width:10.125%">
@endfor
</colgroup>
<thead>
<tr>
<th class="terr" rowspan="2">Terr.<br>N.</th>
<th class="restituito" rowspan="2">Restituito<br>l&rsquo;ultima volta il*</th>
@for($g = 0; $g < 4; $g++)
<th class="assegnato-a" colspan="2">Assegnato a</th>
@endfor
</tr>
<tr>
@for($g = 0; $g < 4; $g++)
<th class="sotto">Assegnato il</th>
<th class="sotto">Restituito il</th>
@endfor
</tr>
</thead>
<tbody>
@foreach($righe as $riga)
<tr class="riga-nome">
<td class="numero" rowspan="2">{{ $riga['numero'] }}</td>
<td class="rientro-prec" rowspan="2">{{ $riga['rientro_precedente'] }}</td>
@foreach($riga['assegnazioni'] as $a)
@php($nome = $nomeTroncato($a['nome']))
<td class="nome" colspan="2" style="font-size:{{ $nomeFontSize($nome) }}">{{ $nome }}</td>
@endforeach
</tr>
<tr class="riga-date">
@foreach($riga['assegnazioni'] as $a)
<td class="data">{{ $a['assegnato_il'] }}</td>
<td class="data">{{ $a['restituito_il'] }}</td>
@endforeach
</tr>
@endforeach
</tbody>
</table>
<div class="nota">*Quando si inizia un nuovo foglio, registrare in questa colonna l&rsquo;ultima data in cui &egrave; stato restituito ogni territorio.</div>
<div class="codice">S-13-I&nbsp;&nbsp;1/22</div>
</div>
@endforeach
</body>
</html>