ifnex/04_Laravel/resources/views/pdfs/awb.blade.php
Kazem Alghasi f12dff5338 - Add picqer/php-barcode-generator dependency
- Redesign AWB PDF with barcode, From/To, Value, Service, Type
- Redesign Invoice PDF with 9-row table, legal declaration, barcode
- Redesign Label PDF to A5 landscape with large barcode
- Add DOC/PARCEL condition for Invoice (only PARCEL has invoice)
- Fix ShipmentType enum names (DocNormal/DocEconomy)
- Add migration for shipment_items (row_number, unit_price)
- Add migration to make name nullable
- Update PdfService with base64 barcode embedding
- Update ShipmentPdfController with DOC type handling
- Add test_pdf_generation.php script

Phase 3.5 — PDF redesign complete"
2026-08-29 06:40:08 +03:30

360 lines
14 KiB
PHP

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: DejaVu Sans, Arial, sans-serif;
font-size: 10px;
color: #000;
background: #fff;
}
.page {
width: 210mm;
min-height: 297mm;
padding: 8mm;
margin: 0 auto;
}
/* ─── HEADER ─── */
.header {
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 2px solid #f37021;
padding-bottom: 6px;
margin-bottom: 10px;
}
.logo-area {
display: flex;
align-items: center;
gap: 8px;
}
.logo {
width: 50px;
height: 50px;
}
.brand {
font-size: 18px;
font-weight: bold;
color: #f37021;
}
.header-title {
text-align: center;
flex: 1;
}
.header-title h1 {
font-size: 18px;
color: #000;
margin-bottom: 2px;
}
.header-tagline {
font-size: 9px;
color: #666;
font-style: italic;
}
.header-date {
font-size: 10px;
text-align: right;
}
/* ─── AWB BARCODE ─── */
.awb-barcode-area {
text-align: center;
margin-bottom: 10px;
padding: 8px;
border: 2px solid #000;
}
.awb-barcode-area img {
height: 50px;
}
.awb-no-display {
font-size: 16px;
font-weight: bold;
letter-spacing: 2px;
margin-top: 4px;
}
/* ─── MAIN SECTIONS ─── */
.section-row {
display: flex;
gap: 6px;
margin-bottom: 8px;
}
.section {
flex: 1;
border: 1px solid #000;
padding: 6px;
}
.section-title {
background: #f37021;
color: #fff;
padding: 3px 6px;
font-weight: bold;
font-size: 11px;
margin: -6px -6px 6px -6px;
}
.row {
display: flex;
margin-bottom: 3px;
font-size: 9px;
}
.label {
width: 80px;
font-weight: bold;
color: #444;
}
.value {
flex: 1;
color: #000;
}
.from-to {
font-weight: bold;
font-size: 11px;
color: #f37021;
margin-bottom: 4px;
}
/* ─── SHIPMENT & PAYMENT ─── */
.shipment-row {
display: flex;
gap: 6px;
margin-bottom: 8px;
}
.shipment-section {
flex: 1;
border: 1px solid #000;
padding: 6px;
}
.shipment-section.payment {
background: #f9f9f9;
}
/* ─── SHIPMENT DETAILS ─── */
.shipment-details {
border: 1px solid #000;
padding: 6px;
margin-bottom: 8px;
}
.shipment-details table {
width: 100%;
border-collapse: collapse;
font-size: 9px;
}
.shipment-details th,
.shipment-details td {
border: 1px solid #ccc;
padding: 3px;
text-align: left;
}
.shipment-details th {
background: #eee;
font-weight: bold;
}
/* ─── NOTES ─── */
.notes {
border: 1px solid #000;
padding: 6px;
margin-bottom: 8px;
font-size: 8px;
line-height: 1.5;
background: #fffde7;
}
.notes strong {
color: #f37021;
}
/* ─── SIGNATURE ─── */
.signature-row {
display: flex;
justify-content: space-between;
margin-bottom: 8px;
}
.signature-box {
width: 45%;
text-align: center;
font-size: 9px;
}
.signature-line {
border-top: 1px solid #000;
margin-top: 25px;
padding-top: 3px;
}
/* ─── FOOTER ─── */
.footer {
border-top: 2px solid #f37021;
padding-top: 5px;
text-align: center;
font-size: 9px;
}
.footer-brand {
color: #f37021;
font-weight: bold;
}
.track-url {
font-size: 10px;
margin-top: 2px;
}
/* ─── UTILITY ─── */
.total-row {
background: #f37021;
color: #fff;
font-weight: bold;
}
.total-row .label,
.total-row .value {
color: #fff;
}
</style>
</head>
<body>
<div class="page">
<!-- HEADER -->
<div class="header">
<div class="logo-area">
<img src="{{ public_path('logo.png') }}" class="logo" alt="IFNEX">
<div class="brand">IFNEx</div>
</div>
<div class="header-title">
<h1>Shipment Waybill</h1>
<div class="header-tagline">We Deliver Value</div>
</div>
<div class="header-date">
Date: {{ $shipment->created_at?->format('m/d/Y') }}
</div>
</div>
<!-- AWB BARCODE -->
<div class="awb-barcode-area">
@if($barcode_base64)
<img src="{{ $barcode_base64 }}" alt="barcode">
@endif
<div class="awb-no-display">{{ $shipment->awb_no }}</div>
</div>
<!-- SHIPPER & RECEIVER -->
<div class="section-row">
<div class="section">
<div class="section-title">SHIPPER</div>
<div class="from-to">From: {{ $shipper['city'] }}, {{ $shipment->fromCountry?->name }} ({{ $shipment->fromCountry?->iso_code }})</div>
<div class="row"><span class="label">Company Name:</span><span class="value">{{ $shipper['company'] ?: '—' }}</span></div>
<div class="row"><span class="label">Contact Name:</span><span class="value">{{ $shipper['name'] }}</span></div>
<div class="row"><span class="label">Tel / Mob:</span><span class="value">{{ $shipper['phone'] }}</span></div>
<div class="row"><span class="label">Email:</span><span class="value">{{ $shipper['email'] ?: '—' }}</span></div>
<div class="row"><span class="label">Address:</span><span class="value">{{ $shipper['address'] }}</span></div>
<div class="row"><span class="label">ID Number:</span><span class="value">{{ $shipper['id_number'] ?: '—' }}</span></div>
<div class="row"><span class="label">Zip Code:</span><span class="value">{{ $shipper['zip'] ?: '—' }}</span></div>
</div>
<div class="section">
<div class="section-title">RECEIVER</div>
<div class="from-to">To: {{ $receiver['city'] }}, {{ $shipment->toCountry?->name }} ({{ $shipment->toCountry?->iso_code }})</div>
<div class="row"><span class="label">Company Name:</span><span class="value">{{ $receiver['company'] ?: '—' }}</span></div>
<div class="row"><span class="label">Contact Name:</span><span class="value">{{ $receiver['name'] }}</span></div>
<div class="row"><span class="label">Tel / Mobile:</span><span class="value">{{ $receiver['phone'] }}</span></div>
<div class="row"><span class="label">Email:</span><span class="value">{{ $receiver['email'] ?: '—' }}</span></div>
<div class="row"><span class="label">Address:</span><span class="value">{{ $receiver['address'] }}</span></div>
<div class="row"><span class="label">City:</span><span class="value">{{ $receiver['city'] ?: '—' }}</span></div>
<div class="row"><span class="label">Zip Code:</span><span class="value">{{ $receiver['zip'] ?: '—' }}</span></div>
</div>
</div>
<!-- SHIPMENT & PAYMENT -->
<div class="shipment-row">
<div class="shipment-section">
<div class="section-title">SHIPMENT</div>
<div class="row"><span class="label">Gross Weight:</span><span class="value">{{ $shipment->weight }} (Kg)</span></div>
<div class="row"><span class="label">Dimensions:</span><span class="value">{{ $shipment->dimensions ?: '—' }} (cm)</span></div>
<div class="row"><span class="label">Volumetric Weight:</span><span class="value">{{ $shipment->volumetric_weight }} (Kg)</span></div>
<div class="row"><span class="label">Chargeable Weight:</span><span class="value">{{ $shipment->chargeable_weight ?: max($shipment->weight, $shipment->volumetric_weight) }} (Kg)</span></div>
<div class="row"><span class="label">Value:</span><span class="value">{{ $invoice_total_usd > 0 ? number_format($invoice_total_usd, 0) . ' (USD)' : '—' }}</span></div>
<div class="row"><span class="label">Service:</span><span class="value">{{ $service_label }}</span></div>
<div class="row"><span class="label">Type:</span><span class="value">{{ $type_label }}</span></div>
<div class="row"><span class="label">Content:</span><span class="value">{{ $shipment->content_description ?: $shipment->reason_for_export ?: 'General Goods' }}</span></div>
</div>
<div class="shipment-section payment">
<div class="section-title">PAYMENT</div>
<div class="row"><span class="label">Shipping Price:</span><span class="value">{{ $shipment->shipping_price ? number_format($shipment->shipping_price, 2) : '—' }}</span></div>
<div class="row"><span class="label">Extra Service:</span><span class="value">{{ number_format($shipment->extra_service ?? 0) }}</span></div>
<div class="row"><span class="label">Domestic Pickup:</span><span class="value">{{ number_format($shipment->domestic_pickup ?? 0) }}</span></div>
<div class="row"><span class="label">Packing Cost:</span><span class="value">{{ number_format($shipment->packing_cost ?? 0) }}</span></div>
<div class="row"><span class="label">Domestic Delivery:</span><span class="value">{{ number_format($shipment->domestic_delivery ?? 0) }}</span></div>
<div class="row"><span class="label">Warehousing:</span><span class="value">{{ number_format($shipment->warehousing_cost ?? 0) }}</span></div>
<div class="row"><span class="label">Discount:</span><span class="value">{{ number_format($shipment->discount ?? 0) }}</span></div>
<div class="row total-row"><span class="label">Total Fee:</span><span class="value">{{ number_format($shipment->total_fee ?? 0) }} IRR</span></div>
<div class="row"><span class="label">Cash on Delivery:</span><span class="value">{{ $shipment->cod_amount ? number_format($shipment->cod_amount, 2) . ' AED' : '—' }}</span></div>
</div>
</div>
<!-- SHIPMENT DETAILS (Items) -->
@if($items->isNotEmpty())
<div class="shipment-details">
<div class="section-title" style="background: #f37021; color: #fff; padding: 3px 6px; margin: -6px -6px 6px -6px;">Shipment Details</div>
<table>
<thead>
<tr>
<th>No</th>
<th>Description</th>
<th>H.S. Code</th>
<th>Qty</th>
<th>Unit Price (USD)</th>
<th>Total (USD)</th>
</tr>
</thead>
<tbody>
@foreach($items as $item)
<tr>
<td>{{ $item->row_number }}</td>
<td>{{ $item->description }}</td>
<td>{{ $item->hs_code }}</td>
<td>{{ $item->quantity }}</td>
<td>{{ number_format($item->unit_price, 2) }}</td>
<td>{{ number_format($item->total_usd, 2) }}</td>
</tr>
@endforeach
<tr style="background: #eee; font-weight: bold;">
<td colspan="5" style="text-align: right;">Total Invoice Amount in USD:</td>
<td>{{ number_format($invoice_total_usd, 2) }}</td>
</tr>
</tbody>
</table>
</div>
@endif
<!-- NOTES -->
<div class="notes">
<strong>Please note that:</strong><br>
Door-to-door Services is only applicable when the shipment is general cargo and does not require any special approvals or regulations in origin &amp; destination.<br>
Only Consignee is aware of the importing rules in the destination and consignee is the person who is in contact with the shipper.<br>
The Courier Company cannot guarantee the clearance since All shipments are subjected to customs approval at Origin and Destination.
</div>
<!-- SIGNATURE -->
<div class="signature-row">
<div class="signature-box">
Shipper Name &amp; Signature:
<div class="signature-line"></div>
</div>
<div class="signature-box">
Date:
<div class="signature-line">...../...../..........</div>
</div>
</div>
<!-- FOOTER -->
<div class="footer">
<div class="footer-brand">IFNEx Logistics We Deliver Value</div>
<div class="track-url">Track Your Shipment at: http://ifnex.net</div>
<div style="margin-top: 3px; font-size: 8px; color: #999;">
AWB: {{ $shipment->awb_no }} | Generated: {{ now()->format('Y-m-d H:i') }}
</div>
</div>
</div>
</body>
</html>