@extends('layouts.app') @section('title', $client->name . ' - Customer Master Page') @section('no-page-header') @section('content')
@if(session('success'))
{{ session('success') }}
@endif

Customer Details

#{{ str_pad($client->id, 4, '0', STR_PAD_LEFT) }} · {{ $client->name }} · {{ $client->accountType->type_name ?? 'Account type unavailable' }}

@if ($client->isClosed()) {{-- Closed account: no action buttons --}} CLOSED ACCOUNT @else Manage Members @endif Back
{{-- Closed Account Banner --}} @if ($client->isClosed())
CLOSED ACCOUNT
@if ($client->closed_at)
Closed on: {{ \Carbon\Carbon::parse($client->closed_at)->format('d M Y, h:i A') }}
@endif @if ($client->closedByUser)
Closed by: {{ $client->closedByUser->name }}
@endif @if ($client->close_reason)
Reason: {{ $client->close_reason }}
@endif @if ($client->key_returned !== null)
Keys returned: {{ $client->key_returned ? 'Yes' : 'No' }}
@endif @if ($client->key_deposit_settlement)
Key deposit: {{ str($client->key_deposit_settlement)->replace('_', ' ')->title() }}
@endif @if ($client->key_deposit_settlement === 'refunded' && $client->refund_bank_name)
Refund bank: {{ $client->refund_bank_name }} · {{ $client->refund_account_name }} · •••• {{ substr($client->refund_account_number, -4) }}@if($client->refund_ifsc_code) · IFSC {{ $client->refund_ifsc_code }}@endif
@endif
@endif
Customer Information
@if (!$client->isClosed())Edit@endif

#{{ str_pad($client->id, 4, '0', STR_PAD_LEFT) }}

{{ $client->name }}

{{ $client->phone }}

{{ $client->landline ?? '-' }}

Address Information
@if (!$client->isClosed())Edit@endif

{{ $client->address }}

{{ $client->cityRel?->name ?? $client->city ?? '-' }}

{{ $client->stateRel->name ?? '-' }}

{{ $client->countryRel->name ?? '-' }}

{{ $client->postal_code ?? '-' }}

@if ($client->website) @endif
@php $setupRegistrations = $client->lockerRegistrations->filter(fn ($registration) => in_array(strtolower(trim((string) $registration->status)), ['active', 'pending'], true) ); if ($setupRegistrations->isEmpty()) { $setupRegistrations = $client->lockerRegistrations->take(1); } $setupLockerNumbers = $setupRegistrations->flatMap(function ($registration) { $numbers = $registration->items ? $registration->items->filter(fn ($item) => strtolower(trim((string) $item->status)) === 'active')->pluck('locker_number')->filter() : collect(); return $numbers->isNotEmpty() ? $numbers : collect([$registration->locker?->locker_number])->filter(); })->map(fn ($number) => trim((string) $number))->filter()->unique(); $setupSafeBoxCount = $setupLockerNumbers->count() ?: (int) $setupRegistrations->sum('safebox_count'); @endphp
Account Setup

{{ $client->accountType->type_name ?? 'N/A' }}

{{ $setupSafeBoxCount }}

{{ ($keyDeposit = $client->lockerRegistrations->where('status', 'Active')->first()?->key_deposit) !== null ? 'RM ' . number_format($keyDeposit, 0) : 'N/A' }}

{{ $client->auth_count }}

@if ($client->date_of_birth)

{{ \Carbon\Carbon::parse($client->date_of_birth)->format('M d, Y') }}

@endif
@php $statusName = $client->status->name ?? 'active'; $statusClass = $client->status->class ?? 'green'; @endphp {{ ucfirst($statusName) }}
@if ($client->contract_start_date || $client->contract_end_date || $client->membershipPlan)
Contract Information

{{ $client->contract_start_date ? \Carbon\Carbon::parse($client->contract_start_date)->format('M d, Y') : 'N/A' }}

{{ $client->contract_end_date ? \Carbon\Carbon::parse($client->contract_end_date)->format('M d, Y') : 'N/A' }}

{{ $client->membershipPlan->name ?? 'N/A' }}

@if ($client->contract_start_date && $client->contract_end_date) {{ round(\Carbon\Carbon::parse($client->contract_start_date)->diffInDays(\Carbon\Carbon::parse($client->contract_end_date))) }} days @else N/A @endif

@endif @php // Open accounts show only current registrations. Renewed/expired records remain // available through invoice history; closed accounts retain their complete history. $displayRegistrations = $client->isClosed() ? $client->lockerRegistrations : $client->lockerRegistrations->filter(function ($registration) { return in_array(strtolower(trim((string) $registration->status)), ['active', 'pending'], true); }); $displayLockerNumbers = $displayRegistrations->flatMap(function ($registration) use ($client) { $itemsForCount = $registration->items ?? collect(); if (!$client->isClosed()) { $itemsForCount = $itemsForCount->filter(fn ($item) => strtolower(trim((string) $item->status)) === 'active'); } $itemNumbers = $itemsForCount->pluck('locker_number')->filter(); if ($itemNumbers->isNotEmpty()) { return $itemNumbers; } return collect([$registration->locker?->locker_number])->filter(); })->map(fn ($number) => trim((string) $number))->filter()->unique(); $displayLockerCount = $displayLockerNumbers->count(); $historicalRegistrationIds = collect(); if ($client->isClosed()) { $seenClosedLockerNumbers = collect(); $displayRegistrations->each(function ($registration) use (&$seenClosedLockerNumbers, &$historicalRegistrationIds) { $numbers = $registration->items?->pluck('locker_number')->filter() ?? collect(); if ($numbers->isEmpty() && $registration->locker?->locker_number) { $numbers = collect([$registration->locker->locker_number]); } $numbers = $numbers->map(fn ($number) => trim((string) $number))->filter()->unique(); if ($numbers->isNotEmpty() && $numbers->every(fn ($number) => $seenClosedLockerNumbers->contains($number))) { $historicalRegistrationIds->push($registration->id); } else { $seenClosedLockerNumbers = $seenClosedLockerNumbers->merge($numbers)->unique()->values(); } }); } $openInvoices = $client->invoices->filter(function ($invoice) { $status = strtolower(trim((string) $invoice->status)); $paid = max((float) $invoice->paid_amount, (float) $invoice->payments->filter(fn ($payment) => strtolower(trim((string) $payment->status)) === 'paid')->sum('paid_amount')); $balance = max(0, (float) $invoice->total_amount - $paid); return in_array($status, ['draft', 'sent', 'pending', 'partial', 'overdue'], true) || $balance > 0.009; }); $outstandingBalance = $openInvoices->sum(function ($invoice) { $paid = max((float) $invoice->paid_amount, (float) $invoice->payments->filter(fn ($payment) => strtolower(trim((string) $payment->status)) === 'paid')->sum('paid_amount')); return max(0, (float) $invoice->total_amount - $paid); }); $pendingPayments = $client->lockerRegistrations->flatMap->payments ->filter(fn ($payment) => in_array(strtolower(trim((string) $payment->status)), ['pending', 'partial'], true)); $expiredRegistrations = $client->lockerRegistrations->filter(function ($registration) { return $registration->contract_end_date && \Carbon\Carbon::parse($registration->contract_end_date)->startOfDay()->lt(today()) && strtolower(trim((string) $registration->status)) === 'active'; }); @endphp
Account Alerts & Outstanding Payments
@if ($openInvoices->isEmpty() && $pendingPayments->isEmpty() && $expiredRegistrations->isEmpty()) No outstanding items @endif

Unpaid Invoices

{{ $openInvoices->count() }}

Outstanding RM {{ number_format($outstandingBalance, 2) }}

Pending Payments

{{ $pendingPayments->count() }}

Awaiting completion

Expired Registrations

{{ $expiredRegistrations->count() }}

Requires renewal or review

@if ($client->isClosed()) Locker Details ({{ $displayLockerCount }}) @else Locker Registrations ({{ $displayRegistrations->count() }}) | Lockers ({{ $displayLockerCount ?: $displayRegistrations->sum('safebox_count') }}) @endif
@if ($client->isClosed() && $historicalRegistrationIds->isNotEmpty()) @endif @if (!$client->isClosed()) Change Locker Add Locker @endif
@foreach ($displayRegistrations as $registration) @php $isExpiredRegistration = $registration->contract_end_date && \Carbon\Carbon::parse($registration->contract_end_date)->startOfDay()->lt(today()); @endphp @php $isHistoricalRegistration = $historicalRegistrationIds->contains($registration->id); @endphp @endforeach
Locker Membership Plan Expiry Date Status Actions
@php $displayItems = $registration->items ? ($client->isClosed() ? $registration->items : $registration->items->where('status', 'active')) : collect(); @endphp @if ($displayItems->count() > 0) {{-- @php echo "
";
                                    print_r($activeItems->toarray()); exit;
                                @endphp --}}
                                            @foreach ($displayItems as $item)
                                                @php
                                                    $isBlockedLocker = in_array($item->locker?->status, ['blocked', 'Blocked'], true);
                                                    $feeItem = $client->lockerRegistrations
                                                        ->flatMap(fn ($clientRegistration) => $clientRegistration->items ?? collect())
                                                        ->where('locker_number', $item->locker_number)
                                                        ->first(fn ($historyItem) =>
                                                            (float) ($historyItem->stamping_fee ?? 0) > 0
                                                            || (float) ($historyItem->key_deposit ?? 0) > 0
                                                            || (float) ($historyItem->insurance_charges ?? 0) > 0
                                                            || (float) ($historyItem->discount_amount ?? 0) > 0
                                                        ) ?? $item;
                                                    $usesOriginalFees = (int) $feeItem->id !== (int) $item->id;
                                                    $ledgerDeposit = \Illuminate\Support\Facades\Schema::hasTable('locker_deposit_transactions')
                                                        ? app(\App\Services\LockerDepositService::class)->balance($item, false)
                                                        : 0;
                                                    $displayKeyDeposit = max($ledgerDeposit, (float) ($feeItem->key_deposit ?? 0));
                                                    $displayStampingFee = (float) ($feeItem->stamping_fee ?? 0);
                                                    $displayInsurance = (float) ($feeItem->insurance_charges ?? 0);
                                                    $displayDiscount = (float) ($feeItem->discount_amount ?? 0);
                                                    if ($displayKeyDeposit <= 0 && $displayItems->count() === 1) {
                                                        $displayKeyDeposit = (float) ($registration->key_deposit ?? 0);
                                                    }
                                                    if ($displayItems->count() === 1) {
                                                        if ($displayStampingFee <= 0) $displayStampingFee = (float) ($registration->stamping_fee ?? 0);
                                                        if ($displayInsurance <= 0) $displayInsurance = (float) ($registration->insurance_charges ?? 0);
                                                        if ($displayDiscount <= 0) $displayDiscount = (float) ($registration->discount_amount ?? 0);
                                                    }
                                                @endphp
                                                
{{ $item->locker_number }} @if ($isBlockedLocker) Blocked @endif | {{ ucfirst($item->size) }} | RM{{ ucfirst($item->amount) }} | {{ $item->locker_group }} | {{ $item->locker_position }}
{{ $usesOriginalFees ? 'Original setup fees:' : 'Charges:' }} Stamping RM {{ number_format($displayStampingFee, 2) }} Key Deposit RM {{ number_format($displayKeyDeposit, 2) }} Insurance RM {{ number_format($displayInsurance, 2) }} Discount RM {{ number_format($displayDiscount, 2) }} @if (!$client->isClosed() && $setupSafeBoxCount > 1 && strtolower((string) $registration->status) === 'active') @endif
@endforeach @elseif($registration->locker) @php $isBlockedLocker = in_array($registration->locker?->status, ['blocked', 'Blocked'], true); @endphp
{{ $registration->locker->locker_number }} @if ($isBlockedLocker) Blocked @endif | {{ ucfirst($registration->locker->locker_size) }}
@else N/A @endif
@if ($client->isClosed()) - @elseif ($registration->locker_password !== null && $registration->locker_password !== '') @else Not set @endif
{{ $registration->membershipPlan->name ?? 'N/A' }} {{ $registration->contract_end_date ? \Carbon\Carbon::parse($registration->contract_end_date)->format('d-m-Y') : 'N/A' }} {{ $isExpiredRegistration && $registration->status === 'Active' ? 'Expired' : $registration->status }}
@if ($registration->status == 'Pending') @if (!$client->isClosed()) Pay @endif @endif @if (!$client->isClosed()) Renew @endif Invoice
Invoice & Payment History
{{ $client->invoices->count() }} invoice(s)
@if ($client->invoices->isNotEmpty())
@foreach ($client->invoices as $invoice) @php $invoiceStatus = strtolower(trim((string) $invoice->status)); $invoicePaid = max((float) $invoice->paid_amount, (float) $invoice->payments->filter(fn ($payment) => strtolower(trim((string) $payment->status)) === 'paid')->sum('paid_amount')); $invoiceBalance = max(0, (float) $invoice->total_amount - $invoicePaid); $isInvoiceOpen = in_array($invoiceStatus, ['draft', 'sent', 'pending', 'partial', 'overdue'], true) || $invoiceBalance > 0.009; $invoiceType = strtolower(trim((string) $invoice->payment_type)); $invoicePurpose = match ($invoiceType) { 'create', 'registration_fee' => 'Account Opening', 'renewal' => 'Locker Renewal', 'add' => 'Additional Locker', 'change' => 'Locker Change', 'rent' => 'Locker Rent', 'deposit' => 'Deposit', 'penalty' => 'Penalty', 'maintenance' => 'Maintenance', default => $invoiceType !== '' ? str($invoiceType)->headline()->toString() : 'Other', }; $purposeClass = match ($invoiceType) { 'renewal' => 'bg-blue-50 text-blue-700 border-blue-200', 'add' => 'bg-purple-50 text-purple-700 border-purple-200', 'change' => 'bg-orange-50 text-orange-700 border-orange-200', default => 'bg-gray-50 text-gray-700 border-gray-200', }; @endphp @endforeach
Invoice Invoice For Date / Due Total Paid Balance Status Actions
{{ $invoice->invoice_number }} {{ $invoicePurpose }} @if ($invoice->locker_number)
Locker: {{ $invoice->locker_number }}
@endif
{{ optional($invoice->invoice_date)->format('d M Y') ?? '-' }}
Due: {{ $invoice->due_date ? \Carbon\Carbon::parse($invoice->due_date)->format('d M Y') : '-' }}
RM {{ number_format($invoice->total_amount, 2) }} RM {{ number_format($invoicePaid, 2) }} RM {{ number_format($invoiceBalance, 2) }} {{ ucfirst($invoiceStatus) }}
@else
No invoices found.
@endif
@if (!$client->isClosed()) @endif @php $blockableLockers = collect(); foreach ($client->lockerRegistrations->where('status', 'Active') as $reg) { $activeItems = $reg->items ? $reg->items->where('status', 'active') : collect(); if ($activeItems->count() > 0) { foreach ($activeItems as $item) { $blockableLockers->push([ 'locker_id' => (int) $item->locker_id, 'locker_number' => $item->locker_number, 'status' => $item->locker?->status, ]); } } elseif ($reg->locker) { $blockableLockers->push([ 'locker_id' => (int) $reg->locker->id, 'locker_number' => $reg->locker->locker_number, 'status' => $reg->locker->status, ]); } } $blockableLockers = $blockableLockers->unique('locker_id')->values(); $initialBlockedIds = $blockableLockers ->filter(fn($l) => in_array($l['status'], ['blocked', 'Blocked'], true)) ->pluck('locker_id') ->values(); @endphp @php $displayMembers = $client->isClosed() ? $client->customerMembers : $client->customerMembers->where('is_active', 1); @endphp
Authorized Members @if ($client->isClosed()) ({{ $displayMembers->count() }} recorded) @else ({{ $displayMembers->count() }}/{{ $client->auth_count }}) @endif @if ($client->isClosed()) Complete history @endif
@php $totalMembers = $client->customerMembers->where('is_active', 1)->count(); $authLimitReached = $totalMembers >= (int) ($client->auth_count ?? 0); @endphp @if (!$client->isClosed()) @endif
@if ($displayMembers->count() > 0)
@foreach ($displayMembers as $member) @endforeach
Member Mobile Identity Authentication Status

{{ $member->name }}

@if($member->email)

{{ $member->email }}

@endif
{{ $member->mobile ?: '-' }}

{{ $member->proof_type === 'ic_number' ? 'IC Number' : ucfirst($member->proof_type ?? 'Proof') }}

{{ $member->proof_number ?: '-' }}

{{ $member->required_auth ? 'Required member' : 'Optional member' }} Face: {{ $member->is_face_verified ? 'Verified' : 'Pending' }}
{{ $member->is_active ? 'Active' : 'Inactive' }}
@else
@if ($client->isClosed() && (int) $client->auth_count > 0)

Authorized-member details were not recorded

This legacy account was configured for {{ $client->auth_count }} member(s), but no member names or identity records exist in the database. The missing details cannot be reconstructed.

@else

No authorized members found

@endif @if (!$client->isClosed()) Add First Member @endif
@endif
Account Opening Documents
{{ $client->documents->count() }} document(s)
@php $documentLabels = [ 'joint_consent_form' => 'Joint Account Consent Form', 'ssm_document' => 'SSM Registration Document', 'board_resolution' => 'Board Resolution', 'agm_document' => 'AGM Document', 'ros_approval' => 'ROS Approval Document', 'change_resolution' => 'Change of Resolution', ]; @endphp @if ($client->documents->isNotEmpty())
@foreach ($client->documents as $document)

{{ $documentLabels[$document->document_type] ?? str($document->document_type)->headline() }}

@if ($document->description)

{{ $document->description }}

@endif
{{ optional($document->created_at)->format('d M Y, h:i A') ?? 'Date unavailable' }} {{ $document->is_verified ? 'Checked' : 'Pending check' }}
View
@endforeach
@else

No account opening documents

Documents uploaded during new account registration will appear here.

@endif
@if ($client->proof_type || $client->proof_number || $client->gst_number || $client->pan_number)
Document Information
@if ($client->proof_type)

{{ ucfirst($client->proof_type) }}

@endif @if ($client->proof_number)

{{ $client->proof_number }}

@endif @if ($client->gst_number)

{{ $client->gst_number }}

@endif @if ($client->pan_number)

{{ $client->pan_number }}

@endif
@endif
{{-- ═══════════════════════════════════════════════════════════════ CLOSE ACCOUNT CONFIRMATION MODAL ═══════════════════════════════════════════════════════════════ --}} @if (!$client->isClosed()) @push('scripts') @endpush @endif @push('scripts') @endpush @endsection