@extends('layouts.portal') @section('title', 'Finance overview') @section('subtitle', 'Invoiced, collected, outstanding and overdue — with installments, revenue mix and learner balances.') @section('actions') Export balances (CSV) New payment plan @endsection @section('content')
Last 12 months
Total invoiced{{ money($kpis['invoiced']) }}{{ $from->format('d M Y') }} – {{ $to->format('d M Y') }}
Total collected{{ money($kpis['collected']) }}{{ $kpis['collection_rate'] !== null ? $kpis['collection_rate'].'% collection rate' : 'verified payments' }}
Outstanding{{ money($kpis['outstanding']) }}open invoices, all time
Overdue{{ money($kpis['overdue']) }}past due installments & invoices
Due in 30 days{{ money($kpis['upcoming_30']) }}upcoming installments
Active plans{{ number_format($kpis['plans_active']) }}installment plans running
Waived{{ money($kpis['waived']) }}authorised waivers in period
Refunded{{ money($kpis['refunded']) }}reversed payments in period

Revenue by month

collected
@include('partials.charts.bars', ['data' => $byMonth, 'height' => 210, 'format' => 'money', 'title' => 'Revenue by month'])

Revenue by course

top 10
@include('partials.charts.donut', ['data' => $byCourse, 'size' => 160, 'format' => 'money', 'title' => 'Revenue by course', 'center' => 'Collected'])

Installment status

All plans →
@forelse(collect(\App\Models\Installment::STATUSES)->keys()->filter(fn ($k) => isset($instStatus[$k])) as $k) @empty @endforelse
StatusInstallmentsAmountOutstanding
{{ $instStatus[$k]['count'] }}{{ money2($instStatus[$k]['amount']) }}{{ money2($instStatus[$k]['outstanding']) }}
No installment plans yet.

Payment methods

collected in period
@include('partials.charts.donut', ['data' => $methods, 'size' => 150, 'format' => 'money', 'title' => 'Payment methods', 'center' => 'Methods'])

Overdue installments

{{ $overdue->count() }}
@include('admin.finance._inst', ['rows' => $overdue, 'empty' => 'Nothing is overdue — great collection!'])

Upcoming payments

next 10
@include('admin.finance._inst', ['rows' => $upcoming, 'empty' => 'No upcoming installments.'])

Revenue by batch

collected in period
@forelse($byBatch as $b) @empty @endforelse
BatchCoursePaying learnersCollected
{{ $b->batch_code }}{{ $b->title }}{{ $b->learners }}{{ money2($b->collected) }}
No batch revenue in this period.

Student balances

Download all (CSV)
@forelse($balances as $r) @php($p = $r['plan']) @empty @endforelse
LearnerPlanTotalPaidRemainingOverdueNext due
{{ $p->customer_name }}{{ $p->course?->title }} {{ $p->code }} {{ money2($p->total) }} {{ money2($p->paidAmount()) }} {{ money2($r['remaining']) }} {{ money2($r['overdue']) }} @if($r['next']){{ $r['next']->due_date->format('d M Y') }}{{ money2($r['next']->outstanding()) }}@else — @endif
No active payment plans.
@endsection