diff --git a/app/Http/Controllers/Reports/AnalisaController.php b/app/Http/Controllers/Reports/AnalisaController.php index df7401b..c538f83 100644 --- a/app/Http/Controllers/Reports/AnalisaController.php +++ b/app/Http/Controllers/Reports/AnalisaController.php @@ -11,6 +11,11 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use App\Services\Reports\GadaianService as ReportGadaianService; use App\Helper; +use Carbon\Carbon; +use App\Pekerjaan; +use App\Poskod; +use App\TransactionOnline; +use Log; use App\Services\Reports\RingkasanHarianService as ReportRingkasanHarianService; @@ -162,6 +167,197 @@ public function getSummaryLaporanPelangganAktif(Request $request) return response()->json($response); } + public function getActiveCawanganConnections() + { + $cawangan_details = Cawangan::select(['details_caw', 'mysql'])->get(); + + $cawangan_details = $cawangan_details->filter(fn($x) => !in_array(strtolower($x->details_caw), config('report.excluded_cawangan'))); + + $connection_active_cawangan = Helper::getActiveCawanganDbConnection(); + + return collect($cawangan_details->filter(fn($x) => in_array($x->mysql, $connection_active_cawangan))); + + } + + public function getSummaryLaporanDataPelanggan(Request $request) + { + $year = $request->year; + if (!$year) { + return response()->json(['error' => 'Sila pilih tahun'], 400); + } + + Carbon::setLocale('ms'); + + // 1️⃣ Ambil semua pelanggan tahun ini + $pelanggan = Customer::whereYear('tarikhdaftar', $year) + ->select('id','nama','kpbaru','kplama','t_lahir','jantina', + 'kodkerja','poskod','kodcaw','tarikhdaftar','tujuangadai') + ->get(); + + $connections = $this->getActiveCawanganConnections(); + + // Ambil semua pekerjaan & poskod sekali untuk map cepat + $pekerjaanAll = Pekerjaan::pluck('keterangan','kodkerja'); + $poskodAll = Poskod::with('daerah')->get()->keyBy('poskod'); + + // 2️⃣ Ambil semua nokp pelanggan + $nokps = $pelanggan->map(fn($p) => $p->kpbaru ?? $p->kplama)->filter()->values(); + + // 3️⃣ Ambil semua transaksi gadai + tebus untuk nokp tu dari semua cawangan + $allTransaksi = collect(); + foreach ($connections as $conn) { + $data = DB::connection($conn->mysql) + ->table('gadai as g') + ->leftJoin('tebus as t', 'g.norujukan', '=', 't.norujukan') + ->leftJoin('lelong as l', 'g.norujukan', '=', 'l.norujukan') + ->whereIn('g.nokp', $nokps) + ->select('g.nokp','g.norujukan','g.t_gadai','t.t_tebus','g.pinjaman','g.upah12','g.tempoh','l.t_lelong') + ->get(); + $allTransaksi = $allTransaksi->concat($data); + } + + // 4️⃣ Group by nokp + $transGrouped = $allTransaksi->groupBy('nokp'); + + // 5️⃣ Ambil semua norujukan transaksi online + $onlineNorujukan = TransactionOnline::pluck('norujukan')->unique()->values(); + + + // 6️⃣ Map pelanggan + $result = $pelanggan->map(function($row) use ($transGrouped, $onlineNorujukan, $pekerjaanAll, $poskodAll, $year) { + + $nokp = $row->kpbaru ?? $row->kplama ?? null; + + $tempohData = $transGrouped->get($nokp, collect()); + + // Norujukan pelanggan spesifik + $norujukanPelanggan = $tempohData->pluck('norujukan')->unique()->values(); + + // Cara Bayaran + // $caraBayaran = $norujukanPelanggan->intersect($onlineNorujukan)->isNotEmpty() ? 'Online' : 'Kaunter'; + $adaOnline = $norujukanPelanggan->contains(fn($nr) => isset($onlineNorujukan[$nr])); + $caraBayaran = $adaOnline ? 'Online' : 'Kaunter'; + if ($adaOnline) { + \Log::info("Pelanggan {$row->nama} ({$nokp}): Bayaran Online - YA"); + } + + + + // Bilangan transaksi + $bilTransaksi = $tempohData->count(); + + // Bilangan tebus + $bilTebus = $tempohData->whereNotNull('t_tebus')->count(); + + // Jumlah pinjaman + $jumlahPinjaman = $tempohData->sum('pinjaman'); + + // Jumlah ujrah ikut tempoh surat + $jumlahUjrah = $tempohData->reduce(function ($carry, $trx) { + if (!$trx->upah12 || !$trx->tempoh) return $carry; + return $carry + ($trx->upah12 / 12 * $trx->tempoh); + }, 0); + + // Tarikh mula & tamat + $tarikhMula = $tempohData->min('t_gadai'); + $tarikhTamat = $tempohData->max('t_tebus'); + $tarikhLelong = $tempohData->max('t_lelong'); + + // Tempoh Pajakan + if (!$tarikhMula) { + $tempohPajakan = '-'; + } elseif (!$tarikhTamat || $tarikhMula == $tarikhTamat) { + $tempohPajakan = Carbon::parse($tarikhMula)->translatedFormat('M Y'); + } else { + $tempohPajakan = Carbon::parse($tarikhMula)->translatedFormat('M Y') . + ' - ' . + Carbon::parse($tarikhTamat)->translatedFormat('M Y'); + } + + // Hari sejak transaksi terakhir + $hariTempohPajakan = $tarikhMula + ? Carbon::parse($tarikhMula)->diffInDays($tarikhTamat ? Carbon::parse($tarikhTamat) : Carbon::now()) + : null; + + // Tujuan gadai + $tujuangadai = $row->tujuangadai ?: '-'; + + // Status aktif: ada transaksi dalam tahun tu + $statusAktif = $tempohData->contains(function ($trx) use ($year) { + if (!$trx->t_gadai) return false; + $tGadai = Carbon::parse($trx->t_gadai); + $tTebus = $trx->t_tebus ? Carbon::parse($trx->t_tebus) : null; + + return $tGadai->lte(Carbon::create($year,12,31)->endOfDay()) + && (is_null($tTebus) || $tTebus->gt(Carbon::create($year,12,31)->endOfDay())); + }); + + // Umur + $umur = $row->t_lahir ? Carbon::parse($row->t_lahir)->age : null; + + // Pekerjaan + $pekerjaan = $row->kodkerja + ? ($pekerjaanAll[ltrim($row->kodkerja,'0')] ?? 'Lain-lain') + : '-'; + + // Daerah / lokasi + $lokasi = $row->poskod && isset($poskodAll[$row->poskod]) + ? $poskodAll[$row->poskod]->daerah->namadaerah ?? 'Lain-lain' + : 'Lain-lain'; + + return [ + 'cawangan' => $row->kodcaw ?? '-', + 'nama' => $row->nama, + 'nokp' => $nokp ?? '-', + 'tarikhdaftar' => Carbon::parse($row->tarikhdaftar)->format('d-m-Y'), + 'umur' => $umur, + 'jantina' => $row->jantina ?? '-', + 'pekerjaan' => $pekerjaan, + 'daerah' => $lokasi, + 'tempoh_pajakan' => $tempohPajakan, + 'tarikh_mula' => $tarikhMula ? Carbon::parse($tarikhMula)->format('d-m-Y') : null, + 'tarikh_tamat' => $tarikhTamat ? Carbon::parse($tarikhTamat)->format('d-m-Y') : null, + 'hari_sejak_transaksi' => $hariTempohPajakan, + 'bil_transaksi' => $bilTransaksi, + 'bil_tebus' => $bilTebus, + 'jumlah_pinjaman' => $jumlahPinjaman, + 'norujukan' => $norujukanPelanggan, + 'jumlah_ujrah' => $jumlahUjrah, + 'tujuan_gadai' => $tujuangadai, + 'status_aktif' => $statusAktif ? 'AKTIF' : 'TIDAK AKTIF', + 'cara_bayaran' => $caraBayaran, + 'tarikh_lelong' => $tarikhLelong ? Carbon::parse($tarikhLelong)->format('d-m-Y') : null, + ]; + }); + + return response()->json([ + 'year' => $year, + 'summary' => [ + 'total_pelanggan' => $result->count(), + 'jumlah_cawangan' => $result->pluck('cawangan')->unique()->count(), + ], + 'pelanggan' => $result->values(), + ], 200); + } + + private function formatTempohPajakan($start, $end) + { + if (!$start || !$end) { + return '-'; + } + + $mula = Carbon::parse($start); + $tamat = Carbon::parse($end); + + if ($mula->year === $tamat->year) { + return $mula->translatedFormat('M') . ' – ' . + $tamat->translatedFormat('M Y'); + } + + return $mula->translatedFormat('M Y') . ' – ' . + $tamat->translatedFormat('M Y'); + } + diff --git a/routes/report.php b/routes/report.php index ce9aab6..2ed721d 100644 --- a/routes/report.php +++ b/routes/report.php @@ -57,5 +57,7 @@ $router->group(['prefix' => 'api/reports'], function () use ($router) { $router->get('gadaitebusmasa/{kod_cawangan}', ['uses' => 'GadaianController@getLaporanGadaiTebusMasaCawangan']); $router->get('saringan/gadaian', ['uses' => 'SaringanGadaianController@getLaporanGadai']); + + $router->get('data-pelanggan', ['uses' => 'AnalisaController@getSummaryLaporanDataPelanggan']); }); });