@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
Close Account
@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
Client ID
#{{ str_pad($client->id, 4, '0', STR_PAD_LEFT) }}
Customer
{{ $client->name }}
Phone
{{ $client->phone }}
Landline
{{ $client->landline ?? '-' }}
Address Information
@if (!$client->isClosed())
Edit@endif
Address
{{ $client->address }}
City
{{ $client->cityRel?->name ?? $client->city ?? '-' }}
State
{{ $client->stateRel->name ?? '-' }}
Country
{{ $client->countryRel->name ?? '-' }}
Postal Code
{{ $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
Account Type
{{ $client->accountType->type_name ?? 'N/A' }}
Safe Boxes
{{ $setupSafeBoxCount }}
Key Deposit
{{ ($keyDeposit = $client->lockerRegistrations->where('status', 'Active')->first()?->key_deposit) !== null
? 'RM ' . number_format($keyDeposit, 0)
: 'N/A' }}
Authorized
{{ $client->auth_count }}
@if ($client->date_of_birth)
DOB
{{ \Carbon\Carbon::parse($client->date_of_birth)->format('M d, Y') }}
@endif
Status
@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
Contract Start Date
{{ $client->contract_start_date ? \Carbon\Carbon::parse($client->contract_start_date)->format('M d, Y') : 'N/A' }}
Contract End Date
{{ $client->contract_end_date ? \Carbon\Carbon::parse($client->contract_end_date)->format('M d, Y') : 'N/A' }}
Membership Plan
{{ $client->membershipPlan->name ?? 'N/A' }}
Contract Duration
@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())
Show Past History ({{ $historicalRegistrationIds->count() }})
@endif
@if (!$client->isClosed())
Change Locker
Add Locker
Block Locker
@endif
Locker
Membership Plan
Expiry Date
Status
Actions
@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
@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')
Release Locker
@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
Locker password
@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
@endforeach
Invoice & Payment History
{{ $client->invoices->count() }} invoice(s)
@if ($client->invoices->isNotEmpty())
Invoice
Invoice For
Date / Due
Total
Paid
Balance
Status
Actions
@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
{{ $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) }}
@endforeach
@else
No invoices found.
@endif
@if (!$client->isClosed())
Release Locker
The locker becomes available and its key deposit is added to pending refunds.
@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
Block / Unblock Lockers
@csrf
@if ($blockableLockers->isEmpty())
No active lockers found for this client.
@else
Select lockers to Block . Uncheck to Unblock .
@foreach ($blockableLockers as $lockerRow)
@php
$isBlocked = in_array($lockerRow['status'], ['blocked', 'Blocked'], true);
@endphp
@endforeach
Reason *
@endif
Cancel
Save
@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)
Member
Mobile
Identity
Authentication
Status
@foreach ($displayMembers as $member)
{{ $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' }}
@endforeach
@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)
Proof Type
{{ ucfirst($client->proof_type) }}
@endif
@if ($client->proof_number)
Proof Number
{{ $client->proof_number }}
@endif
@if ($client->gst_number)
GST Number
{{ $client->gst_number }}
@endif
@if ($client->pan_number)
PAN Number
{{ $client->pan_number }}
@endif
@endif