@php $primary = $setting?->primary_color ?: '#124a61'; $accent = $setting?->accent_color ?: '#2e86ab'; $companyName = $setting?->company_name ?: $invoice->team?->name; $symbol = $currencySymbol ?: ''; $code = $invoice->currency_code ?: ''; $money = function ($value) use ($symbol, $code) { $formatted = number_format((float) $value, 2); return ($symbol !== '' ? $symbol . ' ' : ($code !== '' ? $code . ' ' : '')) . $formatted; }; $logoUrl = $setting?->logoSrc(); // Where to pay, for this invoice's currency only, resolved through the same // helper the PDF uses so the page and the download always agree — including // on whether the bank details show at all, which follows the invoice's // payment method. $banking = \App\Support\DocumentBanking::for( $invoice->team_id, $invoice->currency_code, $setting, $invoice->paymentMethod ); $hasBanking = $banking['showsBanking']; $hasBalance = (float) $invoice->balance_due > 0.01 && ! in_array($invoice->status, ['VOID', 'PAID'], true); $paynowConfigured = $paynowConfigured ?? false; $canPayOnline = $hasBalance && $paynowConfigured; $isPaid = ! $hasBalance && $invoice->status !== 'VOID'; $total = (float) $invoice->total; $paid = (float) $invoice->amount_paid; $paidPct = $total > 0 ? min(100, round(($paid / $total) * 100)) : ($isPaid ? 100 : 0); $itemCount = $invoice->lineItems->count(); // Status as a customer would say it, not as the database stores it. $statusMeta = [ 'UNPAID' => ['label' => __('Unpaid'), 'icon' => 'shield-check', 'bg' => '#fff7ed', 'text' => '#c2410c'], 'PARTIAL' => ['label' => __('Partially paid'), 'icon' => 'clock', 'bg' => '#fefce8', 'text' => '#a16207'], 'PAID' => ['label' => __('Paid'), 'icon' => 'check', 'bg' => '#ecfdf5', 'text' => '#047857'], 'OVERDUE' => ['label' => __('Unpaid, overdue'), 'icon' => 'exclamation-triangle','bg' => '#fff1f2', 'text' => '#be123c'], 'VOID' => ['label' => __('Cancelled'), 'icon' => 'x-mark', 'bg' => '#f1f5f9', 'text' => '#475569'], ]; $status = $statusMeta[$invoice->isOverdue() ? 'OVERDUE' : $invoice->displayStatus()]; // Wallets Paynow can push a prompt to. Each shows its own logo from // public/images/wallets/ when the file is there, and falls back to a // wordmark in the brand colour so a missing asset never breaks the card. $walletLogo = function (string $slug): ?string { foreach (['svg', 'png', 'webp'] as $extension) { $path = "images/wallets/{$slug}.{$extension}"; if (is_file(public_path($path))) { return asset($path); } } return null; }; // Until the logo files land, each wallet is drawn as its own two-tone // wordmark, which is how all three brands actually split their colours. // Closer to the real mark than one flat colour, and it never 404s. // Each logo gets its own height. A wordmark 5x wider than it is tall and a // stacked mark only 2x wider cannot share one, sizing them alike leaves the // stacked one a smudge. Heights are optical, matched by eye at 100% zoom. $wallets = [ 'ecocash' => [ 'label' => 'EcoCash', 'hint' => __('Econet'), 'tone' => '#e5262c', 'height' => 'h-[17px]', 'parts' => [['Eco', '#0056a4'], ['Cash', '#e5262c']], ], 'onemoney' => [ 'label' => 'OneMoney', 'hint' => __('NetOne'), 'tone' => '#f58220', 'height' => 'h-[30px]', 'parts' => [['One', '#231f20'], ['Money', '#f58220']], ], 'innbucks' => [ 'label' => 'InnBucks', 'hint' => __('Any network'), 'tone' => '#12284c', 'height' => 'h-[19px]', 'parts' => [['Inn', '#12284c'], ['Bucks', '#12284c']], 'dots' => ['#f3b41b', '#8e5ea2', '#2faf8e', '#e1252b'], ], ]; foreach ($wallets as $slug => $wallet) { $wallets[$slug]['logo'] = $walletLogo($slug); } $selectedWallet = old('method', 'ecocash'); @endphp
{{ $companyName }}
{{ $isPaid ? __('Amount paid') : __('Amount due') }}
{{ $isPaid ? $money($invoice->total) : $money($invoice->balance_due) }}
@if ($isPaid)
{{ $money($paid) }} {{ __('of') }} {{ $money($total) }} {{ __('paid') }}
{{ __('Due') }} {{ $invoice->due_date->format('M j, Y') }}
@endif{{ __('Secure online payments through Paynow.') }}
{{ __('Pay via Visa / Mastercard through Paynow Secure Payments.') }}
{{ __('Secured by Paynow. :company never sees your PIN or card details.', ['company' => $companyName]) }}
{{ $method->name }} @if ($method->instructions) {{ $method->instructions }} @endif
@endforeach{{ $payment->channel }}
{{ optional($payment->paid_at)->format('d M Y') }} @if ($payment->reference) · {{ $payment->reference }} @endif @if ((float) $payment->surcharge > 0) · +{{ $money($payment->surcharge) }} {{ __('fee') }} @endif
{{ $money($payment->amount) }}
{{ __('Notes') }}
{{ $invoice->notes }}
{{ __('Banking Details') }} @if ($banking['accounts']->isNotEmpty()) · {{ $invoice->currency_code }} @endif
{{ __('Terms & Conditions') }}
{{ $line->name }}
@if ($line->description){!! nl2br(e($line->description)) !!}
@endif{{ rtrim(rtrim(number_format((float) $line->qty, 2), '0'), '.') }} × {{ $money($line->unit_price) }}
{{ $money($line->line_total) }}
{{ __('No items.') }}
@endforelse{{ $companyName }}
@if ($setting?->email || $setting?->phone){{ __('Questions about this invoice?') }} @if ($setting?->email) {{ $setting->email }} @endif @if ($setting?->email && $setting?->phone) · @endif @if ($setting?->phone) {{ $setting->phone }} @endif
@endif