Files
Kent-logistics-Laravel/resources/views/admin/pdf/invoice.blade.php

623 lines
24 KiB
PHP
Raw Normal View History

2025-11-17 10:33:11 +05:30
<!DOCTYPE html>
<html lang="en">
2025-11-17 10:33:11 +05:30
<head>
<meta charset="UTF-8">
<title>Invoice #{{ $invoice->invoice_number }}</title>
2025-11-17 10:33:11 +05:30
<style>
body {
font-family: 'DejaVu Sans', sans-serif;
font-size: 10px;
color: #1a202c;
line-height: 1.4;
2025-11-21 16:15:10 +05:30
margin: 0;
padding: 18px;
background: #fff;
}
/* ── TOP HEADER ── */
.top-header {
margin-bottom: 8px;
border-bottom: 2px solid #1a202c;
padding-bottom: 6px;
}
.header-table {
width: 100%;
border-collapse: collapse;
}
.header-table td {
vertical-align: middle;
2025-11-21 16:15:10 +05:30
padding: 0;
2025-11-17 10:33:11 +05:30
}
/* Logo cell — fixed width, logo fits inside */
.logo-cell {
width: 60px;
}
.logo-cell img {
width: 55px;
height: 55px;
display: block;
}
/* Company name cell */
.title-cell {
padding-left: 10px;
text-align: left;
}
.company-name {
font-size: 18px;
2025-11-17 10:33:11 +05:30
font-weight: bold;
color: #1a202c;
text-transform: uppercase;
letter-spacing: 2px;
2025-11-17 10:33:11 +05:30
}
.company-subtitle {
font-size: 11px;
font-weight: bold;
color: #2d3748;
letter-spacing: 1px;
}
.company-tagline {
font-size: 8px;
color: #718096;
margin-top: 3px;
}
/* ── INFO TABLE (Customer | Invoice side by side) ── */
.info-outer {
width: 100%;
border-collapse: collapse;
border: 1px solid #cbd5e0;
margin-bottom: 10px;
2025-11-17 10:33:11 +05:30
}
.info-outer td {
vertical-align: top;
padding: 10px 12px;
2025-11-21 16:15:10 +05:30
}
.info-left { width: 50%; }
.info-right { width: 50%; border-left: 1px solid #cbd5e0; }
.section-title {
font-size: 8px;
2025-11-17 10:33:11 +05:30
font-weight: bold;
text-transform: uppercase;
letter-spacing: 1px;
color: #718096;
border-bottom: 1px solid #e2e8f0;
padding-bottom: 3px;
margin-bottom: 5px;
2025-11-17 10:33:11 +05:30
}
.info-line {
font-size: 9px;
color: #2d3748;
2025-11-21 16:15:10 +05:30
margin-bottom: 2px;
line-height: 1.5;
2025-11-21 16:15:10 +05:30
}
/* ── STATUS BADGE ── */
.badge {
display: inline;
padding: 2px 6px;
font-size: 8px;
2025-11-21 16:15:10 +05:30
font-weight: bold;
text-transform: uppercase;
border-radius: 3px;
}
.badge-paid { background: #c6f6d5; color: #22543d; }
.badge-pending { background: #fef3c7; color: #92400e; }
.badge-paying { background: #dbeafe; color: #1e40af; }
.badge-overdue { background: #fee2e2; color: #991b1b; }
/* ── BILL TO ── */
.bill-to-box {
border: 1px solid #cbd5e0;
padding: 8px 12px;
margin-bottom: 10px;
background: #f7fafc;
2025-11-21 16:15:10 +05:30
}
.bill-to-label {
font-size: 8px;
font-weight: bold;
text-transform: uppercase;
letter-spacing: 1px;
color: #718096;
margin-bottom: 4px;
2025-11-17 10:33:11 +05:30
}
.bill-name { font-size: 12px; font-weight: bold; color: #1a202c; margin-bottom: 2px; }
.bill-sub { font-size: 10px; font-weight: bold; color: #2d3748; margin-bottom: 2px; }
.bill-detail { font-size: 9px; color: #4a5568; line-height: 1.8; }
2025-11-17 10:33:11 +05:30
/* ── SUMMARY GRID — 4 boxes per row ── */
.summary-wrap { margin-bottom: 12px; }
.summary-label {
font-size: 9px;
2025-11-17 10:33:11 +05:30
font-weight: bold;
text-transform: uppercase;
letter-spacing: 1px;
color: #4a5568;
2025-11-21 16:15:10 +05:30
margin-bottom: 4px;
2025-11-17 10:33:11 +05:30
}
.summary-outer {
width: 100%;
border-collapse: collapse;
}
.sbox {
width: 25%;
border: 1px solid #cbd5e0;
padding: 7px 8px;
text-align: center;
vertical-align: middle;
}
.sbox-row1 { background: #ffffff; }
.sbox-row2 { background: #f7fafc; }
.sbox-lbl {
font-size: 7px;
font-weight: bold;
text-transform: uppercase;
letter-spacing: 1px;
color: #718096;
margin-bottom: 3px;
}
.sbox-val {
font-size: 11px;
font-weight: bold;
color: #1a202c;
}
.sbox-sub {
font-size: 7px;
color: #a0aec0;
margin-top: 1px;
2025-11-17 10:33:11 +05:30
}
/* ── CHARGE GROUPS ── */
.cg-header {
font-size: 10px;
font-weight: bold;
color: #ffffff;
background: #2d3748;
padding: 5px 10px;
text-transform: uppercase;
letter-spacing: 1px;
}
.cg-group-wrap {
border: 1px solid #cbd5e0;
margin-bottom: 10px;
}
.cg-sum-table {
2025-11-17 10:33:11 +05:30
width: 100%;
border-collapse: collapse;
font-size: 9px;
2025-11-17 10:33:11 +05:30
}
.cg-sum-table th {
background: #edf2f7;
padding: 5px;
font-size: 8px;
font-weight: bold;
text-transform: uppercase;
color: #4a5568;
border: 1px solid #cbd5e0;
2025-11-21 16:15:10 +05:30
text-align: left;
2025-11-17 10:33:11 +05:30
}
.cg-sum-table td {
padding: 5px;
border: 1px solid #cbd5e0;
color: #2d3748;
font-size: 9px;
2025-11-21 16:15:10 +05:30
}
.cg-item-table {
width: 100%;
border-collapse: collapse;
font-size: 8px;
2025-11-21 16:15:10 +05:30
}
.cg-item-table th {
background: #f0fff4;
padding: 4px 5px;
font-size: 7px;
2025-11-21 16:15:10 +05:30
font-weight: bold;
text-transform: uppercase;
color: #276749;
border: 1px solid #c6f6d5;
text-align: left;
white-space: nowrap;
2025-11-21 16:15:10 +05:30
}
.cg-item-table td {
padding: 4px 5px;
border: 1px solid #e2e8f0;
color: #2d3748;
white-space: nowrap;
2025-11-21 16:15:10 +05:30
}
.row-even { background: #f7fafc; }
/* ── GRAND TOTAL ── */
.grand-outer {
width: 100%;
border-collapse: collapse;
margin-top: 10px;
margin-bottom: 10px;
2025-11-18 14:35:58 +05:30
}
.grand-spacer { width: 60%; }
.grand-inner { width: 40%; vertical-align: top; }
.grand-table { width: 100%; border-collapse: collapse; font-size: 9px; }
.grand-table td { padding: 4px 8px; border: 1px solid #e2e8f0; }
.g-lbl { text-align: right; font-weight: bold; color: #4a5568; background: #f7fafc; }
.g-val { text-align: right; font-weight: bold; color: #1a202c; }
.g-total-lbl { text-align: right; font-size: 11px; font-weight: bold; color: #1a202c; background: #ebf8ff; border-top: 2px solid #2b6cb0; }
.g-total-val { text-align: right; font-size: 11px; font-weight: bold; color: #1a202c; background: #ebf8ff; border-top: 2px solid #2b6cb0; }
/* ── INSTALLMENTS ── */
.install-section { margin-top: 12px; }
.install-header {
font-size: 9px;
font-weight: bold;
color: #fff;
background: #2d3748;
padding: 5px 10px;
text-transform: uppercase;
letter-spacing: 1px;
2025-11-18 14:35:58 +05:30
}
.install-table { width: 100%; border-collapse: collapse; font-size: 9px; }
.install-table th {
background: #edf2f7;
padding: 5px 6px;
font-size: 8px;
font-weight: bold;
text-transform: uppercase;
color: #4a5568;
border: 1px solid #cbd5e0;
2025-11-17 10:33:11 +05:30
}
.install-table td { padding: 4px 6px; border: 1px solid #e2e8f0; color: #2d3748; }
/* ── HELPERS ── */
.tr { text-align: right; }
.tc { text-align: center; }
.bold { font-weight: bold; }
/* ── FOOTER ── */
2025-11-21 16:15:10 +05:30
.footer {
margin-top: 16px;
padding-top: 8px;
border-top: 1px solid #e2e8f0;
font-size: 8px;
color: #718096;
2025-11-21 16:15:10 +05:30
text-align: center;
}
2025-11-17 10:33:11 +05:30
</style>
</head>
<body>
{{-- ══ VARIABLES ══ --}}
@php
$companyName = $invoice->company_name ?: ($invoice->customer->company_name ?? null);
$custName = $invoice->customer_name;
$custAddress = $invoice->customer_address ?: ($invoice->customer->address ?? null);
$custPincode = $invoice->pincode ?: ($invoice->customer->pincode ?? null);
$custEmail = $invoice->customer_email ?: ($invoice->customer->email ?? null);
$custMobile = $invoice->customer_mobile ?: ($invoice->customer->mobile_no ?? null);
@endphp
{{-- ══ 1) HEADER Logo + Company Name ══ --}}
<div class="top-header">
<table class="header-table">
<tr>
{{-- Logo: 55x55px DomPDF साठी public_path() वापरतो --}}
<td class="logo-cell">
<img src="{{ public_path('images/kent_logo2.png') }}" alt="Logo" width="55" height="55">
</td>
{{-- Company Name + Subtitle + Tagline --}}
<td class="title-cell">
<div class="company-name">KENT</div>
<div class="company-subtitle">International Pvt. Ltd.</div>
<div class="company-tagline">
Address Line 1, City, State Pincode &nbsp;|&nbsp;
Email: info@company.com &nbsp;|&nbsp;
Phone: +91 1234567890
2025-11-21 16:15:10 +05:30
</div>
</td>
</tr>
</table>
</div>
{{-- ══ 2) CUSTOMER | INVOICE ══ --}}
<table class="info-outer">
<tr>
<td class="info-left">
<div class="section-title">Customer Details</div>
@if($companyName)
<div class="info-line bold" style="font-size:11px;">{{ $companyName }}</div>
<div class="info-line">{{ $custName }}</div>
@else
<div class="info-line bold" style="font-size:11px;">{{ $custName }}</div>
@endif
@if($custAddress)<div class="info-line">{{ $custAddress }}</div>@endif
@if($custPincode)<div class="info-line">{{ $custPincode }}</div>@endif
@if($custEmail)<div class="info-line">Email: {{ $custEmail }}</div>@endif
@if($custMobile)<div class="info-line">Phone: {{ $custMobile }}</div>@endif
</td>
<td class="info-right">
<div class="section-title">Invoice Details</div>
<div class="info-line"><strong>Invoice #:</strong> {{ $invoice->invoice_number }}</div>
<div class="info-line"><strong>Date:</strong> {{ \Carbon\Carbon::parse($invoice->invoice_date)->format('d M, Y') }}</div>
<div class="info-line"><strong>Due Date:</strong> {{ \Carbon\Carbon::parse($invoice->due_date)->format('d M, Y') }}</div>
<div class="info-line">
<strong>Status:</strong>
<span class="badge badge-{{ strtolower($invoice->status) }}">{{ strtoupper($invoice->status) }}</span>
2025-11-21 16:15:10 +05:30
</div>
<div class="info-line"><strong>GST Type:</strong> {{ strtoupper($invoice->tax_type ?? 'GST') }}</div>
<div class="info-line"><strong>GST %:</strong> {{ number_format($invoice->gst_percent ?? 0, 2) }}%</div>
</td>
</tr>
</table>
{{-- ══ 3) BILL TO ══ --}}
<div class="bill-to-box">
<div class="bill-to-label">Bill To</div>
@if($companyName)
<div class="bill-name">{{ $companyName }}</div>
<div class="bill-sub">{{ $custName }}</div>
@else
<div class="bill-name">{{ $custName }}</div>
@endif
<div class="bill-detail">
@if($custAddress){{ $custAddress }}<br>@endif
@if($custPincode){{ $custPincode }}<br>@endif
@if($custEmail)Email: {{ $custEmail }}<br>@endif
@if($custMobile)Phone: {{ $custMobile }}@endif
</div>
</div>
{{-- ══ 4) 8 SUMMARY BOXES ══ --}}
@php
$allGroupItems = $invoice->chargeGroups->flatMap(fn($g) => $g->items);
$invoiceItemIds = $allGroupItems->pluck('invoice_item_id')->unique()->values();
$invoiceItems = $invoice->items->whereIn('id', $invoiceItemIds);
$totalMarkCount = $invoiceItems->pluck('mark_no')->filter()->unique()->count();
$totalCtn = $invoiceItems->sum('ctn');
$totalQty = $invoiceItems->sum('ttl_qty');
$totalCbm = $invoiceItems->sum('ttl_cbm');
$totalKg = $invoiceItems->sum('ttl_kg');
@endphp
<div class="summary-wrap">
<div class="summary-label">Container &amp; Shipment Summary</div>
<table class="summary-outer">
<tr>
<td class="sbox sbox-row1">
<div class="sbox-lbl">Container Name</div>
<div class="sbox-val">{{ $invoice->container->container_name ?? '—' }}</div>
</td>
<td class="sbox sbox-row1">
<div class="sbox-lbl">Container Date</div>
<div class="sbox-val">
@if($invoice->container && $invoice->container->container_date)
{{ \Carbon\Carbon::parse($invoice->container->container_date)->format('d M, Y') }}
@else@endif
2025-11-21 16:15:10 +05:30
</div>
</td>
<td class="sbox sbox-row1">
<div class="sbox-lbl">Container No.</div>
<div class="sbox-val">{{ $invoice->container->container_number ?? '—' }}</div>
</td>
<td class="sbox sbox-row1">
<div class="sbox-lbl">Total Mark No.</div>
<div class="sbox-val">{{ $totalMarkCount }}</div>
<div class="sbox-sub">Unique marks</div>
</td>
</tr>
<tr>
<td class="sbox sbox-row2">
<div class="sbox-lbl">Total CTN</div>
<div class="sbox-val">{{ number_format($totalCtn, 0) }}</div>
<div class="sbox-sub">Cartons</div>
</td>
<td class="sbox sbox-row2">
<div class="sbox-lbl">Total QTY</div>
<div class="sbox-val">{{ number_format($totalQty, 0) }}</div>
<div class="sbox-sub">Pieces</div>
</td>
<td class="sbox sbox-row2">
<div class="sbox-lbl">Total CBM</div>
<div class="sbox-val">{{ number_format($totalCbm, 3) }}</div>
<div class="sbox-sub">Cubic Meter</div>
</td>
<td class="sbox sbox-row2">
<div class="sbox-lbl">Total KG</div>
<div class="sbox-val">{{ number_format($totalKg, 2) }}</div>
<div class="sbox-sub">Kilograms</div>
</td>
</tr>
</table>
</div>
{{-- ══ 5) CHARGE GROUPS ══ --}}
@if($invoice->chargeGroups && $invoice->chargeGroups->count() > 0)
<div style="margin-bottom:14px;">
<div class="cg-header">Charge Groups</div>
@foreach($invoice->chargeGroups as $group)
@php
$groupItemIds = $group->items->pluck('invoice_item_id')->toArray();
$groupInvItems = $invoice->items->whereIn('id', $groupItemIds);
@endphp
<div class="cg-group-wrap">
<table class="cg-sum-table">
<thead>
2025-11-21 16:15:10 +05:30
<tr>
<th style="width:22%;">Group Name</th>
<th style="width:11%;">Basis</th>
<th style="width:11%;">Basis Value</th>
<th style="width:10%;">Rate</th>
<th style="width:13%;" class="tr">Total Charge</th>
<th style="width:8%;">GST %</th>
<th style="width:9%;">Tax Type</th>
<th style="width:16%;" class="tr">Total With GST</th>
2025-11-21 16:15:10 +05:30
</tr>
</thead>
<tbody>
2025-11-21 16:15:10 +05:30
<tr>
<td><strong>{{ $group->group_name ?? 'Group '.$group->id }}</strong></td>
<td>{{ strtoupper($group->basis_type) }}</td>
<td>{{ number_format($group->basis_value, 3) }}</td>
<td>{{ number_format($group->rate, 2) }}</td>
<td class="tr">{{ number_format($group->total_charge, 2) }}</td>
<td>{{ number_format($group->gst_percent ?? 0, 2) }}%</td>
<td>{{ strtoupper($group->tax_type ?? 'GST') }}</td>
<td class="tr"><strong>{{ number_format($group->total_with_gst, 2) }}</strong></td>
2025-11-21 16:15:10 +05:30
</tr>
</tbody>
</table>
@if($groupInvItems->count() > 0)
<table class="cg-item-table">
<thead>
<tr>
<th style="width:3%;">#</th>
<th style="width:15%;">Description</th>
<th style="width:7%;">Mark No</th>
<th style="width:5%;" class="tc">QTY</th>
<th style="width:6%;" class="tr">TTL QTY</th>
<th style="width:6%;" class="tr">CBM</th>
<th style="width:6%;" class="tr">TTL CBM</th>
<th style="width:5%;" class="tr">KG</th>
<th style="width:6%;" class="tr">TTL KG</th>
<th style="width:7%;" class="tr">TTL Amt</th>
<th style="width:5%;" class="tr">Rate</th>
<th style="width:7%;" class="tr">Total Charge</th>
<th style="width:5%;" class="tr">GST %</th>
<th style="width:6%;" class="tr">Item GST</th>
<th style="width:6%;" class="tr">Item Total</th>
</tr>
</thead>
<tbody>
@foreach($groupInvItems as $idx => $item)
@php
$groupBasisTotal = $groupInvItems->sum(function($i) use ($group) {
return match($group->basis_type) {
'ttl_qty' => $i->ttl_qty ?? 0,
'ttl_cbm' => $i->ttl_cbm ?? 0,
'ttl_kg' => $i->ttl_kg ?? 0,
'amount' => $i->ttl_amount ?? 0,
default => $i->ttl_amount ?? 0,
};
});
$itemBasisValue = match($group->basis_type) {
'ttl_qty' => $item->ttl_qty ?? 0,
'ttl_cbm' => $item->ttl_cbm ?? 0,
'ttl_kg' => $item->ttl_kg ?? 0,
'amount' => $item->ttl_amount ?? 0,
default => $item->ttl_amount ?? 0,
};
$itemCharge = $groupBasisTotal > 0
? ($itemBasisValue / $groupBasisTotal) * $group->total_charge
: 0;
$gstPct = $group->gst_percent ?? 0;
$itemGst = $itemCharge * $gstPct / 100;
$itemTotal = $itemCharge + $itemGst;
@endphp
<tr class="{{ $idx % 2 === 1 ? 'row-even' : '' }}">
<td class="tc">{{ $idx + 1 }}</td>
<td>{{ $item->description }}</td>
<td>{{ $item->mark_no ?? '—' }}</td>
<td class="tc">{{ $item->qty ?? 0 }}</td>
<td class="tr">{{ number_format($item->ttl_qty ?? 0, 0) }}</td>
<td class="tr">{{ number_format($item->cbm ?? 0, 3) }}</td>
<td class="tr">{{ number_format($item->ttl_cbm ?? 0, 3) }}</td>
<td class="tr">{{ number_format($item->kg ?? 0, 2) }}</td>
<td class="tr">{{ number_format($item->ttl_kg ?? 0, 2) }}</td>
<td class="tr">{{ number_format($item->ttl_amount ?? 0, 2) }}</td>
<td class="tr">{{ number_format($group->rate, 2) }}</td>
<td class="tr">{{ number_format($itemCharge, 2) }}</td>
<td class="tr">{{ number_format($gstPct, 2) }}%</td>
<td class="tr">{{ number_format($itemGst, 2) }}</td>
<td class="tr"><strong>{{ number_format($itemTotal, 2) }}</strong></td>
</tr>
2025-11-21 16:15:10 +05:30
@endforeach
</tbody>
</table>
@endif
</div>
@endforeach
</div>
@endif
{{-- ══ GRAND TOTAL ══ --}}
<table class="grand-outer">
<tr>
<td class="grand-spacer"></td>
<td class="grand-inner">
<table class="grand-table">
<tr>
<td class="g-lbl">Charge Groups Total:</td>
<td class="g-val">{{ number_format($invoice->charge_groups_total ?? 0, 2) }}</td>
2025-11-21 16:15:10 +05:30
</tr>
<tr>
<td class="g-lbl">GST Amount ({{ number_format($invoice->gst_percent ?? 0, 2) }}%):</td>
<td class="g-val">{{ number_format($invoice->gst_amount ?? 0, 2) }}</td>
2025-11-21 16:15:10 +05:30
</tr>
<tr>
<td class="g-total-lbl">Grand Total:</td>
<td class="g-total-val">{{ number_format($invoice->grand_total_with_charges ?? 0, 2) }}</td>
2025-11-21 16:15:10 +05:30
</tr>
</table>
</td>
</tr>
</table>
{{-- ══ INSTALLMENTS ══ --}}
@if($invoice->installments && $invoice->installments->count() > 0)
<div class="install-section">
<div class="install-header">Payment Installments</div>
<table class="install-table">
<thead>
<tr>
<th style="width:6%;" class="tc">#</th>
<th style="width:20%;">Date</th>
<th style="width:25%;">Payment Method</th>
<th style="width:25%;">Reference No</th>
<th style="width:24%;" class="tr">Amount ()</th>
</tr>
</thead>
<tbody>
@foreach($invoice->installments as $idx => $inst)
<tr>
<td class="tc">{{ $idx + 1 }}</td>
<td>{{ \Carbon\Carbon::parse($inst->installment_date)->format('d M, Y') }}</td>
<td>{{ strtoupper($inst->payment_method) }}</td>
<td>{{ $inst->reference_no ?? '—' }}</td>
<td class="tr">{{ number_format($inst->amount, 2) }}</td>
</tr>
@endforeach
</tbody>
</table>
@php
$totalPaid = $invoice->installments->sum('amount');
$grandTotal = $invoice->grand_total_with_charges ?? 0;
$remaining = max(0, $grandTotal - $totalPaid);
@endphp
<table class="grand-outer" style="margin-top:6px;">
<tr>
<td class="grand-spacer"></td>
<td class="grand-inner">
<table class="grand-table">
<tr>
<td class="g-lbl" style="color:#059669;">Total Paid:</td>
<td class="g-val" style="color:#059669;">{{ number_format($totalPaid, 2) }}</td>
</tr>
<tr>
<td class="g-lbl" style="color:#dc2626;">Remaining:</td>
<td class="g-val" style="color:#dc2626;">{{ number_format($remaining, 2) }}</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
@endif
{{-- ══ FOOTER ══ --}}
<div class="footer">
Thank you for your business! &nbsp;|&nbsp; For queries: info@company.com &nbsp;|&nbsp; +91 1234567890
</div>
2025-11-17 10:33:11 +05:30
</body>
</html>