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.
483 lines
20 KiB
PHP
483 lines
20 KiB
PHP
<!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 }} | 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 & 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 }} | Generated: {{ now()->format('Y-m-d H:i') }} | © {{ date('Y') }} IFNEX Logistics
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</body>
|
||
</html> |