diff --git a/REMARK.md b/REMARK.md index 313b68a..a80c8c5 100644 --- a/REMARK.md +++ b/REMARK.md @@ -3,3 +3,25 @@ - MOHAMAD KHAIRULNIZAN BIN JUSOF - TELLER - MOHAMAD AZUHAIDIE BIN AHMAD - PPC - WAN NURUL AMIRA BINTI WAN HARON - PC + +## Akaun +- admin@test.com +- admin2@test.com + +Module Gadai Online: +- Langkah 1 +- Langkah 2 +[x] PC akan tekan submit, then customer akan masuk ke senarai online mengikut batch +[x] PC boleh semak list customer yang pilih gadai online +- Langkah 3 (Operasi) +[x] dapat dalam bentuk list +[x] Apa jadi kalau operasi reject? - patah balik ke pc, untuk pc buat semakan balik +- Langkah 4 +- Langkah 5 +- Langkah 6 +- Langkah 7 +[x] Macam mana PC nak tahu pembayaran berjaya (Tally PAID page) +[x] Kalau online, dia kena upload kat mana (Operasi: PAID + bukti) +- Langkah 8 +[x] PC semak senarai pelanggan gadai tu tally atau tak +[ ] PC tekan butang blast ke (tanda selesai ada; WhatsApp/SMS belum wire) \ No newline at end of file diff --git a/app/Http/Controllers/GadaianController.php b/app/Http/Controllers/GadaianController.php index a6cbbbe..2dff367 100644 --- a/app/Http/Controllers/GadaianController.php +++ b/app/Http/Controllers/GadaianController.php @@ -211,13 +211,50 @@ class GadaianController extends Controller 'teller' => $auth_user['name'] ]); - $this->AliranTunaiController->alirantunaiGadai($request, $auth_user['name']); + $caraTerima = strtoupper((string) $request->input('cara_terima', 'TUNAI')); + $pinjamanAmt = round((float) $request->pinjaman, 2); + + // Online only for RM5k–50k; otherwise force cash path. + if ($caraTerima === 'ONLINE' && ($pinjamanAmt < 5000 || $pinjamanAmt > 50000)) { + $caraTerima = 'TUNAI'; + } + + if ($caraTerima === 'ONLINE') { + $online = Http::withOptions(['verify' => config('app.api_verify')]) + ->asForm() + ->post(config('api.url') . '/api/pembiayaan-online/' . $auth_user['cawangan'], [ + 'norujukan' => $request->norujukan_gadai, + 'nokp' => $request->nokp, + 'pinjaman' => $pinjamanAmt, + 'kodbank' => $request->kodbank, + 'noakaun' => $request->noakaun, + 'nama_bank' => $request->nama_bank, + 'nama_akaun' => $request->nama_akaun ?: $request->nama_pelanggan, + 'nama_pelanggan' => $request->nama_pelanggan, + 'nopelanggan' => $request->nopelanggan, + 'created_by' => $auth_user['name'], + 'update_customer_bank' => true, + ]); + + if (!$online->successful()) { + $body = $online->json(); + $msg = is_array($body) && isset($body['message']) + ? $body['message'] + : 'Gagal daftar pembiayaan online. Sila cuba lagi.'; + return redirect()->back()->with('error', $msg); + } + } else { + $this->AliranTunaiController->alirantunaiGadai($request, $auth_user['name']); + } event(new GadaiNotify('lulus', $auth_user['cawangan'])); $request->session()->forget('page_reload'); $request->session()->forget('norujukan'); $request->session()->flash('activate_tab', 'SAG_baru'); + if ($caraTerima === 'ONLINE') { + $request->session()->flash('message', 'Gadai berjaya. Pembiayaan online menunggu semakan PC.'); + } return redirect()->route('customer_info'); } diff --git a/app/Http/Controllers/PembiayaanOnlineController.php b/app/Http/Controllers/PembiayaanOnlineController.php new file mode 100644 index 0000000..f7414a2 --- /dev/null +++ b/app/Http/Controllers/PembiayaanOnlineController.php @@ -0,0 +1,744 @@ +middleware('auth'); + } + + protected function api() + { + return Http::withOptions(['verify' => config('app.api_verify')]); + } + + protected function kodcaw() + { + return Auth::user()->cawangan; + } + + /** + * PC senarai queue + batch history. + */ + public function index(Request $request) + { + $auth_user = Auth::user(); + $kodcaw = $this->kodcaw(); + $api_url = config('api.url'); + + $cawangan_info = $this->api() + ->get($api_url . '/api/cawangan/' . $kodcaw) + ->json(); + + $queue = $this->api() + ->get($api_url . '/api/pembiayaan-online/' . $kodcaw . '/queue') + ->json(); + + $batches = $this->api() + ->get($api_url . '/api/pembiayaan-online/' . $kodcaw . '/batches') + ->json(); + + $banks = $this->api()->get($api_url . '/api/bank')->json(); + if (!is_array($banks)) { + $banks = []; + } + + $modal = $this->api() + ->get($api_url . '/api/modal-online/' . $kodcaw) + ->json(); + + $lines = $queue['data'] ?? []; + $slot = $queue['slot_cadangan'] ?? null; + if (!is_array($batches)) { + $batches = []; + } + + return view('pembiayaan_online.pc.senarai', compact( + 'auth_user', + 'kodcaw', + 'api_url', + 'cawangan_info', + 'lines', + 'batches', + 'banks', + 'modal', + 'slot', + 'queue' + )); + } + + /** + * Update bank/docs for a queue line. + */ + public function updateLine(Request $request, $id) + { + $kodcaw = $this->kodcaw(); + $api_url = config('api.url'); + + $payload = [ + 'kodbank' => $request->input('kodbank'), + 'noakaun' => $request->input('noakaun'), + 'nama_bank' => $request->input('nama_bank'), + 'nama_akaun' => $request->input('nama_akaun'), + 'nota' => $request->input('nota'), + 'update_customer_bank' => true, + ]; + + $res = $this->api() + ->asForm() + ->put($api_url . '/api/pembiayaan-online/' . $kodcaw . '/lines/' . $id, $payload); + + if (!$res->successful()) { + $body = $res->json(); + $msg = is_array($body) && isset($body['message']) ? $body['message'] : 'Gagal kemaskini rekod.'; + return redirect()->back()->with('error', $msg); + } + + return redirect()->route('pembiayaan.online.pc')->with('message', 'Rekod dikemaskini.'); + } + + /** + * Submit selected lines as a batch to Operasi. + */ + public function submitBatch(Request $request) + { + $kodcaw = $this->kodcaw(); + $api_url = config('api.url'); + $auth_user = Auth::user(); + + $ids = $request->input('ids', []); + if (!is_array($ids)) { + $ids = array_filter(explode(',', (string) $ids)); + } + + $res = $this->api() + ->asForm() + ->post($api_url . '/api/pembiayaan-online/' . $kodcaw . '/batches/submit', [ + 'ids' => $ids, + 'pc_submitted_by' => $auth_user['name'], + 'slot' => $request->input('slot'), + ]); + + if (!$res->successful()) { + $body = $res->json(); + $msg = is_array($body) && isset($body['message']) ? $body['message'] : 'Gagal hantar batch.'; + return redirect()->back()->with('error', $msg); + } + + $batchNo = $res->json()['batch']['batch_no'] ?? ''; + return redirect()->route('pembiayaan.online.pc') + ->with('message', 'Batch dihantar ke Operasi' . ($batchNo ? ': ' . $batchNo : '.')); + } + + /** + * Batch detail. + */ + public function showBatch($batchId) + { + $kodcaw = $this->kodcaw(); + $api_url = config('api.url'); + + $cawangan_info = $this->api() + ->get($api_url . '/api/cawangan/' . $kodcaw) + ->json(); + + $detail = $this->api() + ->get($api_url . '/api/pembiayaan-online/' . $kodcaw . '/batches/' . $batchId) + ->json(); + + if (!is_array($detail) || empty($detail['batch'])) { + return redirect()->route('pembiayaan.online.pc')->with('error', 'Batch tidak dijumpai.'); + } + + return view('pembiayaan_online.pc.batch', [ + 'batch' => $detail['batch'], + 'lines' => $detail['lines'] ?? [], + 'kodcaw' => $kodcaw, + 'api_url' => $api_url, + 'cawangan_info' => $cawangan_info, + ]); + } + + /** + * PC: senarai PAID untuk tally + blast. + */ + public function paidIndex(Request $request) + { + $auth_user = Auth::user(); + $kodcaw = $this->kodcaw(); + $api_url = config('api.url'); + $blastFilter = $request->input('blast_sent', '0'); + + $cawangan_info = $this->api() + ->get($api_url . '/api/cawangan/' . $kodcaw) + ->json(); + + $query = []; + if ($blastFilter !== 'all' && $blastFilter !== '') { + $query['blast_sent'] = $blastFilter; + } + + $paid = $this->api() + ->get($api_url . '/api/pembiayaan-online/' . $kodcaw . '/paid', $query) + ->json(); + + $lines = $paid['data'] ?? []; + if (!is_array($lines)) { + $lines = []; + } + + $bilangan = $paid['bilangan'] ?? count($lines); + $jumlah = $paid['jumlah'] ?? 0; + + return view('pembiayaan_online.pc.paid', compact( + 'auth_user', + 'kodcaw', + 'api_url', + 'cawangan_info', + 'lines', + 'bilangan', + 'jumlah', + 'blastFilter' + )); + } + + /** + * PC: view/download bukti bayaran inline. + */ + public function viewBukti($id) + { + $kodcaw = $this->kodcaw(); + $res = $this->api() + ->get(config('api.url') . '/api/pembiayaan-online/' . $kodcaw . '/lines/' . $id . '/bukti'); + + if (!$res->successful()) { + $body = $res->json(); + $msg = is_array($body) && isset($body['message']) ? $body['message'] : 'Bukti tidak dijumpai.'; + return redirect()->back()->with('error', $msg); + } + + $payload = $res->json(); + $bukti = $payload['bukti'] ?? null; + if (!$bukti || empty($bukti['data'])) { + return redirect()->back()->with('error', 'Fail bukti kosong.'); + } + + $raw = $bukti['data']; + if (strpos($raw, 'base64,') !== false) { + $raw = substr($raw, strpos($raw, 'base64,') + 7); + } + $binary = base64_decode($raw, true); + if ($binary === false) { + $binary = base64_decode($bukti['data']); + } + + $type = $bukti['type'] ?? 'application/octet-stream'; + $filename = $bukti['filename'] ?? ('bukti-' . $id); + + return response($binary, 200, [ + 'Content-Type' => $type, + 'Content-Disposition' => 'inline; filename="' . $filename . '"', + ]); + } + + /** + * PC: tanda rekod PAID sebagai selesai semak / blast. + */ + public function markBlast(Request $request) + { + $kodcaw = $this->kodcaw(); + $ids = $request->input('ids', []); + if (!is_array($ids)) { + $ids = array_filter(explode(',', (string) $ids)); + } + + if (count($ids) === 0) { + return redirect()->back()->with('error', 'Sila pilih sekurang-kurangnya satu rekod.'); + } + + $res = $this->api() + ->asForm() + ->post(config('api.url') . '/api/pembiayaan-online/' . $kodcaw . '/paid/blast', [ + 'ids' => $ids, + 'blast_by' => Auth::user()['name'], + ]); + + if (!$res->successful()) { + $body = $res->json(); + $msg = is_array($body) && isset($body['message']) ? $body['message'] : 'Gagal tanda selesai.'; + return redirect()->back()->with('error', $msg); + } + + $n = $res->json()['dikemaskini'] ?? count($ids); + return redirect() + ->route('pembiayaan.online.pc.paid') + ->with('message', $n . ' rekod ditanda selesai semak/blast.'); + } + + /** + * Operasi: senarai batch semua cawangan. + */ + public function operasiIndex(Request $request) + { + $auth_user = Auth::user(); + $api_url = config('api.url'); + $status = $request->input('status', 'SUBMITTED'); + $tarikh = $request->input('tarikh'); + + $query = ['status' => $status]; + if ($tarikh) { + $query['tarikh'] = $tarikh; + } + + $res = $this->api() + ->get($api_url . '/api/pembiayaan-online/operasi/batches', $query) + ->json(); + + $batches = $res['data'] ?? []; + if (!is_array($batches)) { + $batches = []; + } + + return view('pembiayaan_online.operasi.senarai', compact( + 'auth_user', + 'api_url', + 'batches', + 'status', + 'tarikh' + )); + } + + /** + * Operasi: detail batch + lines. + */ + public function operasiShowBatch($kodcaw, $batchId) + { + $auth_user = Auth::user(); + $api_url = config('api.url'); + + $cawangan_info = $this->api() + ->get($api_url . '/api/cawangan/' . $kodcaw) + ->json(); + + $detail = $this->api() + ->get($api_url . '/api/pembiayaan-online/operasi/' . $kodcaw . '/batches/' . $batchId) + ->json(); + + if (!is_array($detail) || empty($detail['batch'])) { + return redirect() + ->route('pembiayaan.online.operasi') + ->with('error', 'Batch tidak dijumpai.'); + } + + return view('pembiayaan_online.operasi.batch', [ + 'auth_user' => $auth_user, + 'batch' => $detail['batch'], + 'lines' => $detail['lines'] ?? [], + 'kodcaw' => $kodcaw, + 'api_url' => $api_url, + 'cawangan_info' => $cawangan_info, + ]); + } + + public function operasiApproveLine(Request $request, $kodcaw, $id) + { + $res = $this->api() + ->asForm() + ->post(config('api.url') . '/api/pembiayaan-online/operasi/' . $kodcaw . '/lines/' . $id . '/approve', [ + 'ops_by' => Auth::user()['name'], + ]); + + return $this->opsRedirect($res, $kodcaw, $request->input('batch_id'), 'Rekod diluluskan.'); + } + + public function operasiRejectLine(Request $request, $kodcaw, $id) + { + $reason = trim((string) $request->input('reject_reason', '')); + if ($reason === '') { + return redirect()->back()->with('error', 'Sebab tolak diperlukan.'); + } + + $res = $this->api() + ->asForm() + ->post(config('api.url') . '/api/pembiayaan-online/operasi/' . $kodcaw . '/lines/' . $id . '/reject', [ + 'ops_by' => Auth::user()['name'], + 'reject_reason' => $reason, + ]); + + return $this->opsRedirect($res, $kodcaw, $request->input('batch_id'), 'Rekod ditolak. Dikembalikan ke PC.'); + } + + public function operasiApproveBatch(Request $request, $kodcaw, $batchId) + { + $res = $this->api() + ->asForm() + ->post(config('api.url') . '/api/pembiayaan-online/operasi/' . $kodcaw . '/batches/' . $batchId . '/approve', [ + 'ops_by' => Auth::user()['name'], + ]); + + return $this->opsRedirect($res, $kodcaw, $batchId, 'Semua rekod menunggu dalam batch diluluskan.'); + } + + public function operasiMarkPaid(Request $request, $kodcaw, $id) + { + $payload = $this->buildPaidPayload($request); + if (isset($payload['error'])) { + return redirect()->back()->with('error', $payload['error']); + } + + $res = $this->api() + ->asForm() + ->post(config('api.url') . '/api/pembiayaan-online/operasi/' . $kodcaw . '/lines/' . $id . '/paid', $payload); + + return $this->opsRedirect($res, $kodcaw, $request->input('batch_id'), 'Rekod ditanda PAID.'); + } + + public function operasiMarkPaidBatch(Request $request, $kodcaw, $batchId) + { + $payload = $this->buildPaidPayload($request); + if (isset($payload['error'])) { + return redirect()->back()->with('error', $payload['error']); + } + + $res = $this->api() + ->asForm() + ->post(config('api.url') . '/api/pembiayaan-online/operasi/' . $kodcaw . '/batches/' . $batchId . '/paid', $payload); + + return $this->opsRedirect($res, $kodcaw, $batchId, 'Rekod APPROVED dalam batch ditanda PAID.'); + } + + /** + * @return array + */ + protected function buildPaidPayload(Request $request) + { + $noRujukan = trim((string) $request->input('no_rujukan_bayaran', '')); + if ($noRujukan === '') { + return ['error' => 'No. rujukan bayaran diperlukan.']; + } + + if (!$request->hasFile('bukti')) { + return ['error' => 'Fail bukti bayaran diperlukan.']; + } + + $file = $request->file('bukti'); + if (!$file->isValid()) { + return ['error' => 'Fail bukti tidak sah.']; + } + + $raw = base64_encode(file_get_contents($file->getRealPath())); + $mime = $file->getMimeType() ?: 'application/octet-stream'; + + return [ + 'ops_by' => Auth::user()['name'], + 'no_rujukan_bayaran' => $noRujukan, + 'tarikh_bayaran' => $request->input('tarikh_bayaran') ?: date('Y-m-d'), + 'bukti_data' => $raw, + 'bukti_filename' => $file->getClientOriginalName(), + 'bukti_type' => $mime, + ]; + } + + protected function opsRedirect($res, $kodcaw, $batchId, $successMsg) + { + $batchId = $batchId ?: null; + + if (!$res->successful()) { + $body = $res->json(); + $msg = is_array($body) && isset($body['message']) ? $body['message'] : 'Tindakan gagal.'; + return redirect()->back()->with('error', $msg); + } + + if ($batchId) { + return redirect() + ->route('pembiayaan.online.operasi.batch', ['kodcaw' => $kodcaw, 'batchId' => $batchId]) + ->with('message', $successMsg); + } + + return redirect()->route('pembiayaan.online.operasi')->with('message', $successMsg); + } + + /** + * PC: modal online float + top-up request form/history. + */ + public function topupIndex(Request $request) + { + $auth_user = Auth::user(); + $kodcaw = $this->kodcaw(); + $api_url = config('api.url'); + $status = $request->input('status', ''); + + $cawangan_info = $this->api() + ->get($api_url . '/api/cawangan/' . $kodcaw) + ->json(); + + $modal = $this->api() + ->get($api_url . '/api/modal-online/' . $kodcaw) + ->json(); + + $query = []; + if ($status !== '' && $status !== 'all') { + $query['status'] = $status; + } + + $reqRes = $this->api() + ->get($api_url . '/api/modal-online/' . $kodcaw . '/topup/requests', $query) + ->json(); + + $requests = $reqRes['data'] ?? []; + if (!is_array($requests)) { + $requests = []; + } + + $pendingRes = $this->api() + ->get($api_url . '/api/modal-online/' . $kodcaw . '/topup/requests', ['status' => 'PENDING']) + ->json(); + $pendingList = $pendingRes['data'] ?? []; + $hasPending = is_array($pendingList) && count($pendingList) > 0; + $isMissing = !empty($modal['missing']); + $pendingRequest = $modal['pending_request'] ?? null; + if (!$pendingRequest && $hasPending) { + $pendingRequest = $pendingList[0]; + } + + return view('pembiayaan_online.pc.topup', compact( + 'auth_user', + 'kodcaw', + 'api_url', + 'cawangan_info', + 'modal', + 'requests', + 'status', + 'hasPending', + 'isMissing', + 'pendingRequest' + )); + } + + /** + * PC: submit top-up request. + */ + public function topupRequest(Request $request) + { + $kodcaw = $this->kodcaw(); + $amaun = (float) $request->input('amaun', 0); + + if ($amaun <= 0) { + return redirect()->back()->with('error', 'Amaun mesti lebih daripada 0.'); + } + + $res = $this->api() + ->asForm() + ->post(config('api.url') . '/api/modal-online/' . $kodcaw . '/topup/request', [ + 'amaun' => $amaun, + 'dimohon_oleh' => Auth::user()['name'], + 'nota' => $request->input('nota'), + ]); + + if (!$res->successful()) { + $body = $res->json(); + $msg = is_array($body) && isset($body['message']) ? $body['message'] : 'Gagal hantar permohonan.'; + return redirect()->back()->with('error', $msg)->withInput(); + } + + return redirect() + ->route('pembiayaan.online.pc.topup') + ->with('message', 'Permohonan modal online dihantar. Menunggu kelulusan Operasi.'); + } + + /** + * Operasi: senarai permohonan tambah modal online. + */ + public function operasiTopupIndex(Request $request) + { + $auth_user = Auth::user(); + $api_url = config('api.url'); + $status = $request->input('status', 'PENDING'); + $tarikh = $request->input('tarikh'); + + $query = []; + if ($status === 'all') { + $query['status'] = 'all'; + } elseif ($status !== '' && $status !== null) { + $query['status'] = $status; + } else { + $query['status'] = 'PENDING'; + } + if ($tarikh) { + $query['tarikh'] = $tarikh; + } + + $res = $this->api() + ->get($api_url . '/api/modal-online/operasi/topup/requests', $query) + ->json(); + + $requests = $res['data'] ?? []; + if (!is_array($requests)) { + $requests = []; + } + + return view('pembiayaan_online.operasi.topup', compact( + 'auth_user', + 'api_url', + 'requests', + 'status', + 'tarikh' + )); + } + + public function operasiTopupApprove(Request $request, $id) + { + $amaun = $request->input('amaun'); + if ($amaun !== null && $amaun !== '' && (float) $amaun <= 0) { + return redirect()->back()->with('error', 'Amaun diluluskan mesti lebih daripada 0.'); + } + + $res = $this->api() + ->asForm() + ->post(config('api.url') . '/api/modal-online/operasi/topup/' . $id . '/approve', [ + 'diluluskan_oleh' => Auth::user()['name'], + 'nota' => $request->input('nota'), + 'amaun' => $amaun, + ]); + + if (!$res->successful()) { + $body = $res->json(); + $msg = is_array($body) && isset($body['message']) ? $body['message'] : 'Gagal lulus permohonan.'; + return redirect()->back()->with('error', $msg); + } + + $amaunLulus = $res->json()['request']['amaun'] ?? $amaun; + return redirect() + ->route('pembiayaan.online.operasi.topup') + ->with('message', 'Permohonan diluluskan RM ' . number_format((float) $amaunLulus, 2) . '. Modal online cawangan dikemas kini.'); + } + + public function operasiTopupReject(Request $request, $id) + { + $res = $this->api() + ->asForm() + ->post(config('api.url') . '/api/modal-online/operasi/topup/' . $id . '/reject', [ + 'diluluskan_oleh' => Auth::user()['name'], + 'nota' => $request->input('nota'), + ]); + + if (!$res->successful()) { + $body = $res->json(); + $msg = is_array($body) && isset($body['message']) ? $body['message'] : 'Gagal tolak permohonan.'; + return redirect()->back()->with('error', $msg); + } + + return redirect() + ->route('pembiayaan.online.operasi.topup') + ->with('message', 'Permohonan ditolak.'); + } + + /** + * PC: EOD close branch modal online. + */ + public function closeModal(Request $request) + { + $kodcaw = $this->kodcaw(); + + $res = $this->api() + ->asForm() + ->post(config('api.url') . '/api/modal-online/' . $kodcaw . '/close', [ + 'ditutup_oleh' => Auth::user()['name'], + ]); + + if (!$res->successful()) { + $body = $res->json(); + $msg = is_array($body) && isset($body['message']) ? $body['message'] : 'Gagal tutup modal online.'; + return redirect()->back()->with('error', $msg); + } + + $dikembalikan = $res->json()['dikembalikan'] ?? 0; + return redirect() + ->route('pembiayaan.online.pc.topup') + ->with('message', 'Modal online ditutup. Baki dikembalikan RM ' . number_format((float) $dikembalikan, 2) . '.'); + } + + /** + * Operasi: EOD dashboard semua cawangan. + */ + public function operasiEodIndex(Request $request) + { + $auth_user = Auth::user(); + $api_url = config('api.url'); + $tarikh = $request->input('tarikh') ?: date('Y-m-d'); + + $res = $this->api() + ->get($api_url . '/api/modal-online/operasi/eod', [ + 'zone' => 'all', + 'tarikh' => $tarikh, + ]) + ->json(); + + $rows = $res['data'] ?? []; + if (!is_array($rows)) { + $rows = []; + } + + $summary = [ + 'open' => $res['open'] ?? 0, + 'closed' => $res['closed'] ?? 0, + 'missing' => $res['missing'] ?? 0, + 'bilangan' => $res['bilangan'] ?? count($rows), + ]; + + return view('pembiayaan_online.operasi.eod', compact( + 'auth_user', + 'api_url', + 'rows', + 'tarikh', + 'summary' + )); + } + + public function operasiCloseModal(Request $request, $kodcaw) + { + $res = $this->api() + ->asForm() + ->post(config('api.url') . '/api/modal-online/' . $kodcaw . '/close', [ + 'ditutup_oleh' => Auth::user()['name'], + ]); + + if (!$res->successful()) { + $body = $res->json(); + $msg = is_array($body) && isset($body['message']) ? $body['message'] : 'Gagal tutup modal online.'; + return redirect()->back()->with('error', $msg); + } + + return redirect() + ->route('pembiayaan.online.operasi.eod') + ->with('message', 'Modal online ' . $kodcaw . ' ditutup.'); + } + + public function operasiCloseAllModal(Request $request) + { + $res = $this->api() + ->asForm() + ->post(config('api.url') . '/api/modal-online/operasi/eod/close-all', [ + 'ditutup_oleh' => Auth::user()['name'], + 'zone' => 'all', + ]); + + if (!$res->successful()) { + $body = $res->json(); + $msg = is_array($body) && isset($body['message']) ? $body['message'] : 'Gagal tutup semua modal online.'; + return redirect()->back()->with('error', $msg); + } + + $closed = $res->json()['closed'] ?? 0; + $skipped = $res->json()['skipped'] ?? 0; + return redirect() + ->route('pembiayaan.online.operasi.eod') + ->with('message', 'EOD selesai: ' . $closed . ' ditutup, ' . $skipped . ' sudah ditutup.'); + } +} diff --git a/resources/views/customers/v2/info.blade.php b/resources/views/customers/v2/info.blade.php index 13fa1f4..c9ad3a5 100644 --- a/resources/views/customers/v2/info.blade.php +++ b/resources/views/customers/v2/info.blade.php @@ -230,7 +230,6 @@ // 4️⃣ Hantar permohonan ke backend (Laravel) const response = await fetch("{{ route('operasi.createkelulusan-anggota') }}", { - method: 'POST', headers: { "Content-Type": "application/json", @@ -238,15 +237,14 @@ }, body: JSON.stringify({ mohon: "Assign Anggota", - noic: noic, + nokp: noic, norujukan: norujukan, komen: komen, teller: "{{ Auth::user()->name }}", tagoperasi: 1 // 1 = tunggu kelulusan operasi }) - - console.log(`Response: ${response}`); }); + console.log(`Response: ${response}`); const result = await response.json(); diff --git a/resources/views/gadaian/v2/index.blade.php b/resources/views/gadaian/v2/index.blade.php index bdbb457..94b2512 100644 --- a/resources/views/gadaian/v2/index.blade.php +++ b/resources/views/gadaian/v2/index.blade.php @@ -217,6 +217,68 @@ +
@@ -684,6 +746,7 @@ var nokp = $('#nokp').val(); //console.log('DEBUG NOKP:', nokp, kadarupah); + toggleCaraTerima(pinjaman); // var keuntungan_sebulan = pinjaman * kadarupah; // var keuntungan_6bln = keuntungan_sebulan * 6; @@ -1195,9 +1258,170 @@ .then(response => response.json()); } + function toggleCaraTerima(pinjaman) { + if (pinjaman >= 5000 && pinjaman <= 50000) { + $('#cara_terima_section').show(); + toggleBankOnlineSection(); + } else { + $('#cara_terima_section').hide(); + $('#bank_online_section').hide(); + $('#cara_terima_tunai').prop('checked', true); + } + } + + function toggleBankOnlineSection() { + if ($('input[name="cara_terima"]:checked').val() === 'ONLINE') { + $('#bank_online_section').show(); + var nama = $('#gadai_kodbank option:selected').data('nama') || ''; + $('#gadai_nama_bank').val(nama); + refreshModalOnlineStatus(); + } else { + $('#bank_online_section').hide(); + } + } + + $(document).on('change', 'input[name="cara_terima"]', function () { + toggleBankOnlineSection(); + }); + + $(document).on('change', '#gadai_kodbank', function () { + $('#gadai_nama_bank').val($('#gadai_kodbank option:selected').data('nama') || ''); + }); + + async function getModalOnline() { + let kodcaw = $('#kodcaw').val(); + let apiUrl = api_url + '/api/modal-online/' + kodcaw; + return $.ajax({ + method: 'GET', + url: apiUrl, + dataType: 'json', + }); + } + + async function refreshModalOnlineStatus() { + var $el = $('#modal_online_status'); + $el.removeClass('text-success text-danger text-warning text-muted').addClass('text-muted').text('Memeriksa baki...'); + try { + var modal = await getModalOnline(); + var pending = modal.pending_request || null; + var closed = Number(modal.ditutup || 0) === 1; + var missing = !!modal.missing; + var baki = Number(modal.baki || 0); + var had = Number(modal.had || 0) + Number(modal.tambah || 0); + + if (closed) { + $el.removeClass('text-muted').addClass('text-danger') + .text('Modal online hari ini sudah ditutup (EOD). Gadai online tidak dibenarkan.'); + return modal; + } + + if (pending) { + $el.removeClass('text-muted').addClass('text-warning') + .text('Menunggu kelulusan Operasi: RM ' + formatter.format(Number(pending.amaun || 0)) + + ' (' + (pending.dimohon_oleh || '-') + ').'); + } else if (missing) { + $el.removeClass('text-muted').addClass('text-danger') + .text('Belum ada had hari ini. Sila hubungi PC.'); + } else { + $el.removeClass('text-muted').addClass('text-success') + .text('Baki RM ' + formatter.format(baki) + ' / Had RM ' + formatter.format(had)); + } + return modal; + } catch (e) { + $el.removeClass('text-muted').addClass('text-danger').text('Gagal semak modal online.'); + return null; + } + } + + async function checkDisbursementFloat(pinjaman) { + var cara = $('input[name="cara_terima"]:checked').val() || 'TUNAI'; + if (!(pinjaman >= 5000 && pinjaman <= 50000)) { + cara = 'TUNAI'; + } + + if (cara === 'ONLINE') { + var kodbank = $('#gadai_kodbank').val(); + var noakaun = ($('#gadai_noakaun').val() || '').trim(); + $('#gadai_nama_bank').val($('#gadai_kodbank option:selected').data('nama') || ''); + if (!kodbank || !noakaun) { + Swal.fire({ + icon: 'error', + title: 'Amaran!', + text: 'Sila lengkapkan maklumat bank untuk pembayaran online.' + }); + return false; + } + + var modal; + try { + modal = await getModalOnline(); + } catch (e) { + Swal.fire({ + icon: 'error', + title: 'Amaran!', + text: 'Gagal semak modal online. Sila cuba lagi.' + }); + return false; + } + + if (Number(modal.ditutup || 0) === 1) { + Swal.fire({ + icon: 'error', + title: 'Amaran!', + text: 'Modal online hari ini sudah ditutup (EOD). Sila pilih Tunai.' + }); + return false; + } + + if (modal.pending_request) { + Swal.fire({ + icon: 'info', + title: 'Menunggu Operasi', + text: 'Permohonan RM ' + formatter.format(Number(modal.pending_request.amaun || 0)) + + ' masih PENDING. Sila tunggu kelulusan Operasi atau pilih Tunai.' + }); + return false; + } + + if (modal.missing) { + Swal.fire({ + icon: 'error', + title: 'Amaran!', + text: 'Belum ada had modal online hari ini. Sila hubungi PC.' + }); + return false; + } + + if (Number(modal.baki || 0) < pinjaman) { + Swal.fire({ + icon: 'error', + title: 'Amaran!', + text: 'Baki modal online tidak mencukupi. Sila hubungi PC untuk mohon tambah modal, atau pilih Tunai.' + }); + return false; + } + + return true; + } + + let dataCawangan = await getDataCawangan(); + let bakiAkhir = dataCawangan.baki; + if (bakiAkhir < pinjaman) { + Swal.fire({ + icon: 'error', + title: 'Amaran!', + text: 'Baki Akhir Tunai Lebih Rendah Daripada Nilai Marhun Yang Ingin Digadaikan. Sila Tambah Pendahuluan di Laman Aliran Tunai Segera. ' + }); + return false; + } + return true; + } + async function verifyGadai(func){ $("#terima_gadai").prop('disabled', true); - event.preventDefault(); + if (typeof event !== 'undefined' && event && event.preventDefault) { + event.preventDefault(); + } var kodcaw = $('#kodcaw').val(); var nokp = $('#nokp').val(); var nopelanggan = $('#nopelanggan').val(); @@ -1224,23 +1448,16 @@ title: 'Amaran!', text: 'Pembiayaan Tidak Lengkap' }); - event.preventDefault(); return false; } - let dataCawangan = await getDataCawangan(); - let bakiAkhir = dataCawangan.baki; - - if(bakiAkhir < pinjaman){ + let floatOk = await checkDisbursementFloat(pinjaman); + if (!floatOk) { $("#terima_gadai").prop('disabled', false); - Swal.fire({ - icon: 'error', - title: 'Amaran!', - text: 'Baki Akhir Tunai Lebih Rendah Daripada Nilai Marhun Yang Ingin Digadaikan. Sila Tambah Pendahuluan di Laman Aliran Tunai Segera. ' - }); - event.preventDefault(); return false; - }else{ + } + + if(true){ if($.isNumeric(pinjaman) == false){ $("#terima_gadai").prop('disabled', false); diff --git a/resources/views/homepage/khazanah/home.blade.php b/resources/views/homepage/khazanah/home.blade.php index 79b5de0..2b69225 100644 --- a/resources/views/homepage/khazanah/home.blade.php +++ b/resources/views/homepage/khazanah/home.blade.php @@ -262,6 +262,10 @@ Pendahuluan - Serahan
+
+ Pembiayaan Online +
Surat Wakil diff --git a/resources/views/homepage/operasi/home.blade.php b/resources/views/homepage/operasi/home.blade.php index 8c73baf..1463e39 100644 --- a/resources/views/homepage/operasi/home.blade.php +++ b/resources/views/homepage/operasi/home.blade.php @@ -14,13 +14,16 @@
- Kelulusan Anggota - Kelulusan - Kakitangan - Parameter - Komoditi - Perubatan - Laporan Audit + Kelulusan Anggota + Kelulusan + Pembiayaan Online + Modal Online + EOD Modal Online + Kakitangan + Parameter + Komoditi + Perubatan + Laporan Audit
diff --git a/resources/views/pembiayaan_online/operasi/batch.blade.php b/resources/views/pembiayaan_online/operasi/batch.blade.php new file mode 100644 index 0000000..fd0e14d --- /dev/null +++ b/resources/views/pembiayaan_online/operasi/batch.blade.php @@ -0,0 +1,271 @@ +@extends('layouts.app_operasi') +@section('content') +@php + $pendingCount = collect($lines)->whereIn('status', ['IN_BATCH', 'OPS_REVIEW'])->count(); + $approvedCount = collect($lines)->where('status', 'APPROVED')->count(); + $cawName = $cawangan_info['nama'] ?? $cawangan_info['namacaw'] ?? $kodcaw; +@endphp +
+
+
+ + + @if(session()->has('message')) +
{{ session('message') }}
+ @endif + @if(session()->has('error')) +
{{ session('error') }}
+ @endif + +
+
+
+
Batch No
{{ $batch['batch_no'] ?? '-' }}
+
Cawangan
{{ $cawName }} ({{ $kodcaw }})
+
Tarikh
{{ $batch['tarikh'] ?? '-' }}
+
Slot
{{ $batch['slot'] ?? '-' }}
+
Status
{{ $batch['status'] ?? '-' }}
+
+
+
Bilangan
{{ $batch['bilangan'] ?? count($lines) }}
+
Jumlah
RM {{ number_format((float)($batch['jumlah_keseluruhan'] ?? 0), 2) }}
+
Dihantar Oleh
{{ $batch['pc_submitted_by'] ?? '-' }}
+
Dihantar Pada
{{ $batch['submitted_at'] ?? '-' }}
+
+
+
+ +
+
+
Senarai Dalam Batch
+
+ Kembali + @if($pendingCount > 0) +
+ @csrf + +
+ @endif + @if($approvedCount > 0) + + @endif +
+
+
+ + + + + + + + + + + + + + + + + @forelse($lines as $line) + @php + $st = $line['status'] ?? ''; + $badge = 'badge-secondary'; + if ($st === 'APPROVED') $badge = 'badge-success'; + elseif ($st === 'PAID') $badge = 'badge-dark'; + elseif ($st === 'REJECTED_PC') $badge = 'badge-danger'; + elseif (in_array($st, ['IN_BATCH', 'OPS_REVIEW'], true)) $badge = 'badge-primary'; + @endphp + + + + + + + + + + + + + @empty + + + + @endforelse + +
StatusSAGPelangganNo KPBankNo AkaunNama AkaunPinjaman (RM)Rujukan BayaranTindakan
{{ $st ?: '-' }}{{ $line['norujukan'] ?? '-' }}{{ $line['nama_pelanggan'] ?? '-' }}{{ $line['nokp'] ?? '-' }}{{ $line['nama_bank'] ?? $line['kodbank'] ?? '-' }}{{ $line['noakaun'] ?? '-' }}{{ $line['nama_akaun'] ?? '-' }}{{ number_format((float)($line['pinjaman'] ?? 0), 2) }}{{ $line['no_rujukan_bayaran'] ?? '-' }} + @if(in_array($st, ['IN_BATCH', 'OPS_REVIEW'], true)) +
+ @csrf + + +
+ + @elseif($st === 'APPROVED') + + + @elseif($st === 'PAID') + Selesai + @else + - + @endif +
Tiada rekod dalam batch.
+
+
+
+
+
+ +{{-- Reject modal --}} + + +{{-- Paid line modal --}} + + +{{-- Paid batch modal --}} + + + +@endsection diff --git a/resources/views/pembiayaan_online/operasi/eod.blade.php b/resources/views/pembiayaan_online/operasi/eod.blade.php new file mode 100644 index 0000000..588e0a6 --- /dev/null +++ b/resources/views/pembiayaan_online/operasi/eod.blade.php @@ -0,0 +1,152 @@ +@extends('layouts.app_operasi') +@section('content') +
+
+
+ + + @if(session()->has('message')) +
{{ session('message') }}
+ @endif + @if(session()->has('error')) +
{{ session('error') }}
+ @endif + +
+
+
+
Tarikh
+

{{ $tarikh }}

+
+
+
+
+
Masih Dibuka
+

{{ $summary['open'] ?? 0 }}

+
+
+
+
+
Sudah Ditutup
+

{{ $summary['closed'] ?? 0 }}

+
+
+
+
+
Belum Ada Rekod
+

{{ $summary['missing'] ?? 0 }}

+
+
+
+ +
+
+
+ + + + Top-up +
+ @if(($summary['open'] ?? 0) > 0) +
+ @csrf + +
+ @endif +
+
+ +
+
+
Status Modal Online Mengikut Cawangan
+
+
+ + + + + + + + + + + + + + + + @forelse($rows as $row) + @php + $closed = (int)($row['ditutup'] ?? 0) === 1; + $missing = !empty($row['missing']); + @endphp + + + + + + + + + + + + @empty + + + + @endforelse + +
CawanganHadTambahDigunakanKurang (EOD)BakiStatusDitutup Oleh
+
{{ $row['cawangan_nama'] ?? '-' }}
+ {{ $row['kodcaw'] ?? '' }} +
{{ number_format((float)($row['had'] ?? 0), 2) }}{{ number_format((float)($row['tambah'] ?? 0), 2) }}{{ number_format((float)($row['digunakan'] ?? 0), 2) }}{{ number_format((float)($row['kurang'] ?? 0), 2) }} + @if($missing) + — + @else + {{ number_format((float)($row['baki'] ?? 0), 2) }} + @endif + + @if($closed) + DITUTUP + @elseif($missing) + TIADA + @else + DIBUKA + @endif + + @if($closed) + {{ $row['ditutup_oleh'] ?? '-' }}
+ {{ $row['ditutup_at'] ?? '' }} + @else + — + @endif +
+ @if($closed) + OK + @elseif($missing) + Tiada had + @else +
+ @csrf + +
+ @endif +
Tiada data cawangan.
+
+
+
+
+
+@endsection diff --git a/resources/views/pembiayaan_online/operasi/senarai.blade.php b/resources/views/pembiayaan_online/operasi/senarai.blade.php new file mode 100644 index 0000000..2f2e650 --- /dev/null +++ b/resources/views/pembiayaan_online/operasi/senarai.blade.php @@ -0,0 +1,102 @@ +@extends('layouts.app_operasi') +@section('content') +
+
+
+ + + @if(session()->has('message')) +
{{ session('message') }}
+ @endif + @if(session()->has('error')) +
{{ session('error') }}
+ @endif + +
+
+
+ + + + + + Reset +
+
+
+ +
+
+
Senarai Batch Pembiayaan Online
+
+ Modal Online + EOD + {{ count($batches) }} batch +
+
+
+ + + + + + + + + + + + + + + + @forelse($batches as $batch) + @php + $st = $batch['status'] ?? ''; + $badge = 'badge-secondary'; + if ($st === 'SUBMITTED') $badge = 'badge-primary'; + elseif ($st === 'PARTIAL') $badge = 'badge-warning'; + elseif ($st === 'OPS_DONE') $badge = 'badge-success'; + elseif ($st === 'PAID') $badge = 'badge-dark'; + @endphp + + + + + + + + + + + + @empty + + + + @endforelse + +
Batch NoCawanganTarikhSlotBilJumlah (RM)StatusDihantar Oleh
{{ $batch['batch_no'] ?? '-' }} +
{{ $batch['cawangan_nama'] ?? '-' }}
+ {{ $batch['kodcaw'] ?? '' }} +
{{ $batch['tarikh'] ?? '-' }}{{ $batch['slot'] ?? '-' }}{{ $batch['bilangan'] ?? 0 }}{{ number_format((float)($batch['jumlah_keseluruhan'] ?? 0), 2) }}{{ $st ?: '-' }}{{ $batch['pc_submitted_by'] ?? '-' }} + + Semak + +
Tiada batch untuk tapisan ini.
+
+
+
+
+
+@endsection diff --git a/resources/views/pembiayaan_online/operasi/topup.blade.php b/resources/views/pembiayaan_online/operasi/topup.blade.php new file mode 100644 index 0000000..139a0ae --- /dev/null +++ b/resources/views/pembiayaan_online/operasi/topup.blade.php @@ -0,0 +1,198 @@ +@extends('layouts.app_operasi') +@section('content') +
+
+
+ + + @if(session()->has('message')) +
{{ session('message') }}
+ @endif + @if(session()->has('error')) +
{{ session('error') }}
+ @endif + +
+
+
+ + + + + + Reset + Batch Online +
+
+
+ +
+
+
Permohonan Had / Tambah Modal Online
+ {{ count($requests) }} rekod +
+
+ + + + + + + + + + + + + + + @forelse($requests as $req) + @php + $st = $req['status'] ?? ''; + $badge = 'badge-secondary'; + if ($st === 'PENDING') $badge = 'badge-warning'; + elseif ($st === 'APPROVED') $badge = 'badge-success'; + elseif ($st === 'REJECTED') $badge = 'badge-danger'; + @endphp + + + + + + + + + + + @empty + + + + @endforelse + +
IDCawanganTarikhAmaun (RM)Dimohon OlehStatusNotaTindakan
{{ $req['id'] ?? '-' }} +
{{ $req['cawangan_nama'] ?? '-' }}
+ {{ $req['kodcaw'] ?? '' }} +
{{ $req['tarikh'] ?? '-' }}{{ number_format((float)($req['amaun'] ?? 0), 2) }}{{ $req['dimohon_oleh'] ?? '-' }}{{ $st ?: '-' }}{{ $req['nota'] ?? '-' }} + @if($st === 'PENDING') + + + @else + {{ $req['diluluskan_oleh'] ?? '-' }} + @endif +
Tiada permohonan untuk tapisan ini.
+
+
+
+
+
+ + + + + + +@endsection diff --git a/resources/views/pembiayaan_online/pc/batch.blade.php b/resources/views/pembiayaan_online/pc/batch.blade.php new file mode 100644 index 0000000..ac2db5a --- /dev/null +++ b/resources/views/pembiayaan_online/pc/batch.blade.php @@ -0,0 +1,65 @@ +@extends('layouts.app') +@section('content') +
+
+
+ + +
+
+
+
Batch No
{{ $batch['batch_no'] ?? '-' }}
+
Tarikh
{{ $batch['tarikh'] ?? '-' }}
+
Slot
{{ $batch['slot'] ?? '-' }}
+
Status
{{ $batch['status'] ?? '-' }}
+
Jumlah
RM {{ number_format((float)($batch['jumlah_keseluruhan'] ?? 0), 2) }}
+
+
+
+ +
+
+
Senarai Dalam Batch
+ Kembali +
+
+ + + + + + + + + + + + + + + @foreach($lines as $line) + + + + + + + + + + + @endforeach + +
StatusSAGPelangganNo KPBankNo AkaunPinjaman (RM)Rujukan Bayaran
{{ $line['status'] ?? '-' }}{{ $line['norujukan'] ?? '-' }}{{ $line['nama_pelanggan'] ?? '-' }}{{ $line['nokp'] ?? '-' }}{{ $line['nama_bank'] ?? $line['kodbank'] ?? '-' }}{{ $line['noakaun'] ?? '-' }}{{ number_format((float)($line['pinjaman'] ?? 0), 2) }}{{ $line['no_rujukan_bayaran'] ?? '-' }}
+
+
+
+
+
+@endsection diff --git a/resources/views/pembiayaan_online/pc/paid.blade.php b/resources/views/pembiayaan_online/pc/paid.blade.php new file mode 100644 index 0000000..138ba46 --- /dev/null +++ b/resources/views/pembiayaan_online/pc/paid.blade.php @@ -0,0 +1,187 @@ +@extends('layouts.app') +@section('content') +
+
+
+ + + @if(session()->has('message')) +
{{ session('message') }}
+ @endif + @if(session()->has('error')) +
{{ session('error') }}
+ @endif + +
+
+
+
+
Bilangan PAID
+

{{ $bilangan }} rekod

+
+
+
+
+
+
+
Jumlah Pinjaman
+

RM {{ number_format((float) $jumlah, 2) }}

+
+
+
+
+
+
+
Tapisan
+

+ @if(($blastFilter ?? '0') === '0') Belum Blast + @elseif(($blastFilter ?? '') === '1') Sudah Blast + @else Semua + @endif +

+
+
+
+
+ +
+
+
+ + + + Kembali Queue +
+
+
+ +
+
+
Senarai Pembiayaan Online — PAID
+ +
+
+

+ Semak jumlah & bukti bayaran sepadan dengan pelanggan. Setelah semak, tanda selesai. + (WhatsApp/SMS blast boleh disambung kemudian — butang ini menanda rekod sebagai selesai semak.) +

+
+ @csrf +
+ + + + + + + + + + + + + + + + + + + @forelse($lines as $line) + @php $blasted = (int)($line['blast_sent'] ?? 0) === 1; @endphp + + + + + + + + + + + + + + + @empty + + + + @endforelse + + @if(count($lines) > 0) + + + + + + + + @endif +
+ @if(($blastFilter ?? '0') !== '1') + + @endif + BlastSAGPelangganNo KPBankNo AkaunPinjaman (RM)Rujukan BayaranTarikh BayaranPaid AtBukti
+ @if(!$blasted) + + @else + — + @endif + + @if($blasted) + SELESAI + @else + BELUM + @endif + {{ $line['norujukan'] ?? '-' }}{{ $line['nama_pelanggan'] ?? '-' }}{{ $line['nokp'] ?? '-' }}{{ $line['nama_bank'] ?? $line['kodbank'] ?? '-' }}{{ $line['noakaun'] ?? '-' }}{{ number_format((float)($line['pinjaman'] ?? 0), 2) }}{{ $line['no_rujukan_bayaran'] ?? '-' }}{{ $line['tarikh_bayaran'] ?? '-' }}{{ $line['paid_at'] ?? '-' }} + @if(!empty($line['bukti_file_id'])) + + Lihat + + @else + Tiada + @endif +
Tiada rekod PAID untuk tapisan ini.
Jumlah dipaparkan{{ number_format((float) $jumlah, 2) }}
+
+
+
+
+
+
+
+ + +@endsection diff --git a/resources/views/pembiayaan_online/pc/senarai.blade.php b/resources/views/pembiayaan_online/pc/senarai.blade.php new file mode 100644 index 0000000..a26b481 --- /dev/null +++ b/resources/views/pembiayaan_online/pc/senarai.blade.php @@ -0,0 +1,304 @@ +@extends('layouts.app') +@section('content') +
+
+
+ + + + + @if(session()->has('message')) +
{{ session('message') }}
+ @endif + @if(session()->has('error')) +
{{ session('error') }}
+ @endif + + @php + $isMissing = !empty($modal['missing']); + $isClosed = (int)($modal['ditutup'] ?? 0) === 1; + $pendingReq = $modal['pending_request'] ?? null; + if (is_object($pendingReq)) { + $pendingReq = json_decode(json_encode($pendingReq), true); + } + @endphp + + @if($isClosed) +
Modal online hari ini sudah ditutup (EOD).
+ @elseif($isMissing) +
+ Belum ada had modal online hari ini. + @if($pendingReq) + Permohonan RM {{ number_format((float)($pendingReq['amaun'] ?? 0), 2) }} + daripada {{ $pendingReq['dimohon_oleh'] ?? '-' }} masih PENDING. + @else + Mohon had di + Had Modal Online. + @endif +
+ @elseif($pendingReq) +
+ Permohonan tambah RM {{ number_format((float)($pendingReq['amaun'] ?? 0), 2) }} + daripada {{ $pendingReq['dimohon_oleh'] ?? '-' }} menunggu kelulusan Operasi. + Semak +
+ @endif + +
+
+
+
+
Modal Online Hari Ini
+

+ @if(!empty($modal['missing'])) + Belum ada had + @else + Baki RM {{ number_format((float)($modal['baki'] ?? 0), 2) }} + @endif +

+ + @if(!empty($modal['missing'])) + Tunggu kelulusan Operasi + @else + Digunakan RM {{ number_format((float)($modal['digunakan'] ?? 0), 2) }} + / Had RM {{ number_format((float)($modal['had'] ?? 0) + (float)($modal['tambah'] ?? 0), 2) }} + @endif + +
+
+
+
+
+
+
Queue PC
+

{{ count($lines) }} rekod

+ Jumlah RM {{ number_format((float)($queue['jumlah'] ?? 0), 2) }} +
+
+
+
+
+
+
Slot Cadangan
+

{{ $slot['slot'] ?? '-' }}

+ {{ $slot['nota'] ?? '' }} +
+
+
+
+ +
+
+
Senarai Menunggu (PENDING / REJECTED)
+ +
+
+
+ @csrf + +
+ + + + + + + + + + + + + + + + + @forelse($lines as $line) + + + + + + + + + + + + + @empty + + + + @endforelse + +
StatusSAGPelangganNo KPBankNo AkaunPinjaman (RM)Sebab TolakTindakan
+ + + @if(($line['status'] ?? '') === 'REJECTED_PC') + REJECTED + @else + PENDING + @endif + {{ $line['norujukan'] ?? '-' }}{{ $line['nama_pelanggan'] ?? '-' }}{{ $line['nokp'] ?? '-' }}{{ $line['nama_bank'] ?? $line['kodbank'] ?? '-' }}{{ $line['noakaun'] ?? '-' }}{{ number_format((float)($line['pinjaman'] ?? 0), 2) }}{{ $line['reject_reason'] ?? '-' }} + +
Tiada rekod dalam queue.
+
+
+
+
+ +
+
+
Sejarah Batch
+
+
+
+ + + + + + + + + + + + + + + @forelse($batches as $batch) + + + + + + + + + + + @empty + + + + @endforelse + +
Batch NoTarikhSlotBilJumlah (RM)StatusDihantar Oleh
{{ $batch['batch_no'] ?? '-' }}{{ $batch['tarikh'] ?? '-' }}{{ $batch['slot'] ?? '-' }}{{ $batch['bilangan'] ?? 0 }}{{ number_format((float)($batch['jumlah_keseluruhan'] ?? 0), 2) }}{{ $batch['status'] ?? '-' }}{{ $batch['pc_submitted_by'] ?? '-' }} + + Lihat + +
Belum ada batch.
+
+
+
+
+
+
+ +{{-- Edit modal --}} + + + +@endsection diff --git a/resources/views/pembiayaan_online/pc/topup.blade.php b/resources/views/pembiayaan_online/pc/topup.blade.php new file mode 100644 index 0000000..18a5fec --- /dev/null +++ b/resources/views/pembiayaan_online/pc/topup.blade.php @@ -0,0 +1,215 @@ +@extends('layouts.app') +@section('content') +@php + $isClosed = (int)($modal['ditutup'] ?? 0) === 1; + $isMissing = !empty($isMissing) || !empty($modal['missing']); + $pendingRequest = $pendingRequest ?? ($modal['pending_request'] ?? null); +@endphp +
+
+
+ + + @if(session()->has('message')) +
{{ session('message') }}
+ @endif + @if(session()->has('error')) +
{{ session('error') }}
+ @endif + + @if($isClosed) +
+ Modal online hari ini sudah ditutup (EOD) + oleh {{ $modal['ditutup_oleh'] ?? '-' }} + pada {{ $modal['ditutup_at'] ?? '-' }}. + Esok PC perlu mohon had baru daripada Operasi. +
+ @elseif($isMissing) +
+ Belum ada had modal online hari ini. + Mohon amaun di bawah. Operasi akan luluskan permohonan. +
+ @endif + + @if($hasPending && $pendingRequest) +
+ Permohonan PENDING RM {{ number_format((float)($pendingRequest['amaun'] ?? 0), 2) }} + daripada {{ $pendingRequest['dimohon_oleh'] ?? '-' }}. + Menunggu kelulusan Operasi. +
+ @endif + +
+
+
+
+
Baki Hari Ini
+

+ @if($isMissing) + — + @else + RM {{ number_format((float)($modal['baki'] ?? 0), 2) }} + @endif +

+
+
+
+
+
+
+
Had Asas
+

+ @if($isMissing) + — + @else + RM {{ number_format((float)($modal['had'] ?? 0), 2) }} + @endif +

+
+
+
+
+
+
+
Tambah Diluluskan
+

RM {{ number_format((float)($modal['tambah'] ?? 0), 2) }}

+
+
+
+
+
+
+
Digunakan
+

RM {{ number_format((float)($modal['digunakan'] ?? 0), 2) }}

+
+
+
+
+ +
+
+
+
+
{{ $isMissing ? 'Mohon Had Modal Online' : 'Mohon Tambah Modal Online' }}
+
+
+ @if($isClosed) +
+ Tidak boleh mohon selepas EOD. +
+ @else + @if($hasPending) +
+ Masih ada permohonan PENDING. Tunggu kelulusan Operasi sebelum mohon lagi. +
+ @endif +
+ @csrf +
+ + +
+
+ + +
+ + Kembali +
+ @endif +
+
+ +
+
+
Tutup Modal Online (EOD)
+
+
+

+ Tutup hari ini: baki yang tidak digunakan akan dikembalikan, + dan tiada lagi gadai online / permohonan untuk hari ini. + Esok mohon had baru daripada Operasi. +

+ @if($isClosed) + + @elseif($isMissing) + + @else +
+ @csrf + +
+ @endif +
+
+
+ +
+
+
+
Permohonan PC
+
+ +
+
+
+ + + + + + + + + + + + + @forelse($requests as $req) + @php + $st = $req['status'] ?? ''; + $badge = 'badge-secondary'; + if ($st === 'PENDING') $badge = 'badge-warning'; + elseif ($st === 'APPROVED') $badge = 'badge-success'; + elseif ($st === 'REJECTED') $badge = 'badge-danger'; + @endphp + + + + + + + + + @empty + + + + @endforelse + +
TarikhAmaun (RM)StatusDimohon OlehDiluluskan OlehNota
{{ $req['tarikh'] ?? '-' }}{{ number_format((float)($req['amaun'] ?? 0), 2) }}{{ $st ?: '-' }}{{ $req['dimohon_oleh'] ?? '-' }}{{ $req['diluluskan_oleh'] ?? '-' }}{{ $req['nota'] ?? '-' }}
Belum ada permohonan.
+
+
+
+
+
+
+
+@endsection diff --git a/resources/views/print/resittebus_ujrah.blade.php b/resources/views/print/resittebus_ujrah.blade.php index fb8da19..309fa63 100644 --- a/resources/views/print/resittebus_ujrah.blade.php +++ b/resources/views/print/resittebus_ujrah.blade.php @@ -634,7 +634,7 @@ (-) Rebat Untung : RM - {{ number_format($keuntungan_rebate,2) }} + {{ number_format($totalrebate['onepercent'], 2) }} @@ -644,7 +644,7 @@ (-) Rebat Lain-Lain Caj : RM - {{ number_format($ujrah_rebate, 2) }} + {{ number_format($totalrebate['ujrah'], 2) }} Jumlah Keuntungan + Lain-Lain Caj @@ -867,7 +867,7 @@ (-) Rebat Untung : RM - {{ number_format($keuntungan_rebate, 2) }} + {{ number_format($totalrebate['onepercent'], 2) }} @@ -877,7 +877,7 @@ (-) Rebat Lain-Lain Caj : RM - {{ number_format($ujrah_rebate, 2) }} + {{ number_format($totalrebate['ujrah'], 2) }} Jumlah Keuntungan + Lain-Lain Caj diff --git a/routes/web.php b/routes/web.php index a570aee..e16df24 100644 --- a/routes/web.php +++ b/routes/web.php @@ -172,6 +172,33 @@ Route::post('/khazanah/pendahuluanserahanHQ',['as'=>'khazanah.pendahuluanserahan Route::get('/penebusankhazanah/{norujukan}',['as'=>'penebusan.khazanah','uses' => 'PenebusanController@PenebusanKhazanah'])->middleware('auth','khazanah'); Route::get('/lelongankhazanah/{norujukan}',['as'=>'lelongan.khazanah','uses' => 'KhazanahController@lelongan'])->middleware('auth','khazanah'); Route::get('/permohonan',['as'=>'permohonan.index','uses' => 'KhazanahController@PaparanPermohonan'])->middleware('auth','khazanah'); + +// Pembiayaan Online — PC +Route::get('/pembiayaan-online/pc',['as'=>'pembiayaan.online.pc','uses'=>'PembiayaanOnlineController@index'])->middleware('auth','khazanah'); +Route::put('/pembiayaan-online/pc/lines/{id}',['as'=>'pembiayaan.online.pc.update','uses'=>'PembiayaanOnlineController@updateLine'])->middleware('auth','khazanah'); +Route::post('/pembiayaan-online/pc/batches/submit',['as'=>'pembiayaan.online.pc.submit','uses'=>'PembiayaanOnlineController@submitBatch'])->middleware('auth','khazanah'); +Route::get('/pembiayaan-online/pc/batches/{batchId}',['as'=>'pembiayaan.online.pc.batch','uses'=>'PembiayaanOnlineController@showBatch'])->middleware('auth','khazanah'); +Route::get('/pembiayaan-online/pc/paid',['as'=>'pembiayaan.online.pc.paid','uses'=>'PembiayaanOnlineController@paidIndex'])->middleware('auth','khazanah'); +Route::get('/pembiayaan-online/pc/lines/{id}/bukti',['as'=>'pembiayaan.online.pc.bukti','uses'=>'PembiayaanOnlineController@viewBukti'])->middleware('auth','khazanah'); +Route::post('/pembiayaan-online/pc/paid/blast',['as'=>'pembiayaan.online.pc.blast','uses'=>'PembiayaanOnlineController@markBlast'])->middleware('auth','khazanah'); +Route::get('/pembiayaan-online/pc/topup',['as'=>'pembiayaan.online.pc.topup','uses'=>'PembiayaanOnlineController@topupIndex'])->middleware('auth','khazanah'); +Route::post('/pembiayaan-online/pc/topup',['as'=>'pembiayaan.online.pc.topup.request','uses'=>'PembiayaanOnlineController@topupRequest'])->middleware('auth','khazanah'); +Route::post('/pembiayaan-online/pc/topup/close',['as'=>'pembiayaan.online.pc.topup.close','uses'=>'PembiayaanOnlineController@closeModal'])->middleware('auth','khazanah'); + +// Pembiayaan Online — Operasi +Route::get('/pembiayaan-online/operasi',['as'=>'pembiayaan.online.operasi','uses'=>'PembiayaanOnlineController@operasiIndex'])->middleware('auth','operasi'); +Route::get('/pembiayaan-online/operasi/topup',['as'=>'pembiayaan.online.operasi.topup','uses'=>'PembiayaanOnlineController@operasiTopupIndex'])->middleware('auth','operasi'); +Route::post('/pembiayaan-online/operasi/topup/{id}/approve',['as'=>'pembiayaan.online.operasi.topup.approve','uses'=>'PembiayaanOnlineController@operasiTopupApprove'])->middleware('auth','operasi'); +Route::post('/pembiayaan-online/operasi/topup/{id}/reject',['as'=>'pembiayaan.online.operasi.topup.reject','uses'=>'PembiayaanOnlineController@operasiTopupReject'])->middleware('auth','operasi'); +Route::get('/pembiayaan-online/operasi/eod',['as'=>'pembiayaan.online.operasi.eod','uses'=>'PembiayaanOnlineController@operasiEodIndex'])->middleware('auth','operasi'); +Route::post('/pembiayaan-online/operasi/eod/close-all',['as'=>'pembiayaan.online.operasi.eod.closeall','uses'=>'PembiayaanOnlineController@operasiCloseAllModal'])->middleware('auth','operasi'); +Route::post('/pembiayaan-online/operasi/eod/{kodcaw}/close',['as'=>'pembiayaan.online.operasi.eod.close','uses'=>'PembiayaanOnlineController@operasiCloseModal'])->middleware('auth','operasi'); +Route::get('/pembiayaan-online/operasi/{kodcaw}/batches/{batchId}',['as'=>'pembiayaan.online.operasi.batch','uses'=>'PembiayaanOnlineController@operasiShowBatch'])->middleware('auth','operasi'); +Route::post('/pembiayaan-online/operasi/{kodcaw}/lines/{id}/approve',['as'=>'pembiayaan.online.operasi.approve','uses'=>'PembiayaanOnlineController@operasiApproveLine'])->middleware('auth','operasi'); +Route::post('/pembiayaan-online/operasi/{kodcaw}/lines/{id}/reject',['as'=>'pembiayaan.online.operasi.reject','uses'=>'PembiayaanOnlineController@operasiRejectLine'])->middleware('auth','operasi'); +Route::post('/pembiayaan-online/operasi/{kodcaw}/batches/{batchId}/approve',['as'=>'pembiayaan.online.operasi.approve.batch','uses'=>'PembiayaanOnlineController@operasiApproveBatch'])->middleware('auth','operasi'); +Route::post('/pembiayaan-online/operasi/{kodcaw}/lines/{id}/paid',['as'=>'pembiayaan.online.operasi.paid','uses'=>'PembiayaanOnlineController@operasiMarkPaid'])->middleware('auth','operasi'); +Route::post('/pembiayaan-online/operasi/{kodcaw}/batches/{batchId}/paid',['as'=>'pembiayaan.online.operasi.paid.batch','uses'=>'PembiayaanOnlineController@operasiMarkPaidBatch'])->middleware('auth','operasi'); Route::get('/permohonan/rekod',['as'=>'permohonan.rekod','uses' => 'KhazanahController@RekodPermohonan'])->middleware('auth','khazanah'); Route::post('/permohonan/simpan',['as'=>'permohonan.simpan','uses' => 'KhazanahController@SimpanPermohonan'])->middleware('auth','khazanah'); Route::get('/permohonan/status/{mohonid}',['as'=>'permohonan.status','uses' => 'KhazanahController@StatusPermohonan'])->middleware('auth','khazanah'); @@ -356,6 +383,8 @@ Route::post('/barcodescanned',['as'=>'barcode.scanned','uses'=>'KhazanahControll Route::get('/operasi/kelulusan','OperasiController@kelulusan')->name('operasi.kelulusan')->middleware('auth','operasi'); Route::get('/operasi/kelulusan/anggota','OperasiController@kelulusanAnggota')->name('operasi.kelulusananggota')->middleware('auth','operasi'); Route::post('/operasi/createkelulusan',['as'=>'operasi.createkelulusan','uses'=>'OperasiController@createkelulusan'])->middleware('auth','teller'); +Route::post('/operasi/createkelulusan-by-khazanah',['as'=>'operasi.createkelulusan-by-khazanah','uses'=>'OperasiController@createkelulusanByKhazanah'])->middleware('auth','khazanah'); +Route::post('/operasi/createkelulusan-anggota',['as'=>'operasi.createkelulusan-anggota','uses'=>'OperasiController@createkelulusanAnggota'])->middleware('auth','teller'); Route::get('/operasi/getkelulusan',['as'=>'operasi.getkelulusan','uses'=>'OperasiController@getkelulusan'])->middleware('auth','teller'); Route::put('/operasi/updatekelulusan',['as'=>'operasi.updatekelulusan','uses'=>'OperasiController@updatekelulusan'])->middleware('auth','operasi'); Route::put('/operasi/updatekelulusananggota',['as'=>'operasi.updatekelulusananggota','uses'=>'OperasiController@updatekelulusananggota'])->middleware('auth','operasi');