ifnex/04_Laravel/resources/views/pdfs/awb.blade.php
Kazem Alghasi 93bcfb9ce7 refactor(pdf): switch AWB template to landscape orientation
Update the AWB document generation to use landscape mode and adjust
the layout to utilize the additional horizontal space.

Key changes:
- Change `PdfService` orientation from portrait to landscape for AWB.
- Refactor `awb.blade.php` to use a side-by-side layout for terms
  and signatures.
- Adjust grid column widths from 50% to 25% to accommodate the
  new orientation.
- Update `@page` margin definitions for better print alignment.
2026-10-03 20:33:15 +03:30

483 lines
20 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
/* ════════ Base Reset & Page ════════ */
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: DejaVu Sans, Arial, sans-serif;
font-size: 9px;
color: #111827;
line-height: 1.4;
}
/* ⚠️ Dompdf از box-sizing: border-box پشتیبانی نمی‌کند —
width باید 100% ناحیه قابل چاپ باشد و حاشیه‌ها با @page داده شوند؛
width: 210mm + padding یعنی 230mm واقعی و بیرون‌زدگی از سمت راست.
موقتی یه تغییری برای تست میدهیم. */
@page {
margin-top: 10mm;
margin-bottom: 10mm;
margin-left: 15mm;
margin-right: 15mm;
}
/* ════════ Brand Colors ════════ */
/* Navy: #1a1a2e | Orange accent: #f59e0b | Gray bg: #f3f4f6 */
/* ════════ Header ════════ */
.header-table {
width: 100%;
table-layout: fixed; /* ✅ ستون‌ها به عرض مشخص محدود می‌شوند */
border-collapse: collapse;
border-bottom: 3px solid #1a1a2e;
margin-bottom: 6px;
}
.header-table td {
vertical-align: middle;
padding: 4px 6px 8px 6px;
word-wrap: break-word; /* ✅ متن طولانی می‌شکند */
}
.header-logo {
width: 90px; /* ✅ کوچک‌تر شد */
height: auto;
}
.header-brand {
font-size: 20px;
font-weight: bold;
color: #1a1a2e;
letter-spacing: 1px;
}
.header-tagline {
font-size: 8px;
color: #6b7280;
margin-top: 1px;
}
.header-title {
font-size: 14px;
font-weight: bold;
color: #1a1a2e;
text-align: center;
letter-spacing: 1px;
}
.header-awb {
font-size: 11px; /* ✅ کوچک‌تر */
font-weight: bold;
color: #1a1a2e;
text-align: right;
letter-spacing: 1px; /* ✅ کمتر */
}
.header-date {
font-size: 8px;
color: #6b7280;
text-align: right;
}
.header-barcode {
text-align: right;
}
.header-barcode img {
max-width: 50mm; /* ✅ حداکثر عرض برای جا ماندن در ستون */
height: 32px; /* ✅ کمی کوچک‌تر */
width: auto;
}
/* ════════ Route Bar ════════ */
.route-bar {
width: 100%;
background: #f3f4f6;
border: 1px solid #d1d5db;
padding: 4px 8px;
margin-bottom: 6px;
font-size: 10px;
font-weight: bold;
color: #1a1a2e;
}
.route-bar .route-arrow {
color: #f59e0b;
font-weight: bold;
font-size: 12px;
}
.route-bar .route-meta {
float: left;
font-size: 9px;
color: #4b5563;
font-weight: normal;
}
/* ════════ Main Grid (2×2) ════════ */
.grid-table {
width: 100%;
border-collapse: collapse;
margin-bottom: 6px;
}
.grid-table > tbody > tr > td {
width: 25%; /* ✅ ۴ ستونه در عرضی */
vertical-align: top;
border: 1.5px solid #1a1a2e;
border-right: 0.5px solid #1a1a2e;
padding: 0;
}
.grid-table > tbody > tr > td.left {
border-right: 0.5px solid #1a1a2e;
}
/* ════════ Section Header (navy bar) ════════ */
.section-header {
background: #1a1a2e;
color: #ffffff;
padding: 4px 8px;
font-weight: bold;
font-size: 11px;
letter-spacing: 1.5px;
border-bottom: 1px solid #1a1a2e;
}
/* ════════ Section Body (label-value rows) ════════ */
.field-table {
width: 100%;
border-collapse: collapse;
font-size: 9px;
}
.field-table td {
padding: 2px 8px;
vertical-align: top;
border-bottom: 0.5px solid #e5e7eb;
}
.field-table td.label {
width: 40%;
color: #6b7280;
font-weight: bold;
}
.field-table td.value {
color: #111827;
font-weight: normal;
}
.field-table tr:last-child td {
border-bottom: none;
}
/* ════════ Payment Total Row ════════ */
.total-row td {
background: #f59e0b !important;
color: #ffffff !important;
font-weight: bold !important;
font-size: 11px !important;
padding: 4px 8px !important;
}
/* ════════ Shipment Details Table ════════ */
.details-section {
border: 1.5px solid #1a1a2e;
margin-bottom: 6px;
}
.details-table {
width: 100%;
border-collapse: collapse;
font-size: 8px;
}
.details-table th {
background: #1a1a2e;
color: #ffffff;
padding: 3px 4px;
text-align: left;
font-weight: bold;
border: 0.5px solid #1a1a2e;
}
.details-table td {
padding: 2px 4px;
border: 0.5px solid #d1d5db;
color: #111827;
}
.details-table tr:nth-child(even) td {
background: #f9fafb;
}
.details-total td {
background: #f3f4f6 !important;
font-weight: bold;
color: #1a1a2e;
}
/* ════════ Notes ════════ */
.notes {
border: 1px solid #d1d5db;
padding: 5px 8px;
margin-bottom: 6px;
font-size: 7.5px;
line-height: 1.5;
color: #4b5563;
background: #ffffff;
}
.notes-title {
font-weight: bold;
color: #1a1a2e;
font-size: 8px;
margin-bottom: 2px;
}
/* ════════ Signature ════════ */
.signature-table {
width: 100%;
border-collapse: collapse;
margin-bottom: 6px;
}
.signature-table td {
width: 50%;
padding: 8px;
text-align: center;
font-size: 8px;
color: #6b7280;
}
.sig-line {
border-top: 1px solid #1a1a2e;
margin-top: 28px;
padding-top: 3px;
font-size: 8px;
color: #6b7280;
}
/* ════════ Footer ════════ */
.footer {
border-top: 2px solid #1a1a2e;
padding-top: 4px;
text-align: center;
font-size: 8px;
color: #6b7280;
}
.footer-brand {
color: #1a1a2e;
font-weight: bold;
font-size: 10px;
margin-bottom: 1px;
}
.footer-track {
font-size: 9px;
color: #f59e0b;
font-weight: bold;
margin: 1px 0;
}
.footer-meta {
font-size: 7px;
color: #9ca3af;
margin-top: 2px;
}
</style>
</head>
<body>
<div class="page">
<!-- ════════ HEADER ════════ -->
<table class="header-table">
<tr>
<td style="width: 25%;">
<img src="{{ public_path('images/ifnex-logo.png') }}" class="header-logo" alt="IFNEX">
</td>
<td style="width: 38%;" align="center">
<div class="header-brand">IFNEX</div>
<div class="header-tagline">We Deliver Value</div>
<div class="header-title" style="margin-top:4px;">SHIPMENT WAYBILL</div>
</td>
<td style="width: 37%;" class="header-barcode">
@if($barcode_base64)
<img src="{{ $barcode_base64 }}" alt="barcode"><br>
@endif
<div class="header-awb">{{ $shipment->awb_no }}</div>
<div class="header-date">Date: {{ $shipment->created_at?->format('m/d/Y') }}</div>
</td>
</tr>
</table>
<!-- ════════ ROUTE BAR ════════ -->
<div class="route-bar">
<span class="route-meta">
Service: {{ $service_label }} &nbsp;|&nbsp; Type: {{ $type_label }}
</span>
From: {{ strtoupper($shipment->fromCountry?->name ?? '—') }} ({{ $shipment->fromCountry?->iso_code }})
<span class="route-arrow"> → </span>
To: {{ strtoupper($shipment->toCountry?->name ?? '—') }} ({{ $shipment->toCountry?->iso_code }})
</div>
<!-- ════════ GRID 2×2: Shipper / Receiver ════════ -->
<table class="grid-table">
<tr>
<!-- SHIPPER -->
<td class="left">
<div class="section-header">SHIPPER</div>
<table class="field-table">
@if($shipper['company'])
<tr><td class="label">Company</td><td class="value">{{ $shipper['company'] }}</td></tr>
@endif
<tr><td class="label">Contact Name</td><td class="value">{{ $shipper['name'] ?: '—' }}</td></tr>
<tr><td class="label">Phone</td><td class="value">{{ $shipper['phone'] ?: '—' }}</td></tr>
@if($shipper['email'])
<tr><td class="label">Email</td><td class="value">{{ $shipper['email'] }}</td></tr>
@endif
<tr><td class="label">Address</td><td class="value">{{ $shipper['address'] ?: '—' }}</td></tr>
@if($shipper['city'])
<tr><td class="label">City</td><td class="value">{{ $shipper['city'] }}</td></tr>
@endif
@if($shipper['zip'])
<tr><td class="label">Zip Code</td><td class="value">{{ $shipper['zip'] }}</td></tr>
@endif
@if($shipper['id_number'])
<tr><td class="label">ID Number</td><td class="value">{{ $shipper['id_number'] }}</td></tr>
@endif
</table>
</td>
<!-- RECEIVER -->
<td>
<div class="section-header">RECEIVER</div>
<table class="field-table">
@if($receiver['company'])
<tr><td class="label">Company</td><td class="value">{{ $receiver['company'] }}</td></tr>
@endif
<tr><td class="label">Contact Name</td><td class="value">{{ $receiver['name'] ?: '—' }}</td></tr>
<tr><td class="label">Phone</td><td class="value">{{ $receiver['phone'] ?: '—' }}</td></tr>
@if($receiver['email'])
<tr><td class="label">Email</td><td class="value">{{ $receiver['email'] }}</td></tr>
@endif
<tr><td class="label">Address</td><td class="value">{{ $receiver['address'] ?: '—' }}</td></tr>
@if($receiver['city'])
<tr><td class="label">City</td><td class="value">{{ $receiver['city'] }}</td></tr>
@endif
@if($receiver['zip'])
<tr><td class="label">Zip Code</td><td class="value">{{ $receiver['zip'] }}</td></tr>
@endif
@if($receiver['id_number'])
<tr><td class="label">ID Number</td><td class="value">{{ $receiver['id_number'] }}</td></tr>
@endif
</table>
</td>
</tr>
</table>
<!-- ════════ GRID 2×2: Shipment / Payment ════════ -->
<table class="grid-table">
<tr>
<!-- SHIPMENT -->
<td class="left">
<div class="section-header">SHIPMENT</div>
<table class="field-table">
<tr><td class="label">Gross Weight</td><td class="value">{{ $shipment->weight ?: '—' }} Kg</td></tr>
@if($shipment->dimensions)
<tr><td class="label">Dimensions</td><td class="value">{{ $shipment->dimensions }} cm</td></tr>
@endif
@if($shipment->volumetric_weight)
<tr><td class="label">Volumetric Weight</td><td class="value">{{ $shipment->volumetric_weight }} Kg</td></tr>
@endif
<tr><td class="label">Chargeable Weight</td><td class="value">{{ $shipment->chargeable_weight ?: max($shipment->weight ?? 0, $shipment->volumetric_weight ?? 0) }} Kg</td></tr>
@if($invoice_total_usd > 0)
<tr><td class="label">Declared Value</td><td class="value">{{ number_format($invoice_total_usd, 0) }} USD</td></tr>
@endif
@php
$contentDesc = $items->isNotEmpty()
? $items->pluck('description')->implode(', ')
: ($shipment->content_description ?: $shipment->reason_for_export ?: 'General Goods');
@endphp
<tr><td class="label">Content</td><td class="value">{{ $contentDesc }}</td></tr>
</table>
</td>
<!-- PAYMENT -->
<td>
<div class="section-header">PAYMENT</div>
<table class="field-table">
<tr><td class="label">Shipping Price</td><td class="value">{{ $shipment->shipping_price ? number_format($shipment->shipping_price, 0) : '—' }}</td></tr>
@if(($shipment->extra_service ?? 0) > 0)
<tr><td class="label">Extra Service</td><td class="value">{{ number_format($shipment->extra_service) }}</td></tr>
@endif
@if(($shipment->domestic_pickup ?? 0) > 0)
<tr><td class="label">Domestic Pickup</td><td class="value">{{ number_format($shipment->domestic_pickup) }}</td></tr>
@endif
@if(($shipment->packing_cost ?? 0) > 0)
<tr><td class="label">Packing Cost</td><td class="value">{{ number_format($shipment->packing_cost) }}</td></tr>
@endif
@if(($shipment->domestic_delivery ?? 0) > 0)
<tr><td class="label">Domestic Delivery</td><td class="value">{{ number_format($shipment->domestic_delivery) }}</td></tr>
@endif
@if(($shipment->warehousing_cost ?? 0) > 0)
<tr><td class="label">Warehousing</td><td class="value">{{ number_format($shipment->warehousing_cost) }}</td></tr>
@endif
@if(($shipment->discount ?? 0) > 0)
<tr><td class="label">Discount</td><td class="value" style="color:#dc2626;">-{{ number_format($shipment->discount) }}</td></tr>
@endif
<tr class="total-row"><td class="label">TOTAL FEE</td><td class="value">{{ number_format($shipment->total_fee ?? 0) }} IRR</td></tr>
@if($shipment->cod_amount)
<tr><td class="label">Cash on Delivery</td><td class="value">{{ number_format($shipment->cod_amount, 0) }} AED</td></tr>
@endif
</table>
</td>
</tr>
</table>
<!-- ════════ SHIPMENT DETAILS (Items table — only if items exist) ════════ -->
@if($items->isNotEmpty())
<div class="details-section">
<div class="section-header">SHIPMENT DETAILS</div>
<table class="details-table">
<thead>
<tr>
<th style="width: 5%;">No</th>
<th style="width: 40%;">Description</th>
<th style="width: 15%;">H.S. Code</th>
<th style="width: 10%;">Qty</th>
<th style="width: 15%;">Unit Price (USD)</th>
<th style="width: 15%;">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 class="details-total">
<td colspan="5" style="text-align: right;">Total Invoice Amount (USD):</td>
<td>{{ number_format($invoice_total_usd, 2) }}</td>
</tr>
</tbody>
</table>
</div>
@endif
<!-- ════════ NOTES + SIGNATURE (side by side in landscape) ════════ -->
<table style="width: 100%; table-layout: fixed; border-collapse: collapse; margin-bottom: 6px;">
<tr>
<td style="width: 60%; vertical-align: top; padding-right: 6px;">
<div class="notes" style="height: 45mm;">
<div class="notes-title">⚠ Terms &amp; Conditions</div>
Door-to-door service applies only to general cargo without special approvals. Consignee is responsible for import rules at destination. All shipments are subject to customs approval at origin and destination.
</div>
</td>
<td style="width: 40%; vertical-align: top;">
<table class="signature-table" style="height: 45mm;">
<tr>
<td style="border-left: 1px solid #e5e7eb;">
Shipper Signature
<div class="sig-line"></div>
</td>
<td>
Date
<div class="sig-line">...../...../..........</div>
</td>
</tr>
</table>
</td>
</tr>
</table>
<!-- ════════ FOOTER ════════ -->
<div class="footer">
<div class="footer-brand">IFNEX LOGISTICS — We Deliver Value</div>
<div class="footer-track">Track Your Shipment: http://ifnex.net</div>
<div class="footer-meta">
AWB: {{ $shipment->awb_no }} &nbsp;|&nbsp; Generated: {{ now()->format('Y-m-d H:i') }} &nbsp;|&nbsp; © {{ date('Y') }} IFNEX Logistics
</div>
</div>
</div>
</body>
</html>