- Ajout page infrastructure/bovine avec CRUD - Refacto BuildingCase (suppression Statut, simplification) - Commande EnrichBovinesCommand pour enrichir les données bovins - 4 migrations Doctrine - Mise à jour composables shipment/weighing - Mise à jour README et CHANGELOG Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
372 lines
12 KiB
Twig
372 lines
12 KiB
Twig
<!doctype html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<style>
|
|
/* =========================
|
|
DOMPDF FRIENDLY SETTINGS
|
|
========================= */
|
|
@page { size: A4 landscape; }
|
|
|
|
html, body {
|
|
margin: 0;
|
|
padding: 6mm;
|
|
font-family: Helvetica, sans-serif;
|
|
font-size: 8px;
|
|
}
|
|
|
|
body {
|
|
/* DejaVu Sans est très bien géré par dompdf (accents, stabilité) */
|
|
font-family: Helvetica, sans-serif;
|
|
font-size: 10px;
|
|
color: #111;
|
|
}
|
|
|
|
.sheet { width: auto; }
|
|
|
|
h1 {
|
|
margin: 8px 0 16px 0;
|
|
padding: 0;
|
|
line-height: 1;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
table-layout: fixed;
|
|
}
|
|
|
|
th, td {
|
|
border: 2px solid #2b2b2b;
|
|
padding: 2px 3px;
|
|
text-align: center;
|
|
vertical-align: middle;
|
|
line-height: 1.1;
|
|
white-space: nowrap; /* important pour dompdf */
|
|
overflow: hidden; /* évite les débordements */
|
|
text-overflow: clip;
|
|
}
|
|
|
|
/* =========================
|
|
HEADER (mise en page)
|
|
========================= */
|
|
.header-layout,
|
|
.header-layout td {
|
|
border: 0;
|
|
padding: 0;
|
|
}
|
|
|
|
.header-left td,
|
|
.header-right td {
|
|
border: 2px solid #2b2b2b;
|
|
font-weight: 700;
|
|
padding: 0;
|
|
}
|
|
|
|
/* Bloc CASE */
|
|
.header-left td {
|
|
height: 34px;
|
|
font-size: 10px;
|
|
}
|
|
|
|
.header-left .case-label {
|
|
width: 34%;
|
|
letter-spacing: 0.2px;
|
|
}
|
|
|
|
.header-left .case-number {
|
|
width: 66%;
|
|
font-size: 18px; /* volontairement compact pour dompdf */
|
|
line-height: 1;
|
|
}
|
|
|
|
/* Bloc PROVENANCE / RACE */
|
|
.header-right .label {
|
|
font-size: 11px;
|
|
height: 18px;
|
|
letter-spacing: 0;
|
|
}
|
|
|
|
.header-right .mini {
|
|
height: 18px;
|
|
font-size: 10px;
|
|
}
|
|
|
|
.header-right .mini-empty {
|
|
height: 18px;
|
|
font-size: 9px;
|
|
}
|
|
|
|
.header-right .race {
|
|
height: 24px;
|
|
font-size: 11px;
|
|
letter-spacing: 0;
|
|
}
|
|
|
|
.header-right .breed {
|
|
font-size: 9px;
|
|
font-weight: 700;
|
|
padding: 0 2px;
|
|
}
|
|
|
|
/* =========================
|
|
TABLEAU PRINCIPAL
|
|
========================= */
|
|
.main {
|
|
margin-top: 2px;
|
|
}
|
|
|
|
.main th {
|
|
background: #ffffff;
|
|
font-weight: 700;
|
|
padding: 2px 1px;
|
|
}
|
|
|
|
.main .head-big {
|
|
font-size: 14px;
|
|
font-weight: 700;
|
|
white-space: normal; /* permet les <br> */
|
|
line-height: 1.15;
|
|
}
|
|
|
|
.main .month {
|
|
font-size: 12px;
|
|
}
|
|
|
|
.main .days {
|
|
font-size: 12px;
|
|
}
|
|
|
|
.main .sub-title {
|
|
font-size: 16px;
|
|
font-weight: 700;
|
|
letter-spacing: 0;
|
|
padding: 8px;
|
|
}
|
|
|
|
.main .base {
|
|
font-size: 12px;
|
|
}
|
|
|
|
/* Hauteurs de lignes d'en-tête (stables en dompdf) */
|
|
.main thead tr:nth-child(1) th { height: 24px; }
|
|
.main thead tr:nth-child(2) th { height: 18px; }
|
|
.main thead tr:nth-child(3) th { height: 18px; }
|
|
.main thead tr:nth-child(4) th { height: 18px; }
|
|
|
|
/* Lignes data */
|
|
.data-row td {
|
|
height: 18px;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.row-work {
|
|
text-align: center;
|
|
font-size: 18px !important;
|
|
font-weight: 700;
|
|
line-height: 1;
|
|
}
|
|
|
|
.row-weight,
|
|
.row-birth,
|
|
.row-month {
|
|
font-size: 9px;
|
|
line-height: 1;
|
|
}
|
|
|
|
/* =========================
|
|
FOOTER VACCINS / NOTES
|
|
========================= */
|
|
.footer {
|
|
font-size: 12px;
|
|
}
|
|
|
|
/* Header droit sans bordures par défaut */
|
|
.header-right-free,
|
|
.header-right-free td {
|
|
padding: 0;
|
|
width: 6.25%;
|
|
}
|
|
|
|
</style>
|
|
</head>
|
|
<body>
|
|
{% set firstArrivalDate = rows is not empty ? rows[0].arrivalDate : null %}
|
|
{% set monthCount = ((monthHeaders|default([]))|length) > 0 ? ((monthHeaders|default([]))|length) : 12 %}
|
|
|
|
<div class="sheet">
|
|
|
|
<!-- =========================
|
|
EN-TÊTE (CASE / PROVENANCE / RACE)
|
|
========================= -->
|
|
<h1 style="color: red; text-align: center; width: 100%; font-size: 36px">
|
|
Arrivage du {{ firstArrivalDate ?? '-' }}
|
|
</h1>
|
|
<table style="width:100%; border-collapse:collapse; table-layout:fixed; margin-bottom: 16px">
|
|
<tr>
|
|
<td style="width:40%; vertical-align:top; padding-right:2mm; border:0;">
|
|
<table style="width:100%; border-collapse:collapse; table-layout:fixed;">
|
|
<tr>
|
|
<td style="border: 0; height: 20px"></td>
|
|
</tr>
|
|
<tr>
|
|
<td style="font-weight:700; text-align: left; border: none; font-size: 24px">CASE N° {{ buildingCase.caseNumber ?? '' }}</td>
|
|
</tr>
|
|
</table>
|
|
</td>
|
|
|
|
<td style="width:60%; vertical-align:top; padding-left:2mm; border:0;">
|
|
<table class="header-right-free" style="width:100%; border-collapse:collapse; table-layout:fixed;">
|
|
<tr>
|
|
<td style="border:0; text-align:center; font-weight:700; height: 20px;" colspan="5"></td>
|
|
<td style="border:0;" colspan="2"></td>
|
|
<td style="border:1px solid #2b2b2b; text-align:center; font-weight:700; height: 20px;">1</td>
|
|
<td style="border:0; height: 20px;"></td>
|
|
<td style="border:1px solid #2b2b2b; text-align:center; font-weight:700; height: 20px;">2</td>
|
|
<td style="border:0; height: 20px;"></td>
|
|
<td style="border:1px solid #2b2b2b; text-align:center; font-weight:700; height: 20px;">3</td>
|
|
<td style="border:0; height: 20px;"></td>
|
|
<td style="border:1px solid #2b2b2b; text-align:center; font-weight:700; height: 20px;">4</td>
|
|
<td style="border:0;" colspan="2"></td>
|
|
</tr>
|
|
<tr>
|
|
<td style="border:0; text-align:left; font-weight:700; font-size: 24px; width:40%; height: 20px;" colspan="5">PROVENANCE</td>
|
|
<td style="border:0;" colspan="2"></td>
|
|
<td style="border:1px solid #2b2b2b;"></td>
|
|
<td style="border:0;"></td>
|
|
<td style="border:1px solid #2b2b2b;"></td>
|
|
<td style="border:0;"></td>
|
|
<td style="border:1px solid #2b2b2b;"></td>
|
|
<td style="border:0;"></td>
|
|
<td style="border:1px solid #2b2b2b;"></td>
|
|
<td style="border: 0; width: 20%;" colspan="2"></td>
|
|
</tr>
|
|
<tr>
|
|
<td style="border: 0; height: 20px" colspan="16"></td>
|
|
</tr>
|
|
<tr>
|
|
<td style="border: 0; text-align:left; font-weight:700; font-size: 24px" colspan="3">RACE</td>
|
|
<td style="border:1px solid #2b2b2b; text-align:center; font-weight:700;" colspan="3">LIMOUSIN</td>
|
|
<td style="border:1px solid #2b2b2b; text-align:center; font-weight:700;" colspan="1"></td>
|
|
<td style="border: 0; text-align:center; font-weight:700;" colspan="1"></td>
|
|
<td style="border:1px solid #2b2b2b; text-align:center; font-weight:700;" colspan="3">CHAROLAIS</td>
|
|
<td style="border:1px solid #2b2b2b; text-align:center; font-weight:700;" colspan="1"></td>
|
|
<td style="border: 0; text-align:center; font-weight:700;" colspan="1"></td>
|
|
<td style="border:1px solid #2b2b2b; text-align:center; font-weight:700;" colspan="2">Autre</td>
|
|
<td style="border:1px solid #2b2b2b; text-align:center; font-weight:700;" colspan="1"></td>
|
|
</tr>
|
|
</table>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<!-- =========================
|
|
TABLEAU PRINCIPAL
|
|
========================= -->
|
|
<table class="main">
|
|
<thead>
|
|
<tr>
|
|
<th rowspan="4" class="head-big" style="width:5%">N° de<br>travail</th>
|
|
<th rowspan="4" class="head-big" style="width:5%">N° de<br>travail</th>
|
|
<th rowspan="4" class="head-big head-big-weight" style="width:4%">Poids<br>(kg)</th>
|
|
<th rowspan="4" class="head-big" style="width:7%">Date de<br>naissance</th>
|
|
|
|
{% for month in monthHeaders|default([]) %}
|
|
<th class="month" style="width:6.58%">{{ month.name }}</th>
|
|
{% endfor %}
|
|
</tr>
|
|
|
|
<tr>
|
|
{% for month in monthHeaders|default([]) %}
|
|
<th class="days">{{ month.days }}</th>
|
|
{% endfor %}
|
|
</tr>
|
|
|
|
<tr>
|
|
<th colspan="{{ monthHeaders|length }}" class="sub-title">POIDS PAR MOIS</th>
|
|
</tr>
|
|
|
|
<tr>
|
|
{% for month in monthHeaders|default([]) %}
|
|
<th class="base">
|
|
{% if month.baseValue is defined %}
|
|
{{ month.baseValue|round(0, 'common') }} kg
|
|
{% elseif month.base is defined %}
|
|
{{ month.base }}
|
|
{% endif %}
|
|
</th>
|
|
{% endfor %}
|
|
</tr>
|
|
</thead>
|
|
|
|
<tbody>
|
|
{# 11 lignes comme dans ton code (0..10) #}
|
|
{% for i in 0..12 %}
|
|
{% set row = rows[i] ?? null %}
|
|
{% set baseWeight = row ? (row.receivedWeight ?? null) : null %}
|
|
|
|
<tr class="data-row">
|
|
<td class="row-work"></td>
|
|
<td class="row-work">{{ row ? (row.workNumber ?? '') : '' }}</td>
|
|
<td class="row-weight">{{ baseWeight ?? '' }}</td>
|
|
<td class="row-birth">
|
|
{% if row and row.birthDate %}
|
|
{% set birthParts = row.birthDate|split('/') %}
|
|
{{ birthParts|length == 3 ? birthParts[1] ~ '/' ~ birthParts[2] : row.birthDate }}
|
|
{% endif %}
|
|
</td>
|
|
{% for idx in 0..(monthCount > 0 ? monthCount - 1 : 0) %}
|
|
{% set projectedWeight = row and row.projectedWeights is defined ? (row.projectedWeights[idx] ?? null) : null %}
|
|
<td class="row-month"{% if loop.index0 < 4 %} style="background:#e0e0e0;"{% endif %}>
|
|
{{ projectedWeight is not null ? projectedWeight|round(0, 'common') : '' }}
|
|
</td>
|
|
{% endfor %}
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
<!-- =========================
|
|
FOOTER (traitements / vaccins)
|
|
========================= -->
|
|
<table class="footer" style="border-collapse:collapse; margin-top: 32px">
|
|
<tr>
|
|
<td style="height: 20px; border: 0" colspan="4"></td>
|
|
<td style="font-weight: 700" colspan="2">Grippe</td>
|
|
<td style="font-weight: 700" colspan="2">Protivity</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="height: 20px">Date</td>
|
|
<td>Antibiotique</td>
|
|
<td>Date</td>
|
|
<td>Antero</td>
|
|
<td>Date</td>
|
|
<td>Intranasale</td>
|
|
<td>Date</td>
|
|
<td>Rappel 30 jours</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="height: 20px"></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td style="height: 20px"></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</body>
|
|
</html>
|