@extends('layouts.app') @section('title', $customer->display_name) @section('content')

{{ $customer->display_name }}

{{ $customer->customer_number }} · {{ $customer->status }} · {{ title_case_words($customer->segment) }} @if ($customer->kyc_status === 'verified') · KYC verified @else · KYC {{ $customer->kyc_status }} @endif

Statement Take payment + Add service Edit
@include('components.kpi', ['label' => 'Account balance', 'value' => money($customer->account_balance, $customer->currency), 'variant' => $customer->account_balance > 0 ? 'warn' : 'good', 'href' => route('customers.statement', $customer)]) @include('components.kpi', ['label' => 'Monthly recurring', 'value' => money($customer->mrr, $customer->currency), 'variant' => 'good', 'href' => '#services']) @include('components.kpi', ['label' => 'Active services', 'value' => $customer->services()->where('status','active')->count(), 'href' => '#services']) @include('components.kpi', ['label' => 'Open tickets', 'value' => $customer->tickets()->open()->count(), 'variant' => $customer->tickets()->open()->count() > 0 ? 'warn' : '', 'href' => '#tickets']) @include('components.kpi', ['label' => 'Outstanding', 'value' => money($customer->outstanding, $customer->currency), 'variant' => $customer->is_overdue ? 'bad' : 'good', 'href' => '#invoices']) @include('components.kpi', ['label' => 'Customer since', 'value' => $customer->joined_at?->format('M Y') ?? '—', 'href' => '#'])
@if ($customer->is_overdue)
⚠
This account has invoices past their due date totalling {{ money($customer->outstanding, $customer->currency) }}.
Collect now
@endif
Services ({{ $services->total() }}) Invoices ({{ $invoices->total() }}) Payments ({{ $payments->total() }}) Tickets ({{ $tickets->count() }}) Details
{{-- ============ SERVICES ============ --}}

Subscriptions

+ Provision service
@forelse ($services as $service) @empty @endforelse
ServicePlanRADIUS userSpeed PriceStatusNext bill
{{ $service->service_number }}
{{ $service->installation_address }}
{{ $service->plan?->name }} {{ $service->username }} {{ $service->download_kbps ? round($service->download_kbps/1024).' / '.round($service->upload_kbps/1024).' Mbps' : ($service->plan?->speed_label ?? '—') }} {{ money($service->effective_price, $customer->currency) }} {{ $service->status }} {{ $service->next_billing_date?->format('d M Y') ?: '—' }} Open
@include('components.empty-state', ['icon' => '⇄', 'title' => 'No services yet', 'message' => 'Provision a subscription to start billing this customer.', 'action' => '+ Provision service'])
@if ($services->hasPages())
{{ $services->links('partials.pagination') }}
@endif
{{-- ============ INVOICES ============ --}}

Invoices

Outstanding: {{ money($customer->outstanding, $customer->currency) }}
@forelse ($invoices as $invoice) @empty @endforelse
InvoiceIssuedDueTotal PaidBalanceStatus
{{ $invoice->invoice_number }} {{ $invoice->issue_date->format('d M Y') }} {{ $invoice->due_date->format('d M Y') }} {{ money($invoice->total, $invoice->currency) }} {{ money($invoice->amount_paid, $invoice->currency) }} {{ money($invoice->balance, $invoice->currency) }} {{ $invoice->status }} View
@include('components.empty-state', ['icon' => '📄', 'title' => 'No invoices yet'])
@if ($invoices->hasPages())
{{ $invoices->links('partials.pagination') }}
@endif
{{-- ============ PAYMENTS ============ --}}

Payment history

@forelse ($payments as $payment) @empty @endforelse
ReferenceDateMethodAmountStatusCollected by
{{ $payment->reference }} {{ $payment->paid_at?->format('d M Y H:i') ?: '—' }} {{ title_case_words($payment->method) }} {{ money($payment->amount, $payment->currency) }} {{ $payment->status }} {{ $payment->collector?->name ?: 'Gateway' }}
@include('components.empty-state', ['icon' => '💳', 'title' => 'No payments recorded'])
@if ($payments->hasPages())
{{ $payments->links('partials.pagination') }}
@endif
{{-- ============ TICKETS ============ --}}

Support tickets

+ Raise ticket
@forelse ($tickets as $ticket) @empty @endforelse
TicketSubjectPriorityStatusOwnerOpened
{{ $ticket->ticket_number }} {{ $ticket->subject }} {{ $ticket->priority }} {{ title_case_words($ticket->status) }} {{ $ticket->assignee?->name ?: 'Unassigned' }}
@include('components.empty-state', ['icon' => '✉', 'title' => 'No tickets raised'])
{{-- ============ DETAILS ============ --}}

Contact & identity

Account type
{{ title_case_words($customer->type) }}
Full name
{{ trim("{$customer->first_name} {$customer->last_name}") ?: '—' }}
Company
{{ $customer->company_name ?: '—' }}
Primary phone
{{ $customer->phone }}
Alternate
{{ $customer->alt_phone ?: '—' }}
Email
{{ $customer->email ?: '—' }}
Billing email
{{ $customer->billing_email ?: '—' }}
ID document
{{ $customer->id_type ? title_case_words($customer->id_type).': '.$customer->id_number : 'Not provided' }}
KYC verified
{{ $customer->kyc_verified_at?->format('d M Y H:i') ?: 'Not verified' }}
Branch
{{ $customer->branch?->name ?: 'Head office' }}
Sales agent
{{ $customer->salesAgent?->name ?: '—' }}

Billing configuration

Payment terms
{{ title_case_words($customer->payment_terms) }}
Currency
{{ $customer->currency }}
Tax treatment
{{ title_case_words($customer->tax_exempt) }}
Credit limit
{{ money($customer->credit_limit, $customer->currency) }}
Auto invoicing
{{ $customer->auto_invoice ? 'Enabled' : 'Disabled' }}
Auto suspension
{{ $customer->auto_suspend ? 'Enabled' : 'Disabled' }}
Language
{{ strtoupper($customer->language) }}
Timezone
{{ $customer->timezone }}

Address
{{ $customer->billing_address ?: '—' }}
City
{{ $customer->city ?: '—' }}
Region
{{ $customer->region ?: '—' }}
Country
{{ $customer->country }}
@if ($credits->isNotEmpty())

Credit & deposit movements

@foreach ($credits as $credit) @endforeach
DateTypeDescriptionAmountBalance
{{ $credit->created_at->format('d M Y') }} {{ $credit->type }} {{ $credit->description }} {{ money($credit->amount, $customer->currency) }} {{ money($credit->balance, $customer->currency) }}
@endif @if ($contracts->isNotEmpty())

Contracts

@foreach ($contracts as $contract) @endforeach
ContractTitleTermMonthlyStatus
{{ $contract->contract_number }} {{ $contract->title }} {{ $contract->starts_on->format('M Y') }} – {{ $contract->ends_on->format('M Y') }} ({{ $contract->term_months }} mo) {{ money($contract->monthly_value, $customer->currency) }} {{ $contract->status }}
@endif @if ($customer->notes)

Internal notes

{{ $customer->notes }}

@endif

People on this account

{{ $customer->contacts->count() }}
@if ($customer->contacts->isEmpty())

No named contacts yet — who should be called about a bill, and who about an outage?

@else @foreach ($customer->contacts as $contact) @endforeach
NameRoleContact
{{ $contact->name }} @if ($contact->is_primary)primary@endif @if ($contact->position)
{{ $contact->position }}
@endif
{{ title_case_words($contact->type) }} {{ $contact->phone }} @if ($contact->email)
{{ $contact->email }}
@endif
@csrf @method('DELETE')
@endif
@csrf

Documents

@csrf
@if ($customer->documents->isEmpty())

No identity or contract documents on file.

@else @foreach ($customer->documents as $doc) @endforeach
TitleTypeExpiresStatus
{{ $doc->title }}
{{ $doc->size_bytes ? number_format($doc->size_bytes / 1024, 1).' KB' : 'reference only' }}
{{ title_case_words($doc->type) }} {{ $doc->expires_on?->format('d M Y') ?: '—' }} @if ($doc->expires_on && $doc->expires_on->lt(now()) && $doc->status === 'valid') lapsed @endif {{ title_case_words($doc->status) }} Get
@csrf @method('DELETE')
@endif
@csrf

Records a document held elsewhere. Use the upload endpoint for a file stored on this server.

Danger zone

Delete this customer

Only possible when no services remain attached. This action cannot be undone.

@csrf @method('DELETE')
@endsection @push('scripts') @endpush