184 lines
8.9 KiB
PHP
184 lines
8.9 KiB
PHP
@extends('layouts.app')
|
|
|
|
@section('title', 'Kemaskini Bayaran Pukal')
|
|
@section('page-title', 'Kemaskini Bayaran Pukal')
|
|
@section('page-label', 'Modul Staff')
|
|
|
|
@section('page-actions')
|
|
<a href="{{ route('staff.bulk-payments.template') }}" class="btn btn-outline-primary">
|
|
<i class="bi bi-download me-1"></i> Download Template Excel
|
|
</a>
|
|
@endsection
|
|
|
|
@section('content')
|
|
<div class="row g-4 mb-4">
|
|
<div class="col-md-4">
|
|
<div class="card stat-card p-4 h-100">
|
|
<div class="stat-icon mb-3"><i class="bi bi-person-check-fill"></i></div>
|
|
<div class="mini-label">Akaun Aktif</div>
|
|
<div class="h3 fw-bold mb-0">{{ $activeAccountCount }}</div>
|
|
<div class="text-muted small">Akaun ansuran yang sedang aktif.</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="card stat-card p-4 h-100">
|
|
<div class="stat-icon mb-3"><i class="bi bi-list-check"></i></div>
|
|
<div class="mini-label">Ansuran Dalam Excel</div>
|
|
<div class="h3 fw-bold mb-0">{{ $activeSchedules->count() }}</div>
|
|
<div class="text-muted small">{{ $unpaidScheduleCount }} belum bayar, {{ $paidScheduleCount }} sudah dibayar.</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="card stat-card p-4 h-100">
|
|
<div class="stat-icon mb-3"><i class="bi bi-cash-coin"></i></div>
|
|
<div class="mini-label">Jumlah Belum Direkod</div>
|
|
<div class="h3 fw-bold mb-0">RM {{ number_format($totalUnpaidAmount, 2) }}</div>
|
|
<div class="text-muted small">Jumlah ansuran aktif yang belum dibayar.</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-4">
|
|
<div class="col-lg-5">
|
|
<div class="card surface-card p-4 h-100">
|
|
<h2 class="h5 fw-bold mb-3">Upload Excel/CSV Bayaran</h2>
|
|
<p class="text-muted">
|
|
Gunakan template daripada sistem supaya setiap baris mempunyai <strong>Installment_Schedule_ID</strong>,
|
|
<strong>No_Akaun</strong> dan <strong>Ansuran_Ke</strong>. Staff hanya perlu isi No_Resit, Tarikh_Bayaran,
|
|
Amaun_Bayaran dan catatan jika perlu. Baris yang sudah dibayar akan membawa transaksi sedia ada untuk semakan atau kemaskini.
|
|
</p>
|
|
|
|
<div class="alert alert-info small">
|
|
Hanya akaun berstatus <strong>aktif</strong> akan diproses. Ansuran <strong>belum bayar/lewat</strong>
|
|
akan direkodkan sebagai bayaran baharu, manakala ansuran <strong>dibayar</strong> akan mengemaskini
|
|
transaksi bayaran sedia ada dalam database.
|
|
</div>
|
|
|
|
<form method="POST" action="{{ route('staff.bulk-payments.store') }}" enctype="multipart/form-data" class="d-grid gap-3">
|
|
@csrf
|
|
<div>
|
|
<label class="form-label">Fail Bayaran Pukal</label>
|
|
<input type="file" name="file" class="form-control" accept=".xlsx,.xls,.csv" required>
|
|
@error('file')
|
|
<div class="text-danger small mt-1">{{ $message }}</div>
|
|
@enderror
|
|
</div>
|
|
|
|
<button class="btn btn-primary btn-lg">
|
|
<i class="bi bi-upload me-1"></i> Muat Naik & Kemaskini Bayaran
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-lg-7">
|
|
<div class="card surface-card p-4 h-100">
|
|
<h2 class="h5 fw-bold mb-3">Ringkasan Proses Terakhir</h2>
|
|
|
|
@if ($importResult)
|
|
<div class="row g-3 mb-3">
|
|
<div class="col-6 col-md-3">
|
|
<div class="border rounded-4 p-3">
|
|
<div class="mini-label">Diproses</div>
|
|
<div class="h4 fw-bold mb-0">{{ $importResult['processed'] }}</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-6 col-md-3">
|
|
<div class="border rounded-4 p-3">
|
|
<div class="mini-label">Berjaya</div>
|
|
<div class="h4 fw-bold text-success mb-0">{{ $importResult['success'] }}</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-6 col-md-3">
|
|
<div class="border rounded-4 p-3">
|
|
<div class="mini-label">Gagal</div>
|
|
<div class="h4 fw-bold text-danger mb-0">{{ $importResult['failed'] }}</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-6 col-md-3">
|
|
<div class="border rounded-4 p-3">
|
|
<div class="mini-label">Diabaikan</div>
|
|
<div class="h4 fw-bold text-muted mb-0">{{ $importResult['skipped'] }}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
@if (! empty($importResult['errors']))
|
|
<div class="alert alert-warning mb-0">
|
|
<div class="fw-semibold mb-2">Ralat yang perlu disemak</div>
|
|
<ul class="mb-0 ps-3">
|
|
@foreach ($importResult['errors'] as $error)
|
|
<li>{{ $error }}</li>
|
|
@endforeach
|
|
</ul>
|
|
</div>
|
|
@else
|
|
<div class="alert alert-success mb-0">
|
|
Semua baris bayaran yang lengkap berjaya dikemaskini.
|
|
</div>
|
|
@endif
|
|
@else
|
|
<div class="text-muted">
|
|
Belum ada proses upload bayaran pukal dalam sesi ini.
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card surface-card p-4 mt-4">
|
|
<div class="d-flex flex-wrap justify-content-between align-items-center gap-3 mb-3">
|
|
<div>
|
|
<h2 class="h5 fw-bold mb-1">Senarai Ansuran Aktif Untuk Template</h2>
|
|
<div class="text-muted small">Paparan ini menunjukkan ansuran akaun aktif termasuk transaksi yang sudah dibayar.</div>
|
|
</div>
|
|
<a href="{{ route('staff.bulk-payments.template') }}" class="btn btn-outline-primary">
|
|
Download Template
|
|
</a>
|
|
</div>
|
|
|
|
<div class="table-responsive">
|
|
<table class="table align-middle">
|
|
<thead>
|
|
<tr>
|
|
<th>No Akaun</th>
|
|
<th>No Permohonan</th>
|
|
<th>Pemohon</th>
|
|
<th>Ansuran</th>
|
|
<th>Tarikh Jadual</th>
|
|
<th>Amaun</th>
|
|
<th>Status</th>
|
|
<th>No Resit</th>
|
|
<th>No Transaksi</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@forelse ($activeSchedules as $schedule)
|
|
@php($payment = $schedule->payments->sortByDesc(fn ($item) => $item->paid_at?->timestamp ?? $item->id)->first())
|
|
<tr>
|
|
<td>
|
|
<div class="fw-semibold">{{ $schedule->application?->no_akaun }}</div>
|
|
<div class="text-muted small">{{ $schedule->application?->no_akaun_tunggakan }}</div>
|
|
</td>
|
|
<td>{{ $schedule->application?->application_no }}</td>
|
|
<td>{{ $schedule->application?->user?->displayName() }}</td>
|
|
<td>Ansuran {{ $schedule->installment_no }}</td>
|
|
<td>{{ optional($schedule->due_date)->format('d/m/Y') ?: '-' }}</td>
|
|
<td>RM {{ number_format((float) $schedule->amount, 2) }}</td>
|
|
<td>@include('components.status-badge', ['status' => $schedule->payment_status])</td>
|
|
<td>{{ $payment?->receipt_no ?: '-' }}</td>
|
|
<td>{{ $payment?->transaction_no ?: '-' }}</td>
|
|
</tr>
|
|
@empty
|
|
<tr>
|
|
<td colspan="9" class="text-center text-muted py-4">
|
|
Tiada ansuran akaun aktif setakat ini.
|
|
</td>
|
|
</tr>
|
|
@endforelse
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
@endsection
|