@php function numberToWords($number) { $ones = ['','One','Two','Three','Four','Five','Six','Seven','Eight','Nine','Ten', 'Eleven','Twelve','Thirteen','Fourteen','Fifteen','Sixteen','Seventeen','Eighteen','Nineteen']; $tens = ['','','Twenty','Thirty','Forty','Fifty','Sixty','Seventy','Eighty','Ninety']; if ($number == 0) return 'Zero'; $words = ''; $num = (int) $number; if ($num >= 1000) { $words .= numberToWords((int)floor($num/1000)) . ' Thousand '; $num %= 1000; } if ($num >= 100) { $words .= $ones[(int)floor($num/100)] . ' Hundred '; $num %= 100; } if ($num >= 20) { $words .= $tens[(int)floor($num/10)] . ' '; $num %= 10; } if ($num > 0) { $words .= $ones[$num] . ' '; } return trim($words); } $taxType = $invoice->tax_type ?? 'exclusive'; $overallDiscount = (float) ($invoice->discount_amount ?? 0); $totals = \App\Models\Invoice::computeTotals($invoice->line_items, $taxType, $overallDiscount); $itemsSubtotal = $totals['itemsSubtotal']; $lineDiscountTotal = $totals['lineDiscountTotal']; $gstAmount = $totals['gstAmount']; $pstAmount = $totals['pstAmount']; $gstLabel = \App\Models\Invoice::taxSummaryLabel('GST', $totals['gstRateTotal'] ?? 0); $pstLabel = \App\Models\Invoice::taxSummaryLabel('HST/PST', $totals['pstRateTotal'] ?? 0); $totalExact = $totals['totalExact']; $totalRounded = $totals['totalRounded']; $roundedOff = $totals['roundedOff']; $showLineDiscount = $setting->usesLineItemDiscount(); $rawNum = $invoice->invoice_number; $numOnly = ltrim(preg_replace('/^INV-0*/i', '', $rawNum), '0') ?: '0'; $displayNum = '#' . $numOnly; $dueDate = $invoice->due_date ? $invoice->due_date->format('F d, Y') : $invoice->invoice_date->copy()->addDays(30)->format('F d, Y'); @endphp {{-- ─── HEADER ─── --}}
@if(!empty($setting->logo_path) && file_exists(public_path('storage/'.$setting->logo_path))) {{ $setting->business_name }} @else {{ $setting->business_name }} @endif INVOICE
{{ $displayNum }}
Original Copy
{{-- ─── INFO ROW: FROM | AMOUNT DUE ─── --}}
{{ $setting->business_name }}
{{ $setting->address }}
@if($setting->phone) Phone: {{ $setting->phone }}
@endif @if($setting->email) Email: {{ $setting->email }}
@endif @if($setting->website) Website: {{ $setting->website }}
@endif @include('admin.invoices.partials._tax-registration-lines', ['invoiceGstNumber' => $invoice->gst_number ?? null])
{{-- Amount Due black banner --}}
Amount Due: ${{ number_format($totalRounded, 2) }}
{{-- Issue / Due dates box --}}
@if($invoice->payment_terms) @endif
Invoice No: {{ $invoice->invoice_number }}
Terms: {{ \App\Models\Invoice::paymentTermsOptions()[$invoice->payment_terms] ?? $invoice->payment_terms }}
Issue Date: {{ $invoice->invoice_date->format('d - M - Y') }}
Due Date: {{ $dueDate }}
{{-- ─── BILL TO ─── --}}
Bill To
{{ $invoice->customer_name }}
@if($invoice->customer_phone)
{{ $invoice->customer_phone }}
@endif @if($invoice->customer_email)
{{ $invoice->customer_email }}
@endif @if($invoice->customer_address)
{{ $invoice->customer_address }}
@endif @if($invoice->customer_country)
{{ $invoice->customer_country }}
@endif
{{-- ─── ITEMS TABLE ─── --}} @if($showLineDiscount) @endif @if($taxType === 'exclusive') @endif @foreach($invoice->line_items as $i => $item) @php $li = \App\Models\Invoice::computeLineItem($item, $taxType); $itemDesc = $invoice->lineItemDescriptionForDisplay($item, $loop->first); @endphp @if($showLineDiscount) @endif @if($taxType === 'exclusive') @endif @endforeach
# Item & Description Qty PriceDisc%GST HST/PSTAmount
{{ $i + 1 }}
{{ $item['description'] }}
@if($itemDesc)
{!! nl2br(e($itemDesc)) !!}
@endif @if($loop->first && ($linkedItems = $invoice->linkedItemsLabel()))
Item(s): {{ $linkedItems }}
@endif
{{ $li['qty'] % 1 == 0 ? (int)$li['qty'] : $li['qty'] }} ${{ number_format($li['displayRate'], 2) }} @if($li['discPct'] > 0) {{ number_format($li['discPct'], 0) }}% @else @endif @if($li['gstRate'] > 0 || ($li['gstRate'] + $li['pstRate'] === 0.0 && ($item['tax_rate'] ?? 0) > 0)) ${{ number_format($li['gstAmt'], 2) }}
{{ number_format($li['gstRate'] + $li['pstRate'] === 0.0 ? ($item['tax_rate'] ?? 0) : $li['gstRate'], 0) }}% @else @endif
@if($li['pstRate'] > 0) ${{ number_format($li['pstAmt'], 2) }}
{{ number_format($li['pstRate'], 0) }}% @else @endif
${{ number_format($li['rowAmt'], 2) }}
{{-- ─── BOTTOM: Terms (left) | Summary (right) ─── --}} {{-- Left: Terms & Conditions + Payment info --}} {{-- Right: Summary table --}}
@if($invoice->notes)
Terms & Conditions
@php $notesContent = $invoice->notes; // If it's plain text (no HTML tags), convert newlines to
$notesHtml = (strip_tags($notesContent) === $notesContent) ? nl2br(e($notesContent)) : $notesContent; @endphp
{!! $notesHtml !!}
@endif @php $termsContent = $setting->terms_conditions ?? ''; $termsHtml = (strip_tags($termsContent) === $termsContent) ? nl2br(e($termsContent)) : $termsContent; @endphp @if($termsContent)
{!! $termsHtml !!}
@else
Please make E-Transfer Payment at {{ $setting->email }}
@endif
@if($showLineDiscount && $lineDiscountTotal > 0) @endif @if($overallDiscount > 0) @endif @if($taxType !== 'inclusive' && $gstAmount > 0) @endif @if($taxType !== 'inclusive' && $pstAmount > 0) @endif
Subtotal ${{ number_format($itemsSubtotal, 2) }}
Discount -${{ number_format($lineDiscountTotal, 2) }}
Overall Discount{{ $invoice->discount_type === 'percent' ? ' ('.$invoice->discount_value.'%)' : '' }} -${{ number_format($overallDiscount, 2) }}
{{ $gstLabel }} ${{ number_format($gstAmount, 2) }}
{{ $pstLabel }} ${{ number_format($pstAmount, 2) }}
Total before rounding ${{ number_format($totalExact, 2) }}
Rounded Off {{ $roundedOff >= 0 ? '+' : '' }}{{ number_format($roundedOff, 2) }}
TOTAL ${{ number_format($totalRounded, 2) }}
* $ {{ numberToWords($totalRounded) }} Only