@php $logoPath = (string) config('invoice.logo_path', resource_path('filament/images/logo.png')); $logoDataUri = null; if ($logoPath !== '' && is_file($logoPath)) { $mime = mime_content_type($logoPath) ?: 'image/png'; $binary = file_get_contents($logoPath); if ($binary !== false) { $logoDataUri = 'data:'.$mime.';base64,'.base64_encode($binary); } } $placeName = (string) ($invoice->place_snapshot['name'] ?? ''); $companyName = (string) ($invoice->place_snapshot['company_name'] ?? $placeName); $companyAddress = (string) ($invoice->place_snapshot['company_address'] ?? ($invoice->place_snapshot['address'] ?? '')); $companyPhone = (string) ($invoice->place_snapshot['company_phone'] ?? ($invoice->place_snapshot['phone'] ?? '')); $companyWebsite = (string) ($invoice->place_snapshot['company_website'] ?? ''); $companyEmail = (string) ($invoice->place_snapshot['company_email'] ?? ($invoice->place_snapshot['email'] ?? '')); $companyTin = (string) ($invoice->place_snapshot['company_tin'] ?? ($invoice->place_snapshot['registration_number'] ?? '')); $customerName = (string) ($invoice->customer_snapshot['name'] ?? ''); $billToPrimary = trim((string) ($invoice->customer_snapshot['bill_to_primary'] ?? $customerName)); $billToSecondary = trim((string) ($invoice->customer_snapshot['bill_to_secondary'] ?? '')); $billToAddress = trim((string) ($invoice->customer_snapshot['postal_address'] ?? '')); $billToEmail = trim((string) ($invoice->customer_snapshot['bill_to_email'] ?? ($invoice->customer_snapshot['email'] ?? ''))); $issuedDate = $invoice->issued_at->format('d/m/Y'); $currency = strtoupper((string) $invoice->total_currency); $symbol = match ($currency) { 'USD', 'BSD' => '$', 'EUR' => '€', default => $currency, }; $symbolByCurrency = static function (string $currencyCode): string { return match (strtoupper(trim($currencyCode))) { 'USD', 'BSD' => '$', 'EUR' => '€', default => strtoupper(trim($currencyCode)), }; }; $vatRaw = $invoice->place_snapshot['vat'] ?? 0; $vatRate = is_numeric($vatRaw) ? (float) $vatRaw : 0.0; $vatFraction = $vatRate > 1 ? ($vatRate / 100) : $vatRate; $vatDisplay = $vatRate > 1 ? $vatRate : ($vatRate * 100); $totalMinor = (int) $invoice->total_amount; if ($vatFraction > 0) { $subtotalMinor = (int) round($totalMinor / (1 + $vatFraction)); $taxMinor = $totalMinor - $subtotalMinor; } else { $subtotalMinor = $totalMinor; $taxMinor = 0; } $paymentLines = config("invoice.payment_instructions.{$currency}", config('invoice.payment_instructions.default', [])); if (! is_array($paymentLines) || count($paymentLines) === 0) { $paymentLines = match ($currency) { 'USD' => [ 'USD Currency', 'Beneficiary Name: Champion Spirit International Ltd.', 'Beneficiary Address: Lot 9 & 10 South Ocean Road, Little Cocoa Hill, Nassau, The Bahamas', 'Intermediary Bank: JP Morgan Chase', 'SWIFT Code: CHASUS33', 'Beneficiary Bank: RBC Royal Bank (Bahamas) Limited', 'SWIFT Code: ROYCBSNS', 'Branch Number: 30785', 'Account Number: 4000006', 'We also offer Bitcoin / Cryptocurrency as method of payment.', ], 'BSD' => [ 'BSD Currency', 'Beneficiary Name: Champion Spirit International Ltd.', 'Beneficiary Address: Lot 9 & 10 South Ocean Road, Little Cocoa Hill, Nassau, The Bahamas', 'Beneficiary Bank: RBC Royal Bank (Bahamas) Limited', 'Branch Number: 30785', 'Account Number: 1000017', ], default => [ 'Beneficiary Name: Champion Spirit International Ltd.', 'Beneficiary Address: Lot 9 & 10 South Ocean Road, Little Cocoa Hill, Nassau, The Bahamas', 'Beneficiary Bank: RBC Royal Bank (Bahamas) Limited', ], }; } $paymentEntriesRaw = data_get($invoice->customer_snapshot, 'payments', []); $paymentEntries = []; if (is_array($paymentEntriesRaw)) { foreach ($paymentEntriesRaw as $entry) { if (! is_array($entry)) { continue; } $paymentEntries[] = [ 'type' => strtoupper(trim((string) ($entry['type'] ?? ''))), 'date' => trim((string) ($entry['date'] ?? '')), 'amount_minor' => is_numeric($entry['amount_minor'] ?? null) ? (int) $entry['amount_minor'] : null, 'currency' => strtoupper(trim((string) ($entry['currency'] ?? $currency))), ]; } } if ($paymentEntries === []) { $paymentDetails = is_array($order->payment_details ?? null) ? $order->payment_details : []; $paymentType = strtoupper((string) ($order->payment_provider?->value ?? 'unknown')); $paymentTimezone = (string) ($order->place?->timezone ?? config('app.timezone')); $paidAtRaw = data_get($paymentDetails, 'paid_at'); $paidAt = null; if ($paidAtRaw instanceof \DateTimeInterface) { $paidAt = \Carbon\CarbonImmutable::instance($paidAtRaw); } elseif (is_numeric($paidAtRaw)) { $paidAt = \Carbon\CarbonImmutable::createFromTimestamp((int) $paidAtRaw); } elseif (is_string($paidAtRaw) && trim($paidAtRaw) !== '') { try { $paidAt = \Carbon\CarbonImmutable::parse($paidAtRaw); } catch (\Throwable) { $paidAt = null; } } if ($paidAt === null && $order->status === \App\Enums\OrderStatus::PAID && $order->updated_at !== null) { $paidAt = $order->updated_at->toImmutable(); } $paymentAmountMinor = $order->money_total->getMinorAmount()->toInt(); $paymentCurrency = strtoupper($order->money_total->getCurrency()->getCurrencyCode()); $paymentEntries[] = [ 'type' => $paymentType, 'date' => $paidAt?->setTimezone($paymentTimezone)->format('d/m/Y H:i') ?? '', 'amount_minor' => $paymentAmountMinor, 'currency' => $paymentCurrency, ]; } $lineItems = is_array($invoice->line_items) ? $invoice->line_items : []; $lineItemsCount = count($lineItems); $lineNetRatio = $totalMinor > 0 ? ($subtotalMinor / $totalMinor) : 1.0; $runningNetMinor = 0; $formatMoney = static function (int $minorAmount, string $currencySymbol): string { return trim($currencySymbol.' '.number_format($minorAmount / 100, 2, ',', ' ')); }; @endphp
{{ $companyName }}
@if($companyAddress !== '')
{!! nl2br(e($companyAddress)) !!}
@endif @if($companyPhone !== '')
Tel : {{ $companyPhone }}
@endif @if($companyWebsite !== '')
{{ $companyWebsite }}
@endif @if($companyEmail !== '')
{{ $companyEmail }}
@endif @if($companyTin !== '')
TIN {{ $companyTin }}
@endif
BILL TO
{{ $billToPrimary !== '' ? $billToPrimary : $customerName }}
@if($billToSecondary !== '')
{{ $billToSecondary }}
@endif @if($billToAddress !== '')
{!! nl2br(e($billToAddress)) !!}
@endif @if($billToEmail !== '')
{{ $billToEmail }}
@endif
@if($logoDataUri !== null) @endif
VAT Invoice {{ $invoice->invoice_number }}
DATE{{ $issuedDate }}
@foreach($lineItems as $index => $item) @php $itemQty = max(1, (int) ($item['quantity'] ?? 1)); $itemGrossTotalMinor = (int) ($item['total'] ?? 0); if ($index === $lineItemsCount - 1) { $itemNetTotalMinor = $subtotalMinor - $runningNetMinor; } else { $itemNetTotalMinor = (int) round($itemGrossTotalMinor * $lineNetRatio); } $runningNetMinor += $itemNetTotalMinor; $itemNetUnitMinor = (int) round($itemNetTotalMinor / $itemQty); $itemTitle = trim((string) ($item['type'] ?? 'Item')); $itemDescription = trim((string) ($item['description'] ?? '')); if ($itemTitle !== '' && $itemDescription !== '') { $pattern = '/^\s*'.preg_quote($itemTitle, '/').'\s*[:\-–]?\s*/iu'; $itemDescription = (string) preg_replace($pattern, '', $itemDescription, 1); if (str_contains($itemDescription, ':')) { $prefix = trim((string) strstr($itemDescription, ':', true)); $normalize = static function (string $value): string { $value = mb_strtolower(trim($value)); $value = preg_replace('/\s+/u', '', $value) ?? $value; $value = preg_replace('/[^a-z0-9]+/iu', '', $value) ?? $value; return rtrim($value, 's'); }; if ($prefix !== '' && $normalize($prefix) === $normalize($itemTitle)) { $itemDescription = ltrim(substr($itemDescription, strlen($prefix) + 1)); } } $itemDescription = trim($itemDescription); } if ($itemDescription === '') { $itemDescription = '-'; } @endphp @endforeach
Description Qty Rate Amount
{{ $itemTitle }} {{ $itemDescription }} {{ number_format($itemQty, 0) }} {{ $formatMoney($itemNetUnitMinor, $symbol) }} {{ $formatMoney($itemNetTotalMinor, $symbol) }}
Subtotal {{ $formatMoney($subtotalMinor, $symbol) }}
Tax @if($vatFraction > 0)({{ rtrim(rtrim(number_format($vatDisplay, 2), '0'), '.') }}%)@endif {{ $formatMoney($taxMinor, $symbol) }}
Total {{ $formatMoney($totalMinor, $symbol) }}
Total Due {{ $formatMoney($totalMinor, $symbol) }}
Payments:
@foreach($paymentEntries as $paymentEntry) @php $paymentAmountMinor = is_int($paymentEntry['amount_minor'] ?? null) ? $paymentEntry['amount_minor'] : null; $paymentSymbol = $symbolByCurrency((string) ($paymentEntry['currency'] ?? $currency)); @endphp
{{ $paymentEntry['type'] !== '' ? $paymentEntry['type'] : 'UNKNOWN' }} @if($paymentEntry['date'] !== '') · {{ $paymentEntry['date'] }} @endif @if(is_int($paymentAmountMinor)) · {{ $formatMoney($paymentAmountMinor, $paymentSymbol) }} @endif
@endforeach