@php $statusBadge = [ 'DRAFT' => 'slate', 'SENT' => 'sky', 'PARTIAL' => 'amber', 'PAID' => 'emerald', 'OVERDUE' => 'rose', 'VOID' => 'slate', ]; $kpiAccent = [ 'indigo' => '#6366f1', 'amber' => '#f59e0b', 'emerald' => '#10b981', 'sky' => '#0ea5e9', 'rose' => '#f43f5e', ]; $avatarColors = [ 'bg-indigo-100 text-indigo-700', 'bg-emerald-100 text-emerald-700', 'bg-amber-100 text-amber-700', 'bg-sky-100 text-sky-700', 'bg-rose-100 text-rose-700', 'bg-violet-100 text-violet-700', ]; $initials = function (?string $name): string { $parts = collect(preg_split('/\s+/', trim((string) $name)))->filter(); if ($parts->isEmpty()) { return '—'; } return $parts->take(2)->map(fn ($w) => mb_strtoupper(mb_substr($w, 0, 1)))->implode(''); }; $avatarColor = fn (?string $name): string => $avatarColors[abs(crc32((string) $name)) % count($avatarColors)]; // Public links the customer gets: the portal page is the payment page (Pay // button where Paynow is live, banking details otherwise), and WhatsApp // shares that same link with the balance owed pre-filled. Both come off the // model so the wording can't drift from what the emails send. $paymentUrl = fn ($invoice) => $invoice->portalUrl(); $whatsappUrl = fn ($invoice) => $invoice->whatsAppShareUrl(); @endphp
{{ $kpi['label'] }}
{{ $kpi['value'] }}
{{ $kpi['sub'] }}| {{ __('Invoice No.') }} | {{ __('Customer') }} | {{ __('For') }} | {{ __('Status') }} | {{ __('Total') }} | {{ __('Date') }} | ||
|---|---|---|---|---|---|---|---|
|
{{-- The note count stays on the row, not in the selection bar:
it is an at-a-glance signal, and nobody ticks a row to
discover there was something written on it. --}}
#{{ $invoice->id }} |
{{ $initials($invoice->payerName()) }}
{{ $invoice->payerName() ?: '—' }} @if ($invoice->payerEmail()){{ $invoice->payerEmail() }} @endif |
|
|
{{ $invoice->currency_code }} {{ number_format((float) $invoice->total, 2) }} @if ($isPartial){{ __('Bal') }}: {{ number_format((float) $invoice->balance_due, 2) }} @endif @if ((float) $invoice->refunded_total > 0){{ __('Refunded') }}: {{ number_format((float) $invoice->refunded_total, 2) }} @endif @if ((float) $invoice->credited_total > 0){{ __('Credited') }}: {{ number_format((float) $invoice->credited_total, 2) }} @endif |
{{ $invoice->created_at?->format('Y-m-d') }} @if ($showDue) @if ($daysLeft < 0){{ __('Overdue') }} @elseif ($daysLeft === 0){{ __('Due today') }} @else{{ trans_choice('{1} :count day to due|[2,*] :count days to due', $daysLeft, ['count' => $daysLeft]) }} @endif @elseif ($invoice->status === 'PAID'){{ __('Paid') }} @endif |
{{ $invoice->payerName() ?: '—' }}
{{ $invoice->currency_code }} {{ number_format((float) $invoice->total, 2) }}
@if ($isPartial){{ __('Balance') }}: {{ number_format((float) $invoice->balance_due, 2) }}
@endif @if ((float) $invoice->refunded_total > 0){{ __('Refunded') }}: {{ number_format((float) $invoice->refunded_total, 2) }}
@endif @if ((float) $invoice->credited_total > 0){{ __('Credited') }}: {{ number_format((float) $invoice->credited_total, 2) }}
@endif{{ $invoice->created_at?->format('Y-m-d') }} @if ($showDue) @if ($daysLeft < 0) · {{ __('Overdue') }} @elseif ($daysLeft === 0) · {{ __('Due today') }} @else · {{ trans_choice('{1} :count day to due|[2,*] :count days to due', $daysLeft, ['count' => $daysLeft]) }} @endif @endif
| {{ __('Customer') }} | {{ __('Frequency') }} | {{ __('Status') }} | {{ __('Amount') }} | {{ __('Next Run') }} | {{ __('Ends') }} | {{ __('Actions') }} |
|---|---|---|---|---|---|---|
| {{ $profile->customer?->name ?: '—' }} | {{ __('Every') }} {{ $profile->interval > 1 ? $profile->interval . ' ' : '' }}{{ ucfirst($profile->frequency) }} |
|
{{ $profile->currency_code }} {{ number_format($amount, 2) }} | {{ $profile->next_run_date?->format('Y-m-d') ?: '—' }} | {{ $profile->end_date?->format('Y-m-d') ?: '—' }} |
@if ($canManageRecurring)
|
|
|
||||||
{{ $profile->customer?->name ?: '—' }}
{{ __('Every') }} {{ $profile->interval > 1 ? $profile->interval . ' ' : '' }}{{ ucfirst($profile->frequency) }}
{{ $profile->currency_code }} {{ number_format($amount, 2) }}
{{ __('Next') }}: {{ $profile->next_run_date?->format('Y-m-d') ?: '—' }}
{{ __('A credit note is cash still in the bank that has stopped being revenue. It comes back as revenue when the customer spends it on another invoice.') }}
| {{ __('Credit note') }} | {{ __('Customer') }} | {{ __('Status') }} | {{ __('Amount') }} | {{ __('Remaining') }} | {{ __('Issued') }} | {{ __('Actions') }} |
|---|---|---|---|---|---|---|
|
{{ $note->credit_number ?: '—' }} {{ $note->source_label }} |
{{ $note->customer?->name ?: '—' }} @if ($note->invoice){{ __('From') }} {{ $note->invoice->invoice_number }} @endif |
|
{{ $note->currency_code }} {{ number_format((float) $note->amount, 2) }} | {{ number_format($note->remaining, 2) }} |
{{ $note->issued_at?->format('Y-m-d') }}
{{ $note->issuer?->name }} |
@if ($note->isOpen())
@if ($canRecordPayment)
@endif
@if ($canApproveVoid)
@endif
@else
{{ __('Closed') }}
@endif
|
|
|
||||||
{{ $note->credit_number ?: '—' }}
{{ $note->customer?->name ?: '—' }}
{{ $note->currency_code }} {{ number_format((float) $note->amount, 2) }}
{{ __('Left') }}: {{ number_format($note->remaining, 2) }}
@if ($lineMode === 'per_sqm')
{{ __('Methods carrying a charge add it to the total.') }} {{ __('Set rates') }}
{{-- Says out loud what the choice does to the printed document: the account number rides on the bank method alone, because that is the only total that has the transfer charge in it. --}} @php $bankingMethod = $paymentMethods->firstWhere('id', (int) $payment_method_id); @endphp{{ $bankingMethod?->isBankTransfer() ? __('Your bank details will print on this invoice.') : __('No bank details will print on this invoice.') }}
{{ __('This invoice has already been paid against') }}
{{ __(':paid of :total has been collected. If you drop the total below that, the difference becomes a credit note the customer can spend or take back. If you raise it, the invoice goes back to part-paid with a balance due.', [ 'paid' => $edited?->currency_code . ' ' . number_format((float) ($edited?->amount_paid ?? 0), 2), 'total' => number_format((float) ($edited?->total ?? 0), 2), ]) }}
{{ __('Total') }}
{{ $payInvoice->currency_code }} {{ number_format((float) $payInvoice->total, 2) }}
{{ __('Paid') }}
{{ number_format((float) $payInvoice->amount_paid, 2) }}
{{ __('Balance Due') }}
{{ number_format((float) $payInvoice->balance_due, 2) }}
{{ __('Deposits and balances are reported as separate income lines. Suggested from this invoice’s history — change it if the customer called it something else.') }}
{{ __('The surcharge is added to what the customer pays and lands in treasury; it does not reduce the invoice balance.') }}
{{ __('No active :currency account exists. Create one under Treasury first.', ['currency' => $payInvoice->currency_code]) }}
@else{{ __('Which account this money lands in.') }}
@endif{{ __('Bank/EcoCash fee this account skims off the deposit. Leave blank if none.') }}
@if ($paySuggestedCharge !== '' && $pay_charge === $paySuggestedCharge && $payInvoice?->paymentMethod){{ __('Suggested from :method (:rate). Change it if the statement says otherwise.', [ 'method' => $payInvoice->paymentMethod->name, 'rate' => $payInvoice->paymentMethod->costLabel(), ]) }}
@endif{{ __('The invoice is still settled in full; the fee is booked as a bank charge in your P&L.') }}
{{ $payInvoice->currency_code }} {{ number_format((float) $item->amount, 2) }} · {{ $item->channel }}
{{ optional($item->paid_at)->format('Y-m-d H:i') }} @if ((float) $item->surcharge > 0) · {{ __('surcharge') }} {{ number_format((float) $item->surcharge, 2) }} @endif @if ($item->reference) · {{ $item->reference }} @endif
- {{ $payInvoice->currency_code }} {{ number_format((float) $item->amount, 2) }} · {{ __('Refund') }} · {{ $item->reason_label }}
{{ optional($item->refunded_at)->format('Y-m-d H:i') }} @if ($item->reference) · {{ $item->reference }} @endif
{{ __('Paid') }}
{{ $refundInvoice->currency_code }} {{ number_format((float) $refundInvoice->amount_paid, 2) }}
{{ __('Already refunded') }}
{{ number_format($refundedTotal, 2) }}
{{ __('Net collected') }}
{{ number_format($netCollected, 2) }}
{{ __('A refund returns cash to the customer and reduces recognised revenue by the same amount. The invoice stays settled, its total and balance do not change.') }}
@endif{{ __('No active :currency account exists. Create one under Treasury first.', ['currency' => $refundInvoice->currency_code]) }}
@else{{ __('Which account the money leaves from.') }}
@endif{{ __('Bank/EcoCash fee to send the money out. Booked as a bank charge. Leave blank if none.') }}
{{ $refundInvoice->currency_code }} {{ number_format((float) $refund->amount, 2) }} · {{ $refund->reason_label }}
{{ optional($refund->refunded_at)->format('Y-m-d H:i') }} @if ($refund->reference) · {{ $refund->reference }} @endif
{{ $voidInvoice->invoice_number }}
{{ $voidInvoice->payerName() ?: '—' }}
{{ __('Collected') }}
{{ $cur }} {{ number_format($unsettled, 2) }}
{{ __('Spent on job') }}
{{ $cur }} {{ number_format($voidCostsIncurred, 2) }}
{{ __('Requested by :who, :when', [ 'who' => $voidInvoice->voidRequester?->name ?? __('a colleague'), 'when' => $voidInvoice->void_requested_at?->diffForHumans(), ]) }}
{{ $voidInvoice->void_reason }}
{{ __('Writes off :loss of work you have already paid for.', ['loss' => $cur . ' ' . number_format($shortfall, 2)]) }}
@endif{{ $void_settlement === 'refund' ? __('Leaves the account today and shows in Treasury as a refund.') : __('No money moves. They can spend it on a future invoice, or take it in cash later.') }}
{{ __('Nothing was collected on this invoice, so there is nothing to settle.') }}
@endif {{-- What happens to the production job(s) --}} @if ($voidInvoice->jobs->isNotEmpty()){{ $void_job_action === 'cancel' ? __('Confirmed productions are reversed and the stock goes back. What you cannot recover stays costed.') : __('Nothing is unwound. The job keeps its costs and earns only the charge above.') }} · {{ $voidInvoice->jobs->pluck('job_number')->join(', ') }}
{{ __('The invoice, its payments and its line items are all kept. The reversal is dated today, so the month the money came in is never rewritten, and costs on the cancelled work move out of cost of sales.') }}
{{ __('The invoice stands. The request and your refusal both stay on record, so tell them why.') }}
{{ $credit->credit_number }}
{{ $credit->customer?->name }} · {{ __('remaining') }} {{ $credit->currency_code }} {{ number_format($credit->remaining, 2) }}
{{ __('This customer has no unpaid invoices in :currency.', ['currency' => $credit->currency_code]) }}
@endif{{ __('No cash moves, the money is already in the bank. The invoice is settled and the revenue is recognised now, in this month.') }}
{{ __('Hand :amount back to :customer. The money leaves the account today; profit does not change, because this credit stopped counting as revenue when it was raised.', [ 'amount' => $credit->currency_code . ' ' . number_format($credit->remaining, 2), 'customer' => $credit->customer?->name ?: __('the customer'), ]) }}
{{ __('The customer will never spend the remaining :amount and it is not going back to them. Writing it off returns that money to revenue in this month.', [ 'amount' => $credit->currency_code . ' ' . number_format($credit->remaining, 2), ]) }}