Files
Verde-Web/resources/views/pdf/qr-batch.blade.php
admin d458e74301 feat(backend): complete Module 7 — QR code system (core)
qr_code_batches + qr_codes tables. State machine via
spatie/laravel-model-states (unassigned → allocated → active → used,
plus expired/voided). Serial format PH-{area}-{YYMM}-{batch}-{code}-
{checksum} with 2-char SHA-256-derived checksum. BatchGenerator
bulk-inserts in chunks. QrAllocator allocates free codes to verified
households (prefers area-targeted batch, falls back to any). Real
HouseholdVerified listener replaces the placeholder. QrBalanceLow
event for Module 11.

Admin: batch CRUD, mark-printed, void code, lifecycle search, PDF
print sheet (24/A4 via dompdf + endroid/qr-code + picqer/barcode).
Resident: list own codes, balance with low_balance flag, activate
allocated codes.

Removed explicit Event::listen for HouseholdVerified — Laravel 11
auto-discovers it via handle() type-hint, and double-registering was
causing double-dispatch.

130 feature tests passing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 02:12:41 +08:00

61 lines
2.0 KiB
PHP

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Verde QR Batch {{ $batch->batch_number }}</title>
<style>
@page { margin: 8mm; }
* { box-sizing: border-box; }
body { font-family: DejaVu Sans, sans-serif; margin: 0; padding: 0; }
.header { font-size: 9pt; margin-bottom: 4mm; }
.header strong { font-size: 11pt; }
.grid {
width: 100%;
border-collapse: collapse;
table-layout: fixed;
}
.grid td {
width: 25%;
border: 1px dashed #999;
padding: 3mm 2mm;
vertical-align: top;
text-align: center;
}
.qr { width: 32mm; height: 32mm; }
.barcode { width: 38mm; height: 9mm; margin-top: 1mm; }
.serial { font-size: 7pt; word-break: break-all; margin-top: 1mm; font-family: monospace; }
.pagebreak { page-break-after: always; }
</style>
</head>
<body>
@foreach ($pages as $pageIndex => $page)
<div class="header">
<strong>Verde Batch {{ $batch->batch_number }}</strong>
&nbsp; · {{ $batch->purpose }}
&nbsp; · {{ count($page) }} of {{ $batch->quantity }} codes
&nbsp; · page {{ $pageIndex + 1 }}/{{ count($pages) }}
</div>
<table class="grid">
@php $rows = array_chunk($page, 4); @endphp
@foreach ($rows as $row)
<tr>
@foreach ($row as $cell)
<td>
<img class="qr" src="{{ $cell['qr_data_uri'] }}" alt="QR">
<img class="barcode" src="{{ $cell['barcode_data_uri'] }}" alt="Code-128">
<div class="serial">{{ $cell['serial'] }}</div>
</td>
@endforeach
@for ($i = count($row); $i < 4; $i++)
<td>&nbsp;</td>
@endfor
</tr>
@endforeach
</table>
@if ($pageIndex < count($pages) - 1)
<div class="pagebreak"></div>
@endif
@endforeach
</body>
</html>