381 lines
14 KiB
PHP
381 lines
14 KiB
PHP
<?php
|
||
|
||
namespace App\Http\Controllers\Reports;
|
||
|
||
use App\Http\Controllers\Controller;
|
||
use App\Cawangan;
|
||
use App\Gadai;
|
||
use App\Customer;
|
||
use App\Tebus;
|
||
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;
|
||
|
||
|
||
class AnalisaController extends Controller
|
||
{
|
||
public function getLaporanCawangan(string $kod_cawangan, Request $request)
|
||
{
|
||
$reportGadaianService = new ReportGadaianService($kod_cawangan, $request);
|
||
return $reportGadaianService->getCawanganReport();
|
||
}
|
||
|
||
public function getSummaryLaporanPelangganBaru(Request $request)
|
||
{
|
||
$startDate = $request->startDate;
|
||
$endDate = $request->endDate;
|
||
|
||
// Get active branch DBs from helper
|
||
$active_cawangan_db_connection = Helper::getActiveCawanganDbConnection();
|
||
|
||
// Fetch branch details with mysql info
|
||
$cawangan_available = Cawangan::select('kodcaw', 'details_caw', 'mysql')
|
||
->whereIn('mysql', $active_cawangan_db_connection)
|
||
->get();
|
||
|
||
$active_cawangan_db_connection = array_column($cawangan_available->toArray(), 'mysql');
|
||
|
||
$active_cawangan_detail = $cawangan_available->map(function ($c) {
|
||
return [
|
||
'kodcaw' => $c->kodcaw,
|
||
'details_caw' => $c->details_caw,
|
||
];
|
||
})->values()->toArray();
|
||
|
||
// Iterate through each branch and get data
|
||
$response = array_map(function ($db_connection, $cawangan_detail) use ($request) {
|
||
// Pass the required parameters to the service constructor
|
||
$reportRingkasanHarianService = new ReportRingkasanHarianService($cawangan_detail['kodcaw'], $request);
|
||
|
||
// Get the customer count from the service
|
||
$bilangan_customer_baru = $reportRingkasanHarianService->getCustomerSummary(); // Call public method
|
||
|
||
// Return the response
|
||
return [
|
||
'kodcaw' => $cawangan_detail['kodcaw'],
|
||
'details_caw' => $cawangan_detail['details_caw'],
|
||
'total_pelanggan_baru' => $bilangan_customer_baru,
|
||
];
|
||
}, $active_cawangan_db_connection, $active_cawangan_detail);
|
||
|
||
return response()->json($response);
|
||
}
|
||
|
||
// public function getSummaryLaporanPelangganAktif(Request $request)
|
||
// {
|
||
// $startDate = $request->startDate;
|
||
// $endDate = $request->endDate;
|
||
|
||
// // Dapatkan senarai cawangan aktif
|
||
// $active_cawangan_db_connection = Helper::getActiveCawanganDbConnection();
|
||
|
||
// // Dapatkan maklumat cawangan
|
||
// $cawangan_available = Cawangan::select('kodcaw', 'details_caw', 'mysql')
|
||
// ->whereIn('mysql', $active_cawangan_db_connection)
|
||
// ->get();
|
||
|
||
// $active_cawangan_detail = $cawangan_available->map(function ($c) {
|
||
// return [
|
||
// 'kodcaw' => $c->kodcaw,
|
||
// 'details_caw' => $c->details_caw,
|
||
// 'mysql' => $c->mysql,
|
||
// ];
|
||
// })->toArray();
|
||
|
||
// $response = array_map(function ($cawangan) use ($startDate, $endDate) {
|
||
// $db_connection = $cawangan['mysql'];
|
||
|
||
// $total_aktif = Gadai::on($db_connection)
|
||
// ->where(function ($query) use ($startDate) {
|
||
// $query->where('sttebus', '')
|
||
// ->where('t_update', '>=', $startDate);
|
||
// })
|
||
// ->where('t_gadai', '<=', $endDate)
|
||
// ->distinct('nokp')
|
||
// ->count('nokp');
|
||
|
||
// return [
|
||
// 'kodcaw' => $cawangan['kodcaw'],
|
||
// 'details_caw' => $cawangan['details_caw'],
|
||
// 'total_pelanggan_aktif' => $total_aktif,
|
||
// ];
|
||
// }, $active_cawangan_detail);
|
||
|
||
|
||
// return response()->json($response);
|
||
// }
|
||
|
||
|
||
public function getSummaryLaporanPelangganAktif(Request $request)
|
||
{
|
||
$startDate = $request->startDate;
|
||
$endDate = $request->endDate;
|
||
|
||
$active_cawangan = Cawangan::select('kodcaw', 'details_caw', 'mysql')
|
||
->whereIn('mysql', Helper::getActiveCawanganDbConnection())
|
||
->get();
|
||
|
||
$response = $active_cawangan->map(function ($cawangan) use ($startDate, $endDate) {
|
||
$db = $cawangan->mysql;
|
||
|
||
// Ambil nokp dari Gadai
|
||
$nokp_gadai = DB::connection($db)->table('gadai')
|
||
->whereBetween('t_gadai', [$startDate, $endDate])
|
||
->pluck('nokp')
|
||
->toArray();
|
||
|
||
// Ambil nokp dari Tebus
|
||
$nokp_tebus = DB::connection($db)->table('tebus as t')
|
||
->join('gadai as g', 't.norujukan', '=', 'g.norujukan')
|
||
->whereBetween('t.t_tebus', [$startDate, $endDate])
|
||
->pluck('g.nokp')
|
||
->toArray();
|
||
|
||
// Gabung semua nokp
|
||
$semua_nokp = collect(array_merge($nokp_gadai, $nokp_tebus))
|
||
->filter(fn($item) => !empty($item))
|
||
->unique()
|
||
->values();
|
||
|
||
if ($semua_nokp->isEmpty()) {
|
||
// Jika array kosong, kita kembalikan hasil kosong
|
||
$pelanggan_aktif = collect();
|
||
} else {
|
||
$pelanggan_aktif = Customer::on($db)
|
||
->where(function ($query) use ($semua_nokp) {
|
||
$query->whereIn('kpbaru', $semua_nokp)
|
||
->orWhereIn('kplama', $semua_nokp);
|
||
})
|
||
->get(['nama', 'kpbaru', 'kplama'])
|
||
->toArray();;
|
||
}
|
||
|
||
return [
|
||
'kodcaw' => $cawangan->kodcaw,
|
||
'details_caw' => $cawangan->details_caw,
|
||
'total_pelanggan_aktif' => count($semua_nokp),
|
||
];
|
||
});
|
||
|
||
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
|
||
$now = Carbon::now();
|
||
|
||
$endOfYear = Carbon::create($year, 12, 31)->endOfDay();
|
||
$startOfYear = Carbon::create($year, 1, 1)->startOfDay();
|
||
|
||
$statusAktif = $tempohData->contains(function ($trx) use ($startOfYear, $endOfYear) {
|
||
|
||
if (!$trx->t_gadai) return false;
|
||
|
||
$tGadai = Carbon::parse($trx->t_gadai);
|
||
$tTebus = $trx->t_tebus ? Carbon::parse($trx->t_tebus) : null;
|
||
|
||
// SAG wujud dalam tahun laporan
|
||
return
|
||
$tGadai->lte($endOfYear) &&
|
||
(
|
||
is_null($tTebus) || // belum ditebus
|
||
$tTebus->gte($startOfYear) // ditebus dalam / selepas tahun
|
||
);
|
||
});
|
||
|
||
// 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');
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
}
|