From 1f27d90698c2acdb7a2d3b47671cee5a0f225a10 Mon Sep 17 00:00:00 2001 From: aiman Date: Sun, 14 Sep 2025 16:03:49 +0800 Subject: [PATCH 01/80] Tukar step pampasan v3 ke v2: --- app/Http/Controllers/BarangkesController.php | 88 +++++++++++++++----- config/app_parameter.php | 4 +- 2 files changed, 69 insertions(+), 23 deletions(-) diff --git a/app/Http/Controllers/BarangkesController.php b/app/Http/Controllers/BarangkesController.php index dd4f10c..8e37309 100644 --- a/app/Http/Controllers/BarangkesController.php +++ b/app/Http/Controllers/BarangkesController.php @@ -10,34 +10,78 @@ use Illuminate\Http\Request; use Carbon\Carbon; use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Http; class BarangkesController extends Controller { public function LaporanBarangKes(Request $request) { + $status = $request->status; - $cawangan = Cawangan::on('mysql7')->where('kodcaw', $request->kodcaw)->first(); + $cawangan = Cawangan::on('mysql7')->where('kodcaw', $request->kodcaw)->first(); - if (!$cawangan) { - return response()->json(['error' => 'Invalid kodcaw'], 403); + if (!$cawangan) { + return response()->json(['error' => 'Invalid kodcaw'], 403); + } + + $query = DB::connection($cawangan['mysql'])->table('palsu') + ->select([ + 'tarikh', + 'norujukan', + 'nota', + 'pembiayaan', + 'nilaimarhun', + 'jbg', + 'untung', + 'untungonepercent', + 'untungcajlain' + ]); + + // Only apply whereBetween if tarikh_mula and tarikh_akhir are provided + if ($request->filled('tarikh_mula') && $request->filled('tarikh_akhir')) { + $query->whereBetween('tarikh', [$request->tarikh_mula, $request->tarikh_akhir]); + } + + $result = $query->get(); + + $pampasan = Http::get(config('app_parameter.api_v3') . "pampasan", ['kodcaw' => $request->kodcaw]) + ->json()['data']; + + $palsu_array = $result->toArray(); + + // dd($pampasan, $palsu_array); + + $indexedArray2 = collect($pampasan)->keyBy('norujukan'); + + $merged = collect($palsu_array)->map(function ($item) use ($indexedArray2) { + $id = $item->norujukan; + $itemArray = (array) $item; // Convert object to array + $additional = $indexedArray2->get($id, []); + return array_merge($itemArray, $additional); + })->values()->toArray(); + + // dd($merged, $status); + + $filteredResults = []; + + if ($status == 'dituntut') { + foreach ($merged as $pampasan) { + if (isset($pampasan['status']) && $pampasan['status'] == 1) { + $filteredResults[] = $pampasan; + } + } + } + if ($status == 'belum-tuntut') { + foreach ($merged as $pampasan) { + if (!isset($pampasan['status']) ) { + $filteredResults[] = $pampasan; + } + } + } + if ($status == 'all') { + $filteredResults = $merged; + } + + return response()->json($filteredResults); } - - $query = DB::connection($cawangan['mysql'])->table('palsu') - ->select([ - 'tarikh', - 'norujukan', - 'nota', - 'pembiayaan', - 'nilaimarhun', - 'jbg', - 'untung', - 'untungonepercent', - 'untungcajlain' - ]) - ->whereBetween('tarikh', [$request->tarikh_mula, $request->tarikh_akhir]); - - $result = $query->get(); - - return response()->json($result); } -} \ No newline at end of file diff --git a/config/app_parameter.php b/config/app_parameter.php index a6cf4d8..c46f175 100644 --- a/config/app_parameter.php +++ b/config/app_parameter.php @@ -2,5 +2,7 @@ return [ 'url' => env('APP_URL', url('/')), - 'api_arrahnbid' => env('API_ARRAHNBID', 'http://lelong.test/api/') + 'api_arrahnbid' => env('API_ARRAHNBID', 'http://lelong.test/api/'), + 'api_v3' => env('API_V3', 'http://apiv3.localhost/api/') ]; + From 977fab853dfa162925196d5820ef9e33f5b69594 Mon Sep 17 00:00:00 2001 From: aiman Date: Sun, 14 Sep 2025 15:54:31 +0800 Subject: [PATCH 02/80] Tukar step pampasan v3 ke v2: --- app/.DS_Store | Bin 12292 -> 12292 bytes app/Http/Controllers/PampasanController.php | 94 ++++++++++++++++++ app/Pampasan.php | 33 ++++++ ...tung_pembiayaan_columns_to_palsu_table.php | 32 +++--- ...025_08_28_150140_create_pampasan_table.php | 57 +++++++++++ routes/web.php | 5 + 6 files changed, 205 insertions(+), 16 deletions(-) create mode 100644 app/Http/Controllers/PampasanController.php create mode 100644 app/Pampasan.php create mode 100644 database/migrations/2025_08_28_150140_create_pampasan_table.php diff --git a/app/.DS_Store b/app/.DS_Store index aba4526fd74a7b7bfd2123fff717d1802f630e69..c05d45cf3ec83c70d240a152fa214bbb44a0caa7 100644 GIT binary patch delta 37 tcmZokXi1ph&zQ6^U^hRb?PeZ<-|UljONwkxlvu?+S%J}QGq=J|egFj24IKag delta 56 zcmZokXi1ph&zQV1U^hRb-DVzv-|URSlMhIUaw;$+GvqTAFjP+7ASlJeY&Tg?Qhu|v M#47g9+zLPW0q~{}h5!Hn diff --git a/app/Http/Controllers/PampasanController.php b/app/Http/Controllers/PampasanController.php new file mode 100644 index 0000000..6592327 --- /dev/null +++ b/app/Http/Controllers/PampasanController.php @@ -0,0 +1,94 @@ +validate($request, [ + 'norujukan' => 'required|string', + 'baucerno' => 'required|string', + 'kodcaw' => 'required|string', + 'jumlah_pampasan' => 'required|numeric', + 'denominasi' => 'nullable|array', + 'teller' => 'required|string', + ]); + + try { + $cawangan = Cawangan::on('mysql7')->where('kodcaw', $request->kodcaw)->first(); + + if (!$cawangan) { + return response()->json([ + 'success' => false, + 'message' => 'Cawangan tidak dijumpai untuk kodcaw: ' . $request->kodcaw, + ], 404); + } + + $pampasan = Pampasan::on($cawangan['mysql'])->create([ + 'norujukan' => $validated['norujukan'], + 'baucerno' => $validated['baucerno'], + 'kodcaw' => $validated['kodcaw'], + 'jumlah_pampasan' => $validated['jumlah_pampasan'], + 'denominasi' => isset($validated['denominasi']) ? json_encode($validated['denominasi']) : null, + 'teller' => $validated['teller'], + ]); + + return response()->json([ + 'success' => true, + 'message' => 'Pampasan berjaya dibayar.', + 'data' => $pampasan, + ], 201); + } catch (\Exception $e) { + return response()->json([ + 'success' => false, + 'message' => 'Database error: ' . $e->getMessage(), + ], 500); + } + } + + public function updateStatusPampasan(Request $request) + { + $norujukan = $request->norujukan; + $kodcaw = $request->kodcaw; + + $cawangan = Cawangan::on('mysql7')->where('kodcaw', $request->kodcaw)->first(); + + $pampasan = Pampasan::on($cawangan['mysql'])->where("norujukan", $norujukan)->first(); + + $pampasan->status = 1; + + $pampasan->save(); + + // dd($pampasan); + + return response()->json([ + 'success' => true, + 'message' => 'Status Pampasan berjaya dituntut.', + 'data' => $pampasan, + ], 201); + } + + public function getPampasan() + { + $pampasan = Pampasan::on('mysql71')->get(); + + return response()->json([ + 'success' => true, + 'message' => 'Status Pampasan berjaya dituntut.', + 'data' => $pampasan, + ], 201); + } + + public function getPampasanByNoRujukan() + { + + } +} diff --git a/app/Pampasan.php b/app/Pampasan.php new file mode 100644 index 0000000..5aed11d --- /dev/null +++ b/app/Pampasan.php @@ -0,0 +1,33 @@ +hasColumn('palsu', 'norujukan')) { // Add index to norujukan column for better performance - $table->index('norujukan'); + // $table->index('norujukan'); // Add foreign key constraint named 'norujukan' - $table->foreign('norujukan', 'norujukan')->references('norujukan')->on('gadai'); + // $table->foreign('norujukan', 'norujukan')->references('norujukan')->on('gadai'); } }); @@ -87,21 +87,21 @@ class AddNmJbgUntungPembiayaanColumnsToPalsuTable extends Migration Schema::connection($dbase)->table('palsu', function (Blueprint $table) use ($dbase) { // Drop foreign key constraint and index from norujukan column - if (Schema::connection($dbase)->hasColumn('palsu', 'norujukan')) { - try { - $table->dropForeign('norujukan'); - echo "Dropped foreign key 'norujukan' on connection '{$dbase}'\n"; - } catch (\Exception $e) { - echo "Warning: Could not drop foreign key 'norujukan' on connection '{$dbase}': " . $e->getMessage() . "\n"; - } + // if (Schema::connection($dbase)->hasColumn('palsu', 'norujukan')) { + // try { + // $table->dropForeign('norujukan'); + // echo "Dropped foreign key 'norujukan' on connection '{$dbase}'\n"; + // } catch (\Exception $e) { + // echo "Warning: Could not drop foreign key 'norujukan' on connection '{$dbase}': " . $e->getMessage() . "\n"; + // } - try { - $table->dropIndex(['norujukan']); - echo "Dropped index on 'norujukan' column on connection '{$dbase}'\n"; - } catch (\Exception $e) { - echo "Warning: Could not drop index on 'norujukan' on connection '{$dbase}': " . $e->getMessage() . "\n"; - } - } + // try { + // $table->dropIndex(['norujukan']); + // echo "Dropped index on 'norujukan' column on connection '{$dbase}'\n"; + // } catch (\Exception $e) { + // echo "Warning: Could not drop index on 'norujukan' on connection '{$dbase}': " . $e->getMessage() . "\n"; + // } + // } // Drop other columns if they exist $columnsToCheck = ['nilaimarhun', 'jbg', 'untung','untungonepercent','untungcajlain', 'pembiayaan']; diff --git a/database/migrations/2025_08_28_150140_create_pampasan_table.php b/database/migrations/2025_08_28_150140_create_pampasan_table.php new file mode 100644 index 0000000..3c867a7 --- /dev/null +++ b/database/migrations/2025_08_28_150140_create_pampasan_table.php @@ -0,0 +1,57 @@ +select('SELECT 1'); + return true; + } catch (\Exception $e) { + return false; + } + }); + return $db_connection ? array_values($db_connection) : []; + } + + public function up() + { + foreach ($this->getActiveDB() as $dbase) { + if (!Schema::connection($dbase)->hasTable('pampasan')) { + Schema::connection($dbase)->create('pampasan', function (Blueprint $table) { + $table->bigIncrements('id'); + $table->string('norujukan', 50)->unique()->index(); + $table->string('baucerno', 30)->index(); + $table->string('kodcaw', 20)->index(); + $table->decimal('jumlah_pampasan', 11, 2); + + if (Schema::getConnection()->getPdo()->getAttribute(PDO::ATTR_SERVER_VERSION) >= '5.7') { + $table->json('denominasi')->nullable(); + } else { + $table->longText('denominasi')->nullable(); + } + $table->string('teller', 100); + $table->tinyInteger('status') + ->default(0) + ->comment('0 = belum dituntut, 1 = dituntut'); + $table->timestamps(); + }); + } + } + } + + public function down() + { + foreach ($this->getActiveDB() as $dbase) { + Schema::connection($dbase)->dropIfExists('pampasan'); + } + } +} diff --git a/routes/web.php b/routes/web.php index 9f025c3..fcb9b81 100644 --- a/routes/web.php +++ b/routes/web.php @@ -379,6 +379,11 @@ $router->group(['prefix'=>'api'], function () use ($router){ $router->post('CreatePanjar/{kodcaw}',['uses'=>'PanjarController@create']); $router->post('DeletePanjar/{kodcaw}',['uses'=>'PanjarController@delete']); + //API PAMPASAN GUNA PANJAR + $router->post('pampasan/terimaPampasan',['uses'=>'PampasanController@terimaPampasan']); + $router->put('pampasan/updateStatusPampasan', ['uses' => 'PampasanController@updateStatusPampasan']); + $router->get('pampasan', ['uses' => 'PampasanController@getPampasan']); + //API KELULUSAN $router->get('SenaraiKelulusan/{kodcaw}',['uses'=>'KelulusanController@list']); From 59aeeb57f922ddca653fbc0565351b67d1213d79 Mon Sep 17 00:00:00 2001 From: Afiq Hamzah Date: Wed, 17 Sep 2025 12:38:51 +0800 Subject: [PATCH 03/80] Continue dev on pampasan module --- app/Http/Controllers/BarangkesController.php | 45 +++--- app/Http/Controllers/PampasanController.php | 6 + app/Palsu.php | 8 ++ ...092001_add_jenis_column_to_palsu_table.php | 68 +++++++++ ...jenis_to_pampasan_for_semporna_records.php | 78 +++++++++++ ...on_semporna_records_jenis_to_hapuskira.php | 130 ++++++++++++++++++ ...93118_add_status_column_to_palsu_table.php | 73 ++++++++++ ..._093624_update_all_palsu_status_to_one.php | 80 +++++++++++ ...update_semporna_records_status_to_zero.php | 78 +++++++++++ 9 files changed, 545 insertions(+), 21 deletions(-) create mode 100644 database/migrations/2025_09_17_092001_add_jenis_column_to_palsu_table.php create mode 100644 database/migrations/2025_09_17_093116_update_jenis_to_pampasan_for_semporna_records.php create mode 100644 database/migrations/2025_09_17_093117_update_non_semporna_records_jenis_to_hapuskira.php create mode 100644 database/migrations/2025_09_17_093118_add_status_column_to_palsu_table.php create mode 100644 database/migrations/2025_09_17_093624_update_all_palsu_status_to_one.php create mode 100644 database/migrations/2025_09_17_093756_update_semporna_records_status_to_zero.php diff --git a/app/Http/Controllers/BarangkesController.php b/app/Http/Controllers/BarangkesController.php index 8e37309..06ef56e 100644 --- a/app/Http/Controllers/BarangkesController.php +++ b/app/Http/Controllers/BarangkesController.php @@ -6,6 +6,8 @@ use App\Audit; use App\Polis; use App\Cawangan; use App\LookupAlasan; +use App\Pampasan; +use App\Palsu; use Illuminate\Http\Request; use Carbon\Carbon; @@ -24,7 +26,7 @@ class BarangkesController extends Controller return response()->json(['error' => 'Invalid kodcaw'], 403); } - $query = DB::connection($cawangan['mysql'])->table('palsu') + $palsu_query = Palsu::on($cawangan['mysql']) ->select([ 'tarikh', 'norujukan', @@ -35,33 +37,34 @@ class BarangkesController extends Controller 'untung', 'untungonepercent', 'untungcajlain' - ]); + ]) + ->when($request->filled('jenis'), function($query) use($request){ + return $query->where('jenis', $request->jenis); + }) + ->when($request->filled('tarikh_mula') && $request->filled('tarikh_akhir'), function($query) use($request){ + return $query->whereBetween('tarikh', [$request->tarikh_mula, $request->tarikh_akhir]); + }) + ->with('tebus:norujukan'); - // Only apply whereBetween if tarikh_mula and tarikh_akhir are provided - if ($request->filled('tarikh_mula') && $request->filled('tarikh_akhir')) { - $query->whereBetween('tarikh', [$request->tarikh_mula, $request->tarikh_akhir]); - } + $palsu_array = $palsu_query->get()->toArray(); + $pampasan_array = Pampasan::on($cawangan['mysql'])->where('kodcaw', $request->kodcaw)->get()->toArray(); - $result = $query->get(); - - $pampasan = Http::get(config('app_parameter.api_v3') . "pampasan", ['kodcaw' => $request->kodcaw]) - ->json()['data']; - - $palsu_array = $result->toArray(); - - // dd($pampasan, $palsu_array); - - $indexedArray2 = collect($pampasan)->keyBy('norujukan'); + $indexedArray2 = collect($pampasan_array)->keyBy('norujukan'); $merged = collect($palsu_array)->map(function ($item) use ($indexedArray2) { - $id = $item->norujukan; - $itemArray = (array) $item; // Convert object to array + $id = $item['norujukan']; + $itemArray = $item; // Already an array from toArray() $additional = $indexedArray2->get($id, []); + + // Add exists_in_tebus flag based on relationship + $itemArray['gadaian_sudah_tebus'] = !is_null($item['tebus']); + + // Remove the tebus relationship data to keep response clean + unset($itemArray['tebus']); + return array_merge($itemArray, $additional); })->values()->toArray(); - // dd($merged, $status); - $filteredResults = []; if ($status == 'dituntut') { @@ -78,7 +81,7 @@ class BarangkesController extends Controller } } } - if ($status == 'all') { + if ($status == 'all' || $status == null) { $filteredResults = $merged; } diff --git a/app/Http/Controllers/PampasanController.php b/app/Http/Controllers/PampasanController.php index 6592327..3ec2ebd 100644 --- a/app/Http/Controllers/PampasanController.php +++ b/app/Http/Controllers/PampasanController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers; use App\Cawangan; +use App\Palsu; use App\Pampasan; use Illuminate\Http\Request; use Carbon\Carbon; @@ -67,6 +68,11 @@ class PampasanController extends Controller $pampasan->save(); + // Update corresponding palsu table record status to 1 + Palsu::on($cawangan['mysql']) + ->where('norujukan', $norujukan) + ->update(['status' => 1]); + // dd($pampasan); return response()->json([ diff --git a/app/Palsu.php b/app/Palsu.php index 06c5eaa..98d6f3b 100644 --- a/app/Palsu.php +++ b/app/Palsu.php @@ -4,6 +4,7 @@ namespace App; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\HasOne; use App\Audit; use Illuminate\Support\Carbon; @@ -30,6 +31,8 @@ class Palsu extends Model 'untungonepercent', 'untungcajlain', 'pembiayaan', + 'jenis', + 'status', ]; // public static function boot() @@ -87,4 +90,9 @@ class Palsu extends Model // { // return $this->belongsTo(Daerah::class, 'koddaerah', 'koddaerah'); // } + + public function tebus(): HasOne + { + return $this->hasOne(Tebus::class, 'norujukan', 'norujukan'); + } } diff --git a/database/migrations/2025_09_17_092001_add_jenis_column_to_palsu_table.php b/database/migrations/2025_09_17_092001_add_jenis_column_to_palsu_table.php new file mode 100644 index 0000000..a9de2a2 --- /dev/null +++ b/database/migrations/2025_09_17_092001_add_jenis_column_to_palsu_table.php @@ -0,0 +1,68 @@ +select('SELECT 1'); + return true; + } catch (\Exception $e) { + return false; + } + }); + + return $db_connection ? array_values($db_connection) : []; + } + + /** + * Run the migrations. + * + * @return void + */ + public function up() + { + $db_connection = $this->getActiveDB(); + + foreach ($db_connection as $dbase) { + Schema::connection($dbase)->table('palsu', function (Blueprint $table) use ($dbase) { + if (!Schema::connection($dbase)->hasColumn('palsu', 'jenis')) { + $table->string('jenis', 50)->nullable()->comment('Jenis/Type classification'); + } + }); + } + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + $db_connection = $this->getActiveDB(); + + foreach ($db_connection as $dbase) { + Schema::connection($dbase)->table('palsu', function (Blueprint $table) use ($dbase) { + if (Schema::connection($dbase)->hasColumn('palsu', 'jenis')) { + $table->dropColumn('jenis'); + } + }); + } + } +} diff --git a/database/migrations/2025_09_17_093116_update_jenis_to_pampasan_for_semporna_records.php b/database/migrations/2025_09_17_093116_update_jenis_to_pampasan_for_semporna_records.php new file mode 100644 index 0000000..424a87b --- /dev/null +++ b/database/migrations/2025_09_17_093116_update_jenis_to_pampasan_for_semporna_records.php @@ -0,0 +1,78 @@ +getSempornaRecords(); + + // Update jenis to 'pampasan' for Semporna records in mysql34 (Semporna branch) + try { + $updated = DB::connection('mysql34')->table('palsu') + ->whereIn('norujukan', $semporna_records) + ->update(['jenis' => 'pampasan']); + + echo "Updated {$updated} Semporna records with jenis = 'pampasan'\n"; + } catch (\Exception $e) { + echo "Error updating Semporna records: " . $e->getMessage() . "\n"; + } + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + $semporna_records = $this->getSempornaRecords(); + + // Revert jenis to null for Semporna records + try { + $reverted = DB::connection('mysql34')->table('palsu') + ->whereIn('norujukan', $semporna_records) + ->update(['jenis' => null]); + + echo "Reverted {$reverted} Semporna records jenis to null\n"; + } catch (\Exception $e) { + echo "Error reverting Semporna records: " . $e->getMessage() . "\n"; + } + } +} diff --git a/database/migrations/2025_09_17_093117_update_non_semporna_records_jenis_to_hapuskira.php b/database/migrations/2025_09_17_093117_update_non_semporna_records_jenis_to_hapuskira.php new file mode 100644 index 0000000..44594a3 --- /dev/null +++ b/database/migrations/2025_09_17_093117_update_non_semporna_records_jenis_to_hapuskira.php @@ -0,0 +1,130 @@ +select('SELECT 1'); + return true; + } catch (\Exception $e) { + return false; + } + }); + + return $db_connection ? array_values($db_connection) : []; + } + + /** + * Semporna norujukan records to exclude + */ + private function getSempornaRecords(): array + { + return [ + '011237240808-0003', + '011237240719-0015', + '011237240806-0011', + '011237240828-0001', + '011237240904-0007', + '011237240904-0008', + '011237240904-0009', + '011237240719-0023', + '011237240719-0024', + '011237240719-0025', + '011237240618-0026', + '011237240719-0027', + '011237240719-0028', + '011237240618-0020', + '011237240719-0030', + '011237240618-0029', + '011237240731-0026', + '011237240912-0009' + ]; + } + + /** + * Run the migrations. + * + * @return void + */ + public function up() + { + $db_connection = $this->getActiveDB(); + $semporna_records = $this->getSempornaRecords(); + + foreach ($db_connection as $dbase) { + try { + if ($dbase == 'mysql34') { + // For Semporna (mysql34), update only non-Semporna records to 'hapuskira' + $updated = DB::connection($dbase)->table('palsu') + ->whereNotIn('norujukan', $semporna_records) + ->update(['jenis' => 'hapuskira']); + + if ($updated > 0) { + echo "Updated {$updated} non-Semporna records in {$dbase} to jenis = 'hapuskira'\n"; + } + } else { + // For all other databases, update all records to 'hapuskira' + $updated = DB::connection($dbase)->table('palsu') + ->update(['jenis' => 'hapuskira']); + + if ($updated > 0) { + echo "Updated {$updated} records in {$dbase} to jenis = 'hapuskira'\n"; + } + } + } catch (\Exception $e) { + echo "Error updating {$dbase}: " . $e->getMessage() . "\n"; + } + } + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + $db_connection = $this->getActiveDB(); + + foreach ($db_connection as $dbase) { + try { + // Revert all jenis values to null except Semporna records which should remain 'pampasan' + if ($dbase == 'mysql34') { + $semporna_records = $this->getSempornaRecords(); + $reverted = DB::connection($dbase)->table('palsu') + ->whereNotIn('norujukan', $semporna_records) + ->update(['jenis' => null]); + + if ($reverted > 0) { + echo "Reverted {$reverted} non-Semporna records in {$dbase} jenis to null\n"; + } + } else { + $reverted = DB::connection($dbase)->table('palsu') + ->update(['jenis' => null]); + + if ($reverted > 0) { + echo "Reverted {$reverted} records in {$dbase} jenis to null\n"; + } + } + } catch (\Exception $e) { + echo "Error reverting {$dbase}: " . $e->getMessage() . "\n"; + } + } + } +} diff --git a/database/migrations/2025_09_17_093118_add_status_column_to_palsu_table.php b/database/migrations/2025_09_17_093118_add_status_column_to_palsu_table.php new file mode 100644 index 0000000..6c71628 --- /dev/null +++ b/database/migrations/2025_09_17_093118_add_status_column_to_palsu_table.php @@ -0,0 +1,73 @@ +select('SELECT 1'); + return true; + } catch (\Exception $e) { + return false; + } + }); + + return $db_connection ? array_values($db_connection) : []; + } + + /** + * Run the migrations. + * + * @return void + */ + public function up() + { + $db_connection = $this->getActiveDB(); + + foreach ($db_connection as $dbase) { + Schema::connection($dbase)->table('palsu', function (Blueprint $table) use ($dbase) { + if (!Schema::connection($dbase)->hasColumn('palsu', 'status')) { + $table->unsignedSmallInteger('status')->default(0)->comment('Status value'); + } + }); + + // Update existing rows to have status = 0 + DB::connection($dbase)->table('palsu') + ->whereNull('status') + ->update(['status' => 0]); + } + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + $db_connection = $this->getActiveDB(); + + foreach ($db_connection as $dbase) { + Schema::connection($dbase)->table('palsu', function (Blueprint $table) use ($dbase) { + if (Schema::connection($dbase)->hasColumn('palsu', 'status')) { + $table->dropColumn('status'); + } + }); + } + } +} diff --git a/database/migrations/2025_09_17_093624_update_all_palsu_status_to_one.php b/database/migrations/2025_09_17_093624_update_all_palsu_status_to_one.php new file mode 100644 index 0000000..3cba378 --- /dev/null +++ b/database/migrations/2025_09_17_093624_update_all_palsu_status_to_one.php @@ -0,0 +1,80 @@ +select('SELECT 1'); + return true; + } catch (\Exception $e) { + return false; + } + }); + + return $db_connection ? array_values($db_connection) : []; + } + + /** + * Run the migrations. + * + * @return void + */ + public function up() + { + $db_connection = $this->getActiveDB(); + + foreach ($db_connection as $dbase) { + try { + // Update all status values to 1 in palsu table + $updated = DB::connection($dbase)->table('palsu') + ->update(['status' => 1]); + + if ($updated > 0) { + echo "Updated {$updated} records in {$dbase} palsu table to status = 1\n"; + } + } catch (\Exception $e) { + echo "Error updating {$dbase}: " . $e->getMessage() . "\n"; + } + } + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + $db_connection = $this->getActiveDB(); + + foreach ($db_connection as $dbase) { + try { + // Revert all status values back to 0 in palsu table + $reverted = DB::connection($dbase)->table('palsu') + ->update(['status' => 0]); + + if ($reverted > 0) { + echo "Reverted {$reverted} records in {$dbase} palsu table to status = 0\n"; + } + } catch (\Exception $e) { + echo "Error reverting {$dbase}: " . $e->getMessage() . "\n"; + } + } + } +} diff --git a/database/migrations/2025_09_17_093756_update_semporna_records_status_to_zero.php b/database/migrations/2025_09_17_093756_update_semporna_records_status_to_zero.php new file mode 100644 index 0000000..7731a9d --- /dev/null +++ b/database/migrations/2025_09_17_093756_update_semporna_records_status_to_zero.php @@ -0,0 +1,78 @@ +getSempornaRecords(); + + // Update status to 0 for Semporna records in mysql34 (Semporna branch) + try { + $updated = DB::connection('mysql34')->table('palsu') + ->whereIn('norujukan', $semporna_records) + ->update(['status' => 0]); + + echo "Updated {$updated} Semporna records with status = 0\n"; + } catch (\Exception $e) { + echo "Error updating Semporna records status: " . $e->getMessage() . "\n"; + } + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + $semporna_records = $this->getSempornaRecords(); + + // Revert status to 1 for Semporna records + try { + $reverted = DB::connection('mysql34')->table('palsu') + ->whereIn('norujukan', $semporna_records) + ->update(['status' => 1]); + + echo "Reverted {$reverted} Semporna records status to 1\n"; + } catch (\Exception $e) { + echo "Error reverting Semporna records status: " . $e->getMessage() . "\n"; + } + } +} From 38dd97c4f2d31fe7ecf813191ba7f91bf242c5b2 Mon Sep 17 00:00:00 2001 From: Afiq Hamzah Date: Wed, 17 Sep 2025 14:14:06 +0800 Subject: [PATCH 04/80] Register pampasan to panjar after tuntutan made by pelanggan --- app/Http/Controllers/PampasanController.php | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/PampasanController.php b/app/Http/Controllers/PampasanController.php index 3ec2ebd..48a95c0 100644 --- a/app/Http/Controllers/PampasanController.php +++ b/app/Http/Controllers/PampasanController.php @@ -5,6 +5,7 @@ namespace App\Http\Controllers; use App\Cawangan; use App\Palsu; use App\Pampasan; +use App\Panjar; use Illuminate\Http\Request; use Carbon\Carbon; use Illuminate\Log\Logger; @@ -58,7 +59,6 @@ class PampasanController extends Controller public function updateStatusPampasan(Request $request) { $norujukan = $request->norujukan; - $kodcaw = $request->kodcaw; $cawangan = Cawangan::on('mysql7')->where('kodcaw', $request->kodcaw)->first(); @@ -73,7 +73,19 @@ class PampasanController extends Controller ->where('norujukan', $norujukan) ->update(['status' => 1]); - // dd($pampasan); + Panjar::on($cawangan['mysql']) + ->create([ + 'tarikh' => Carbon::now()->toDateString(), + 'deskripsi' => 'BAYARAN PAMPASAN' . '(' . $pampasan->norujukan . ')', + 'bayaran' => $pampasan->jumlah_pampasan, + 'tag' => 1, + 'kategori' => 'Belanja AM', + 'id' => $pampasan->teller, + 'bakiperubatan' => $request->bakiperubatan, + 'nobaucer' => $pampasan->baucherno, + 'nobil' => Carbon::now()->format('dmy'), + 'tuntutoleh' => $pampasan->teller, + ]); return response()->json([ 'success' => true, From f5874b956db5585bc8540d7d57507caf4d9f18f6 Mon Sep 17 00:00:00 2001 From: Afiq Hamzah Date: Mon, 22 Sep 2025 13:00:08 +0800 Subject: [PATCH 05/80] Update pampasan module with enhanced agreement tracking and semporna processing - Add agreement_printed_at timestamp to pampasan table for tracking printed agreements - Update jenis handling for semporna v2 processing logic - Refactor barangkes controller eager loading for improved performance - Remove obsolete jenis migration files and consolidate schema changes - Update related models and controllers for semporna v2 compatibility --- app/Http/Controllers/BarangkesController.php | 10 +- app/Http/Controllers/PampasanController.php | 180 +++++++++++++----- app/Palsu.php | 6 +- app/Pampasan.php | 4 +- app/Support/Tawarruq.php | 3 + app/Support/v1/Penebusan.php | 13 ++ ...jenis_to_pampasan_for_semporna_records.php | 78 -------- ...on_semporna_records_jenis_to_hapuskira.php | 130 ------------- ...greement_printed_at_to_pampasan_table.php} | 28 +-- routes/web.php | 1 + 10 files changed, 174 insertions(+), 279 deletions(-) delete mode 100644 database/migrations/2025_09_17_093116_update_jenis_to_pampasan_for_semporna_records.php delete mode 100644 database/migrations/2025_09_17_093117_update_non_semporna_records_jenis_to_hapuskira.php rename database/migrations/{2025_09_17_092001_add_jenis_column_to_palsu_table.php => 2025_09_18_141626_add_agreement_printed_at_to_pampasan_table.php} (54%) diff --git a/app/Http/Controllers/BarangkesController.php b/app/Http/Controllers/BarangkesController.php index 06ef56e..ae0f29a 100644 --- a/app/Http/Controllers/BarangkesController.php +++ b/app/Http/Controllers/BarangkesController.php @@ -38,13 +38,10 @@ class BarangkesController extends Controller 'untungonepercent', 'untungcajlain' ]) - ->when($request->filled('jenis'), function($query) use($request){ - return $query->where('jenis', $request->jenis); - }) ->when($request->filled('tarikh_mula') && $request->filled('tarikh_akhir'), function($query) use($request){ return $query->whereBetween('tarikh', [$request->tarikh_mula, $request->tarikh_akhir]); }) - ->with('tebus:norujukan'); + ->with(['tebus:norujukan', 'gadai:norujukan,nokp']); $palsu_array = $palsu_query->get()->toArray(); $pampasan_array = Pampasan::on($cawangan['mysql'])->where('kodcaw', $request->kodcaw)->get()->toArray(); @@ -59,8 +56,13 @@ class BarangkesController extends Controller // Add exists_in_tebus flag based on relationship $itemArray['gadaian_sudah_tebus'] = !is_null($item['tebus']); + // Add nokp customer from gadai relationship + $itemArray['nokp'] = $item['gadai']['nokp']; + // Remove the tebus relationship data to keep response clean unset($itemArray['tebus']); + unset($itemArray['gadai']); + return array_merge($itemArray, $additional); })->values()->toArray(); diff --git a/app/Http/Controllers/PampasanController.php b/app/Http/Controllers/PampasanController.php index 48a95c0..cdbeb86 100644 --- a/app/Http/Controllers/PampasanController.php +++ b/app/Http/Controllers/PampasanController.php @@ -6,6 +6,7 @@ use App\Cawangan; use App\Palsu; use App\Pampasan; use App\Panjar; +use App\Tebus; use Illuminate\Http\Request; use Carbon\Carbon; use Illuminate\Log\Logger; @@ -13,46 +14,37 @@ use Illuminate\Support\Facades\Log; class PampasanController extends Controller { + public function terimaPampasan(Request $request) { $validated = $this->validate($request, [ 'norujukan' => 'required|string', - 'baucerno' => 'required|string', 'kodcaw' => 'required|string', 'jumlah_pampasan' => 'required|numeric', - 'denominasi' => 'nullable|array', + 'denominasi' => 'required|array', 'teller' => 'required|string', ]); try { - $cawangan = Cawangan::on('mysql7')->where('kodcaw', $request->kodcaw)->first(); + $cawangan = $this->getCawangan($request->kodcaw); if (!$cawangan) { - return response()->json([ - 'success' => false, - 'message' => 'Cawangan tidak dijumpai untuk kodcaw: ' . $request->kodcaw, - ], 404); + return $this->errorResponse('Cawangan tidak dijumpai untuk kodcaw: ' . $request->kodcaw, 404); } - $pampasan = Pampasan::on($cawangan['mysql'])->create([ - 'norujukan' => $validated['norujukan'], - 'baucerno' => $validated['baucerno'], - 'kodcaw' => $validated['kodcaw'], + $pampasan = Pampasan::on($cawangan['mysql']) + ->where('norujukan', $validated['norujukan']) + ->first(); + + $pampasan->update([ 'jumlah_pampasan' => $validated['jumlah_pampasan'], 'denominasi' => isset($validated['denominasi']) ? json_encode($validated['denominasi']) : null, 'teller' => $validated['teller'], ]); - return response()->json([ - 'success' => true, - 'message' => 'Pampasan berjaya dibayar.', - 'data' => $pampasan, - ], 201); + return $this->successResponse('Pampasan berjaya dibayar.', $pampasan, 201); } catch (\Exception $e) { - return response()->json([ - 'success' => false, - 'message' => 'Database error: ' . $e->getMessage(), - ], 500); + return $this->errorResponse('Database error: ' . $e->getMessage(), 500); } } @@ -60,7 +52,13 @@ class PampasanController extends Controller { $norujukan = $request->norujukan; - $cawangan = Cawangan::on('mysql7')->where('kodcaw', $request->kodcaw)->first(); + $cawangan = $this->getCawangan($request->kodcaw); + + if (!$cawangan) { + return $this->errorResponse('Cawangan tidak dijumpai untuk kodcaw: ' . $request->kodcaw, 404); + } + + $tebus = Tebus::on($cawangan['mysql'])->where('norujukan', $norujukan)->first(); $pampasan = Pampasan::on($cawangan['mysql'])->where("norujukan", $norujukan)->first(); @@ -73,40 +71,128 @@ class PampasanController extends Controller ->where('norujukan', $norujukan) ->update(['status' => 1]); - Panjar::on($cawangan['mysql']) - ->create([ - 'tarikh' => Carbon::now()->toDateString(), - 'deskripsi' => 'BAYARAN PAMPASAN' . '(' . $pampasan->norujukan . ')', - 'bayaran' => $pampasan->jumlah_pampasan, - 'tag' => 1, - 'kategori' => 'Belanja AM', - 'id' => $pampasan->teller, - 'bakiperubatan' => $request->bakiperubatan, - 'nobaucer' => $pampasan->baucherno, - 'nobil' => Carbon::now()->format('dmy'), - 'tuntutoleh' => $pampasan->teller, + return $this->successResponse('Status Pampasan berjaya dituntut.', $pampasan, 201); + } + + public function getPampasan(Request $request) + { + $cawangan_connection = Cawangan::where('kodcaw', $request->kodcaw)->first()->mysql; + + $pampasan = Pampasan::on($cawangan_connection) + ->when($request->filled('norujukan'), function ($query) use ($request) { + return $query->where('norujukan', $request->norujukan); + }) + ->get(); + + + return $this->successResponse('Senarai pampasan', $pampasan, 201); + } + + public function updateAgreementPrintedAt(Request $request) + { + $validated = $this->validate($request, [ + 'norujukan' => 'required|string', + 'kodcaw' => 'required|string', + ]); + + try { + $cawangan = $this->getCawangan($validated['kodcaw']); + + if (!$cawangan) { + return $this->errorResponse('Cawangan tidak dijumpai untuk kodcaw: ' . $validated['kodcaw'], 404); + } + + $pampasan = Pampasan::on($cawangan['mysql'])->where('norujukan', $validated['norujukan'])->first(); + + if (!$pampasan) { + return $this->errorResponse('Pampasan tidak dijumpai untuk norujukan: ' . $validated['norujukan'], 404); + } + + $pampasan->agreement_printed_at = Carbon::now(); + $pampasan->save(); + + return $this->successResponse('Agreement printed timestamp berjaya dikemaskini.', $pampasan, 200); + } catch (\Exception $e) { + return $this->errorResponse('Database error: ' . $e->getMessage(), 500); + } + } + + public function initiatePampasan(Request $request) + { + $validated = $this->validate($request, [ + 'norujukan' => 'required|string', + 'kodcaw' => 'required|string', + 'teller' => 'required|string', + 'baucerno' => 'required|string', + ]); + + try { + $cawangan = $this->getCawangan($validated['kodcaw']); + + if (!$cawangan) { + return $this->errorResponse('Cawangan tidak dijumpai untuk kodcaw: ' . $validated['kodcaw'], 404); + } + + // Find the palsu record + $palsu = Palsu::on($cawangan['mysql'])->where('norujukan', $validated['norujukan'])->first(); + + if (!$palsu) { + return $this->errorResponse('Barang kes tidak dijumpai untuk norujukan: ' . $validated['norujukan'], 404); + } + + // Check if pampasan already exists for this norujukan + $existingPampasan = Pampasan::on($cawangan['mysql'])->where('norujukan', $validated['norujukan'])->first(); + + if ($existingPampasan) { + // If pampasan exists, just update the agreement_printed_at + $existingPampasan->agreement_printed_at = Carbon::now(); + $existingPampasan->save(); + + return $this->successResponse('Agreement printed timestamp berjaya dikemaskini untuk pampasan sedia ada.', $existingPampasan, 200); + } + + // Create new pampasan record based on palsu data + $pampasan = Pampasan::on($cawangan['mysql'])->create([ + 'norujukan' => $palsu->norujukan, + 'baucerno' => $validated['baucerno'], + 'kodcaw' => $palsu->kodcaw, + 'jumlah_pampasan' => $palsu->nilaimarhun, + 'teller' => $validated['teller'], + 'status' => 0, + 'agreement_printed_at' => Carbon::now(), ]); - return response()->json([ - 'success' => true, - 'message' => 'Status Pampasan berjaya dituntut.', - 'data' => $pampasan, - ], 201); + return $this->successResponse('Pampasan berjaya daftar dari rekod barang kes.', $pampasan, 201); + } catch (\Exception $e) { + return $this->errorResponse('Database error: ' . $e->getMessage(), 500); + } } - public function getPampasan() + private function getCawangan($kodcaw) { - $pampasan = Pampasan::on('mysql71')->get(); + $cawangan = Cawangan::on('mysql7')->where('kodcaw', $kodcaw)->first(); - return response()->json([ - 'success' => true, - 'message' => 'Status Pampasan berjaya dituntut.', - 'data' => $pampasan, - ], 201); + if (!$cawangan) { + return null; + } + + return $cawangan; } - public function getPampasanByNoRujukan() + private function errorResponse($message, $statusCode = 404) { - + return response()->json([ + 'success' => false, + 'message' => $message, + ], $statusCode); + } + + private function successResponse($message, $data = null, $statusCode = 200) + { + return response()->json([ + 'success' => true, + 'message' => $message, + 'data' => $data, + ], $statusCode); } } diff --git a/app/Palsu.php b/app/Palsu.php index 98d6f3b..e03ff42 100644 --- a/app/Palsu.php +++ b/app/Palsu.php @@ -31,7 +31,6 @@ class Palsu extends Model 'untungonepercent', 'untungcajlain', 'pembiayaan', - 'jenis', 'status', ]; @@ -95,4 +94,9 @@ class Palsu extends Model { return $this->hasOne(Tebus::class, 'norujukan', 'norujukan'); } + + public function gadai(): HasOne + { + return $this->hasOne(Gadai::class, 'norujukan', 'norujukan'); + } } diff --git a/app/Pampasan.php b/app/Pampasan.php index 5aed11d..9bc0f0b 100644 --- a/app/Pampasan.php +++ b/app/Pampasan.php @@ -20,8 +20,10 @@ class Pampasan extends Model 'baucerno', 'kodcaw', 'jumlah_pampasan', + 'denominasi', 'teller', - 'nota' + 'nota', + 'agreement_printed_at', ]; /** diff --git a/app/Support/Tawarruq.php b/app/Support/Tawarruq.php index be5506f..785a302 100644 --- a/app/Support/Tawarruq.php +++ b/app/Support/Tawarruq.php @@ -2,11 +2,14 @@ namespace App\Support; +use App\Cawangan; use App\KadarUpah; +use App\Pampasan; use App\Support\v1\GadaiV1 as Version1Gadai; use App\Services\MasterServices; use App\Support\v1\Penebusan; +use Illuminate\Http\JsonResponse; use Illuminate\Http\Request as HttpRequest; use Illuminate\Support\Facades\Log; diff --git a/app/Support/v1/Penebusan.php b/app/Support/v1/Penebusan.php index f85126f..00bde97 100644 --- a/app/Support/v1/Penebusan.php +++ b/app/Support/v1/Penebusan.php @@ -15,6 +15,8 @@ use App\KomuditiPurchase; use App\KomuditiTransaksi; use App\Marhun; use App\Moratorium; +use App\Palsu; +use App\Pampasan; use App\Support\OnePercent; use App\Support\Tawarruq; use App\Support\v1\Calculation as V1Calculation; @@ -479,6 +481,17 @@ class Penebusan $upah_rebet_sebenar = $harga_tebus - $gadai['bakipjm']; } + $isPampasan = Pampasan::on($cawangan['mysql'])->where('norujukan', $request->norujukan)->exists(); + + if($isPampasan){ + $barang_kes = Palsu::on($cawangan['mysql'])->where('norujukan', $norujukan)->first(); + + $harga_tebus = $barang_kes->untung + $barang_kes->pembiayaan; + $upah_tebus = $barang_kes->untung; + $upah_rebet = $this->kiraUpahRebetSebenar($kodcaw,$norujukan); + $upah_rebet_sebenar = $barang_kes->untung; + $rebet = $gadai['hargajualan'] - $harga_tebus; + } $create_tebus = Tebus::on($cawangan['mysql'])->create([ 'kodcaw'=> $kodcaw, diff --git a/database/migrations/2025_09_17_093116_update_jenis_to_pampasan_for_semporna_records.php b/database/migrations/2025_09_17_093116_update_jenis_to_pampasan_for_semporna_records.php deleted file mode 100644 index 424a87b..0000000 --- a/database/migrations/2025_09_17_093116_update_jenis_to_pampasan_for_semporna_records.php +++ /dev/null @@ -1,78 +0,0 @@ -getSempornaRecords(); - - // Update jenis to 'pampasan' for Semporna records in mysql34 (Semporna branch) - try { - $updated = DB::connection('mysql34')->table('palsu') - ->whereIn('norujukan', $semporna_records) - ->update(['jenis' => 'pampasan']); - - echo "Updated {$updated} Semporna records with jenis = 'pampasan'\n"; - } catch (\Exception $e) { - echo "Error updating Semporna records: " . $e->getMessage() . "\n"; - } - } - - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - $semporna_records = $this->getSempornaRecords(); - - // Revert jenis to null for Semporna records - try { - $reverted = DB::connection('mysql34')->table('palsu') - ->whereIn('norujukan', $semporna_records) - ->update(['jenis' => null]); - - echo "Reverted {$reverted} Semporna records jenis to null\n"; - } catch (\Exception $e) { - echo "Error reverting Semporna records: " . $e->getMessage() . "\n"; - } - } -} diff --git a/database/migrations/2025_09_17_093117_update_non_semporna_records_jenis_to_hapuskira.php b/database/migrations/2025_09_17_093117_update_non_semporna_records_jenis_to_hapuskira.php deleted file mode 100644 index 44594a3..0000000 --- a/database/migrations/2025_09_17_093117_update_non_semporna_records_jenis_to_hapuskira.php +++ /dev/null @@ -1,130 +0,0 @@ -select('SELECT 1'); - return true; - } catch (\Exception $e) { - return false; - } - }); - - return $db_connection ? array_values($db_connection) : []; - } - - /** - * Semporna norujukan records to exclude - */ - private function getSempornaRecords(): array - { - return [ - '011237240808-0003', - '011237240719-0015', - '011237240806-0011', - '011237240828-0001', - '011237240904-0007', - '011237240904-0008', - '011237240904-0009', - '011237240719-0023', - '011237240719-0024', - '011237240719-0025', - '011237240618-0026', - '011237240719-0027', - '011237240719-0028', - '011237240618-0020', - '011237240719-0030', - '011237240618-0029', - '011237240731-0026', - '011237240912-0009' - ]; - } - - /** - * Run the migrations. - * - * @return void - */ - public function up() - { - $db_connection = $this->getActiveDB(); - $semporna_records = $this->getSempornaRecords(); - - foreach ($db_connection as $dbase) { - try { - if ($dbase == 'mysql34') { - // For Semporna (mysql34), update only non-Semporna records to 'hapuskira' - $updated = DB::connection($dbase)->table('palsu') - ->whereNotIn('norujukan', $semporna_records) - ->update(['jenis' => 'hapuskira']); - - if ($updated > 0) { - echo "Updated {$updated} non-Semporna records in {$dbase} to jenis = 'hapuskira'\n"; - } - } else { - // For all other databases, update all records to 'hapuskira' - $updated = DB::connection($dbase)->table('palsu') - ->update(['jenis' => 'hapuskira']); - - if ($updated > 0) { - echo "Updated {$updated} records in {$dbase} to jenis = 'hapuskira'\n"; - } - } - } catch (\Exception $e) { - echo "Error updating {$dbase}: " . $e->getMessage() . "\n"; - } - } - } - - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - $db_connection = $this->getActiveDB(); - - foreach ($db_connection as $dbase) { - try { - // Revert all jenis values to null except Semporna records which should remain 'pampasan' - if ($dbase == 'mysql34') { - $semporna_records = $this->getSempornaRecords(); - $reverted = DB::connection($dbase)->table('palsu') - ->whereNotIn('norujukan', $semporna_records) - ->update(['jenis' => null]); - - if ($reverted > 0) { - echo "Reverted {$reverted} non-Semporna records in {$dbase} jenis to null\n"; - } - } else { - $reverted = DB::connection($dbase)->table('palsu') - ->update(['jenis' => null]); - - if ($reverted > 0) { - echo "Reverted {$reverted} records in {$dbase} jenis to null\n"; - } - } - } catch (\Exception $e) { - echo "Error reverting {$dbase}: " . $e->getMessage() . "\n"; - } - } - } -} diff --git a/database/migrations/2025_09_17_092001_add_jenis_column_to_palsu_table.php b/database/migrations/2025_09_18_141626_add_agreement_printed_at_to_pampasan_table.php similarity index 54% rename from database/migrations/2025_09_17_092001_add_jenis_column_to_palsu_table.php rename to database/migrations/2025_09_18_141626_add_agreement_printed_at_to_pampasan_table.php index a9de2a2..01e2154 100644 --- a/database/migrations/2025_09_17_092001_add_jenis_column_to_palsu_table.php +++ b/database/migrations/2025_09_18_141626_add_agreement_printed_at_to_pampasan_table.php @@ -5,7 +5,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\DB; -class AddJenisColumnToPalsuTable extends Migration +class AddAgreementPrintedAtToPampasanTable extends Migration { /** * Get active database connections @@ -16,17 +16,13 @@ class AddJenisColumnToPalsuTable extends Migration $db_connection = array_filter($config_db, function($connection) { try { - if ($connection == 'mysql7') { - return false; - } - + if ($connection === 'mysql7') return false; // ikut pattern sedia ada DB::connection($connection)->select('SELECT 1'); return true; } catch (\Exception $e) { return false; } }); - return $db_connection ? array_values($db_connection) : []; } @@ -37,12 +33,10 @@ class AddJenisColumnToPalsuTable extends Migration */ public function up() { - $db_connection = $this->getActiveDB(); - - foreach ($db_connection as $dbase) { - Schema::connection($dbase)->table('palsu', function (Blueprint $table) use ($dbase) { - if (!Schema::connection($dbase)->hasColumn('palsu', 'jenis')) { - $table->string('jenis', 50)->nullable()->comment('Jenis/Type classification'); + foreach ($this->getActiveDB() as $dbase) { + Schema::connection($dbase)->table('pampasan', function (Blueprint $table) use ($dbase) { + if (!Schema::connection($dbase)->hasColumn('pampasan', 'agreement_printed_at')) { + $table->timestamp('agreement_printed_at')->nullable()->comment('Timestamp when agreement was printed'); } }); } @@ -55,12 +49,10 @@ class AddJenisColumnToPalsuTable extends Migration */ public function down() { - $db_connection = $this->getActiveDB(); - - foreach ($db_connection as $dbase) { - Schema::connection($dbase)->table('palsu', function (Blueprint $table) use ($dbase) { - if (Schema::connection($dbase)->hasColumn('palsu', 'jenis')) { - $table->dropColumn('jenis'); + foreach ($this->getActiveDB() as $dbase) { + Schema::connection($dbase)->table('pampasan', function (Blueprint $table) use ($dbase) { + if (Schema::connection($dbase)->hasColumn('pampasan', 'agreement_printed_at')) { + $table->dropColumn('agreement_printed_at'); } }); } diff --git a/routes/web.php b/routes/web.php index fcb9b81..fb4d452 100644 --- a/routes/web.php +++ b/routes/web.php @@ -380,6 +380,7 @@ $router->group(['prefix'=>'api'], function () use ($router){ $router->post('DeletePanjar/{kodcaw}',['uses'=>'PanjarController@delete']); //API PAMPASAN GUNA PANJAR + $router->post('pampasan/initiatePampasan',['uses'=>'PampasanController@initiatePampasan']); $router->post('pampasan/terimaPampasan',['uses'=>'PampasanController@terimaPampasan']); $router->put('pampasan/updateStatusPampasan', ['uses' => 'PampasanController@updateStatusPampasan']); $router->get('pampasan', ['uses' => 'PampasanController@getPampasan']); From 3b44cec5a2e503ac38cbd631e4d196f6f1b45d89 Mon Sep 17 00:00:00 2001 From: Ain Izazi Date: Mon, 25 Aug 2025 09:40:16 +0800 Subject: [PATCH 06/80] add di function customer nota arcc --- app/Http/Controllers/CallCenterController.php | 75 ++++++++++++++++++- app/Http/Controllers/CustomerController.php | 20 +++++ ...120937_add_nota_arcc_to_customer_table.php | 32 ++++++++ routes/web.php | 6 +- 4 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 database/migrations/2025_08_10_120937_add_nota_arcc_to_customer_table.php diff --git a/app/Http/Controllers/CallCenterController.php b/app/Http/Controllers/CallCenterController.php index 543ea2d..4a8d890 100644 --- a/app/Http/Controllers/CallCenterController.php +++ b/app/Http/Controllers/CallCenterController.php @@ -1649,4 +1649,77 @@ class CallCenterController extends Controller -} + + public function customerUpdate($nokp,Request $request){ + $poskod = Poskod::on('mysql7')->where('poskod','=',$request->poskod)->first(); + $customer_update = Customer::on('mysql7') + ->where('kplama','=',$nokp) + ->orWhere('kpbaru','=',$nokp) + ->update(array( + 'nota_arcc'=>$request->nota_arcc, + )); + + return response()->json($customer_update, 200); + } + + + public function customerUpdateKaunter($nokp,$kodcaw, Request $request){ + $current = Carbon::now(); + + DB::connection('mysql7')->beginTransaction(); + + try{ + $poskod = Poskod::on('mysql7')->where('poskod','=',$request->poskod)->first(); + + $customer_info = DB::connection('mysql7')->table('customer') + ->select('kodcaw','kodkerja','nota_pekerjaan','nota_arcc','tarikhdaftar','nopelanggan','kpbaru','kplama','nama','t_lahir','jantina','poskod') + ->where('kplama','=',$nokp) + ->orWhere('kpbaru','=',$nokp) + ->get()->toArray(); + + + $old_data = json_encode($customer_info); + + $customer_update = Customer::on('mysql7') + ->where('kplama','=',$nokp) + ->orWhere('kpbaru','=',$nokp) + ->update(array( + 'nota_arcc' => $request->nota_arcc, + )); + + if($customer_update) + { + $customer_info_new = DB::connection('mysql7')->table('customer') + ->select('kodcaw','kodkerja','nota_pekerjaan','nota_arcc','tarikhdaftar','nopelanggan','kpbaru','kplama','nama','t_lahir','jantina','alamat1','poskod') + ->where('kplama','=',$nokp) + ->orWhere('kpbaru','=',$nokp) + ->get()->toArray(); + + $new_data = json_encode($customer_info_new); + + $audit_customer = DB::connection('mysql7') + ->table('audit_customer') + ->insert([ + 'username' => $request->namateller, + 'old_data' => $old_data, + 'new_data' => $new_data, + 'kodcaw' => $customer_info[0]->kodcaw, + 'created_at' => Carbon::now()->toDateTimeString(), + 'updated_at' => Carbon::now()->toDateTimeString(), + 'customer_name' => $customer_info[0]->nama, + 'customer_nokp' => $nokp, + ]); + } + + DB::connection('mysql7')->commit(); + + return response()->json($customer_update, 200); + + }catch (\Exception $e) { + DB::connection('mysql7')->rollback(); + return response()->json($e->getMessage(),400); + + } + } + +} \ No newline at end of file diff --git a/app/Http/Controllers/CustomerController.php b/app/Http/Controllers/CustomerController.php index 46c1ae3..6080cac 100644 --- a/app/Http/Controllers/CustomerController.php +++ b/app/Http/Controllers/CustomerController.php @@ -362,6 +362,7 @@ class CustomerController extends Controller 'nota'=>$request->nota, 'kodkerja'=>$request->kodkerja, 'nota_pekerjaan'=>$request->nota_pekerjaan, + // 'nota_arcc'=>$request->nota_arcc, 'tujuangadai'=>$request->tujuangadai ]); @@ -390,6 +391,7 @@ class CustomerController extends Controller 'kodnegeri' => $poskod['kodnegeri'], 'kodkerja'=>$request->kodkerja, 'nota_pekerjaan'=>$request->nota_pekerjaan, + // 'nota_arcc'=>$request->nota_arcc, 'telefon' => $request->telefon1, 'telefon2' => $request->telefon2 )); @@ -424,6 +426,7 @@ class CustomerController extends Controller 'kodkerja' => $request->kodkerja, // 'nota_pekerjaan' => $request->nota_pekerjaan, 'nota_pekerjaan' => $request->kodkerja === '6' ? $request->nota_pekerjaan : null, + // 'nota_arcc' => $request->nota_arcc, 'noakaun' => $request->noakaun, 'nota' => $request->nota, 'alamat1' => $request->alamat, @@ -501,6 +504,7 @@ class CustomerController extends Controller 'kodbank' => $request->kodbank, 'kodkerja' => $request->kodkerja, 'nota_pekerjaan' => $request->nota_pekerjaan, + // 'nota_arcc' => $request->nota_arcc, 'noakaun' => $request->noakaun, 'nota' => $request->nota, 'nama' => $request->nama, @@ -999,4 +1003,20 @@ class CustomerController extends Controller return response()->json($results); } +// public function createNotaArcc($kodcaw, Request $request) +// { +// $current = Carbon::now(); + +// $customer = Customer::on('mysql7')->create([ +// 'kodcaw' => $kodcaw, +// 'tarikhdaftar' => $current->toDateString(), +// 'nota_arcc' => $request->nota_arcc, +// 'teller' => $request->teller, +// 'aktif' => 'A' +// ]); + +// return response()->json($customer, 201); +// } + + } diff --git a/database/migrations/2025_08_10_120937_add_nota_arcc_to_customer_table.php b/database/migrations/2025_08_10_120937_add_nota_arcc_to_customer_table.php new file mode 100644 index 0000000..b61c531 --- /dev/null +++ b/database/migrations/2025_08_10_120937_add_nota_arcc_to_customer_table.php @@ -0,0 +1,32 @@ +string('nota_arcc')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('customer', function (Blueprint $table) { + $table->dropColumn('nota_arcc'); + }); + } +} diff --git a/routes/web.php b/routes/web.php index fb4d452..d826ac1 100644 --- a/routes/web.php +++ b/routes/web.php @@ -63,7 +63,11 @@ $router->group(['prefix'=>'api'], function () use ($router){ //arcc $router->get('customer/searchbyname',['uses'=>'CustomerController@searchByName']); // Route::get('/api/customers/searchbyname', [CustomerController::class, 'searchByName']); - + // $router->put('customers/update/{nokp}', ['uses' => 'CallCenterController@customerUpdate']); //kena tengok api ni + // $router->put('customers/update/kaunter/{nokp}/{kodcaw}', ['uses' => 'CallCenterController@customerUpdateKaunter']); + $router->put('callcenter/customers/update/{nokp}', ['uses' => 'CallCenterController@customerUpdate']); //kena tengok api ni + $router->put('callcenter/customers/update/kaunter/{nokp}/{kodcaw}', ['uses' => 'CallCenterController@customerUpdateKaunter']); + //Change Password $router->post('changepassword/{kodcaw}/{id}',['uses'=>'CustomerController@changepassword']); From 632c2b5190c203b083ef51d299df3a7a7a412d5d Mon Sep 17 00:00:00 2001 From: Nur Izzati Date: Wed, 27 Aug 2025 12:26:19 +0800 Subject: [PATCH 07/80] tambah baik laporan SA by sag --- app/Http/Controllers/StokAuditController.php | 147 +++++++++++++++++++ routes/web.php | 1 + 2 files changed, 148 insertions(+) diff --git a/app/Http/Controllers/StokAuditController.php b/app/Http/Controllers/StokAuditController.php index d0188c1..cc6129f 100644 --- a/app/Http/Controllers/StokAuditController.php +++ b/app/Http/Controllers/StokAuditController.php @@ -432,4 +432,151 @@ class StokAuditController extends Controller 'totaltunggakan'=>$totaltunggakan ?? null]; return response()->json($arrayrekod,200); } + + + public function LaporanAuditKhasByNorujukan($kodcaw, Request $request) + { + $daritempoh = $request->daritempoh; + $hinggatempoh = $request->hinggatempoh; + + $cawangan = Cawangan::on('mysql7')->where('kodcaw', '=', $request->kodcaw)->first(); + + // Ambil semua rekod gadai asas + $audit = Gadai::on($cawangan['mysql']) + ->where([ + ['tagpalsu', '=', 0], + ['tempoh', '>=', $daritempoh], + ['tempoh', '<=', $hinggatempoh], + ['sttebus', '=', ''], + ['taglel', '=', 0], + ]) + ->orderBy('norujukan', 'ASC') // susun ikut norujukan + ->get(); + + $arraynorujukan = $audit->pluck('norujukan')->toArray(); + + // Tarikh terkini ikut trans_type T + $tarikhTerkiniT = Transaction::on('mysql7') + ->select('norujukan', DB::raw('MAX(created_at) as tarikh_max')) + ->where('trans_type', 'T') + ->whereIn('norujukan', $arraynorujukan) + ->groupBy('norujukan') + ->pluck('tarikh_max', 'norujukan') + ->toArray(); + + // Tarikh terkini ikut trans_type A + $tarikhTerkiniA = Transaction::on('mysql7') + ->select('norujukan', DB::raw('MAX(created_at) as tarikh_max')) + ->where('trans_type', 'A') + ->whereIn('norujukan', $arraynorujukan) + ->groupBy('norujukan') + ->pluck('tarikh_max', 'norujukan') + ->toArray(); + + // Filter audit + $rekodaudit = $audit->filter(function ($item) use ($tarikhTerkiniT, $tarikhTerkiniA) { + $norujukan = $item->norujukan; + + $adaTebusTerkini = isset($tarikhTerkiniT[$norujukan]) && + Transaction::on('mysql7') + ->where('norujukan', $norujukan) + ->where('trans_type', 'T') + ->whereDate('created_at', '>=', date('Y-m-d', strtotime($tarikhTerkiniT[$norujukan]))) + ->exists(); + + $adaAnsuranTerkini = isset($tarikhTerkiniA[$norujukan]) && + Transaction::on('mysql7') + ->where('norujukan', $norujukan) + ->where('trans_type', 'A') + ->whereDate('created_at', '>=', date('Y-m-d', strtotime($tarikhTerkiniA[$norujukan]))) + ->exists(); + + return !$adaTebusTerkini && !$adaAnsuranTerkini; + })->values(); + + // Attach customer info + blast untuk setiap norujukan + foreach ($rekodaudit as $index => $rekod) { + $customer = Customer::on('mysql7') + ->where('kpbaru', '=', $rekod->nokp) + ->orWhere('kplama', '=', $rekod->nokp) + ->first(); + + $rekodaudit[$index]['customer'] = $customer; + + $rekodaudit[$index]['blasted'] = BlastWasap::on('mysql7') + ->where('nokp', $rekod->nokp) + ->where('norujukan', $rekod->norujukan) + ->where('kodcaw', $kodcaw) + ->first(); + + // 👉 Kira keuntungan (tunggakan sebenar) guna function + $upah = $this->kiraupahUjrahOnePercent($kodcaw, $rekod->norujukan); + $keuntungan = $upah['ujrah'] + $upah['onepercent']; + + // Save ke dalam rekod + $rekodaudit[$index]['tunggakan'] = $this->floorTo5SenFrom2dp($keuntungan); + } + + // Summary total + $summary = [ + 'totalrekod' => $rekodaudit->count(), + 'totalberat' => $rekodaudit->sum('berat'), + 'totalnilaimarhun'=> $rekodaudit->sum('nilaimarhun'), + 'totalpinjaman' => $rekodaudit->sum('pinjaman'), + 'totalbakipjm' => $rekodaudit->sum('bakipjm'), + 'totaltunggakan' => $rekodaudit->sum('tunggakan'), + ]; + + return response()->json([ + 'rekod' => $rekodaudit, + 'summary' => $summary, + ]); + } + + public function kiraupahUjrahOnePercent($kodcaw,$norujukan){ + $onepercentservices = new OnePercentServices(); + + $cawangan = Cawangan::on('mysql7') + ->where('kodcaw','=',$kodcaw) + ->first(); + + $gadai_data = Gadai::on($cawangan['mysql']) + ->where('norujukan','=',$norujukan) + ->first(); + + if($gadai_data['tempoh'] >= 12.0){ + $tempoh = 12; + }else{ + $tempoh = $gadai_data['tempoh']; + } + + $bilang_bln = $tempoh - $gadai_data['tempohbayar']; + $array_upah = $onepercentservices->kiraanKeuntunganSebenar($gadai_data['pinjaman'],$gadai_data['nilaimarhun'],$gadai_data['kadarupah'],$gadai_data['percentpinj']); + $ujrah = $bilang_bln * $array_upah['ujrah']; + $onepercent = $bilang_bln * $array_upah['onepercent']; + $onepercent_semasa = $onepercent; + $ujrah_semasa = $ujrah; + + return ['ujrah' => $ujrah_semasa, 'onepercent' => $onepercent_semasa]; + } + + // dalam Controller (private/protected) + private function floorTo5SenFrom2dp($amount) + { + // pastikan numeric + $amount = (float) $amount; + + // 1) Tukar ke sen dan buang sebarang pecahan sen (hanya baca 2 dp) + // tambah epsilon kecil untuk elak isu floating point + $cents = (int) floor($amount * 100 + 0.0000001); + + // 2) Floor ke gandaan 5 sen + $cents5 = (int) (floor($cents / 5) * 5); + + // balik ke ringgit + return $cents5 / 100; + } + + + } diff --git a/routes/web.php b/routes/web.php index d826ac1..0a028b5 100644 --- a/routes/web.php +++ b/routes/web.php @@ -672,6 +672,7 @@ $router->group(['prefix'=>'api'], function () use ($router){ //STOKAUDITKHAS $router->get('stokauditkhas/aktif/{kodcaw}',['uses'=>'StokAuditController@LaporanAuditKhasAktif']); + $router->get('stokauditkhasbynorujukan/aktif/{kodcaw}',['uses'=>'StokAuditController@LaporanAuditKhasByNorujukan']); //API BLAST WASAP $router->post('blastwasap/{kodcaw}',['uses'=>'StokAuditController@blastwasap']); From 0a9140c85d47b7f968db5f3179daf2ef636f0d2a Mon Sep 17 00:00:00 2001 From: Afiq Hamzah Date: Thu, 25 Sep 2025 10:58:58 +0800 Subject: [PATCH 08/80] Enhance audit trail system for approval workflows - Add conditional audit data enrichment for specific approval actions - Implement namapelulus and norujukan tracking for pampasan approvals - Improve audit data structure handling for scalar and array values - Add user field validation with fallback defaults for audit records - Optimize approval controller with better request parameter handling --- app/Http/Controllers/KelulusanController.php | 31 ++++++++++++++++++-- app/Http/Controllers/LaporanController.php | 2 +- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/KelulusanController.php b/app/Http/Controllers/KelulusanController.php index c9c357b..a909743 100644 --- a/app/Http/Controllers/KelulusanController.php +++ b/app/Http/Controllers/KelulusanController.php @@ -96,6 +96,7 @@ class KelulusanController extends Controller { $harini = Carbon::now(); $harini = new Carbon; + $kelulusan = null; $cawangan = Cawangan::on('mysql7')->where('kodcaw','=',$kodcaw)->first(); $pengesahan = $request->pengesahan; @@ -193,7 +194,33 @@ class KelulusanController extends Controller $audit = new Audit(); $audit->users = (isset($request->namakhazanah) ? $request->namakhazanah : ''); - $audit->actions = "Pengesahan Kelulusan 75%"; + $audit->actions = $request->actions ?? "pengesahan kelulusan 75%"; + + // Only prepare detailed audit data for Pampasan approval + if($request->actions == 'Pengesahan Pembayaran Pampasan') { + // Prepare data for audit - ensure it's an array + $auditData = []; + + // If kelulusan is a scalar (update result), create array structure + if (is_scalar($kelulusan) || is_null($kelulusan)) { + $auditData = ['update_result' => $kelulusan]; + } else { + $auditData = $kelulusan; + } + + // Add namapelulus and norujukanasal to the audit data + if(isset($request->namaoperasi)) { + $auditData['namapelulus'] = !empty($request->namaoperasi) ? $request->namaoperasi : null; + } + if(isset($request->norujukan)) { + $auditData['norujukan'] = !empty($request->norujukan) ? $request->norujukan : null; + } + } else { + // For other actions, use simple kelulusan data + $auditData = $kelulusan; + } + + $audit->new_data = json_encode($auditData); $audit->kodcaw = $kodcaw; $audit->created_at = $harini; $audit->updated_at = $harini; @@ -275,7 +302,7 @@ public function create(REQUEST $request,$kodcaw,$norujukan,$roles) $audit = new Audit(); $audit->users = (isset($request->teller) ? $request->teller : ''); - $audit->actions = "Minta Pengesahan kelulusan 75%"; + $audit->actions = $request->actions ?? "Minta Pengesahan kelulusan 75%"; $audit->new_data = json_encode($kelulusan); $audit->kodcaw = $kodcaw; $audit->created_at = $harini; diff --git a/app/Http/Controllers/LaporanController.php b/app/Http/Controllers/LaporanController.php index 5b6e285..82acd19 100644 --- a/app/Http/Controllers/LaporanController.php +++ b/app/Http/Controllers/LaporanController.php @@ -1244,7 +1244,7 @@ $date = new Carbon($request->tarikh); array_push($atarray,[ 'tarikh' => $tarikh, 'masa' => $masa, - 'users' => $at['users'], + 'users' => isset($at['users']) && $at['users'] !== '' ? $at['users'] : '-', 'pelulus' => isset($atnewdata['namapelulus']) ? $atnewdata['namapelulus'] : '-', 'actions' => $at['actions'], 'norujukan' => $at['norujukan'], From a858d6d59d7384989cb0886efdac9229821b33c7 Mon Sep 17 00:00:00 2001 From: Afiq Hamzah Date: Wed, 1 Oct 2025 20:07:28 +0800 Subject: [PATCH 09/80] Add conditional peloperasi field for pampasan withdrawal approvals - Implement dynamic field assignment for Kelulusan Pengeluaran Pampasan status - Add peloperasi field only when status matches and request parameter exists - Improve data structure handling in approval creation workflow - Enhance conditional logic for pampasan-specific approval requirements --- app/Http/Controllers/KelulusanController.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/app/Http/Controllers/KelulusanController.php b/app/Http/Controllers/KelulusanController.php index a909743..c663000 100644 --- a/app/Http/Controllers/KelulusanController.php +++ b/app/Http/Controllers/KelulusanController.php @@ -256,9 +256,7 @@ public function create(REQUEST $request,$kodcaw,$norujukan,$roles) if($roles == "khazanah") { - $kelulusan=Mohon::on($cawangan['mysql']) - ->create([ - + $createData = [ 'tarikh'=> $harini->toDateString(), 'norujukan'=> $norujukan, 'siri' => $request->siri, @@ -272,10 +270,14 @@ public function create(REQUEST $request,$kodcaw,$norujukan,$roles) 'jenistebus' => $request->jenistebus, 'teller' => $request->teller, 'pelulus' => ($request->pelulus) ? $request->pelulus : '' + ]; + // Add peloperasi if status is Kelulusan Pengeluaran Pampasan + if($request->status == 'Kelulusan Pengeluaran Pampasan' && isset($request->peloperasi)) { + $createData['peloperasi'] = $request->peloperasi; + } - - ]); + $kelulusan=Mohon::on($cawangan['mysql'])->create($createData); } else if($roles == "operasi") { From 177b253817a6a32debcf46837fa95a3d0a05e87d Mon Sep 17 00:00:00 2001 From: hafifierahman Date: Wed, 1 Oct 2025 21:35:44 +0800 Subject: [PATCH 10/80] fix backdate stock audit that exceed 12 months --- app/Http/Controllers/BackupStokAuditController.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/BackupStokAuditController.php b/app/Http/Controllers/BackupStokAuditController.php index 191806e..fb56b2a 100644 --- a/app/Http/Controllers/BackupStokAuditController.php +++ b/app/Http/Controllers/BackupStokAuditController.php @@ -331,7 +331,7 @@ class BackupStokAuditController extends Controller } public function kiraupahTawarruqStokAudit($tempoh,$tempohbayar,$kadarupah,$bakipinjaman){ - + $tempoh = ($tempoh > 12) ? 12 : $tempoh; $bilang_bln = $tempoh - $tempohbayar; if($bilang_bln > 12){ @@ -458,6 +458,7 @@ class BackupStokAuditController extends Controller public function kiraupahTawarruqStokAuditUjrahOnePercent($tempoh,$tempohbayar,$kadarupah,$bakipinjaman,$nilaimarhun,$margin_semasa){ $onepercentservices = new V2Calculation(); $upah = $onepercentservices->kiraanKeuntunganRebet($bakipinjaman,$nilaimarhun,$kadarupah,$margin_semasa); + $tempoh = ($tempoh > 12) ? 12 : $tempoh; $bilang_bln = $tempoh - $tempohbayar; $keuntungan_semasa = $bilang_bln * $upah['onepercent']; $ujrah_semasa = $bilang_bln * $upah['ujrah']; From 908e6174316620a4fd7e72e3d05f8e3696530b56 Mon Sep 17 00:00:00 2001 From: hafifierahman Date: Sat, 4 Oct 2025 21:24:50 +0800 Subject: [PATCH 11/80] added customer info lelong for arrahnpay --- .../TransactionOnlineController.php | 48 +++++++++++++++++-- routes/web.php | 1 + 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/TransactionOnlineController.php b/app/Http/Controllers/TransactionOnlineController.php index 92b6e6a..dc93906 100644 --- a/app/Http/Controllers/TransactionOnlineController.php +++ b/app/Http/Controllers/TransactionOnlineController.php @@ -8,6 +8,7 @@ use App\Cawangan; use App\Gadai; use App\GlDetail; use App\Http\Controllers\TebusController as TebusController; +use App\Lelong; use App\Services\Loggers\OnlineTransactionLoggerService; use App\Services\OnePercentServices; use App\Support\v2\Calculation; @@ -767,8 +768,49 @@ class TransactionOnlineController extends Controller return 'rejected'; } } - - - + public function CustomerInfoLelong(Request $request){ + $cawangan_all = Cawangan::on('mysql7')->get(); + $totalBakiLelong = 0; + $totalRugiLelong = 0; + + foreach ($cawangan_all as $index => $cawangan) { + $gadai = Gadai::on($cawangan['mysql']) + ->where([['sttebus', '=', ''], ['nokp', '=', $request->ic]]) + ->orderBy('t_gadai', 'desc') + ->get()->toArray(); + + if (sizeof($gadai) != 0) { + foreach ($gadai as $gad) { + $bakilelong = Lelong::on($cawangan['mysql']) + ->where(function($query) { + $query->whereNull('trkhtuntut') + ->orWhere('trkhtuntut', '=', ''); + }) + ->where('baki', '>=', 0) + ->sum('baki'); + + $rugilelong = Lelong::on($cawangan['mysql']) + ->where(function($query) { + $query->whereNull('trkhtuntut') + ->orWhere('trkhtuntut', '=', ''); + }) + ->where('baki','<',0) + ->sum('baki'); + } + + $totalBakiLelong += $bakilelong; + $totalRugiLelong += $rugilelong; + } + } + + return response()->json([ + 'success' => true, + 'message' => 'Data retrieved successfully', + 'data' => [ + 'bakilelong' => $totalBakiLelong, + 'rugilelong' => $totalRugiLelong, + ] + ], 200); + } } diff --git a/routes/web.php b/routes/web.php index 359456b..98df23c 100644 --- a/routes/web.php +++ b/routes/web.php @@ -788,6 +788,7 @@ $router->group(['prefix'=>'portal'], function () use ($router){ $router->get('transaksipelanggan/upah',['uses'=>'TransactionController@TransaksiUpah']); $router->get('searchsagonline',['uses'=>'TransactionOnlineController@searchSAGOnline']); $router->get('customer/info',['uses'=>'TransactionOnlineController@CustomerInfo']); + $router->get('customer/info/lelong',['uses'=>'TransactionOnlineController@CustomerInfoLelong']); }); $router->group(['prefix'=>'admin'], function () use ($router){ From b375073520833bb1ae8b4ac023722f82df57ffc8 Mon Sep 17 00:00:00 2001 From: Nur Izzati Date: Sun, 5 Oct 2025 09:18:47 +0800 Subject: [PATCH 12/80] tambah t_lelong dlm gadai --- app/Http/Controllers/GadaiController.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/GadaiController.php b/app/Http/Controllers/GadaiController.php index 81bc8e9..71f3863 100644 --- a/app/Http/Controllers/GadaiController.php +++ b/app/Http/Controllers/GadaiController.php @@ -3871,11 +3871,13 @@ class GadaiController extends Controller public function updateTagLelong(Request $request){ $norujukan = $request->norujukan; $kodcaw = $request->kodcaw; + $t_lelong = $request->t_lelong; $cawangan = Cawangan::on('mysql7')->where('kodcaw',$request->kodcaw)->first(); $updateTag = Gadai::on($cawangan->mysql)->where('norujukan',$norujukan)->update([ - 'taglel'=>1 + 'taglel'=>1, + 't_lelong' => $t_lelong, ]); return response()->json('success'); @@ -3888,7 +3890,8 @@ class GadaiController extends Controller $cawangan = Cawangan::on('mysql7')->where('kodcaw',$request->kodcaw)->first(); $updateTag = Gadai::on($cawangan->mysql)->where('norujukan',$norujukan)->update([ - 'taglel'=>0 + 'taglel'=>0, + 't_lelong' => null, ]); return response()->json('success'); From b76f804d441f05994e4f2858a67abc89b0e7d644 Mon Sep 17 00:00:00 2001 From: Hafifie PKB Date: Sun, 5 Oct 2025 09:59:37 +0800 Subject: [PATCH 13/80] fix specific norujukan --- app/Http/Controllers/TransactionOnlineController.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/TransactionOnlineController.php b/app/Http/Controllers/TransactionOnlineController.php index dc93906..ebaade7 100644 --- a/app/Http/Controllers/TransactionOnlineController.php +++ b/app/Http/Controllers/TransactionOnlineController.php @@ -776,7 +776,7 @@ class TransactionOnlineController extends Controller foreach ($cawangan_all as $index => $cawangan) { $gadai = Gadai::on($cawangan['mysql']) - ->where([['sttebus', '=', ''], ['nokp', '=', $request->ic]]) + ->where('nokp', '=', $request->ic) ->orderBy('t_gadai', 'desc') ->get()->toArray(); @@ -787,6 +787,7 @@ class TransactionOnlineController extends Controller $query->whereNull('trkhtuntut') ->orWhere('trkhtuntut', '=', ''); }) + ->where('norujukan', '=' ,$gad['norujukan']) ->where('baki', '>=', 0) ->sum('baki'); @@ -795,6 +796,7 @@ class TransactionOnlineController extends Controller $query->whereNull('trkhtuntut') ->orWhere('trkhtuntut', '=', ''); }) + ->where('norujukan', '=' ,$gad['norujukan']) ->where('baki','<',0) ->sum('baki'); } From 233b95b2d95ff35f088b25c1f5cd10be89fe5f07 Mon Sep 17 00:00:00 2001 From: Ain Izazi Date: Sun, 5 Oct 2025 11:43:15 +0800 Subject: [PATCH 14/80] function barangkes di adminv2 --- app/Http/Controllers/BarangkesController.php | 76 +++++++++++++++++++ app/Http/Controllers/CustomerController.php | 80 ++++++++++++++++---- app/Palsu.php | 1 + routes/web.php | 19 +++-- 4 files changed, 155 insertions(+), 21 deletions(-) diff --git a/app/Http/Controllers/BarangkesController.php b/app/Http/Controllers/BarangkesController.php index dd4f10c..b4d6586 100644 --- a/app/Http/Controllers/BarangkesController.php +++ b/app/Http/Controllers/BarangkesController.php @@ -6,10 +6,13 @@ use App\Audit; use App\Polis; use App\Cawangan; use App\LookupAlasan; +use App\Palsu; +use App\Gadai; use Illuminate\Http\Request; use Carbon\Carbon; use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Log; class BarangkesController extends Controller { @@ -40,4 +43,77 @@ class BarangkesController extends Controller return response()->json($result); } + + public function store(Request $request) //cara fifi ajar + { + + $current = Carbon::now(); + $kodcaw = $request->kodcaw; + $cawangan = Cawangan::on('mysql7') + ->where('kodcaw', $kodcaw) + ->first(); + + $insert = Palsu::on($cawangan['mysql'])->create([ + 'kodcaw' => $request->kodcaw, + 'tarikh' => $current->toDateString(), + 'norujukan' => $request->norujukan, + 'teller' => $request->teller, + 'nota' => $request->nota ? $request->nota : '', + 'pembiayaan' => $request->pinjaman, + 'nilaimarhun' => $request->nilaimarhun, + 'jbg' => $request->jbg, + 'untung' => $request->tunggakan, + 'untungonepercent' => $request->tunggakanonepercent, + 'untungcajlain' => $request->tunggakanujrah, + ]); + + // return $insert; + + return response()->json([ + 'success' => true, + 'message' => 'Barang kes berjaya didaftar', + 'data' => $insert + ], 201); + } + + public function update(Request $request) + { + + $current = Carbon::now(); + $kodcaw = $request->kodcaw; + Log::info($request->all()); + + // Cari connection cawangan + $cawangan = Cawangan::on('mysql7') + ->where('kodcaw', $kodcaw) + ->first(); + + if (!$cawangan) { + return response()->json([ + 'success' => false, + 'message' => 'Cawangan tidak dijumpai', + ], 404); + } + + // Update direct (ikut norujukan) + $palsu = palsu::on($cawangan['mysql']) + ->where('norujukan', $request->norujukan) + ->update([ + 'kodcaw' => $request->kodcaw, + 'tarikh' => $request->tarikh, + 'teller' => $request->teller, + 'nota' => $request->nota ?? '', + 'pembiayaan' => $request->pinjaman, + 'nilaimarhun' => $request->nilaimarhun, + 'jbg' => $request->jbg, + 'untung' => $request->tunggakan, + 'untungonepercent' => $request->tunggakanonepercent, + 'untungcajlain' => $request->tunggakanujrah, + ]); + + return response()->json([ + 'success' => $palsu ? true : false, + 'message' => $palsu ? 'Rekod gadai berjaya dikemaskini' : 'Rekod tidak dijumpai', + ], 200); + } } \ No newline at end of file diff --git a/app/Http/Controllers/CustomerController.php b/app/Http/Controllers/CustomerController.php index 6080cac..c19232b 100644 --- a/app/Http/Controllers/CustomerController.php +++ b/app/Http/Controllers/CustomerController.php @@ -14,6 +14,7 @@ use App\Blacklist; use App\AuditCustomer; use Illuminate\Http\Request; use App\TuntutBaki; +use Illuminate\Support\Facades\Auth; use Carbon\Carbon; use Illuminate\Support\Facades\Log; @@ -904,6 +905,69 @@ class CustomerController extends Controller return response()->json($customer); } +public function AdminsearchCustomerBySAG(Request $request) +{ + // Ambil kodcaw dari user login + $kodcaw = $request->kodcaw; + // $norujukan = $request->input('norujukan'); + + // Cari connection untuk cawangan + $cawangan = Cawangan::on('mysql7')->where('kodcaw', $kodcaw)->first(); + if (!$cawangan) { + return response()->json([], 404); + } + + $gadai = optional(Gadai::on($cawangan['mysql'])->where('norujukan',$request->norujukan)->first())->toArray() ?? []; + + if(!empty($gadai)){ + $customer = optional(Customer::on('mysql7')->where(function ($query) use ($gadai) { + $query->where('kpbaru',$gadai['nokp']) + ->orWhere('kplama',$gadai['nokp']); + })->first())->toArray() ?? []; + }else{ + return response()->json(['success' => false,'message' => 'norujukan tidak dijumpainya'], 404); + } + + // cara fifi ajar + $result = [[ + 'id' => $customer['id'], + 'kodcaw' => $gadai['kodcaw'], + 'norujukan' => $gadai['norujukan'], + 'teller' => $gadai['teller'], + 'nota' => $customer['nota'], + 'pinjaman' => $gadai['pinjaman'], + 'nilaimarhun' => $gadai['nilaimarhun'], + 'jbg' => $gadai['jbg'], + 'tunggakan' => $gadai['tunggakan'], + 'tunggakanonepercent' => $gadai['tunggakanonepercent'], + 'tunggakanujrah' => $gadai['tunggakanujrah'], + 'nama' => $customer['nama'], + 'kplama' => $customer['kplama'], + 'kpbaru' => $customer['kpbaru'], + ]]; + + // saya buat sendiri + // Join customer + gadai ikut nokp + // $result = DB::connection($cawangan['mysql']) + // ->table('gadai') + // ->join('online_arrahn.customer as c', function($join) { + // $join->on('gadai.nokp', '=', 'c.kpbaru') + // ->orOn('gadai.nokp', '=', 'c.kplama'); + // }) + // ->where('norujukan', $request->norujukan) + // ->select( + // 'id', + // 'gadai.kodcaw','gadai.norujukan','gadai.teller', + // 'c.nota','gadai.pinjaman','gadai.nilaimarhun','gadai.jbg', + // 'gadai.tunggakan','gadai.tunggakanonepercent','gadai.tunggakanujrah', + // 'c.nama','c.kpbaru','c.kplama' + // ) + // ->take(5) + // ->get(); + + return response()->json($result); +} + public function changepassword(Request $request, $kodcaw, $id) { $current = Carbon::now(); @@ -1003,20 +1067,4 @@ class CustomerController extends Controller return response()->json($results); } -// public function createNotaArcc($kodcaw, Request $request) -// { -// $current = Carbon::now(); - -// $customer = Customer::on('mysql7')->create([ -// 'kodcaw' => $kodcaw, -// 'tarikhdaftar' => $current->toDateString(), -// 'nota_arcc' => $request->nota_arcc, -// 'teller' => $request->teller, -// 'aktif' => 'A' -// ]); - -// return response()->json($customer, 201); -// } - - } diff --git a/app/Palsu.php b/app/Palsu.php index 06c5eaa..f9d2e90 100644 --- a/app/Palsu.php +++ b/app/Palsu.php @@ -21,6 +21,7 @@ class Palsu extends Model protected $fillable = [ 'recno', 'kodcaw', + 'tarikh', 'norujukan', 'teller', 'nota', diff --git a/routes/web.php b/routes/web.php index 98df23c..55de8c1 100644 --- a/routes/web.php +++ b/routes/web.php @@ -56,12 +56,13 @@ $router->group(['prefix'=>'api'], function () use ($router){ $router->put('customers/update/khazanah/{nokp}', ['uses' => 'CustomerController@customerUpdateKhazanah']); $router->get('customers/laporan/{kodcaw}/{tarikh}',['uses'=>'CustomerController@getLaporanCustomers']); $router->get('customers/latest/{kodcaw}',['uses'=>'CustomerController@getLatestCustomer']); - $router->put('customers/information/update/admin', ['uses' => 'CustomerController@customerUpdateAdmin']); + $router->put('customers/information/update/admin', ['uses' => 'CustomerController@customerUpdateAdmin']); //blh refer sini izazi $router->get('admin/customers/nokp/search',['uses'=>'CustomerController@showOneCustomerByICAdmin']); $router->get('customer/blacklist',['uses'=>'CustomerController@blacklistCustomer']); $router->get('customer/eachcawangan/{ic}',['uses'=>'CustomerController@showCustomerByEachCawangan']); //arcc $router->get('customer/searchbyname',['uses'=>'CustomerController@searchByName']); + $router->get('customer/searchbygadai/{kodcaw}/{norujukan}',['uses'=>'CustomerController@AdminsearchGadai']); // Route::get('/api/customers/searchbyname', [CustomerController::class, 'searchByName']); // $router->put('customers/update/{nokp}', ['uses' => 'CallCenterController@customerUpdate']); //kena tengok api ni // $router->put('customers/update/kaunter/{nokp}/{kodcaw}', ['uses' => 'CallCenterController@customerUpdateKaunter']); @@ -87,7 +88,7 @@ $router->group(['prefix'=>'api'], function () use ($router){ $router->get('gadai/cawangan/{kodcaw}/{tarikh}',['uses'=>'GadaiController@showOneGadaiByCawanganOnly']); $router->get('gadai/norujukan/{norujukan}',['uses'=>'GadaiController@showOneGadaiByNorujukan']); $router->get('gadai/norujukankodcaw/{kodcaw}/{norujukan}',['uses'=>'GadaiController@showOneGadaiByNorujukanKodcaw']); - $router->get('gadai/norujukan/{kodcaw}/{norujukan}',['uses'=>'GadaiController@showOneGadaibyRujukanAndCawangan']); + $router->get('gadai/norujukan/{kodcaw}/{norujukan}',['uses'=>'GadaiController@showOneGadaibyRujukanAndCawangan']); // refer sini utk pass gadai $router->post('gadai/{kodcaw}',['uses'=>'GadaiController@create']); $router->post('gadaiold/{kodcaw}',['uses'=>'GadaiController@createold']); $router->get('gadai/{cawangan_code}/{date}',['uses'=>'GadaiController@gadaiTransactionByCawanganAndDay']); @@ -460,8 +461,14 @@ $router->group(['prefix'=>'api'], function () use ($router){ //laporanlelong adminportal $router->get('laporan/lelong',['uses' => 'LelongController@LaporanLelong']); $router->get('lookupbatchlel/{kodcaw}',['uses' => 'LelongController@LookupBatchLel']); - + //barangkes $router->get('palsu/laporan', ['uses' => 'BarangkesController@LaporanBarangKes']); + $router->get('barangkes', ['uses' => 'BarangkesController@index']); // + $router->post('barangkes/store', ['uses' => 'BarangkesController@store']); + + // $router->post('/barangkes/{id}', ['uses' => 'BarangkesController@show']); + $router->put('barangkes/update/{recno}', ['uses' => 'BarangkesController@update']); + //update tagterima Tebus @@ -802,9 +809,11 @@ $router->group(['prefix'=>'admin'], function () use ($router){ $router->get('TuntutBakiTarikhTeller/{kodcaw}',['uses'=>'AdminPageController@showTuntutBakiTarikhTeller']); $router->get('lelong/tarikh/{kodcaw}',['uses'=>'AdminPageController@LelonganTarikh']); $router->post('updateTunaiGTByTarikh/{kodcaw}',['uses'=>'AdminPageController@UpdateTunaiByTarikh']); - $router->get('searchByName',['uses'=>'CustomerController@AdminsearchCustomerByName']); - $router->get('searchByIC',['uses'=>'CustomerController@AdminsearchCustomerByIC']); + $router->get('searchByIC',['uses'=>'CustomerController@AdminsearchCustomerByIC']); //refer ni jugak + + // sag + $router->get('searchBySag',['uses'=>'CustomerController@AdminsearchCustomerBySAG']); //refer ni jugak $router->get('pembiayaanTahunan',['uses'=>'AdminPageController@TahunanGadai']); $router->get('penebusanTahunan',['uses'=>'AdminPageController@TahunanTebus']); From 642d9f01bb1d1ccf75fb4e4892aa840744db3de8 Mon Sep 17 00:00:00 2001 From: hafifierahman Date: Wed, 1 Oct 2025 21:35:44 +0800 Subject: [PATCH 15/80] fix backdate stock audit that exceed 12 months --- app/Http/Controllers/BackupStokAuditController.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/BackupStokAuditController.php b/app/Http/Controllers/BackupStokAuditController.php index 191806e..fb56b2a 100644 --- a/app/Http/Controllers/BackupStokAuditController.php +++ b/app/Http/Controllers/BackupStokAuditController.php @@ -331,7 +331,7 @@ class BackupStokAuditController extends Controller } public function kiraupahTawarruqStokAudit($tempoh,$tempohbayar,$kadarupah,$bakipinjaman){ - + $tempoh = ($tempoh > 12) ? 12 : $tempoh; $bilang_bln = $tempoh - $tempohbayar; if($bilang_bln > 12){ @@ -458,6 +458,7 @@ class BackupStokAuditController extends Controller public function kiraupahTawarruqStokAuditUjrahOnePercent($tempoh,$tempohbayar,$kadarupah,$bakipinjaman,$nilaimarhun,$margin_semasa){ $onepercentservices = new V2Calculation(); $upah = $onepercentservices->kiraanKeuntunganRebet($bakipinjaman,$nilaimarhun,$kadarupah,$margin_semasa); + $tempoh = ($tempoh > 12) ? 12 : $tempoh; $bilang_bln = $tempoh - $tempohbayar; $keuntungan_semasa = $bilang_bln * $upah['onepercent']; $ujrah_semasa = $bilang_bln * $upah['ujrah']; From e320ac8219715295e5458913812a35efc13b2824 Mon Sep 17 00:00:00 2001 From: hafifierahman Date: Sat, 4 Oct 2025 21:24:50 +0800 Subject: [PATCH 16/80] added customer info lelong for arrahnpay --- .../TransactionOnlineController.php | 48 +++++++++++++++++-- routes/web.php | 1 + 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/TransactionOnlineController.php b/app/Http/Controllers/TransactionOnlineController.php index 92b6e6a..dc93906 100644 --- a/app/Http/Controllers/TransactionOnlineController.php +++ b/app/Http/Controllers/TransactionOnlineController.php @@ -8,6 +8,7 @@ use App\Cawangan; use App\Gadai; use App\GlDetail; use App\Http\Controllers\TebusController as TebusController; +use App\Lelong; use App\Services\Loggers\OnlineTransactionLoggerService; use App\Services\OnePercentServices; use App\Support\v2\Calculation; @@ -767,8 +768,49 @@ class TransactionOnlineController extends Controller return 'rejected'; } } - - - + public function CustomerInfoLelong(Request $request){ + $cawangan_all = Cawangan::on('mysql7')->get(); + $totalBakiLelong = 0; + $totalRugiLelong = 0; + + foreach ($cawangan_all as $index => $cawangan) { + $gadai = Gadai::on($cawangan['mysql']) + ->where([['sttebus', '=', ''], ['nokp', '=', $request->ic]]) + ->orderBy('t_gadai', 'desc') + ->get()->toArray(); + + if (sizeof($gadai) != 0) { + foreach ($gadai as $gad) { + $bakilelong = Lelong::on($cawangan['mysql']) + ->where(function($query) { + $query->whereNull('trkhtuntut') + ->orWhere('trkhtuntut', '=', ''); + }) + ->where('baki', '>=', 0) + ->sum('baki'); + + $rugilelong = Lelong::on($cawangan['mysql']) + ->where(function($query) { + $query->whereNull('trkhtuntut') + ->orWhere('trkhtuntut', '=', ''); + }) + ->where('baki','<',0) + ->sum('baki'); + } + + $totalBakiLelong += $bakilelong; + $totalRugiLelong += $rugilelong; + } + } + + return response()->json([ + 'success' => true, + 'message' => 'Data retrieved successfully', + 'data' => [ + 'bakilelong' => $totalBakiLelong, + 'rugilelong' => $totalRugiLelong, + ] + ], 200); + } } diff --git a/routes/web.php b/routes/web.php index 0a028b5..2b27708 100644 --- a/routes/web.php +++ b/routes/web.php @@ -794,6 +794,7 @@ $router->group(['prefix'=>'portal'], function () use ($router){ $router->get('transaksipelanggan/upah',['uses'=>'TransactionController@TransaksiUpah']); $router->get('searchsagonline',['uses'=>'TransactionOnlineController@searchSAGOnline']); $router->get('customer/info',['uses'=>'TransactionOnlineController@CustomerInfo']); + $router->get('customer/info/lelong',['uses'=>'TransactionOnlineController@CustomerInfoLelong']); }); $router->group(['prefix'=>'admin'], function () use ($router){ From 83228e8b2ed3148ce05aac786f11c118a2ff1cad Mon Sep 17 00:00:00 2001 From: Nur Izzati Date: Sun, 5 Oct 2025 09:18:47 +0800 Subject: [PATCH 17/80] tambah t_lelong dlm gadai --- app/Http/Controllers/GadaiController.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/GadaiController.php b/app/Http/Controllers/GadaiController.php index 81bc8e9..71f3863 100644 --- a/app/Http/Controllers/GadaiController.php +++ b/app/Http/Controllers/GadaiController.php @@ -3871,11 +3871,13 @@ class GadaiController extends Controller public function updateTagLelong(Request $request){ $norujukan = $request->norujukan; $kodcaw = $request->kodcaw; + $t_lelong = $request->t_lelong; $cawangan = Cawangan::on('mysql7')->where('kodcaw',$request->kodcaw)->first(); $updateTag = Gadai::on($cawangan->mysql)->where('norujukan',$norujukan)->update([ - 'taglel'=>1 + 'taglel'=>1, + 't_lelong' => $t_lelong, ]); return response()->json('success'); @@ -3888,7 +3890,8 @@ class GadaiController extends Controller $cawangan = Cawangan::on('mysql7')->where('kodcaw',$request->kodcaw)->first(); $updateTag = Gadai::on($cawangan->mysql)->where('norujukan',$norujukan)->update([ - 'taglel'=>0 + 'taglel'=>0, + 't_lelong' => null, ]); return response()->json('success'); From 9c5b0414979df3a1ad2f61d4d2fa7bc2efb3ac40 Mon Sep 17 00:00:00 2001 From: Hafifie PKB Date: Sun, 5 Oct 2025 09:59:37 +0800 Subject: [PATCH 18/80] fix specific norujukan --- app/Http/Controllers/TransactionOnlineController.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/TransactionOnlineController.php b/app/Http/Controllers/TransactionOnlineController.php index dc93906..ebaade7 100644 --- a/app/Http/Controllers/TransactionOnlineController.php +++ b/app/Http/Controllers/TransactionOnlineController.php @@ -776,7 +776,7 @@ class TransactionOnlineController extends Controller foreach ($cawangan_all as $index => $cawangan) { $gadai = Gadai::on($cawangan['mysql']) - ->where([['sttebus', '=', ''], ['nokp', '=', $request->ic]]) + ->where('nokp', '=', $request->ic) ->orderBy('t_gadai', 'desc') ->get()->toArray(); @@ -787,6 +787,7 @@ class TransactionOnlineController extends Controller $query->whereNull('trkhtuntut') ->orWhere('trkhtuntut', '=', ''); }) + ->where('norujukan', '=' ,$gad['norujukan']) ->where('baki', '>=', 0) ->sum('baki'); @@ -795,6 +796,7 @@ class TransactionOnlineController extends Controller $query->whereNull('trkhtuntut') ->orWhere('trkhtuntut', '=', ''); }) + ->where('norujukan', '=' ,$gad['norujukan']) ->where('baki','<',0) ->sum('baki'); } From 13a15c354f977edaab35ccfd1e6cecceb9d9bb2a Mon Sep 17 00:00:00 2001 From: Ain Izazi Date: Sun, 5 Oct 2025 11:43:15 +0800 Subject: [PATCH 19/80] function barangkes di adminv2 --- app/Http/Controllers/BarangkesController.php | 77 ++++++++++++++++++- app/Http/Controllers/CustomerController.php | 80 ++++++++++++++++---- app/Palsu.php | 1 + routes/web.php | 19 +++-- 4 files changed, 155 insertions(+), 22 deletions(-) diff --git a/app/Http/Controllers/BarangkesController.php b/app/Http/Controllers/BarangkesController.php index ae0f29a..4008d14 100644 --- a/app/Http/Controllers/BarangkesController.php +++ b/app/Http/Controllers/BarangkesController.php @@ -8,11 +8,13 @@ use App\Cawangan; use App\LookupAlasan; use App\Pampasan; use App\Palsu; +use App\Gadai; use Illuminate\Http\Request; use Carbon\Carbon; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Http; +use Illuminate\Support\Facades\Log; class BarangkesController extends Controller { @@ -89,4 +91,77 @@ class BarangkesController extends Controller return response()->json($filteredResults); } -} + + public function store(Request $request) //cara fifi ajar + { + + $current = Carbon::now(); + $kodcaw = $request->kodcaw; + $cawangan = Cawangan::on('mysql7') + ->where('kodcaw', $kodcaw) + ->first(); + + $insert = Palsu::on($cawangan['mysql'])->create([ + 'kodcaw' => $request->kodcaw, + 'tarikh' => $current->toDateString(), + 'norujukan' => $request->norujukan, + 'teller' => $request->teller, + 'nota' => $request->nota ? $request->nota : '', + 'pembiayaan' => $request->pinjaman, + 'nilaimarhun' => $request->nilaimarhun, + 'jbg' => $request->jbg, + 'untung' => $request->tunggakan, + 'untungonepercent' => $request->tunggakanonepercent, + 'untungcajlain' => $request->tunggakanujrah, + ]); + + // return $insert; + + return response()->json([ + 'success' => true, + 'message' => 'Barang kes berjaya didaftar', + 'data' => $insert + ], 201); + } + + public function update(Request $request) + { + + $current = Carbon::now(); + $kodcaw = $request->kodcaw; + Log::info($request->all()); + + // Cari connection cawangan + $cawangan = Cawangan::on('mysql7') + ->where('kodcaw', $kodcaw) + ->first(); + + if (!$cawangan) { + return response()->json([ + 'success' => false, + 'message' => 'Cawangan tidak dijumpai', + ], 404); + } + + // Update direct (ikut norujukan) + $palsu = palsu::on($cawangan['mysql']) + ->where('norujukan', $request->norujukan) + ->update([ + 'kodcaw' => $request->kodcaw, + 'tarikh' => $request->tarikh, + 'teller' => $request->teller, + 'nota' => $request->nota ?? '', + 'pembiayaan' => $request->pinjaman, + 'nilaimarhun' => $request->nilaimarhun, + 'jbg' => $request->jbg, + 'untung' => $request->tunggakan, + 'untungonepercent' => $request->tunggakanonepercent, + 'untungcajlain' => $request->tunggakanujrah, + ]); + + return response()->json([ + 'success' => $palsu ? true : false, + 'message' => $palsu ? 'Rekod gadai berjaya dikemaskini' : 'Rekod tidak dijumpai', + ], 200); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/CustomerController.php b/app/Http/Controllers/CustomerController.php index 6080cac..c19232b 100644 --- a/app/Http/Controllers/CustomerController.php +++ b/app/Http/Controllers/CustomerController.php @@ -14,6 +14,7 @@ use App\Blacklist; use App\AuditCustomer; use Illuminate\Http\Request; use App\TuntutBaki; +use Illuminate\Support\Facades\Auth; use Carbon\Carbon; use Illuminate\Support\Facades\Log; @@ -904,6 +905,69 @@ class CustomerController extends Controller return response()->json($customer); } +public function AdminsearchCustomerBySAG(Request $request) +{ + // Ambil kodcaw dari user login + $kodcaw = $request->kodcaw; + // $norujukan = $request->input('norujukan'); + + // Cari connection untuk cawangan + $cawangan = Cawangan::on('mysql7')->where('kodcaw', $kodcaw)->first(); + if (!$cawangan) { + return response()->json([], 404); + } + + $gadai = optional(Gadai::on($cawangan['mysql'])->where('norujukan',$request->norujukan)->first())->toArray() ?? []; + + if(!empty($gadai)){ + $customer = optional(Customer::on('mysql7')->where(function ($query) use ($gadai) { + $query->where('kpbaru',$gadai['nokp']) + ->orWhere('kplama',$gadai['nokp']); + })->first())->toArray() ?? []; + }else{ + return response()->json(['success' => false,'message' => 'norujukan tidak dijumpainya'], 404); + } + + // cara fifi ajar + $result = [[ + 'id' => $customer['id'], + 'kodcaw' => $gadai['kodcaw'], + 'norujukan' => $gadai['norujukan'], + 'teller' => $gadai['teller'], + 'nota' => $customer['nota'], + 'pinjaman' => $gadai['pinjaman'], + 'nilaimarhun' => $gadai['nilaimarhun'], + 'jbg' => $gadai['jbg'], + 'tunggakan' => $gadai['tunggakan'], + 'tunggakanonepercent' => $gadai['tunggakanonepercent'], + 'tunggakanujrah' => $gadai['tunggakanujrah'], + 'nama' => $customer['nama'], + 'kplama' => $customer['kplama'], + 'kpbaru' => $customer['kpbaru'], + ]]; + + // saya buat sendiri + // Join customer + gadai ikut nokp + // $result = DB::connection($cawangan['mysql']) + // ->table('gadai') + // ->join('online_arrahn.customer as c', function($join) { + // $join->on('gadai.nokp', '=', 'c.kpbaru') + // ->orOn('gadai.nokp', '=', 'c.kplama'); + // }) + // ->where('norujukan', $request->norujukan) + // ->select( + // 'id', + // 'gadai.kodcaw','gadai.norujukan','gadai.teller', + // 'c.nota','gadai.pinjaman','gadai.nilaimarhun','gadai.jbg', + // 'gadai.tunggakan','gadai.tunggakanonepercent','gadai.tunggakanujrah', + // 'c.nama','c.kpbaru','c.kplama' + // ) + // ->take(5) + // ->get(); + + return response()->json($result); +} + public function changepassword(Request $request, $kodcaw, $id) { $current = Carbon::now(); @@ -1003,20 +1067,4 @@ class CustomerController extends Controller return response()->json($results); } -// public function createNotaArcc($kodcaw, Request $request) -// { -// $current = Carbon::now(); - -// $customer = Customer::on('mysql7')->create([ -// 'kodcaw' => $kodcaw, -// 'tarikhdaftar' => $current->toDateString(), -// 'nota_arcc' => $request->nota_arcc, -// 'teller' => $request->teller, -// 'aktif' => 'A' -// ]); - -// return response()->json($customer, 201); -// } - - } diff --git a/app/Palsu.php b/app/Palsu.php index e03ff42..00ce962 100644 --- a/app/Palsu.php +++ b/app/Palsu.php @@ -22,6 +22,7 @@ class Palsu extends Model protected $fillable = [ 'recno', 'kodcaw', + 'tarikh', 'norujukan', 'teller', 'nota', diff --git a/routes/web.php b/routes/web.php index 2b27708..0f81536 100644 --- a/routes/web.php +++ b/routes/web.php @@ -56,12 +56,13 @@ $router->group(['prefix'=>'api'], function () use ($router){ $router->put('customers/update/khazanah/{nokp}', ['uses' => 'CustomerController@customerUpdateKhazanah']); $router->get('customers/laporan/{kodcaw}/{tarikh}',['uses'=>'CustomerController@getLaporanCustomers']); $router->get('customers/latest/{kodcaw}',['uses'=>'CustomerController@getLatestCustomer']); - $router->put('customers/information/update/admin', ['uses' => 'CustomerController@customerUpdateAdmin']); + $router->put('customers/information/update/admin', ['uses' => 'CustomerController@customerUpdateAdmin']); //blh refer sini izazi $router->get('admin/customers/nokp/search',['uses'=>'CustomerController@showOneCustomerByICAdmin']); $router->get('customer/blacklist',['uses'=>'CustomerController@blacklistCustomer']); $router->get('customer/eachcawangan/{ic}',['uses'=>'CustomerController@showCustomerByEachCawangan']); //arcc $router->get('customer/searchbyname',['uses'=>'CustomerController@searchByName']); + $router->get('customer/searchbygadai/{kodcaw}/{norujukan}',['uses'=>'CustomerController@AdminsearchGadai']); // Route::get('/api/customers/searchbyname', [CustomerController::class, 'searchByName']); // $router->put('customers/update/{nokp}', ['uses' => 'CallCenterController@customerUpdate']); //kena tengok api ni // $router->put('customers/update/kaunter/{nokp}/{kodcaw}', ['uses' => 'CallCenterController@customerUpdateKaunter']); @@ -87,7 +88,7 @@ $router->group(['prefix'=>'api'], function () use ($router){ $router->get('gadai/cawangan/{kodcaw}/{tarikh}',['uses'=>'GadaiController@showOneGadaiByCawanganOnly']); $router->get('gadai/norujukan/{norujukan}',['uses'=>'GadaiController@showOneGadaiByNorujukan']); $router->get('gadai/norujukankodcaw/{kodcaw}/{norujukan}',['uses'=>'GadaiController@showOneGadaiByNorujukanKodcaw']); - $router->get('gadai/norujukan/{kodcaw}/{norujukan}',['uses'=>'GadaiController@showOneGadaibyRujukanAndCawangan']); + $router->get('gadai/norujukan/{kodcaw}/{norujukan}',['uses'=>'GadaiController@showOneGadaibyRujukanAndCawangan']); // refer sini utk pass gadai $router->post('gadai/{kodcaw}',['uses'=>'GadaiController@create']); $router->post('gadaiold/{kodcaw}',['uses'=>'GadaiController@createold']); $router->get('gadai/{cawangan_code}/{date}',['uses'=>'GadaiController@gadaiTransactionByCawanganAndDay']); @@ -466,8 +467,14 @@ $router->group(['prefix'=>'api'], function () use ($router){ //laporanlelong adminportal $router->get('laporan/lelong',['uses' => 'LelongController@LaporanLelong']); $router->get('lookupbatchlel/{kodcaw}',['uses' => 'LelongController@LookupBatchLel']); - + //barangkes $router->get('palsu/laporan', ['uses' => 'BarangkesController@LaporanBarangKes']); + $router->get('barangkes', ['uses' => 'BarangkesController@index']); // + $router->post('barangkes/store', ['uses' => 'BarangkesController@store']); + + // $router->post('/barangkes/{id}', ['uses' => 'BarangkesController@show']); + $router->put('barangkes/update/{recno}', ['uses' => 'BarangkesController@update']); + //update tagterima Tebus @@ -808,9 +815,11 @@ $router->group(['prefix'=>'admin'], function () use ($router){ $router->get('TuntutBakiTarikhTeller/{kodcaw}',['uses'=>'AdminPageController@showTuntutBakiTarikhTeller']); $router->get('lelong/tarikh/{kodcaw}',['uses'=>'AdminPageController@LelonganTarikh']); $router->post('updateTunaiGTByTarikh/{kodcaw}',['uses'=>'AdminPageController@UpdateTunaiByTarikh']); - $router->get('searchByName',['uses'=>'CustomerController@AdminsearchCustomerByName']); - $router->get('searchByIC',['uses'=>'CustomerController@AdminsearchCustomerByIC']); + $router->get('searchByIC',['uses'=>'CustomerController@AdminsearchCustomerByIC']); //refer ni jugak + + // sag + $router->get('searchBySag',['uses'=>'CustomerController@AdminsearchCustomerBySAG']); //refer ni jugak $router->get('pembiayaanTahunan',['uses'=>'AdminPageController@TahunanGadai']); $router->get('penebusanTahunan',['uses'=>'AdminPageController@TahunanTebus']); From 0a290029a5eb7f6a47bd18eb2f844148c274097d Mon Sep 17 00:00:00 2001 From: aiman Date: Sun, 14 Sep 2025 16:03:49 +0800 Subject: [PATCH 20/80] Tukar step pampasan v3 ke v2: --- app/Http/Controllers/BarangkesController.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/Http/Controllers/BarangkesController.php b/app/Http/Controllers/BarangkesController.php index 4008d14..603efb4 100644 --- a/app/Http/Controllers/BarangkesController.php +++ b/app/Http/Controllers/BarangkesController.php @@ -94,11 +94,11 @@ class BarangkesController extends Controller public function store(Request $request) //cara fifi ajar { - + $current = Carbon::now(); $kodcaw = $request->kodcaw; $cawangan = Cawangan::on('mysql7') - ->where('kodcaw', $kodcaw) + ->where('kodcaw', $kodcaw) ->first(); $insert = Palsu::on($cawangan['mysql'])->create([ @@ -114,7 +114,7 @@ class BarangkesController extends Controller 'untungonepercent' => $request->tunggakanonepercent, 'untungcajlain' => $request->tunggakanujrah, ]); - + // return $insert; return response()->json([ @@ -126,7 +126,7 @@ class BarangkesController extends Controller public function update(Request $request) { - + $current = Carbon::now(); $kodcaw = $request->kodcaw; Log::info($request->all()); @@ -164,4 +164,4 @@ class BarangkesController extends Controller 'message' => $palsu ? 'Rekod gadai berjaya dikemaskini' : 'Rekod tidak dijumpai', ], 200); } -} \ No newline at end of file +} From 6d80afed8f441cc824a6a9c4220591cdd4f953b1 Mon Sep 17 00:00:00 2001 From: Afiq Hamzah Date: Wed, 17 Sep 2025 12:38:51 +0800 Subject: [PATCH 21/80] Continue dev on pampasan module --- app/Http/Controllers/BarangkesController.php | 2 +- app/Http/Controllers/PampasanController.php | 5 + app/Palsu.php | 7 + ...092001_add_jenis_column_to_palsu_table.php | 68 +++++++++ ...jenis_to_pampasan_for_semporna_records.php | 78 +++++++++++ ...on_semporna_records_jenis_to_hapuskira.php | 130 ++++++++++++++++++ 6 files changed, 289 insertions(+), 1 deletion(-) create mode 100644 database/migrations/2025_09_17_092001_add_jenis_column_to_palsu_table.php create mode 100644 database/migrations/2025_09_17_093116_update_jenis_to_pampasan_for_semporna_records.php create mode 100644 database/migrations/2025_09_17_093117_update_non_semporna_records_jenis_to_hapuskira.php diff --git a/app/Http/Controllers/BarangkesController.php b/app/Http/Controllers/BarangkesController.php index 603efb4..fed34b7 100644 --- a/app/Http/Controllers/BarangkesController.php +++ b/app/Http/Controllers/BarangkesController.php @@ -6,9 +6,9 @@ use App\Audit; use App\Polis; use App\Cawangan; use App\LookupAlasan; +use App\Gadai; use App\Pampasan; use App\Palsu; -use App\Gadai; use Illuminate\Http\Request; use Carbon\Carbon; diff --git a/app/Http/Controllers/PampasanController.php b/app/Http/Controllers/PampasanController.php index cdbeb86..1972c2a 100644 --- a/app/Http/Controllers/PampasanController.php +++ b/app/Http/Controllers/PampasanController.php @@ -70,6 +70,11 @@ class PampasanController extends Controller Palsu::on($cawangan['mysql']) ->where('norujukan', $norujukan) ->update(['status' => 1]); +<<<<<<< HEAD +======= + + // dd($pampasan); +>>>>>>> 83d619ac (Continue dev on pampasan module) return $this->successResponse('Status Pampasan berjaya dituntut.', $pampasan, 201); } diff --git a/app/Palsu.php b/app/Palsu.php index 00ce962..7defa11 100644 --- a/app/Palsu.php +++ b/app/Palsu.php @@ -32,6 +32,10 @@ class Palsu extends Model 'untungonepercent', 'untungcajlain', 'pembiayaan', +<<<<<<< HEAD +======= + 'jenis', +>>>>>>> 83d619ac (Continue dev on pampasan module) 'status', ]; @@ -95,9 +99,12 @@ class Palsu extends Model { return $this->hasOne(Tebus::class, 'norujukan', 'norujukan'); } +<<<<<<< HEAD public function gadai(): HasOne { return $this->hasOne(Gadai::class, 'norujukan', 'norujukan'); } +======= +>>>>>>> 83d619ac (Continue dev on pampasan module) } diff --git a/database/migrations/2025_09_17_092001_add_jenis_column_to_palsu_table.php b/database/migrations/2025_09_17_092001_add_jenis_column_to_palsu_table.php new file mode 100644 index 0000000..a9de2a2 --- /dev/null +++ b/database/migrations/2025_09_17_092001_add_jenis_column_to_palsu_table.php @@ -0,0 +1,68 @@ +select('SELECT 1'); + return true; + } catch (\Exception $e) { + return false; + } + }); + + return $db_connection ? array_values($db_connection) : []; + } + + /** + * Run the migrations. + * + * @return void + */ + public function up() + { + $db_connection = $this->getActiveDB(); + + foreach ($db_connection as $dbase) { + Schema::connection($dbase)->table('palsu', function (Blueprint $table) use ($dbase) { + if (!Schema::connection($dbase)->hasColumn('palsu', 'jenis')) { + $table->string('jenis', 50)->nullable()->comment('Jenis/Type classification'); + } + }); + } + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + $db_connection = $this->getActiveDB(); + + foreach ($db_connection as $dbase) { + Schema::connection($dbase)->table('palsu', function (Blueprint $table) use ($dbase) { + if (Schema::connection($dbase)->hasColumn('palsu', 'jenis')) { + $table->dropColumn('jenis'); + } + }); + } + } +} diff --git a/database/migrations/2025_09_17_093116_update_jenis_to_pampasan_for_semporna_records.php b/database/migrations/2025_09_17_093116_update_jenis_to_pampasan_for_semporna_records.php new file mode 100644 index 0000000..424a87b --- /dev/null +++ b/database/migrations/2025_09_17_093116_update_jenis_to_pampasan_for_semporna_records.php @@ -0,0 +1,78 @@ +getSempornaRecords(); + + // Update jenis to 'pampasan' for Semporna records in mysql34 (Semporna branch) + try { + $updated = DB::connection('mysql34')->table('palsu') + ->whereIn('norujukan', $semporna_records) + ->update(['jenis' => 'pampasan']); + + echo "Updated {$updated} Semporna records with jenis = 'pampasan'\n"; + } catch (\Exception $e) { + echo "Error updating Semporna records: " . $e->getMessage() . "\n"; + } + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + $semporna_records = $this->getSempornaRecords(); + + // Revert jenis to null for Semporna records + try { + $reverted = DB::connection('mysql34')->table('palsu') + ->whereIn('norujukan', $semporna_records) + ->update(['jenis' => null]); + + echo "Reverted {$reverted} Semporna records jenis to null\n"; + } catch (\Exception $e) { + echo "Error reverting Semporna records: " . $e->getMessage() . "\n"; + } + } +} diff --git a/database/migrations/2025_09_17_093117_update_non_semporna_records_jenis_to_hapuskira.php b/database/migrations/2025_09_17_093117_update_non_semporna_records_jenis_to_hapuskira.php new file mode 100644 index 0000000..44594a3 --- /dev/null +++ b/database/migrations/2025_09_17_093117_update_non_semporna_records_jenis_to_hapuskira.php @@ -0,0 +1,130 @@ +select('SELECT 1'); + return true; + } catch (\Exception $e) { + return false; + } + }); + + return $db_connection ? array_values($db_connection) : []; + } + + /** + * Semporna norujukan records to exclude + */ + private function getSempornaRecords(): array + { + return [ + '011237240808-0003', + '011237240719-0015', + '011237240806-0011', + '011237240828-0001', + '011237240904-0007', + '011237240904-0008', + '011237240904-0009', + '011237240719-0023', + '011237240719-0024', + '011237240719-0025', + '011237240618-0026', + '011237240719-0027', + '011237240719-0028', + '011237240618-0020', + '011237240719-0030', + '011237240618-0029', + '011237240731-0026', + '011237240912-0009' + ]; + } + + /** + * Run the migrations. + * + * @return void + */ + public function up() + { + $db_connection = $this->getActiveDB(); + $semporna_records = $this->getSempornaRecords(); + + foreach ($db_connection as $dbase) { + try { + if ($dbase == 'mysql34') { + // For Semporna (mysql34), update only non-Semporna records to 'hapuskira' + $updated = DB::connection($dbase)->table('palsu') + ->whereNotIn('norujukan', $semporna_records) + ->update(['jenis' => 'hapuskira']); + + if ($updated > 0) { + echo "Updated {$updated} non-Semporna records in {$dbase} to jenis = 'hapuskira'\n"; + } + } else { + // For all other databases, update all records to 'hapuskira' + $updated = DB::connection($dbase)->table('palsu') + ->update(['jenis' => 'hapuskira']); + + if ($updated > 0) { + echo "Updated {$updated} records in {$dbase} to jenis = 'hapuskira'\n"; + } + } + } catch (\Exception $e) { + echo "Error updating {$dbase}: " . $e->getMessage() . "\n"; + } + } + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + $db_connection = $this->getActiveDB(); + + foreach ($db_connection as $dbase) { + try { + // Revert all jenis values to null except Semporna records which should remain 'pampasan' + if ($dbase == 'mysql34') { + $semporna_records = $this->getSempornaRecords(); + $reverted = DB::connection($dbase)->table('palsu') + ->whereNotIn('norujukan', $semporna_records) + ->update(['jenis' => null]); + + if ($reverted > 0) { + echo "Reverted {$reverted} non-Semporna records in {$dbase} jenis to null\n"; + } + } else { + $reverted = DB::connection($dbase)->table('palsu') + ->update(['jenis' => null]); + + if ($reverted > 0) { + echo "Reverted {$reverted} records in {$dbase} jenis to null\n"; + } + } + } catch (\Exception $e) { + echo "Error reverting {$dbase}: " . $e->getMessage() . "\n"; + } + } + } +} From c80a6764294308299e24255a6f441e5fd077352a Mon Sep 17 00:00:00 2001 From: Afiq Hamzah Date: Sun, 5 Oct 2025 16:29:00 +0800 Subject: [PATCH 22/80] Resolve remaining merge conflicts --- app/Http/Controllers/PampasanController.php | 5 ----- app/Palsu.php | 7 ------- 2 files changed, 12 deletions(-) diff --git a/app/Http/Controllers/PampasanController.php b/app/Http/Controllers/PampasanController.php index 1972c2a..cdbeb86 100644 --- a/app/Http/Controllers/PampasanController.php +++ b/app/Http/Controllers/PampasanController.php @@ -70,11 +70,6 @@ class PampasanController extends Controller Palsu::on($cawangan['mysql']) ->where('norujukan', $norujukan) ->update(['status' => 1]); -<<<<<<< HEAD -======= - - // dd($pampasan); ->>>>>>> 83d619ac (Continue dev on pampasan module) return $this->successResponse('Status Pampasan berjaya dituntut.', $pampasan, 201); } diff --git a/app/Palsu.php b/app/Palsu.php index 7defa11..00ce962 100644 --- a/app/Palsu.php +++ b/app/Palsu.php @@ -32,10 +32,6 @@ class Palsu extends Model 'untungonepercent', 'untungcajlain', 'pembiayaan', -<<<<<<< HEAD -======= - 'jenis', ->>>>>>> 83d619ac (Continue dev on pampasan module) 'status', ]; @@ -99,12 +95,9 @@ class Palsu extends Model { return $this->hasOne(Tebus::class, 'norujukan', 'norujukan'); } -<<<<<<< HEAD public function gadai(): HasOne { return $this->hasOne(Gadai::class, 'norujukan', 'norujukan'); } -======= ->>>>>>> 83d619ac (Continue dev on pampasan module) } From bfb3af49c8cdbca5024f910747cdc236e8366318 Mon Sep 17 00:00:00 2001 From: Afiq Hamzah Date: Sun, 5 Oct 2025 16:48:39 +0800 Subject: [PATCH 23/80] Remove duplicated methods --- app/Http/Controllers/BarangkesController.php | 73 -------------------- 1 file changed, 73 deletions(-) diff --git a/app/Http/Controllers/BarangkesController.php b/app/Http/Controllers/BarangkesController.php index 564119c..ab1b620 100644 --- a/app/Http/Controllers/BarangkesController.php +++ b/app/Http/Controllers/BarangkesController.php @@ -164,77 +164,4 @@ class BarangkesController extends Controller 'message' => $palsu ? 'Rekod gadai berjaya dikemaskini' : 'Rekod tidak dijumpai', ], 200); } - - public function store(Request $request) //cara fifi ajar - { - - $current = Carbon::now(); - $kodcaw = $request->kodcaw; - $cawangan = Cawangan::on('mysql7') - ->where('kodcaw', $kodcaw) - ->first(); - - $insert = Palsu::on($cawangan['mysql'])->create([ - 'kodcaw' => $request->kodcaw, - 'tarikh' => $current->toDateString(), - 'norujukan' => $request->norujukan, - 'teller' => $request->teller, - 'nota' => $request->nota ? $request->nota : '', - 'pembiayaan' => $request->pinjaman, - 'nilaimarhun' => $request->nilaimarhun, - 'jbg' => $request->jbg, - 'untung' => $request->tunggakan, - 'untungonepercent' => $request->tunggakanonepercent, - 'untungcajlain' => $request->tunggakanujrah, - ]); - - // return $insert; - - return response()->json([ - 'success' => true, - 'message' => 'Barang kes berjaya didaftar', - 'data' => $insert - ], 201); - } - - public function update(Request $request) - { - - $current = Carbon::now(); - $kodcaw = $request->kodcaw; - Log::info($request->all()); - - // Cari connection cawangan - $cawangan = Cawangan::on('mysql7') - ->where('kodcaw', $kodcaw) - ->first(); - - if (!$cawangan) { - return response()->json([ - 'success' => false, - 'message' => 'Cawangan tidak dijumpai', - ], 404); - } - - // Update direct (ikut norujukan) - $palsu = palsu::on($cawangan['mysql']) - ->where('norujukan', $request->norujukan) - ->update([ - 'kodcaw' => $request->kodcaw, - 'tarikh' => $request->tarikh, - 'teller' => $request->teller, - 'nota' => $request->nota ?? '', - 'pembiayaan' => $request->pinjaman, - 'nilaimarhun' => $request->nilaimarhun, - 'jbg' => $request->jbg, - 'untung' => $request->tunggakan, - 'untungonepercent' => $request->tunggakanonepercent, - 'untungcajlain' => $request->tunggakanujrah, - ]); - - return response()->json([ - 'success' => $palsu ? true : false, - 'message' => $palsu ? 'Rekod gadai berjaya dikemaskini' : 'Rekod tidak dijumpai', - ], 200); - } } From a8b63af59faf39040c6e4a9e2734e5bc4ceed79c Mon Sep 17 00:00:00 2001 From: Nur Izzati Date: Tue, 7 Oct 2025 15:47:29 +0800 Subject: [PATCH 24/80] update export lelong to api --- app/Http/Controllers/LelongController.php | 309 ++++++++++++++-------- 1 file changed, 193 insertions(+), 116 deletions(-) diff --git a/app/Http/Controllers/LelongController.php b/app/Http/Controllers/LelongController.php index 909391c..ce7709e 100644 --- a/app/Http/Controllers/LelongController.php +++ b/app/Http/Controllers/LelongController.php @@ -1069,44 +1069,79 @@ class LelongController extends Controller public function exportLelong(Request $request) { - $currentDate = Carbon::now(); - $currentDate = $currentDate->toDateString(); + $currentDate = Carbon::now()->toDateString(); - $cawangan = Cawangan::on('mysql7')->where('kodcaw', $request->kodcaw)->first(); + // --- Step 0: Dapatkan Cawangan --- + $cawangan = Cawangan::on('mysql7') + ->where('kodcaw', $request->kodcaw) + ->first(); - $batchlel = BatchLel::on($cawangan['mysql']) - ->select('batchno') - ->orderBy('batchno', 'desc') - ->first(); + if (!$cawangan) { + Log::error("Export Lelong gagal: cawangan tidak ditemui", ['kodcaw' => $request->kodcaw]); + return response()->json(['error' => 'Cawangan tidak ditemui'], 404); + } - $newBatchNo = $batchlel->batchno + 1; - - $newBatchLel = BatchLel::on($cawangan['mysql'])->create([ - 'kodcaw' => $request->kodcaw, - 'batchno' => $newBatchNo, - 'tarikh' => $request->tarikh, - 'tarikh2' => $request->tarikh, - 't_daftar' => $currentDate, - 'masadari' => $request->masadari, - 'masahingga' => $request->masahingga + Log::info("Mula Export Lelong", [ + 'kodcaw' => $cawangan->kodcaw, + 'nama_cawangan' => $cawangan->details_caw, ]); - $lelong = Lelong::on($cawangan['mysql']) - ->select('sirilel') - ->orderBy('batchno', 'desc') - ->first(); + // --- Step 1: Batch (Cegah duplicate) --- + $batchlel = BatchLel::on($cawangan['mysql']) + ->where('kodcaw', $request->kodcaw) + ->whereDate('tarikh', $request->tarikh) + ->where('masadari', $request->masadari) + ->where('masahingga', $request->masahingga) + ->first(); + + if (!$batchlel) { + $lastBatchNo = BatchLel::on($cawangan['mysql'])->max('batchno') ?? 0; + $newBatchNo = $lastBatchNo + 1; + + $batchlel = BatchLel::on($cawangan['mysql'])->create([ + 'kodcaw' => $request->kodcaw, + 'batchno' => $newBatchNo, + 'tarikh' => $request->tarikh, + 'tarikh2' => $request->tarikh, + 't_daftar' => $currentDate, + 'masadari' => $request->masadari, + 'masahingga' => $request->masahingga + ]); + + Log::info("Batch baru dicipta", ['batchno' => $newBatchNo]); + } else { + $newBatchNo = $batchlel->batchno; + Log::info("Batch sedia ada digunakan", ['batchno' => $newBatchNo]); + } + + // --- Step 2: Siri Lelong Terakhir --- + $lastSiriLelong = Lelong::on($cawangan['mysql'])->max('sirilel') ?? 0; + $lelong_arr = []; + + // --- Step 3: Cegah duplicate Lelong --- + $existingNorujukan = Lelong::on($cawangan['mysql']) + ->whereIn('norujukan', collect($request->lelongbid)->pluck('norujukan')) + ->pluck('norujukan') + ->toArray(); foreach ($request->lelongbid as $index) { + if (in_array($index['norujukan'], $existingNorujukan)) { + Log::warning("Skip Lelong duplicate", ['norujukan' => $index['norujukan']]); + continue; + } - $no_pembeli = Pembeli::on($cawangan['mysql'])->where('nokp', '=', $index['user_details']['nokp'])->select('nopembeli')->first(); - if ($no_pembeli) { - $no_pembeli_data = $no_pembeli->nopembeli; - } else { - $last_no_pembeli = Pembeli::on($cawangan['mysql'])->select('nopembeli')->orderBy('nopembeli', 'desc')->first(); - $no_pembeli_data = $last_no_pembeli->nopembeli + 1; + // --- Step 4: Semak / cipta pembeli --- + $no_pembeli = Pembeli::on($cawangan['mysql']) + ->where('nokp', $index['user_details']['nokp']) + ->value('nopembeli'); - $newPembeli = Pembeli::on($cawangan['mysql'])->create([ - 'nopembeli' => $no_pembeli_data, + if (!$no_pembeli) { + $last_no_pembeli = Pembeli::on($cawangan['mysql']) + ->max('nopembeli') ?? 0; + $no_pembeli = $last_no_pembeli + 1; + + Pembeli::on($cawangan['mysql'])->create([ + 'nopembeli' => $no_pembeli, 'nokp' => $index['user_details']['nokp'], 'nama' => $index['user_details']['name'], 'alamat1' => $index['user_details']['alamat'], @@ -1114,105 +1149,147 @@ class LelongController extends Controller ]); } - $update_gadai = Gadai::on($cawangan['mysql'])->where('norujukan','=',$index['norujukan'])->update(array( - 'sttebus' => "L", - 't_update' => $request->tarikh - )); + // --- Step 5: Update gadai --- + Gadai::on($cawangan['mysql']) + ->where('norujukan', $index['norujukan']) + ->update([ + 'sttebus' => "L", + 't_update' => $request->tarikh + ]); - $lelong_to_be_inserted = new Lelong(); - $lelong_to_be_inserted->batchno = $newBatchNo; - $lelong_to_be_inserted->sirilel = $lelong->sirilel + 1; - $lelong_to_be_inserted->kodcaw = $index['kodcaw']; - $lelong_to_be_inserted->norujukan = $index['norujukan']; - $lelong_to_be_inserted->t_lelong = $request->tarikh; - $lelong_to_be_inserted->hargaasas = $index['hargaasas']; - $lelong_to_be_inserted->hargajual = $index['hargajual']; - $lelong_to_be_inserted->glcode = "1000/010"; - $lelong_to_be_inserted->t_jual = $index['t_jual']; - $lelong_to_be_inserted->nopembeli = $no_pembeli_data; - $lelong_to_be_inserted->jbg = $index['jbg']; - $lelong_to_be_inserted->kadarupah = $index['kadarupah']; - $lelong_to_be_inserted->upahsimpan = $index['upahsimpan']; - $lelong_to_be_inserted->ansuran = $index['ansuran']; - $lelong_to_be_inserted->nilaimarhun = $index['nilaimarhun']; - $lelong_to_be_inserted->nilaimarhuns = $index['nmarhuns']; - $lelong_to_be_inserted->pinjaman = $index['pinjaman']; - $lelong_to_be_inserted->bakiupah = $index['bakiupah']; - $lelong_to_be_inserted->cajlelong = $index['cajlelong']; - $lelong_to_be_inserted->baki = $index['baki']; - $lelong_to_be_inserted->teller = $index['teller']; - $lelong_to_be_inserted->prkod = "01"; - $lelong_to_be_inserted->kodgl = "1000/013"; - $lelong_to_be_inserted->berat = $index['berat']; - $lelong_to_be_inserted->marhun = $index['marhun']; - $lelong_to_be_inserted->fasa = $index['fasa']; - $lelong_to_be_inserted->ujrah = $index['ujrah']; - $lelong_to_be_inserted->onepercent = $index['onepercent']; - $lelong_to_be_inserted->tagujrah = $index['tagujrah']; - - $lelong_arr[] = $lelong_to_be_inserted->attributesToArray(); + // --- Step 6: Simpan data Lelong --- + $lelong_arr[] = [ + 'batchno' => $newBatchNo, + 'sirilel' => ++$lastSiriLelong, + 'kodcaw' => $index['kodcaw'], + 'norujukan' => $index['norujukan'], + 't_lelong' => $request->tarikh, + 'hargaasas' => $index['hargaasas'], + 'hargajual' => $index['hargajual'], + 'glcode' => "1000/010", + 't_jual' => $index['t_jual'], + 'nopembeli' => $no_pembeli, + 'jbg' => $index['jbg'], + 'kadarupah' => $index['kadarupah'], + 'upahsimpan' => $index['upahsimpan'], + 'ansuran' => $index['ansuran'], + 'nilaimarhun' => $index['nilaimarhun'], + 'nilaimarhuns' => $index['nmarhuns'], + 'pinjaman' => $index['pinjaman'], + 'bakiupah' => $index['bakiupah'], + 'cajlelong' => $index['cajlelong'], + 'baki' => $index['baki'], + 'teller' => $index['teller'], + 'prkod' => "01", + 'kodgl' => "1000/013", + 'berat' => $index['berat'], + 'marhun' => $index['marhun'], + 'fasa' => $index['fasa'], + 'ujrah' => $index['ujrah'], + 'onepercent' => $index['onepercent'], + 'tagujrah' => $index['tagujrah'], + ]; } - Lelong::on($cawangan['mysql'])->insert($lelong_arr); - - foreach ($request->lelongbidmarhun as $data) { - $lelmarhun_to_be_inserted = new LelMarhun(); - $lelmarhun_to_be_inserted->kodcaw = $request->kodcaw; - $lelmarhun_to_be_inserted->norujukan = $data['norujukan']; - $lelmarhun_to_be_inserted->bil = $data['bil']; - $lelmarhun_to_be_inserted->marhun = $data['marhun']; - $lelmarhun_to_be_inserted->nota = $data['nota']; - $lelmarhun_to_be_inserted->karat = $data['karat']; - $lelmarhun_to_be_inserted->berat = $data['berat']; - $lelmarhun_to_be_inserted->harga = $data['harga']; - $lelmarhun_to_be_inserted->n_marhun = $data['n_marhun']; - $lelmarhun_to_be_inserted->hargaasas = $data['hargaasas']; - $lelmarhun_to_be_inserted->batch_no = $newBatchNo; - // $lelmarhun_to_be_inserted->beratasal = $; - - $lelmarhun_arr[] = $lelmarhun_to_be_inserted->attributesToArray(); - + if ($lelong_arr) { + Lelong::on($cawangan['mysql'])->insert($lelong_arr); + Log::info("Berjaya simpan lelong baru", ['total' => count($lelong_arr)]); } - LelMarhun::on($cawangan['mysql'])->insert($lelmarhun_arr); + // --- Step 7: LELMARHUN (cegah duplicate) --- + if ($request->lelongbidmarhun) { + $existingMarhun = LelMarhun::on($cawangan['mysql']) + ->whereIn('norujukan', collect($request->lelongbidmarhun)->pluck('norujukan')) + ->pluck('norujukan') + ->toArray(); - if ($request->tunai != null) { - $tunai = Tunai::on($cawangan['mysql'])->create([ - 'tarikh' => $request->tarikh, - 'kodcaw' => $request->kodcaw, - 'kodlaluan' => "LELONG", - 'masuk' => $request->tunai, - 'baki' => $request->tunai, - ]); + $lelmarhun_arr = collect($request->lelongbidmarhun) + ->reject(fn($data) => in_array($data['norujukan'], $existingMarhun)) + ->map(function ($data) use ($request, $newBatchNo) { + return [ + 'kodcaw' => $request->kodcaw, + 'norujukan' => $data['norujukan'], + 'bil' => $data['bil'], + 'marhun' => $data['marhun'], + 'nota' => $data['nota'], + 'karat' => $data['karat'], + 'berat' => $data['berat'], + 'harga' => $data['harga'], + 'n_marhun' => $data['n_marhun'], + 'hargaasas' => $data['hargaasas'], + 'batch_no' => $newBatchNo + ]; + }) + ->toArray(); + + if ($lelmarhun_arr) { + LelMarhun::on($cawangan['mysql'])->insert($lelmarhun_arr); + Log::info("LelMarhun baru disimpan", ['total' => count($lelmarhun_arr)]); + } } - if ($request->gldetail != null) { - $gldetail = GlDetail::on($cawangan['mysql'])->create([ - 'kodcaw' => $request->kodcaw, - 'tarikh' => $request->tarikh, - 'dtacct' => "1000/010", - 'ktacct' => "1000/020", - 'descpt' => "SERAHAN LELONG ONLINE, " . $request->tarikh, - 'amaun' => $request->gldetail, - 'teller' => "LELONG ONLINE", - 'serahan' => $request->gldetail, - ]); + // --- Step 8: GL dan Tunai (check duplicate descpt) --- + if ($request->tunai > 0) { + $existsTunai = Tunai::on($cawangan['mysql']) + ->where('kodcaw', $request->kodcaw) + ->where('tarikh', $request->tarikh) + ->where('kodlaluan', 'LELONG') + ->exists(); + + if (!$existsTunai) { + Tunai::on($cawangan['mysql'])->create([ + 'tarikh' => $request->tarikh, + 'kodcaw' => $request->kodcaw, + 'kodlaluan' => "LELONG", + 'masuk' => $request->tunai, + 'baki' => $request->tunai, + ]); + Log::info("Rekod Tunai lelong dimasukkan"); + } else { + Log::warning("Skip Tunai duplicate"); + } } - if ($request->gldetailcdm != null) { - GlDetail::on($cawangan['mysql'])->create([ - 'kodcaw' => $request->kodcaw, - 'tarikh' => $request->tarikh, - 'dtacct' => "1000/010", - 'ktacct' => "1000/020", - 'descpt' => "SERAHAN LELONG CDM, " . $request->tarikh, - 'amaun' => $request->gldetailcdm, - 'teller' => "LELONG ONLINE", - 'serahan' => $request->gldetailcdm, - ]); + $glDescs = [ + 'SERAHAN LELONG ONLINE' => $request->gldetail, + 'SERAHAN LELONG CDM' => $request->gldetailcdm, + ]; + + foreach ($glDescs as $desc => $amount) { + if ($amount > 0) { + $existsGl = GlDetail::on($cawangan['mysql']) + ->where('kodcaw', $request->kodcaw) + ->where('tarikh', $request->tarikh) + ->where('descpt', 'like', "%{$desc}%") + ->exists(); + + if (!$existsGl) { + GlDetail::on($cawangan['mysql'])->create([ + 'kodcaw' => $request->kodcaw, + 'tarikh' => $request->tarikh, + 'dtacct' => "1000/010", + 'ktacct' => "1000/020", + 'descpt' => "{$desc}, {$request->tarikh}", + 'amaun' => $amount, + 'teller' => "LELONG ONLINE", + 'serahan' => $amount, + ]); + Log::info("Rekod GL dimasukkan", ['desc' => $desc]); + } else { + Log::warning("Skip GL duplicate", ['desc' => $desc]); + } + } } - return response()->json("success"); + // --- Step 9: Log Akhir --- + Log::info('Berjaya Export Cawangan:', [ + 'kodcaw' => $cawangan->kodcaw, + 'nama_cawangan' => $cawangan->details_caw, + 'batch_baru' => $newBatchNo, + 'total_lelong' => count($lelong_arr), + ]); + + return response()->json(['status' => 'success']); } public function getRingkasanHarian(Request $request){ From d21ad0f129a1d04e4afb98b42fe538bca44cca6e Mon Sep 17 00:00:00 2001 From: Ain Izazi Date: Sun, 12 Oct 2025 11:52:18 +0800 Subject: [PATCH 25/80] add radio button for report brg kes --- app/Http/Controllers/BarangkesController.php | 32 ++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/BarangkesController.php b/app/Http/Controllers/BarangkesController.php index ab1b620..a5899f6 100644 --- a/app/Http/Controllers/BarangkesController.php +++ b/app/Http/Controllers/BarangkesController.php @@ -71,16 +71,44 @@ class BarangkesController extends Controller $filteredResults = []; + $sudahTuntutSecaraManual = [ + '011237240719-0015', + '011237240806-0011', + '011237240828-0001', + '011237240731-0026', + '011237240912-0009' + ]; + + // if ($status == 'dituntut') { + // foreach ($merged as $pampasan) { + // if (isset($pampasan['status']) && $pampasan['status'] == 1) { + // $filteredResults[] = $pampasan; + // } + // } + // } if ($status == 'dituntut') { foreach ($merged as $pampasan) { - if (isset($pampasan['status']) && $pampasan['status'] == 1) { + if ( + (isset($pampasan['status']) && $pampasan['status'] == 1) + || in_array($pampasan['norujukan'], $sudahTuntutSecaraManual) + ) { $filteredResults[] = $pampasan; } } } + // if ($status == 'belum-tuntut') { + // foreach ($merged as $pampasan) { + // if (!isset($pampasan['status'])) { + // $filteredResults[] = $pampasan; + // } + // } + // } if ($status == 'belum-tuntut') { foreach ($merged as $pampasan) { - if (!isset($pampasan['status'])) { + if ( + !isset($pampasan['status']) + && !in_array($pampasan['norujukan'], $sudahTuntutSecaraManual) + ) { $filteredResults[] = $pampasan; } } From 04bc76ef89d92869a6aa53fc2b086b0753e3e1a8 Mon Sep 17 00:00:00 2001 From: aiman Date: Sun, 12 Oct 2025 12:38:00 +0800 Subject: [PATCH 26/80] Add Baki Lelong for laporan aliran tunai teller --- app/Http/Controllers/LelongController.php | 32 +++++++++++++++++++++++ routes/web.php | 2 ++ 2 files changed, 34 insertions(+) diff --git a/app/Http/Controllers/LelongController.php b/app/Http/Controllers/LelongController.php index ce7709e..b583cc1 100644 --- a/app/Http/Controllers/LelongController.php +++ b/app/Http/Controllers/LelongController.php @@ -1972,4 +1972,36 @@ class LelongController extends Controller return response()->json($arrayblm); } + public function getBakiLelongByTeller($kodcaw, Request $request) + { + $cawangan = Cawangan::on('mysql7')->where('kodcaw', $kodcaw)->first(); + + $date = $request->query('date', Carbon::now()->toDateString()); + + try { + $parsedDate = Carbon::parse($date)->toDateString(); + } catch (\Exception $e) { + return response()->json(['error' => 'Invalid date format. Use YYYY-MM-DD.'], 400); + } + + $rugiLelong = TuntutBaki::on($cawangan['mysql']) + ->whereDate('tarikh', $parsedDate) + ->where('jumlah', '<', 0) + ->sum('jumlah'); + + $bakiLelong = TuntutBaki::on($cawangan['mysql']) + ->whereDate('tarikh', $parsedDate) + ->where('jumlah', '>', 0) + ->sum('jumlah'); + + // dd($parsedDate, $rugiLelong, $bakiLelong); + + return response()->json([ + 'tarikh' => $parsedDate, + 'kod_cawangan' => $kodcaw, + 'rugi_lelong' => $rugiLelong, + 'baki_lelong' => $bakiLelong + ], 200); + } + } diff --git a/routes/web.php b/routes/web.php index 0f81536..2b96904 100644 --- a/routes/web.php +++ b/routes/web.php @@ -194,6 +194,8 @@ $router->group(['prefix'=>'api'], function () use ($router){ $router->get('keluar/lelong',['uses'=>'LelongController@keluarLelong']); + $router->get('lelong/bakilelongbyteller/{kodcaw}',['uses' => 'LelongController@getBakiLelongByTeller']); + //Marhun API From a42d36f69bc4a803befbc67a398d0d9d4844cace Mon Sep 17 00:00:00 2001 From: aiman Date: Tue, 14 Oct 2025 15:55:24 +0800 Subject: [PATCH 27/80] Enable datepicker, new route for laporan aliran tunai teller --- app/Http/Controllers/LelongController.php | 18 +++++------------- app/Http/Controllers/TunaiController.php | 15 +++++++++++++++ routes/web.php | 2 ++ 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/app/Http/Controllers/LelongController.php b/app/Http/Controllers/LelongController.php index b583cc1..ebbac29 100644 --- a/app/Http/Controllers/LelongController.php +++ b/app/Http/Controllers/LelongController.php @@ -1976,29 +1976,21 @@ class LelongController extends Controller { $cawangan = Cawangan::on('mysql7')->where('kodcaw', $kodcaw)->first(); - $date = $request->query('date', Carbon::now()->toDateString()); - - try { - $parsedDate = Carbon::parse($date)->toDateString(); - } catch (\Exception $e) { - return response()->json(['error' => 'Invalid date format. Use YYYY-MM-DD.'], 400); - } + $date = $request->tarikh; $rugiLelong = TuntutBaki::on($cawangan['mysql']) - ->whereDate('tarikh', $parsedDate) + ->whereDate('tarikh', $date) ->where('jumlah', '<', 0) ->sum('jumlah'); $bakiLelong = TuntutBaki::on($cawangan['mysql']) - ->whereDate('tarikh', $parsedDate) + ->whereDate('tarikh', $date) ->where('jumlah', '>', 0) ->sum('jumlah'); - - // dd($parsedDate, $rugiLelong, $bakiLelong); return response()->json([ - 'tarikh' => $parsedDate, - 'kod_cawangan' => $kodcaw, + 'tarikh' => $date, + 'cawangan' => $kodcaw, 'rugi_lelong' => $rugiLelong, 'baki_lelong' => $bakiLelong ], 200); diff --git a/app/Http/Controllers/TunaiController.php b/app/Http/Controllers/TunaiController.php index cd4d83f..12d0fba 100644 --- a/app/Http/Controllers/TunaiController.php +++ b/app/Http/Controllers/TunaiController.php @@ -165,6 +165,21 @@ class TunaiController extends Controller } + public function getTunaiByTarikh(Request $request) + { + $cawangan = Cawangan::on('mysql7')->where('kodcaw','=',$request->kodcaw)->first(); + + $tunai = Tunai::on($cawangan['mysql']) + ->where([['kodcaw','=',$request->kodcaw], + ['tarikh','=',$request->tarikh], + ['kodlaluan','=',$request->kodlaluan] + ]) + ->orderBy('tarikh','desc') + ->first(); + + return response()->json($tunai); + } + public function getTunaiPast($kodcaw,Request $request) { diff --git a/routes/web.php b/routes/web.php index 2b96904..bf0dfe3 100644 --- a/routes/web.php +++ b/routes/web.php @@ -376,6 +376,8 @@ $router->group(['prefix'=>'api'], function () use ($router){ $router->get('laporanpetibesirange/{kodcaw}',['uses'=> 'VaultController@laporanPetiBesiRange']); $router->get('laporanAuditTrail',['uses'=> 'LaporanController@LaporanAuditTrail']); + //Get Tunai By tarikh for Laporan Aliran Tunai Teller + $router->get('getTunaiByTarikh', ['uses' => 'TunaiController@getTunaiByTarikh']); //API PANJAR KHAZANAH $router->get('SenaraiPanjar/{kodcaw}',['uses'=>'PanjarController@list']); From ece4210134aab112de21eea88133374b27bc74b4 Mon Sep 17 00:00:00 2001 From: aiman Date: Wed, 15 Oct 2025 14:55:26 +0800 Subject: [PATCH 28/80] Filter bakiLelong by kodlaluan teller --- app/Http/Controllers/LelongController.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/Http/Controllers/LelongController.php b/app/Http/Controllers/LelongController.php index ebbac29..96529eb 100644 --- a/app/Http/Controllers/LelongController.php +++ b/app/Http/Controllers/LelongController.php @@ -1981,11 +1981,13 @@ class LelongController extends Controller $rugiLelong = TuntutBaki::on($cawangan['mysql']) ->whereDate('tarikh', $date) ->where('jumlah', '<', 0) + ->where('teller','=', $request->kodlaluan) ->sum('jumlah'); $bakiLelong = TuntutBaki::on($cawangan['mysql']) ->whereDate('tarikh', $date) ->where('jumlah', '>', 0) + ->where('teller','=', $request->kodlaluan) ->sum('jumlah'); return response()->json([ From 0184a0f3e1d3d954b4c6fee914194788b22c07af Mon Sep 17 00:00:00 2001 From: Nur Izzati Date: Thu, 30 Oct 2025 11:16:16 +0800 Subject: [PATCH 29/80] update lelong batu permata --- app/Http/Controllers/LelongController.php | 73 +++++++++++++---------- 1 file changed, 42 insertions(+), 31 deletions(-) diff --git a/app/Http/Controllers/LelongController.php b/app/Http/Controllers/LelongController.php index 96529eb..a7a867b 100644 --- a/app/Http/Controllers/LelongController.php +++ b/app/Http/Controllers/LelongController.php @@ -1395,42 +1395,53 @@ class LelongController extends Controller public function showAllLelongByCawanganBatchno($kodcaw) { - $item = array('PMT','batu','permata'); - $cawangan = Cawangan::on('mysql7')->where('kodcaw','=',$kodcaw)->first(); + $item = ['PMT', 'batu', 'permata']; + + // Semak kewujudan cawangan dulu + $cawangan = Cawangan::on('mysql7')->where('kodcaw', $kodcaw)->first(); + if (!$cawangan) { + return response()->json(['error' => 'Cawangan tidak dijumpai.'], 404); + } + + // Ambil data lelong $lelong_data = Lelong::on($cawangan['mysql']) - ->leftJoin('gadai', 'gadai.norujukan', '=', 'lelong.norujukan') - ->join('lelmarhun', 'lelmarhun.norujukan', '=', 'lelong.norujukan') - ->whereNull('upah12') - // ->where('lelong.marhun', 'like', '%PMT%') - // ->orWhere('lelong.marhun', 'like', '%batu%') - // ->orWhere('lelong.marhun', 'like', '%permata%') - ->Where(function ($query) use($item) { - for ($i = 0; $i < count($item); $i++){ - $query->orwhere('lelmarhun.nota', 'like', '%' . $item[$i] .'%'); - } - }) - ->orderBy('lelong.t_lelong','asc') - ->select('lelong.t_lelong','gadai.t_gadai','gadai.nokp','lelong.pinjaman','lelong.baki','lelong.batchno','lelong.norujukan') - ->whereNull('upah12') - ->distinct() - ->get(); - // dd($lelong_data); + ->leftJoin('gadai', 'gadai.norujukan', '=', 'lelong.norujukan') + ->join('lelmarhun', 'lelmarhun.norujukan', '=', 'lelong.norujukan') + ->whereNull('upah12') + ->where(function ($query) use ($item) { + foreach ($item as $i) { + $query->orWhere('lelmarhun.nota', 'like', '%' . $i . '%'); + } + }) + ->orderBy('lelong.t_lelong', 'asc') + ->select( + 'lelong.t_lelong', + 'gadai.t_gadai', + 'gadai.nokp', + 'lelong.pinjaman', + 'lelong.baki', + 'lelong.batchno', + 'lelong.norujukan' + ) + ->distinct() + ->get(); + + // Group by batch number $groupbybatch = $lelong_data->groupBy('batchno'); $lelong = []; - foreach($groupbybatch as $index=>$lelongData){ + foreach ($groupbybatch as $batchno => $lelongData) { $total_pembiayaan = $lelongData->sum('pinjaman'); - // dd($total_pembiayaan); - $total_lelong = $lelongData->count('norujukan'); - array_push($lelong,[ - // "upah12"=> $lelongData->upah12, - "t_lelong"=> $lelongData->groupBy('t_lelong'), - "batchno"=> $index, - "total_pembiayaan"=> $total_pembiayaan, - "total_lelong"=> $total_lelong, - "kodcaw"=> $kodcaw, - ]); - // dd($lelong); + $total_lelong = $lelongData->count(); + $t_lelong = optional($lelongData->first())->t_lelong; // elak error kalau kosong + + $lelong[] = [ + 't_lelong' => $t_lelong, + 'batchno' => $batchno, + 'total_pembiayaan' => $total_pembiayaan, + 'total_lelong' => $total_lelong, + 'kodcaw' => $kodcaw, + ]; } return response()->json($lelong); } From a1f3bc29f5611872b3dbd37a864702844d179504 Mon Sep 17 00:00:00 2001 From: Hafifie PKB Date: Sat, 15 Nov 2025 23:23:14 +0800 Subject: [PATCH 30/80] fix certain for sttebus = 'L' only --- app/Http/Controllers/TransactionOnlineController.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/TransactionOnlineController.php b/app/Http/Controllers/TransactionOnlineController.php index ebaade7..c51ac2e 100644 --- a/app/Http/Controllers/TransactionOnlineController.php +++ b/app/Http/Controllers/TransactionOnlineController.php @@ -777,6 +777,7 @@ class TransactionOnlineController extends Controller foreach ($cawangan_all as $index => $cawangan) { $gadai = Gadai::on($cawangan['mysql']) ->where('nokp', '=', $request->ic) + ->where('sttebus','=','L') ->orderBy('t_gadai', 'desc') ->get()->toArray(); @@ -799,10 +800,10 @@ class TransactionOnlineController extends Controller ->where('norujukan', '=' ,$gad['norujukan']) ->where('baki','<',0) ->sum('baki'); - } $totalBakiLelong += $bakilelong; $totalRugiLelong += $rugilelong; + } } } From e8e94c714bedd0ba274417dba6f0e29e7d6830fb Mon Sep 17 00:00:00 2001 From: Nur Izzati Date: Wed, 26 Nov 2025 16:35:07 +0800 Subject: [PATCH 31/80] tambah list laporan SA lelong_tawarruq = 0 --- app/Http/Controllers/StokAuditController.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/Http/Controllers/StokAuditController.php b/app/Http/Controllers/StokAuditController.php index cc6129f..eb1ddcf 100644 --- a/app/Http/Controllers/StokAuditController.php +++ b/app/Http/Controllers/StokAuditController.php @@ -475,6 +475,9 @@ class StokAuditController extends Controller // Filter audit $rekodaudit = $audit->filter(function ($item) use ($tarikhTerkiniT, $tarikhTerkiniA) { + if ($item->lelong_tawarruq == 0) { + return true; + } $norujukan = $item->norujukan; $adaTebusTerkini = isset($tarikhTerkiniT[$norujukan]) && From e983374a90ac961e5481b4bb874c8c8abe8dc283 Mon Sep 17 00:00:00 2001 From: Amirah Date: Mon, 15 Dec 2025 11:09:24 +0800 Subject: [PATCH 32/80] Add reporting saringan gadaian kb1 --- .../Reports/SaringanGadaianController.php | 129 ++++++++++++++++++ routes/report.php | 2 +- 2 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 app/Http/Controllers/Reports/SaringanGadaianController.php diff --git a/app/Http/Controllers/Reports/SaringanGadaianController.php b/app/Http/Controllers/Reports/SaringanGadaianController.php new file mode 100644 index 0000000..10fe794 --- /dev/null +++ b/app/Http/Controllers/Reports/SaringanGadaianController.php @@ -0,0 +1,129 @@ +startDate ?? now()->startOfMonth()->toDateString(); + $endDate = $request->endDate ?? now()->endOfMonth()->toDateString(); + + $active_dbs = Helper::getActiveCawanganDbConnection(); + + $cawangan = Cawangan::select('kodcaw', 'details_caw', 'mysql') + ->whereIn('mysql', $active_dbs) + ->get(); + + $responses = []; + + foreach ($cawangan as $caw) { + + $db = $caw->mysql; + + $tgb = Tebus::on($db) + ->join('gadai as g1', 'tebus.norujukan', '=', 'g1.norujukan') + ->join('gadai as g2', function ($join) { + $join->on('g2.nokp', '=', 'g1.nokp') + ->on('g2.t_gadai', '=', 'tebus.t_tebus') + ->whereRaw('ABS(g2.berat - g1.berat) <= 0.02') + ->whereColumn('g2.norujukan', '!=', 'g1.norujukan'); + }) + ->whereBetween('tebus.t_tebus', [$startDate, $endDate]) + ->groupBy('tebus.norujukan') + ->selectRaw(" + tebus.norujukan as norujukan_tebus, + MAX(g2.norujukan) as norujukan_gadai_balik, + MAX(g2.nokp) as nokp, + MAX(g2.berat) as berat, + MAX(g2.nilaimarhun) as nilaimarhun, + MAX(g2.pinjaman) as pinjaman, + MAX(g2.t_gadai) as t_gadai, + MAX(g1.taglel) as taglel_lama + ") + ->get() + ->map(function ($row) { + return [ + 'norujukan_tebus' => $row->norujukan_tebus, + 'norujukan_gadai_balik' => $row->norujukan_gadai_balik, + 'nokp' => $row->nokp, + 'berat' => (float) $row->berat, + 'nilaimarhun' => (float) $row->nilaimarhun, + 'pinjaman' => (float) $row->pinjaman, + 'taglel_lama' => $row->taglel_lama, + 't_gadai' => $row->t_gadai, + 'jenis' => $row->taglel_lama == 1 ? 'TGB_LELONG' : 'TGB_BIASA', + ]; + }) + ->toArray(); + + $tgb_norujukan = array_column($tgb, 'norujukan_gadai_balik'); + + + $gadai_biasa = DB::connection($db) + ->table('gadai') + ->whereBetween('t_gadai', [$startDate, $endDate]) + ->whereNotIn('norujukan', $tgb_norujukan) + ->select([ + DB::raw('NULL as norujukan_tebus'), + 'norujukan as norujukan_gadai_balik', + 'nokp', + 'berat', + 'nilaimarhun', + 'pinjaman', + DB::raw('NULL as taglel_lama'), + 't_gadai', + ]) + ->get() + ->map(function ($row) { + return [ + 'norujukan_tebus' => null, + 'norujukan_gadai_balik' => $row->norujukan_gadai_balik, + 'nokp' => $row->nokp, + 'berat' => (float) $row->berat, + 'nilaimarhun' => (float) $row->nilaimarhun, + 'pinjaman' => (float) $row->pinjaman, + 'taglel_lama' => null, + 't_gadai' => $row->t_gadai, + 'jenis' => 'GADAI_BIASA', + ]; + }) + ->toArray(); + + + $details = collect($tgb) + ->merge($gadai_biasa) + ->unique('norujukan_gadai_balik') + ->sortBy(['jenis', 't_gadai']) + ->values() + ->all(); + + + $responses[] = [ + 'kodcaw' => $caw->kodcaw, + 'details_caw' => $caw->details_caw, + 'jumlah_surat' => count($details), + 'total_tgb_lelong' => collect($details)->where('jenis', 'TGB_LELONG')->count(), + 'total_tgb_biasa' => collect($details)->where('jenis', 'TGB_BIASA')->count(), + 'total_gadai_biasa' => collect($details)->where('jenis', 'GADAI_BIASA')->count(), + 'sum_berat' => collect($details)->sum('berat'), + 'sum_nilai_marhun' => collect($details)->sum('nilaimarhun'), + 'sum_pinjaman' => collect($details)->sum('pinjaman'), + 'details' => $details, + ]; + } + + return response()->json($responses); + } +} diff --git a/routes/report.php b/routes/report.php index 6cf98f2..ce9aab6 100644 --- a/routes/report.php +++ b/routes/report.php @@ -56,6 +56,6 @@ $router->group(['prefix' => 'api/reports'], function () use ($router) { $router->get('gadaitebusmasa', ['uses' => 'GadaianController@getSummaryLaporanGadaiTebusMasa']); $router->get('gadaitebusmasa/{kod_cawangan}', ['uses' => 'GadaianController@getLaporanGadaiTebusMasaCawangan']); - + $router->get('saringan/gadaian', ['uses' => 'SaringanGadaianController@getLaporanGadai']); }); }); From 3a8e74c368212315ec3622e6228c5aa4bf1c6fb3 Mon Sep 17 00:00:00 2001 From: BTMS3 Date: Sun, 21 Dec 2025 11:15:57 +0800 Subject: [PATCH 33/80] update wtd --- app/Http/Controllers/AdminPageController.php | 295 +++++++++++++++++- app/WTDSimulasi.php | 32 ++ ...160820_add_t_htr_ag_to_serahbaki_table.php | 83 +++++ ...12_18_163018_create_wtd_simulasi_table.php | 40 +++ routes/web.php | 11 + 5 files changed, 456 insertions(+), 5 deletions(-) create mode 100644 app/WTDSimulasi.php create mode 100644 database/migrations/2025_12_18_160820_add_t_htr_ag_to_serahbaki_table.php create mode 100644 database/migrations/2025_12_18_163018_create_wtd_simulasi_table.php diff --git a/app/Http/Controllers/AdminPageController.php b/app/Http/Controllers/AdminPageController.php index 4f59be5..ac61471 100644 --- a/app/Http/Controllers/AdminPageController.php +++ b/app/Http/Controllers/AdminPageController.php @@ -2364,7 +2364,70 @@ class AdminPageController extends Controller $cawangan = Cawangan::on('mysql7')->where('kodcaw','=',$request->kodcaw)->first(); - $latestbatch = SerahBaki::on($cawangan['mysql'])->where('norujukan','baru')->get()->toArray(); + //$latestbatch = SerahBaki::on($cawangan['mysql'])->where('norujukan','baru')->get()->toArray(); + + //new added + $serahBaki = SerahBaki::on($cawangan['mysql']) + ->where('norujukan', 'baru') + ->get(); + + $allBatchNo = $serahBaki->pluck('batchno')->unique()->toArray(); + + $wtddraftData = WTDDraft::on('mysql7') + ->selectRaw(" + batchno_serah, + YEAR(t_jual) as tahun, + GROUP_CONCAT( + DISTINCT MONTH(t_jual) + ORDER BY MONTH(t_jual) + SEPARATOR ',' + ) as bulan + ") + ->where('kodcaw', $request->kodcaw) + ->whereIn('batchno_serah', $allBatchNo) + ->groupBy('batchno_serah', DB::raw('YEAR(t_jual)')) + ->get() + ->groupBy('batchno_serah') + ->map(function ($rows) { + return $rows->map(function ($row) { + return [ + 'tahun' => $row->tahun, + 'bulan' => $row->bulan + ]; + })->values(); + }); + + $finalData = $serahBaki->map(function ($item) use ($wtddraftData) { + $batchno = $item->batchno; + + $tahun = null; + $bulan = []; + + if (!empty($wtddraftData[$batchno])) { + // ambil tahun pertama (kebiasaannya satu tahun sahaja) + $tahun = $wtddraftData[$batchno][0]['tahun']; + + // convert string "2,3,4,5" → array + $bulan = explode(',', $wtddraftData[$batchno][0]['bulan']); + } + + return [ + 'batchno' => $batchno, + 'norujukan' => $item->norujukan, + 'tarikh' => $item->tarikh, + 't_jual' => $item->t_jual, + 'baki' => $item->baki, + 't_htr_ag' => $item->t_htr_ag, + 'aktif' => $item->aktif, + 'tahun' => $tahun, + 'bulan' => implode(',',$bulan), + // field lain kekal + ]; + }); + + $finalDataArray = $finalData->toArray(); + //end new added + $batch_old = WTDDraft::on('mysql7')->select('kodcaw')->where('batchno_serah',0)->where('kodcaw',$request->kodcaw) ->groupBy('kodcaw')->get(); @@ -2373,15 +2436,20 @@ class AdminPageController extends Controller foreach($batch_old as $index=>$bo) { - array_push($latestbatch,['recno' => 0,'norujukan' => 'lama','batchno' => 0,'baki' => $lelong_data->sum('baki'),'aktif' => 1]); + //array_push($latestbatch,['recno' => 0,'norujukan' => 'lama','batchno' => 0,'baki' => $lelong_data->sum('baki'),'aktif' => 1]); + array_push($finalDataArray,['recno' => 0,'norujukan' => 'lama','batchno' => 0,'baki' => $lelong_data->sum('baki'),'aktif' => 1]); } - $data = $this->paginate($latestbatch,8); + //$data = $this->paginate($latestbatch,8); + $data = $this->paginate($finalDataArray,8); + + //dd($data); return response()->json($data,200); } + public function rekodWTDByBatchNo($batchno,Request $request){ $cawangan = Cawangan::on('mysql7')->where('kodcaw','=',$request->kodcaw)->first(); @@ -2698,8 +2766,9 @@ class AdminPageController extends Controller 't_update' => $current->toDateString())); } - $serahbakiupdate = SerahBaki::on($cawangan['mysql'])->where('batchno',$batchno)->update(array('aktif' => 1,'t_jual' => $current->toDateString(),'nopelanggan' => $request->nocek));; - + //$serahbakiupdate = SerahBaki::on($cawangan['mysql'])->where('batchno',$batchno)->update(array('aktif' => 1,'t_jual' => $current->toDateString(),'nopelanggan' => $request->nocek));; + $serahbakiupdate = SerahBaki::on($cawangan['mysql'])->where('batchno',$batchno)->update(array('aktif' => 1,'t_jual' => $current->toDateString(),'nopelanggan' => $request->nocek,'t_htr_ag' => $request->tarikhAG)); + return response()->json('success',200); }catch (\Throwable $e){ @@ -2710,6 +2779,222 @@ class AdminPageController extends Controller } + public function janaSimulasiWTD(Request $request) + { + $cawangan = Cawangan::on('mysql7')->where('kodcaw', '=', $request->kodcaw)->first(); + + //listing sag belum tuntut cwgn + $sag_cwgn = collect( + Lelong::on($cawangan['mysql']) + ->selectRaw('norujukan') + ->whereYear('t_jual', $request->tahun) + ->whereNull('trkhtuntut') + ->where('baki', '>', 0) + ->pluck('norujukan') // lebih bersih + ); + + //listing sag blocked + $sag_online = collect( + WTDDraft::on('mysql7') + ->selectRaw('norujukan') + ->where('kodcaw', '=', $request->kodcaw) + ->pluck('norujukan') + ); + //dd($sag_online); + //filter sag yg tk wujud dlm wtd_draft + $filtersag = $sag_cwgn->diff($sag_online); + + //query baru + $tarikh_belum_tuntut = Lelong::on($cawangan['mysql']) + ->selectRaw(' + MONTH(t_jual) as bulan, + SUM(pinjaman) as pembiayaan, + ABS(SUM(baki)) as baki, + COUNT(DISTINCT norujukan) as jumlah_norujukan, + kodcaw + ') + ->whereIn('norujukan', $filtersag) + ->groupBy('bulan', 'kodcaw') + ->orderBy('bulan') + ->get(); + + $tarikh_belum_tuntut = $tarikh_belum_tuntut->map(function ($item) { + $item->bulan = \Carbon\Carbon::create()->month($item->bulan)->format('F'); + return $item; + }); + + return response()->json($tarikh_belum_tuntut); + } + + public function RekodSimulasiWTD(Request $request) + { + $cawangan = Cawangan::on('mysql7')->where('kodcaw', '=', $request->kodcaw)->first(); + + $rekod_simulasi = Lelong::on($cawangan['mysql']) + ->join('gadai','lelong.norujukan','=','gadai.norujukan') + ->selectRaw('ABS(lelong.baki) as baki, lelong.t_lelong, lelong.pinjaman, lelong.norujukan, gadai.nokp') + ->whereMonth('lelong.t_jual', $request->month) + ->whereYear('lelong.t_jual', $request->year) + ->whereNull('lelong.trkhtuntut') + ->where('lelong.baki', '>', 0) + ->get(); + + return response()->json($rekod_simulasi); + } + + public function prosesSimulasiWTD(Request $request) + { + $proses = $request->input; + + // dd($proses, $cawangan); + + $baki = 0; + $jumlahPembiayaan = 0; + $simulasi = WTDSimulasi::max('simulasi')+1; + + foreach ($proses as $item) { + WTDSimulasi::create([ + 'bulan' => $item['bulan'], + 'tahun' => $item['tahun'], + 'kodcaw' => $item['kodcaw'], + 'jumlah_sag' => $item['jumlah_sag'], + 'pembiayaan'=> $item['pembiayaan'], + 'baki'=> $item['baki'], + 'simulasi' => $simulasi, + ]); + $baki += $item['baki']; + $jumlahPembiayaan = $item['pembiayaan']; + } + + return response()->json(['status' => 'success','simulasi' => $simulasi,'baki' => $baki,'pinjaman' => $jumlahPembiayaan]); + } + + public function pengesahanSimulasiWTD(Request $request) + { + // Decode the JSON records from the request + $records = json_decode($request->records, true); + + // Retrieve and clean 'kodcaw' from the request + $kodcaw = $request->kodcaw; + $kodcaw_clean = str_replace('"', '', $kodcaw); + + // Get the database connection for the branch (cawangan) + $cawangan = Cawangan::where('kodcaw', $kodcaw_clean)->first(); + + // Check if 'Cawangan' exists + if (!$cawangan) { + return response()->json(['status' => 'error', 'message' => 'Invalid branch code (kodcaw).'], 404); + } + + $cawangan_connection = $cawangan->mysql; + + // Get the latest batch number and increment it + $latestBatch = SerahBaki::on($cawangan_connection)->max('batchno') + 1; + + // Initialize total variables + $totalPembiayaan = 0; + $totalBaki = 0; + + + try { + // Iterate through the records and save them to the WTDDraft table + foreach ($records as $record) { + // Check if 'bulan' and 'tahun' exist in the record + if (!isset($record['bulan']) || !isset($record['tahun'])) { + return response()->json(['status' => 'error', 'message' => 'Missing bulan or tahun in records.'], 400); + } + $month = DateTime::createFromFormat('F', $record["bulan"])->format('n'); + + + // Query norujukan records from the database + $query_norujukan = Lelong::on($cawangan_connection) + ->join('gadai', 'lelong.norujukan', '=', 'gadai.norujukan') + ->selectRaw('ABS(lelong.baki) as baki, lelong.t_lelong, lelong.pinjaman, lelong.norujukan, gadai.nokp, lelong.t_jual') + ->whereMonth('lelong.t_jual', $month) + ->whereYear('lelong.t_jual', $record["tahun"]) + ->whereNull('lelong.trkhtuntut') + ->where('lelong.baki', '>', 0) + ->get(); + + // Save each record to the WTDDraft table + foreach ($query_norujukan as $query) { + $wtddraft = new WTDDraft(); + $wtddraft->nokp = $query['nokp']; + $wtddraft->kodcaw = $kodcaw_clean; + $wtddraft->norujukan = $query['norujukan']; + $wtddraft->t_jual = $query['t_jual']; + $wtddraft->t_gadai = $query['t_gadai'] ?? null; // Optional: ensure 't_gadai' exists + $wtddraft->t_lelong = $query['t_lelong']; + $wtddraft->batchno_serah = $latestBatch; + $wtddraft->save(); + } + + // Accumulate totals + $totalPembiayaan += $record['pembiayaan'] ?? 0; + $totalBaki += $record['baki'] ?? 0; + } + + // Create a new record in the SerahBaki table + SerahBaki::on($cawangan_connection)->create([ + 'norujukan' => 'baru', + 'batchno' => $latestBatch, + 'hargajual' => 0.00, + 'pinjaman' => $totalPembiayaan, + 'upah' => 0.00, + 'cajlel' => 0.00, + 'gst_cl' => 0.00, + 'gst_hj' => 0.00, + 'baki' => $totalBaki, + 'tarikh' => Carbon::now()->toDateString(), + 't_jual' => Carbon::now()->toDateString(), + 'nopelanggan' => '', + 'aktif' => 0, + ]); + + // Return a success response with the new batch number + return response()->json(['status' => 'success', 'batchno' => $latestBatch], 200); + + } catch (\Throwable $e) { + // Log the error and return a failure response + Log::error($e->getMessage()); + Log::error($e->getLine()); + return response()->json(['status' => 'error', 'message' => $e->getMessage()], 500); + } + } + + + + public function simulasiToDraft(Request $request) + { + $bulan = $request->bulan; + + if (!$bulan || count($bulan) === 0) { + return response()->json(['error' => 'Sila pilih sekurang-kurangnya satu bulan.'], 400); + } + + $simulasi = WTDSimulasi::whereIn('bulan', $bulan)->get(); + + if ($simulasi->isEmpty()) { + return response()->json(['error' => 'Tiada data untuk bulan yang dipilih.'], 404); + } + + // foreach ($simulasi as $data) { + // WTDDraft::create([ + // 'nokp' => $data->nokp ?? null, + // 'kodcaw' => $data->kodcaw ?? null, + // 'norujukan' => $data->norujukan ?? null, + // 't_jual' => $data->t_jual ?? null, + // 't_gadai' => $data->t_gadai ?? null, + // 't_lelong' => $data->t_lelong ?? null, + // 'batchno_serah' => $data->simulasi, // Simpan sebagai rujukan + // ]); + // } + + dd($bulan, $simulasi); + + return response()->json(['message' => 'Data berjaya dipindahkan ke WTD Draft!']); + + } public function PenjanaanPC(Request $request){ $timeloni = Carbon::now(); diff --git a/app/WTDSimulasi.php b/app/WTDSimulasi.php new file mode 100644 index 0000000..38a963f --- /dev/null +++ b/app/WTDSimulasi.php @@ -0,0 +1,32 @@ +getPdo(); + return true; + } catch (\Exception $e) { + return false; + } + }); + } + + + public function up() + { + $db_connection = $this->getActiveDB(); + + $key = array_search('mysql7', $db_connection); + + if ($key !== false) { + unset($db_connection[$key]); + } + + foreach ($db_connection as $dbase) { + Schema::connection($dbase)->table('serahbaki', function (Blueprint $table) use ($dbase) { + + if (!Schema::connection($dbase)->hasColumn('serahbaki', 't_htr_ag')) { + $table->date('t_htr_ag')->nullable()->after('aktif'); + } + }); + } + } + + + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + $db_connection = $this->getActiveDB(); + + $key = array_search('mysql7', $db_connection); + + if ($key !== false) { + unset($db_connection[$key]); + } + + foreach ($db_connection as $dbase) { + if (Schema::connection($dbase)->hasColumn('serahbaki', 't_htr_ag')) { + Schema::connection($dbase)->table('serahbaki', function (Blueprint $table) { + $table->dropColumn('t_htr_ag'); + }); + } + } + } +} + diff --git a/database/migrations/2025_12_18_163018_create_wtd_simulasi_table.php b/database/migrations/2025_12_18_163018_create_wtd_simulasi_table.php new file mode 100644 index 0000000..214b2d7 --- /dev/null +++ b/database/migrations/2025_12_18_163018_create_wtd_simulasi_table.php @@ -0,0 +1,40 @@ +id(); + + $table->string('bulan'); + $table->string('tahun'); + $table->string('kodcaw'); + $table->integer('jumlah_sag'); + $table->decimal('pembiayaan', 15, 2); + $table->decimal('baki', 15, 2); + $table->integer('simulasi'); + + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('wtd_simulasi'); + } +} \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index bf0dfe3..dcafcdc 100644 --- a/routes/web.php +++ b/routes/web.php @@ -891,6 +891,17 @@ $router->group(['prefix'=>'admin'], function () use ($router){ $router->post('wtd/delete',['uses'=>'AdminPageController@RemoveDraftWTD']); $router->get('wtd/dalamproses',['uses'=>'AdminPageController@rekodWTDDalamProses']); + //Aiman Ngube WTD + $router->get('wtd/janaSimulasi',['uses'=>'AdminPageController@JanaSimulasiWTD']); + $router->get('wtd/rekodSimulasi',['uses'=>'AdminPageController@RekodSimulasiWTD']); + $router->post('wtd/prosesSimulasi',['uses'=>'AdminPageController@ProsesSimulasiWTD']); + $router->post('wtd/pengesahanSimulasi',['uses'=>'AdminPageController@PengesahanSimulasiWTD']); + + $router->post('wtd/simulasiToDraft',['uses'=>'AdminPageController@SimulasiToDraft']); + + $router->post('wtd/simulasiBaru',['uses'=>'AdminPageController@SimulasiBaru']); + + $router->get('audit/keuntungansebenar',['uses'=>'AdminPageController@KeuntunganSebenarExport']); $router->get('laporan/aging',['uses'=>'AdminPageController@LaporanAging']); $router->get('dashboard/aging',['uses'=>'AdminPageController@DashboardAging']); From 2aff9629815691fddc6af2e2919aa6ca52bf42ff Mon Sep 17 00:00:00 2001 From: Nisha Muhd Date: Tue, 6 Jan 2026 12:52:02 +0800 Subject: [PATCH 34/80] laporan_rumusan_wtd --- app/Http/Controllers/WTDController.php | 87 ++++++++++++++++++++++++++ routes/web.php | 4 +- 2 files changed, 89 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/WTDController.php b/app/Http/Controllers/WTDController.php index fe12c2b..cfd1511 100644 --- a/app/Http/Controllers/WTDController.php +++ b/app/Http/Controllers/WTDController.php @@ -5,8 +5,10 @@ namespace App\Http\Controllers; use App\WTDDraft; use App\TuntutBaki; use App\Cawangan; +use App\Customer; use Illuminate\Http\Request; use Carbon\Carbon; +use App\Helper; use Illuminate\Support\Facades\Http; @@ -34,4 +36,89 @@ class WTDController extends Controller return response()->json($tuntutbaki); } + + public function getSummaryWtd(Request $request){ + + $startDate = $request->startDate ?? now()->startOfMonth()->toDateString(); + $endDate = $request->endDate ?? now()->endOfMonth()->toDateString(); + + $active_dbs = Helper::getActiveCawanganDbConnection(); + + $cawangan = Cawangan::select('kodcaw', 'details_caw', 'mysql') + ->whereIn('mysql', $active_dbs) + ->get(); + + $responses = []; + + foreach ($cawangan as $caw) { + + $db = $caw->mysql; + + $tuntutbaki = TuntutBaki::on($db) + ->join('serahbaki', 'serahbaki.t_jual', '=', 'tuntutbaki.tarikh') + ->join('gadai', 'gadai.norujukan', '=', 'tuntutbaki.norujukan') + ->whereBetween('tuntutbaki.tarikh', [$startDate, $endDate]) + ->where('tuntutbaki.teller', 'DM') + ->where('serahbaki.aktif', 1) + ->selectRaw(" + gadai.nokp as nokp, + tuntutbaki.norujukan as norujukan, + tuntutbaki.jumlah as jumlah, + serahbaki.batchno as batchno, + serahbaki.t_jual as t_jual, + serahbaki.t_htr_ag as t_htr_ag + ") + ->orderByRaw('CAST(serahbaki.batchno AS UNSIGNED)') + ->orderBy('tuntutbaki.norujukan') + ->get(); + + $nokps = $tuntutbaki + ->pluck('nokp') + ->filter() // elak null + //->unique() + ->values(); + + $customers = Customer::on('mysql7') + ->whereIn('kplama', $nokps) + ->orWhereIn('kpbaru', $nokps) + ->get() + ->keyBy(function ($item) { + return $item->kpbaru ?: $item->kplama; + }); + + $wtd_det = []; + + foreach ($tuntutbaki as $tuntut) { + + $nokp = $tuntut->nokp; + $cust = $customers->get($nokp); + + $wtd_det[] = [ + "norujukan" => $tuntut->norujukan, + "nokp" => $nokp, + "jumlah" => (float) $tuntut->jumlah, + "batchno" => $tuntut->batchno, + "t_proses" => $tuntut->t_jual, + "t_htr_ag" => $tuntut->t_htr_ag, + "nama_cust" => $cust->nama ?? null, + ]; + } + + $details = collect($wtd_det) + ->values() + ->all(); + + $responses[] = [ + 'kodcaw' => $caw->kodcaw, + 'details_caw' => $caw->details_caw, + // WEB + 'jumlah_surat' => count($details), + 'sum_baki' => collect($details)->sum('jumlah'), + // EXCEL + 'details' => $details, + ]; + } + return response()->json($responses); + + } } diff --git a/routes/web.php b/routes/web.php index dcafcdc..c0b35af 100644 --- a/routes/web.php +++ b/routes/web.php @@ -896,11 +896,11 @@ $router->group(['prefix'=>'admin'], function () use ($router){ $router->get('wtd/rekodSimulasi',['uses'=>'AdminPageController@RekodSimulasiWTD']); $router->post('wtd/prosesSimulasi',['uses'=>'AdminPageController@ProsesSimulasiWTD']); $router->post('wtd/pengesahanSimulasi',['uses'=>'AdminPageController@PengesahanSimulasiWTD']); - $router->post('wtd/simulasiToDraft',['uses'=>'AdminPageController@SimulasiToDraft']); - $router->post('wtd/simulasiBaru',['uses'=>'AdminPageController@SimulasiBaru']); + //laporan wtd + $router->get('wtd/summaryWtd', ['uses' => 'WTDController@getSummaryWtd']); $router->get('audit/keuntungansebenar',['uses'=>'AdminPageController@KeuntunganSebenarExport']); $router->get('laporan/aging',['uses'=>'AdminPageController@LaporanAging']); From 8756def2cf4d71ed6b07e2c30aea4b7180f3e3ed Mon Sep 17 00:00:00 2001 From: Nur Izzati Date: Wed, 14 Jan 2026 09:25:57 +0800 Subject: [PATCH 35/80] update task uum --- .../Controllers/Reports/AnalisaController.php | 196 ++++++++++++++++++ routes/report.php | 2 + 2 files changed, 198 insertions(+) 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']); }); }); From 133d508625ef05a94ab7445a3f8b6ae6fd458716 Mon Sep 17 00:00:00 2001 From: Nur Izzati Date: Wed, 14 Jan 2026 15:35:29 +0800 Subject: [PATCH 36/80] update code status aktif pelanggan --- .../Controllers/Reports/AnalisaController.php | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/Reports/AnalisaController.php b/app/Http/Controllers/Reports/AnalisaController.php index c538f83..9ab1afc 100644 --- a/app/Http/Controllers/Reports/AnalisaController.php +++ b/app/Http/Controllers/Reports/AnalisaController.php @@ -283,13 +283,25 @@ public function getSummaryLaporanPelangganAktif(Request $request) $tujuangadai = $row->tujuangadai ?: '-'; // Status aktif: ada transaksi dalam tahun tu - $statusAktif = $tempohData->contains(function ($trx) use ($year) { + $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; - return $tGadai->lte(Carbon::create($year,12,31)->endOfDay()) - && (is_null($tTebus) || $tTebus->gt(Carbon::create($year,12,31)->endOfDay())); + // SAG wujud dalam tahun laporan + return + $tGadai->lte($endOfYear) && + ( + is_null($tTebus) || // belum ditebus + $tTebus->gte($startOfYear) // ditebus dalam / selepas tahun + ); }); // Umur From 302519d7231e32342dbc0bebf3052389dbfac5af Mon Sep 17 00:00:00 2001 From: Nur Izzati Date: Thu, 15 Jan 2026 12:30:25 +0800 Subject: [PATCH 37/80] update nopelanggan dalam task uum --- app/Http/Controllers/Reports/AnalisaController.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Reports/AnalisaController.php b/app/Http/Controllers/Reports/AnalisaController.php index 9ab1afc..6a6a95d 100644 --- a/app/Http/Controllers/Reports/AnalisaController.php +++ b/app/Http/Controllers/Reports/AnalisaController.php @@ -191,7 +191,7 @@ public function getSummaryLaporanPelangganAktif(Request $request) // 1️⃣ Ambil semua pelanggan tahun ini $pelanggan = Customer::whereYear('tarikhdaftar', $year) ->select('id','nama','kpbaru','kplama','t_lahir','jantina', - 'kodkerja','poskod','kodcaw','tarikhdaftar','tujuangadai') + 'kodkerja','poskod','kodcaw','tarikhdaftar','tujuangadai','nopelanggan') ->get(); $connections = $this->getActiveCawanganConnections(); @@ -320,6 +320,7 @@ public function getSummaryLaporanPelangganAktif(Request $request) return [ 'cawangan' => $row->kodcaw ?? '-', 'nama' => $row->nama, + 'nopelanggan' => $row->nopelanggan, 'nokp' => $nokp ?? '-', 'tarikhdaftar' => Carbon::parse($row->tarikhdaftar)->format('d-m-Y'), 'umur' => $umur, From ec72c708cda9430d4fa80c8d7da8027f7f0cd43d Mon Sep 17 00:00:00 2001 From: Nisha Muhd Date: Thu, 15 Jan 2026 13:07:11 +0800 Subject: [PATCH 38/80] nisha-checking-wtd --- app/Http/Controllers/WTDController.php | 67 ++++++++++++++++++++++++++ routes/web.php | 3 ++ 2 files changed, 70 insertions(+) diff --git a/app/Http/Controllers/WTDController.php b/app/Http/Controllers/WTDController.php index cfd1511..b08bbc6 100644 --- a/app/Http/Controllers/WTDController.php +++ b/app/Http/Controllers/WTDController.php @@ -9,6 +9,8 @@ use App\Customer; use Illuminate\Http\Request; use Carbon\Carbon; use App\Helper; +use App\SerahBaki; +use App\WTD; use Illuminate\Support\Facades\Http; @@ -121,4 +123,69 @@ class WTDController extends Controller return response()->json($responses); } + + public function getDebugWtd(Request $request){ + + $startDate = $request->startDate ?? now()->startOfMonth()->toDateString(); + $endDate = $request->endDate ?? now()->endOfMonth()->toDateString(); + + $active_dbs = Helper::getActiveCawanganDbConnection(); + + $cawangan = Cawangan::select('kodcaw', 'details_caw', 'mysql') + ->whereIn('mysql', $active_dbs) + ->get(); + + $responses = []; + + foreach ($cawangan as $caw) { + + $db = $caw->mysql; + + $serahbaki = SerahBaki::on($db) + ->whereBetween('t_jual', [$startDate, $endDate]) + ->where('aktif', 1) + //->selectRaw("baki as serahb") + ->sum('baki');; + //->get(); + + $tuntutbaki = TuntutBaki::on($db) + ->whereBetween('tarikh', [$startDate, $endDate]) + ->where('teller', 'DM') + //->selectRaw("jumlah as tuntutb") + ->sum('jumlah'); + //->get(); + + $twtd = WTD::on($db) + ->whereBetween('tarikh', [$startDate, $endDate]) + //->selectRaw("wtd as twtd") + ->sum('wtd'); + //->get(); + + $wtd_det = []; + + $wtd_det[] = [ + "serahb" => $serahbaki, + "tuntutb" => $tuntutbaki, + "twtd" => $twtd, + ]; + + $details = collect($wtd_det) + ->values() + ->all(); + //dd($details); + + $responses[] = [ + 'kodcaw' => $caw->kodcaw, + 'details_caw' => $caw->details_caw, + //collect($details)->sum('jumlah'), + // WEB + 'serahb' => collect($details)->sum('serahb'), + 'tuntutb' => collect($details)->sum('tuntutb'), + 'twtd' => collect($details)->sum('twtd'), + //'debugwtd' => $details, + ]; + } + return response()->json($responses); + + } } diff --git a/routes/web.php b/routes/web.php index c0b35af..2c3c1be 100644 --- a/routes/web.php +++ b/routes/web.php @@ -902,6 +902,9 @@ $router->group(['prefix'=>'admin'], function () use ($router){ //laporan wtd $router->get('wtd/summaryWtd', ['uses' => 'WTDController@getSummaryWtd']); + //debugwtd + $router->get('wtd/debugWtd', ['uses' => 'WTDController@getDebugWtd']); + $router->get('audit/keuntungansebenar',['uses'=>'AdminPageController@KeuntunganSebenarExport']); $router->get('laporan/aging',['uses'=>'AdminPageController@LaporanAging']); $router->get('dashboard/aging',['uses'=>'AdminPageController@DashboardAging']); From 7f1a42a4cd51a66b6774950bf5bd0286831aaa3c Mon Sep 17 00:00:00 2001 From: Nur Izzati Date: Sun, 18 Jan 2026 08:44:37 +0800 Subject: [PATCH 39/80] update code outstanding --- .../Controllers/Reports/AnalisaController.php | 42 ++++++++++++++++--- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/app/Http/Controllers/Reports/AnalisaController.php b/app/Http/Controllers/Reports/AnalisaController.php index 6a6a95d..7f9b8e1 100644 --- a/app/Http/Controllers/Reports/AnalisaController.php +++ b/app/Http/Controllers/Reports/AnalisaController.php @@ -186,6 +186,9 @@ public function getSummaryLaporanPelangganAktif(Request $request) return response()->json(['error' => 'Sila pilih tahun'], 400); } + $startOfYear = Carbon::create($year, 1, 1)->startOfDay(); + $endOfYear = Carbon::create($year, 12, 31)->endOfDay(); + Carbon::setLocale('ms'); // 1️⃣ Ambil semua pelanggan tahun ini @@ -207,12 +210,23 @@ public function getSummaryLaporanPelangganAktif(Request $request) $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(); + ->table('gadai as g') + ->leftJoin('tebus as t', 'g.norujukan', '=', 't.norujukan') + ->leftJoin('lelong as l', 'g.norujukan', '=', 'l.norujukan') + ->whereIn('g.nokp', $nokps) + ->whereBetween('g.t_gadai', [$startOfYear, $endOfYear]) // ⬅️ dalam tahun sahaja + ->select( + 'g.nokp', + 'g.norujukan', + 'g.t_gadai', + 't.t_tebus', + 'g.pinjaman', + 'g.upah12', + 'g.tempoh', + 'l.t_lelong', + 'g.sttebus', + ) + ->get(); $allTransaksi = $allTransaksi->concat($data); } @@ -246,6 +260,21 @@ public function getSummaryLaporanPelangganAktif(Request $request) // Bilangan transaksi $bilTransaksi = $tempohData->count(); + // Bilangan Belum tebus + $endOfYear = Carbon::create($year, 12, 31)->endOfDay(); + $bilOutstanding = $tempohData + ->filter(function ($row) use ($endOfYear) { + + // masih belum tebus langsung + if (empty($row->sttebus)) { + return true; + } + + // dah tebus, tapi tebus selepas hujung tahun + return Carbon::parse($row->t_tebus)->gt($endOfYear); + }) + ->count(); + // Bilangan tebus $bilTebus = $tempohData->whereNotNull('t_tebus')->count(); @@ -332,6 +361,7 @@ public function getSummaryLaporanPelangganAktif(Request $request) 'tarikh_tamat' => $tarikhTamat ? Carbon::parse($tarikhTamat)->format('d-m-Y') : null, 'hari_sejak_transaksi' => $hariTempohPajakan, 'bil_transaksi' => $bilTransaksi, + 'bil_outstanding' => $bilOutstanding, 'bil_tebus' => $bilTebus, 'jumlah_pinjaman' => $jumlahPinjaman, 'norujukan' => $norujukanPelanggan, From 0ac42331d49436b93c01558c335d0f9fda6e8b2d Mon Sep 17 00:00:00 2001 From: Afiq Hamzah Date: Mon, 19 Jan 2026 16:41:10 +0800 Subject: [PATCH 40/80] Add krk changes to prod --- app/Http/Controllers/AdminPageController.php | 4 +-- app/Http/Controllers/MarhunController.php | 4 +-- app/Services/Reports/ImbangDugaService.php | 3 +- .../Reports/RingkasanHarianService.php | 2 +- composer.json | 2 +- composer.lock | 31 +++++++++---------- config/tennant_master.php | 2 +- 7 files changed, 23 insertions(+), 25 deletions(-) diff --git a/app/Http/Controllers/AdminPageController.php b/app/Http/Controllers/AdminPageController.php index ac61471..55d9e2a 100644 --- a/app/Http/Controllers/AdminPageController.php +++ b/app/Http/Controllers/AdminPageController.php @@ -4050,11 +4050,11 @@ class AdminPageController extends Controller 'tarikh' => $request->tarikh, 'kodcaw' => $kodcaw, ]); - $exception_case = $this->AkruKeuntunganSebenar($requestData); + $exception_case = $this->AkruKeuntunganSebenar($requestData)->getData(); } $backdate_keun_sebenar += isset($get_imbangduga['keun_sebenar']) ? $get_imbangduga['keun_sebenar'] : 0; - $backdate_keun_sebenar += $exception_case; + $backdate_keun_sebenar += (float) ($exception_case ?? 0); $recentDate->subYear()->startOfYear(); } diff --git a/app/Http/Controllers/MarhunController.php b/app/Http/Controllers/MarhunController.php index 8c8a7b7..1ae633e 100644 --- a/app/Http/Controllers/MarhunController.php +++ b/app/Http/Controllers/MarhunController.php @@ -203,7 +203,7 @@ class MarhunController extends Controller $marhun = Marhun::on($cawangan['mysql']) ->select('marhun.norujukan','gadai.nokp','customer.nama','marhun.marhun','marhun.nota','marhun.berat','marhun.karat','marhun.harga','marhun.n_marhun','marhun.t_gadai','marhun.tag_permata', 'marhun.berat_batu_permata') ->rightJoin('gadai', 'gadai.norujukan', '=', 'marhun.norujukan') - ->rightJoin('online_arrahn.customer as customer', 'customer.kpbaru','=','gadai.nokp') + ->rightJoin('master_krk.customer as customer', 'customer.kpbaru','=','gadai.nokp') ->where('marhun.t_gadai','=',$tarikh) ->orderBy('marhun.t_gadai') ->get(); @@ -221,7 +221,7 @@ class MarhunController extends Controller $marhun = Marhun::on($cawangan['mysql']) ->select('marhun.norujukan','gadai.sttebus','gadai.pinjaman','gadai.nokp','customer.nama','marhun.marhun','marhun.nota','marhun.berat','marhun.karat','marhun.harga','marhun.n_marhun','marhun.t_gadai') ->rightJoin('gadai', 'gadai.norujukan', '=', 'marhun.norujukan') - ->rightJoin('online_arrahn.customer as customer', 'customer.kpbaru','=','gadai.nokp') + ->rightJoin('master_krk.customer as customer', 'customer.kpbaru','=','gadai.nokp') ->where('marhun.t_gadai','<=',$tarikh) ->whereYear('marhun.t_gadai','=',$current->year) ->where('gadai.sttebus','=','') diff --git a/app/Services/Reports/ImbangDugaService.php b/app/Services/Reports/ImbangDugaService.php index a349f8b..de5f976 100644 --- a/app/Services/Reports/ImbangDugaService.php +++ b/app/Services/Reports/ImbangDugaService.php @@ -377,7 +377,8 @@ class ImbangDugaService return $transaction->trans_type !== 'A'; })->sum('keuntungan_rebet'); - $total = $total_ansuran + $total_tebus + $get_imbangduga['keun_sebenar']; + $backdate_keun_sebenar = isset($get_imbangduga['keun_sebenar']) ? $get_imbangduga['keun_sebenar'] : 0; + $total = $total_ansuran + $total_tebus + $backdate_keun_sebenar; return $total; } diff --git a/app/Services/Reports/RingkasanHarianService.php b/app/Services/Reports/RingkasanHarianService.php index 4167b47..ccb76c5 100644 --- a/app/Services/Reports/RingkasanHarianService.php +++ b/app/Services/Reports/RingkasanHarianService.php @@ -1322,7 +1322,7 @@ class RingkasanHarianService return floatval($totalSerahan); } - return floatval(0); + return floatval($serahanpkbTawarruq); } diff --git a/composer.json b/composer.json index e26171c..458063f 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ "auth0/auth0-php": "^7.4", "doctrine/dbal": "2.13.5", "laravel/lumen-framework": "^7.0", - "laravel/tinker": "^2.8", + "laravel/tinker": "^2.9", "rap2hpoutre/laravel-log-viewer": "^1.7", "spatie/laravel-ray": "^1.33" }, diff --git a/composer.lock b/composer.lock index bc01192..fc82312 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "2a35e67752107934701ceea957a4fd34", + "content-hash": "fd818732ff1c4578859e2cd033cf5114", "packages": [ { "name": "auth0/auth0-php", @@ -2541,25 +2541,25 @@ }, { "name": "laravel/tinker", - "version": "v2.8.2", + "version": "v2.9.0", "source": { "type": "git", "url": "https://github.com/laravel/tinker.git", - "reference": "b936d415b252b499e8c3b1f795cd4fc20f57e1f3" + "reference": "502e0fe3f0415d06d5db1f83a472f0f3b754bafe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/tinker/zipball/b936d415b252b499e8c3b1f795cd4fc20f57e1f3", - "reference": "b936d415b252b499e8c3b1f795cd4fc20f57e1f3", + "url": "https://api.github.com/repos/laravel/tinker/zipball/502e0fe3f0415d06d5db1f83a472f0f3b754bafe", + "reference": "502e0fe3f0415d06d5db1f83a472f0f3b754bafe", "shasum": "" }, "require": { - "illuminate/console": "^6.0|^7.0|^8.0|^9.0|^10.0", - "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0|^10.0", - "illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0", + "illuminate/console": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", + "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", + "illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", "php": "^7.2.5|^8.0", - "psy/psysh": "^0.10.4|^0.11.1", - "symfony/var-dumper": "^4.3.4|^5.0|^6.0" + "psy/psysh": "^0.11.1|^0.12.0", + "symfony/var-dumper": "^4.3.4|^5.0|^6.0|^7.0" }, "require-dev": { "mockery/mockery": "~1.3.3|^1.4.2", @@ -2567,13 +2567,10 @@ "phpunit/phpunit": "^8.5.8|^9.3.3" }, "suggest": { - "illuminate/database": "The Illuminate Database package (^6.0|^7.0|^8.0|^9.0|^10.0)." + "illuminate/database": "The Illuminate Database package (^6.0|^7.0|^8.0|^9.0|^10.0|^11.0)." }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - }, "laravel": { "providers": [ "Laravel\\Tinker\\TinkerServiceProvider" @@ -2604,9 +2601,9 @@ ], "support": { "issues": "https://github.com/laravel/tinker/issues", - "source": "https://github.com/laravel/tinker/tree/v2.8.2" + "source": "https://github.com/laravel/tinker/tree/v2.9.0" }, - "time": "2023-08-15T14:27:00+00:00" + "time": "2024-01-04T16:10:04+00:00" }, { "name": "monolog/monolog", @@ -8396,5 +8393,5 @@ "php": "^7.2.5" }, "platform-dev": [], - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.2.0" } diff --git a/config/tennant_master.php b/config/tennant_master.php index e0e2cbe..6e88ed0 100644 --- a/config/tennant_master.php +++ b/config/tennant_master.php @@ -1,5 +1,5 @@ env('TENNANT_MASTER_DB','master_erahn') + 'database' => env('TENNANT_MASTER_DB','master_krk') ]; From 8fe42c1d9f98af79ed7a9d4fee9d91b7e5bd495e Mon Sep 17 00:00:00 2001 From: Afiq Hamzah Date: Tue, 20 Jan 2026 11:36:41 +0800 Subject: [PATCH 41/80] Refactor tenant database configuration to use dynamic config values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace hardcoded database names (online_arrahn, master_krk, kaunterpkb) with configurable values across the codebase - Rename tennant_master.php to tennant_database.php for clearer naming - Update config keys: 'database' → 'master_db', add 'kaunter_db' - Update env variables: TENNANT_MASTER_DB and TENNANT_KAUNTER_DB - Modify Helper.php to use dynamic database references in getOnlineArrahnConnection(), getActiveCawanganDbConnection(), and getInactiveCawanganDbConnection() methods - Update database JOIN queries in CustomerController and MarhunController to use config values instead of hardcoded database names - Simplify migration logic by removing redundant hardcoded database checks - Update debug messages in CawanganDebugConnections to show actual configured database name - Update bootstrap/app.php to load tennant_database config This change improves multi-environment flexibility and eliminates environment-specific hardcoded values, making the application more configurable for different deployment scenarios (KRK, KGMK, etc). --- app/Console/Commands/CawanganDebugConnections.php | 2 +- app/Helper.php | 6 +++--- app/Http/Controllers/CustomerController.php | 2 +- app/Http/Controllers/MarhunController.php | 4 ++-- bootstrap/app.php | 2 +- config/tennant_database.php | 6 ++++++ config/tennant_master.php | 5 ----- .../2023_11_14_121109_add_columns_to_komuditi_transaksi.php | 4 ++-- tinker/getActiveCawanganDbConnection.php | 2 +- 9 files changed, 17 insertions(+), 16 deletions(-) create mode 100644 config/tennant_database.php delete mode 100644 config/tennant_master.php diff --git a/app/Console/Commands/CawanganDebugConnections.php b/app/Console/Commands/CawanganDebugConnections.php index d4372f8..ec15539 100644 --- a/app/Console/Commands/CawanganDebugConnections.php +++ b/app/Console/Commands/CawanganDebugConnections.php @@ -80,7 +80,7 @@ class CawanganDebugConnections extends Command return $idToNameMap[$item['mysql']] !== $item['database']; }); } catch (\Throwable $th) { - dump(sprintf('Connection %s not found in table online_arrahn.arrahn_master_db but present in config. Make sure both of connection exist in both app/config and arrahn_master_db', $tested_connection)); + dump(sprintf('Connection %s not found in table %s.arrahn_master_db but present in config. Make sure both of connection exist in both app/config and arrahn_master_db', $tested_connection, config('tennant_database.master_db'))); return; } diff --git a/app/Helper.php b/app/Helper.php index 63fb7b7..ceccf4f 100644 --- a/app/Helper.php +++ b/app/Helper.php @@ -12,7 +12,7 @@ class Helper { $online_arrahn_connection = array_filter(config('database.connections'), function ($connection) { - if ($connection['database'] === 'online_arrahn') { + if ($connection['database'] === config('tennant_database.master_db')) { return $connection; } }); @@ -43,7 +43,7 @@ class Helper } }); - $non_cawangan_database = ['lelong', 'online_arrahn', 'kaunterpkb']; + $non_cawangan_database = ['lelong', config('tennant_database.master_db'), config('tennant_database.kaunter_db')]; $all_cawangan_db = array_filter($all_active_db_keys, function ($db_key) use ($non_cawangan_database) { $isNotCawangan = in_array(config('database.connections.' . $db_key . '.database'), $non_cawangan_database); @@ -74,7 +74,7 @@ class Helper } }); - $non_cawangan_database = ['lelong', 'online_arrahn', 'kaunterpkb']; + $non_cawangan_database = ['lelong', config('tennant_database.master_db'), config('tennant_database.kaunter_db')]; $all_cawangan_db = array_filter($all_inactive_db_keys, function ($db_key) use ($non_cawangan_database) { $isNotCawangan = in_array(config('database.connections.' . $db_key . '.database'), $non_cawangan_database); diff --git a/app/Http/Controllers/CustomerController.php b/app/Http/Controllers/CustomerController.php index c19232b..06fc48f 100644 --- a/app/Http/Controllers/CustomerController.php +++ b/app/Http/Controllers/CustomerController.php @@ -720,7 +720,7 @@ class CustomerController extends Controller $customer = Customer::on($cawangan['mysql']) ->where('kplama','=',$nokp) ->orWhere('kpbaru','=',$nokp) - ->rightJoin('online_arrahn.bank', 'bank.id', '=', 'customer.kodbank') + ->rightJoin(config('tennant_database.master_db') . '.bank', 'bank.id', '=', 'customer.kodbank') ->first(); if(!empty($customer)) diff --git a/app/Http/Controllers/MarhunController.php b/app/Http/Controllers/MarhunController.php index 1ae633e..2153483 100644 --- a/app/Http/Controllers/MarhunController.php +++ b/app/Http/Controllers/MarhunController.php @@ -203,7 +203,7 @@ class MarhunController extends Controller $marhun = Marhun::on($cawangan['mysql']) ->select('marhun.norujukan','gadai.nokp','customer.nama','marhun.marhun','marhun.nota','marhun.berat','marhun.karat','marhun.harga','marhun.n_marhun','marhun.t_gadai','marhun.tag_permata', 'marhun.berat_batu_permata') ->rightJoin('gadai', 'gadai.norujukan', '=', 'marhun.norujukan') - ->rightJoin('master_krk.customer as customer', 'customer.kpbaru','=','gadai.nokp') + ->rightJoin(config('tennant_database.master_db') . '.customer as customer', 'customer.kpbaru','=','gadai.nokp') ->where('marhun.t_gadai','=',$tarikh) ->orderBy('marhun.t_gadai') ->get(); @@ -221,7 +221,7 @@ class MarhunController extends Controller $marhun = Marhun::on($cawangan['mysql']) ->select('marhun.norujukan','gadai.sttebus','gadai.pinjaman','gadai.nokp','customer.nama','marhun.marhun','marhun.nota','marhun.berat','marhun.karat','marhun.harga','marhun.n_marhun','marhun.t_gadai') ->rightJoin('gadai', 'gadai.norujukan', '=', 'marhun.norujukan') - ->rightJoin('master_krk.customer as customer', 'customer.kpbaru','=','gadai.nokp') + ->rightJoin(config('tennant_database.master_db') . '.customer as customer', 'customer.kpbaru','=','gadai.nokp') ->where('marhun.t_gadai','<=',$tarikh) ->whereYear('marhun.t_gadai','=',$current->year) ->where('gadai.sttebus','=','') diff --git a/bootstrap/app.php b/bootstrap/app.php index bf393b1..16b5e30 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -61,7 +61,7 @@ $app->singleton( $app->configure('app'); $app->configure('tinker'); -$app->configure('tennant_master'); +$app->configure('tennant_database'); $app->configure('report'); $app->configure('app_parameter'); diff --git a/config/tennant_database.php b/config/tennant_database.php new file mode 100644 index 0000000..09d92cb --- /dev/null +++ b/config/tennant_database.php @@ -0,0 +1,6 @@ + env('TENNANT_MASTER_DB','online_arrahn'), + 'kaunter_db' => env('TENNANT_KAUNTER_DB','kaunterpkb') +]; diff --git a/config/tennant_master.php b/config/tennant_master.php deleted file mode 100644 index 6e88ed0..0000000 --- a/config/tennant_master.php +++ /dev/null @@ -1,5 +0,0 @@ - env('TENNANT_MASTER_DB','master_krk') -]; diff --git a/database/migrations/2023_11_14_121109_add_columns_to_komuditi_transaksi.php b/database/migrations/2023_11_14_121109_add_columns_to_komuditi_transaksi.php index e564eb6..897302e 100644 --- a/database/migrations/2023_11_14_121109_add_columns_to_komuditi_transaksi.php +++ b/database/migrations/2023_11_14_121109_add_columns_to_komuditi_transaksi.php @@ -42,7 +42,7 @@ class AddColumnsToKomuditiTransaksi extends Migration { $online_arrahn_connection_array = array_filter(config('database.connections'), function($connection) { - if($connection['database'] === 'online_arrahn' || $connection['database'] === 'master_krk' || $connection['database'] === config('tennant_master.database')){ + if($connection['database'] === config('tennant_database.master_db')){ return true; } @@ -53,7 +53,7 @@ class AddColumnsToKomuditiTransaksi extends Migration if(empty($online_arrahn_connection_array)){ - throw new Exception("online_arrahn or master_krk doesn't exist in config.database.connections array"); + throw new Exception("Tennant master database (" . config('tennant_database.master_db') . ") doesn't exist in config.database.connections array"); } return array_keys($online_arrahn_connection_array)[0]; diff --git a/tinker/getActiveCawanganDbConnection.php b/tinker/getActiveCawanganDbConnection.php index a9fd113..96df402 100644 --- a/tinker/getActiveCawanganDbConnection.php +++ b/tinker/getActiveCawanganDbConnection.php @@ -11,7 +11,7 @@ $all_active_db_keys = array_filter(array_keys(config('database.connections')), f } }); -$non_cawangan_database = ['lelong', 'online_arrahn', 'kaunterpkb']; +$non_cawangan_database = ['lelong', config('tennant_database.master_db'), config('tennant_database.kaunter_db')]; $all_cawangan_db = array_filter($all_active_db_keys, function($db_key) use($non_cawangan_database){ $isNotCawangan = in_array(config('database.connections.' . $db_key . '.database'), $non_cawangan_database); From 288c10bcc6766c551a15a2eba260527945d01525 Mon Sep 17 00:00:00 2001 From: Afiq Hamzah Date: Tue, 20 Jan 2026 11:42:43 +0800 Subject: [PATCH 42/80] Restore composer.json and composer.lock from production --- composer.json | 2 +- composer.lock | 31 +++++++++++++++++-------------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/composer.json b/composer.json index 458063f..e26171c 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ "auth0/auth0-php": "^7.4", "doctrine/dbal": "2.13.5", "laravel/lumen-framework": "^7.0", - "laravel/tinker": "^2.9", + "laravel/tinker": "^2.8", "rap2hpoutre/laravel-log-viewer": "^1.7", "spatie/laravel-ray": "^1.33" }, diff --git a/composer.lock b/composer.lock index fc82312..bc01192 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "fd818732ff1c4578859e2cd033cf5114", + "content-hash": "2a35e67752107934701ceea957a4fd34", "packages": [ { "name": "auth0/auth0-php", @@ -2541,25 +2541,25 @@ }, { "name": "laravel/tinker", - "version": "v2.9.0", + "version": "v2.8.2", "source": { "type": "git", "url": "https://github.com/laravel/tinker.git", - "reference": "502e0fe3f0415d06d5db1f83a472f0f3b754bafe" + "reference": "b936d415b252b499e8c3b1f795cd4fc20f57e1f3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/tinker/zipball/502e0fe3f0415d06d5db1f83a472f0f3b754bafe", - "reference": "502e0fe3f0415d06d5db1f83a472f0f3b754bafe", + "url": "https://api.github.com/repos/laravel/tinker/zipball/b936d415b252b499e8c3b1f795cd4fc20f57e1f3", + "reference": "b936d415b252b499e8c3b1f795cd4fc20f57e1f3", "shasum": "" }, "require": { - "illuminate/console": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", - "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", - "illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", + "illuminate/console": "^6.0|^7.0|^8.0|^9.0|^10.0", + "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0|^10.0", + "illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0", "php": "^7.2.5|^8.0", - "psy/psysh": "^0.11.1|^0.12.0", - "symfony/var-dumper": "^4.3.4|^5.0|^6.0|^7.0" + "psy/psysh": "^0.10.4|^0.11.1", + "symfony/var-dumper": "^4.3.4|^5.0|^6.0" }, "require-dev": { "mockery/mockery": "~1.3.3|^1.4.2", @@ -2567,10 +2567,13 @@ "phpunit/phpunit": "^8.5.8|^9.3.3" }, "suggest": { - "illuminate/database": "The Illuminate Database package (^6.0|^7.0|^8.0|^9.0|^10.0|^11.0)." + "illuminate/database": "The Illuminate Database package (^6.0|^7.0|^8.0|^9.0|^10.0)." }, "type": "library", "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + }, "laravel": { "providers": [ "Laravel\\Tinker\\TinkerServiceProvider" @@ -2601,9 +2604,9 @@ ], "support": { "issues": "https://github.com/laravel/tinker/issues", - "source": "https://github.com/laravel/tinker/tree/v2.9.0" + "source": "https://github.com/laravel/tinker/tree/v2.8.2" }, - "time": "2024-01-04T16:10:04+00:00" + "time": "2023-08-15T14:27:00+00:00" }, { "name": "monolog/monolog", @@ -8393,5 +8396,5 @@ "php": "^7.2.5" }, "platform-dev": [], - "plugin-api-version": "2.2.0" + "plugin-api-version": "2.3.0" } From 53be2d999e9c99696a4e86dd9995255460317a6e Mon Sep 17 00:00:00 2001 From: Nur Izzati Date: Tue, 27 Jan 2026 16:52:00 +0800 Subject: [PATCH 43/80] update lelong keseleuruhan --- .../Reports/LelonganController.php | 1 + app/Services/Reports/LelonganService.php | 88 +++++++++++++------ 2 files changed, 61 insertions(+), 28 deletions(-) diff --git a/app/Http/Controllers/Reports/LelonganController.php b/app/Http/Controllers/Reports/LelonganController.php index 1e2195f..539ae2e 100644 --- a/app/Http/Controllers/Reports/LelonganController.php +++ b/app/Http/Controllers/Reports/LelonganController.php @@ -60,6 +60,7 @@ class LelonganController extends Controller sum(lelong.cajlain) as sum_cajlain, sum(lelong.cajlelong) as sum_cajlelong, sum(lelong.hargajual) as sum_hargajual, + sum(lelong.hargaasas) as sum_hargaasas, sum(lelong.baki) as sum_baki')); diff --git a/app/Services/Reports/LelonganService.php b/app/Services/Reports/LelonganService.php index af2ed7b..99eec40 100644 --- a/app/Services/Reports/LelonganService.php +++ b/app/Services/Reports/LelonganService.php @@ -58,7 +58,7 @@ class LelonganService $marhun_lelongan = $this->getMarhunLelongan($total_lelongan, $cawangan_connection); $cawangan_detail = $this->getCawanganDetail($cawangan_connection); - $total_lelongan = $total_lelongan->zip($customer_info, $marhun_lelongan)->map(function ($data) { + $total_lelongan = $total_lelongan->zip($customer_info, $marhun_lelongan)->map(function ($data) use ($total_lelongan) { [$lelong, $customer_info, $marhun_lelongan] = $data; @@ -76,31 +76,38 @@ class LelonganService 'bakipjm' => $lelong['bakipjm'], 'keuntungan' => $lelong['bakiupah'], 'cajlelong' => $lelong['cajlelong'], + 'hargaasas' => $lelong['hargaasas'], 'hargajual' => $lelong['hargajual'], 'baki' => $lelong['baki'], 'teller' => $lelong['teller'], ]; - dd($data); }); $total_lelongan = $total_lelongan->groupBy('teller'); - $lelongan_tellers = $total_lelongan->keys(); + $result = []; - $total_lelongan = $total_lelongan - ->zip($total_summary_lelongan_teller) - ->map(function ($data) { + foreach ($total_lelongan as $teller => $lelongan) { + $result[$teller] = [ + 'lelongan' => $lelongan->values(), + 'summary_lelongan_teller' => $total_summary_lelongan_teller[$teller] ?? [ + 'total_lelongan' => 0, + 'total_berat' => 0, + 'total_nilai_marhun' => 0, + 'total_pembiayaan' => 0, + 'total_bakipjm' => 0, + 'total_keuntungan' => 0, + 'total_cajlelong' => 0, + 'total_hargaasas' => 0, + 'total_hargajual' => 0, + 'total_baki' => 0, + ], + ]; + } - [$lelongan, $summary] = $data; + $total_lelongan = collect($result); - return [ - 'lelongan' => $lelongan, - 'summary_lelongan_teller' => $summary, - ]; - }); - - $total_lelongan = $lelongan_tellers->combine($total_lelongan); $data = [ 'query' => [ @@ -143,6 +150,7 @@ class LelonganService sum(gadai.bakipjm) as total_bakipjm, sum(lelong.bakiupah) as total_keuntungan, sum(lelong.cajlelong) as total_cajlelong, + sum(lelong.hargaasas) as total_hargaasas, sum(lelong.hargajual) as total_hargajual, sum(lelong.baki) as total_baki') ->get() @@ -155,32 +163,54 @@ class LelonganService 'total_bakipjm' => $x['total_bakipjm'], 'total_keuntungan' => $x['total_keuntungan'], 'total_cajlelong' => $x['total_cajlelong'], + 'total_hargaasas' => $x['total_hargaasas'], 'total_hargajual' => $x['total_hargajual'], 'total_baki' => $x['total_baki'] ]; }); - // dd($total_summary_lelongan); return $total_summary_lelongan[0]; } + // private function getTotalSummaryLelonganGroupByTeller(Builder $query_total_lelongan) + // { + + // $total_summary_lelongan_groupByTeller = (clone $query_total_lelongan) + // ->selectRaw('count(lelong.norujukan) as total_lelongan, + // sum(lelong.berat) as total_berat, + // sum(lelong.nilaimarhun) as total_nilai_marhun, + // sum(lelong.pinjaman) as total_pembiayaan, + // sum(gadai.bakipjm) as total_bakipjm, + // sum(lelong.bakiupah) as total_keuntungan, + // sum(lelong.cajlelong) as total_cajlelong, + // sum(lelong.hargaasas) as total_hargaasas, + // sum(lelong.hargajual) as total_hargajual, + // sum(lelong.baki) as total_baki') + // ->groupBy('lelong.teller') + // ->get(); + // return $total_summary_lelongan_groupByTeller; + // } private function getTotalSummaryLelonganGroupByTeller(Builder $query_total_lelongan) { - - $total_summary_lelongan_groupByTeller = (clone $query_total_lelongan) - ->selectRaw('count(lelong.norujukan) as total_lelongan, - sum(lelong.berat) as total_berat, - sum(lelong.nilaimarhun) as total_nilai_marhun, - sum(lelong.pinjaman) as total_pembiayaan, - sum(gadai.bakipjm) as total_bakipjm, - sum(lelong.bakiupah) as total_keuntungan, - sum(lelong.cajlelong) as total_cajlelong, - sum(lelong.hargajual) as total_hargajual, - sum(lelong.baki) as total_baki') + return (clone $query_total_lelongan) + ->selectRaw(' + lelong.teller, + count(lelong.norujukan) as total_lelongan, + sum(lelong.berat) as total_berat, + sum(lelong.nilaimarhun) as total_nilai_marhun, + sum(lelong.pinjaman) as total_pembiayaan, + sum(gadai.bakipjm) as total_bakipjm, + sum(lelong.bakiupah) as total_keuntungan, + sum(lelong.cajlelong) as total_cajlelong, + sum(lelong.hargaasas) as total_hargaasas, + sum(lelong.hargajual) as total_hargajual, + sum(lelong.baki) as total_baki + ') ->groupBy('lelong.teller') - ->get(); - return $total_summary_lelongan_groupByTeller; + ->get() + ->keyBy('teller'); // ⭐ PENTING } + private function getTotalLelongan(Builder $query_total_lelongan) { $total_lelongan = (clone $query_total_lelongan) @@ -199,6 +229,7 @@ class LelonganService 'gadai.bakipjm', 'lelong.bakiupah', 'lelong.cajlelong', + 'lelong.hargaasas', 'lelong.hargajual', 'lelong.baki') ->orderBy('lelong.teller') @@ -311,6 +342,7 @@ class LelonganService 'bakipjm' => $lelong['bakipjm'], 'keuntungan' => $lelong['bakiupah'], 'cajlelong' => $lelong['cajlelong'], + 'hargaasas' => $lelong['hargaasas'], 'hargajual' => $lelong['hargajual'], 'baki' => $lelong['baki'], 'teller' => $lelong['teller'], From 96d70bf2a93f7e0fdbb2a94cc3a774660c55acf6 Mon Sep 17 00:00:00 2001 From: Ain Izazi Date: Mon, 2 Feb 2026 10:44:02 +0800 Subject: [PATCH 44/80] fix report gadaian v2 not sync with v3 --- app/Http/Controllers/GadaiController.php | 99 +++++++---- .../Miscellaneous/StatistikService.php | 165 ++++++++++++++++++ 2 files changed, 232 insertions(+), 32 deletions(-) create mode 100644 app/Services/Miscellaneous/StatistikService.php diff --git a/app/Http/Controllers/GadaiController.php b/app/Http/Controllers/GadaiController.php index 71f3863..942cc85 100644 --- a/app/Http/Controllers/GadaiController.php +++ b/app/Http/Controllers/GadaiController.php @@ -29,6 +29,7 @@ use App\KomuditiTransaksi; use App\Advansur; use App\HistoryEmasSandaran; use App\InOutMar; +use App\Services\Miscellaneous\StatistikService; use Illuminate\Http\Request; @@ -587,44 +588,78 @@ class GadaiController extends Controller public function getLaporanGadaiRangeDate($kodcaw,Request $request){ - $cawangan = Cawangan::on('mysql7')->where('kodcaw','=',$kodcaw)->first(); + $mula = $request->mula; + $akhir = $request->akhir; - $gadai_data = Gadai::on($cawangan['mysql'])->select('t_gadai','norujukan','nokp','semakbarcode','masa','berat','nilaimarhun','pinjaman','upah12','percentpinj','teller','nokp','ujrah','onepercent','tagbaru') - ->where('t_gadai','>=',$request->mula) - ->where('t_gadai','<=',$request->akhir) - ->orderBy('t_gadai') - ->orderBy('teller') - ->orderBy('sirig') - ->get(); + $cawangan = Cawangan::on('mysql7')->where('kodcaw', $kodcaw)->first(); - $gadai = []; + $gadai_data = Gadai::on($cawangan['mysql']) + ->whereBetween('t_gadai', [$request->mula, $request->akhir]) + ->orderBy('t_gadai') + ->orderBy('teller') + ->orderBy('sirig') + ->get(); - if($gadai_data){ - foreach($gadai_data as $index=>$gadaiData){ - $customer_info = Customer::on('mysql7')->where('kplama','=',$gadaiData['nokp'])->orWhere('kpbaru','=',$gadaiData['nokp'])->first(); - array_push($gadai,[ - "t_gadai"=> $gadaiData['t_gadai'], - "norujukan"=> $gadaiData['norujukan'], - "nama"=> $customer_info['nama'], - "nokp"=> $gadaiData['nokp'], - "semakbarcode"=> $gadaiData['semakbarcode'], - "masa"=> $gadaiData['masa'], - "berat"=> $gadaiData['berat'], - "nilaimarhun"=> $gadaiData['nilaimarhun'], - "pinjaman"=> $gadaiData['pinjaman'], - "upah12"=> $gadaiData['upah12'], - "percentpinj"=> $gadaiData['percentpinj'], - "alamat1"=> $customer_info['alamat1'], - "teller"=> $gadaiData['teller'], - "ujrah"=> $gadaiData['ujrah'], - "onepercent"=> $gadaiData['onepercent'], - "tagbaru"=> $gadaiData['tagbaru'] + $nokps = $gadai_data->pluck('nokp')->unique(); - ]); + $customers = Customer::on('mysql7') + ->where(function($query) use ($nokps) { + $query->whereIn('kpbaru', $nokps) + ->orWhereIn('kplama', $nokps); + }) + ->get() + ->flatMap(fn($c) => [ + $c->kpbaru => $c, + $c->kplama => $c + ]); + $gadai = $gadai_data->map(function ($g) use ($customers) { + + foreach($customers as $key=>$value){ + if($g->nokp == $value->kpbaru || $g->nokp == $value->kplama){ + $customer = $value; + } } - } - return response()->json($gadai); + return [ + + "nama" => optional($customer)->nama, + "alamat1" => optional($customer)->alamat1, + "t_gadai" => $g->t_gadai, + "norujukan" => $g->norujukan, + "norujukan"=> $g->norujukan, + + "nokp"=> $g->nokp, + "semakbarcode"=> $g->semakbarcode, + "masa"=> $g->masa, + "berat"=> $g->berat, + "nilaimarhun"=> $g->nilaimarhun, + "pinjaman"=> $g->pinjaman, + "upah12"=> $g->upah12, + "percentpinj"=> $g->percentpinj, + "alamat1"=> optional($customer)->alamat1, + "teller"=> $g->teller, + "ujrah"=> $g->ujrah, + "onepercent"=> $g->onepercent, + "tagbaru"=> $g->tagbaru, + "kodkerja"=> optional($customer)->kodkerja, + "bangsa"=> optional($customer)->bangsa, + + ]; + }); + // dd($gadai); + + $statistikService = new StatistikService($kodcaw,$mula,$akhir); + $reportgadai = $statistikService->LaporanStatistik($gadai); + // dd($nokps); + + return response()->json([ + 'gadai' => $gadai, + 'kodcaw' => $kodcaw, + 'mula' => $mula, + 'akhir' => $akhir, + 'statistik' => $reportgadai, + 'jumlah' => $gadai->count(), + ]); } public function getLaporanBatalGadai($kodcaw,$tarikh){ diff --git a/app/Services/Miscellaneous/StatistikService.php b/app/Services/Miscellaneous/StatistikService.php new file mode 100644 index 0000000..3e251b4 --- /dev/null +++ b/app/Services/Miscellaneous/StatistikService.php @@ -0,0 +1,165 @@ +kodcaw = $kodcaw; + $this->mysql = Cawangan::on('mysql7')->where('kodcaw', $kodcaw)->value('mysql'); + $this->mula = $mula; + $this->akhir = $akhir; + } + + public function LaporanStatistik($gadai) : array + { + $reportPembiayaan = $this->countPawnByType($gadai); + $reportLoanAmount = $this->countPawnByLoan($gadai); + $reportMarhunValue = $this->countMarhunByValue($gadai); + $reportMarhunMargin = $this->countMarhunByMargin($gadai); + $reportCustomerJob = $this->countCustomerByJob($gadai); + $reportCustomerRace = $this->countCustomerByRace($gadai); + // dd($reportCustomerRace); + + return [ + 'reportPembiayaan' => $reportPembiayaan, + 'reportLoanAmount' => $reportLoanAmount, + 'reportMarhunValue' => $reportMarhunValue, + 'reportMarhunMargin' => $reportMarhunMargin, + 'reportCustomerJob' => $reportCustomerJob, + 'reportCustomerRace' => $reportCustomerRace, + ]; + } + + private function countPawnByType($gadai) + { + $pembiayaanbaru = Tebus::on($this->mysql) + ->join('gadai as g1', 'tebus.norujukan', '=', 'g1.norujukan') + ->join('gadai as g2', function ($join) { + $join->on('g2.nokp', '=', 'g1.nokp') + ->on('g2.t_gadai', '=', 'tebus.t_tebus') + ->whereRaw('ABS(g2.berat - g1.berat) <= 0.02') + ->whereColumn('g2.norujukan', '!=', 'g1.norujukan'); + }) + ->whereBetween('tebus.t_tebus', [$this->mula, $this->akhir]) + ->groupBy('tebus.norujukan') + ->selectRaw(" + tebus.norujukan as norujukan_tebus, + MAX(g2.norujukan) as norujukanpembiayaansemula, + MAX(g1.taglel) as taglel_lama + ") + ->get() + ->toArray(); + + $pembiayaanbaruNorujukan = array_column($pembiayaanbaru, 'norujukanpembiayaansemula'); + $filteredNorujukanLelongan = array_column( + array_filter($pembiayaanbaru, function ($item) { + return $item['taglel_lama'] == 1; + }), + 'norujukanpembiayaansemula' + ); + $filteredPSNorujukan = array_column( + array_filter($pembiayaanbaru, function ($item) { + return $item['taglel_lama'] == 0; + }), + 'norujukanpembiayaansemula' + ); + + + $pembiayaanbaru = $gadai->whereIn('norujukan', $filteredPSNorujukan)->count(); + $pembiayaansemula = $gadai->whereNotIn('norujukan', $pembiayaanbaruNorujukan)->count(); + $lelongan = $gadai->whereIn('norujukan', $filteredNorujukanLelongan)->count(); + + return [ + 'pembiayaanbaru' => $pembiayaanbaru, + 'pembiayaansemula' => $pembiayaansemula, + 'lelongan' => $lelongan + ]; + } + + private function countPawnByLoan($gadai) + { + return collect($gadai)->countBy(function ($item) { + $loan = $item['pinjaman']; + + if ($loan <= 400.99) return '< 400.99'; + if ($loan >= 401 && $loan <= 2000) return '401 - 2000'; + if ($loan >= 2001 && $loan <= 24999) return '2001 - 2499'; + if ($loan >= 2500) return '>= 2500'; + if ($loan > 101000) return '>101000'; + })->toArray(); + } + + private function countMarhunByValue($gadai) + { + return collect($gadai)->countBy(function ($item) { + $nilaimarhun = $item['nilaimarhun']; + + if ($nilaimarhun <= 400.99) return '< 1-400'; + if ($nilaimarhun >= 401 && $nilaimarhun <= 2000) return '401-2000'; + if ($nilaimarhun > 2001) return '> 2001'; + })->toArray(); + } + + private function countMarhunByMargin($gadai) + { + return collect($gadai)->countBy(function ($item) { + $margin= $item['percentpinj']; + + if ($margin >= 10 && $margin <= 40.99) return '10-40.99'; + if ($margin >= 41 && $margin <= 60.99) return '41-60.99'; + if ($margin >= 61 && $margin <= 80) return '> 61-80'; + })->toArray(); + } + + private function countCustomerByJob($gadai) + { + $jobMap = [ + 1 => 'Peniaga', + 2 => 'Pekerja Swasta', + 3 => 'Pekerja Kerajaan', + 4 => 'Bekerja Sendiri', + 5 => 'Suri Rumah', + 6 => 'Lain-lain', + ]; + + return collect($gadai)->countBy(function ($item) use ($jobMap) { + $kodkerja = floatval($item['kodkerja']); + return $jobMap[$kodkerja] ?? 'Lain-lain'; + })->toArray(); + + } + + private function countCustomerByRace($gadai){ + + $raceMap = [ + 'M' => 'Melayu', + 'C' => 'Cina', + 'I' => 'India', + 'L' => 'Lain-lain', + ]; + + return collect($gadai)->countBy(function ($item) use ($raceMap) { + return $raceMap[$item['bangsa']] ?? 'Lain-lain'; + + })->toArray(); + + } +} From dbbc18516e9e805ad3c32151bb564b705a1cbd11 Mon Sep 17 00:00:00 2001 From: Ain Izazi Date: Mon, 2 Feb 2026 12:48:59 +0800 Subject: [PATCH 45/80] fix report petibesi --- app/Http/Controllers/VaultController.php | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/app/Http/Controllers/VaultController.php b/app/Http/Controllers/VaultController.php index 333008d..04f3290 100644 --- a/app/Http/Controllers/VaultController.php +++ b/app/Http/Controllers/VaultController.php @@ -454,18 +454,26 @@ class VaultController extends Controller return response()->json($arraytunaiditangan,200); } - - public function laporanPetiBesi($kodcaw,$tarikh) { - $current = Carbon::now(); - $current = new Carbon(); + $current = Carbon::now(); + $current = new Carbon(); $cawangan = Cawangan::on('mysql7')->where('kodcaw','=',$kodcaw)->first(); - $vault=Vault::on($cawangan['mysql']) - ->where('kodcaw','=',$kodcaw) - ->where('tarikh','=', $tarikh) - ->orderby('tarikh','desc')->first(); + + if (!$cawangan) { + return response()->json(['error' => 'Cawangan tidak dijumpai'], 404); + } + + $vault = Vault::on($cawangan['mysql']) + ->where('kodcaw','=',$kodcaw) + ->where('tarikh','=', $tarikh) + ->orderby('tarikh','desc') + ->first(); + + if (!$vault) { + return response()->json(['error' => 'Tiada data pada tarikh tersebut'], 404); + } return response()->json($vault); } From a4b235511be5595587b46bd169c813b337654770 Mon Sep 17 00:00:00 2001 From: Nur Izzati Date: Tue, 10 Feb 2026 10:42:18 +0800 Subject: [PATCH 46/80] update tast uum bycaw --- .../Controllers/Reports/AnalisaController.php | 239 ++++++++++++++++++ routes/report.php | 1 + 2 files changed, 240 insertions(+) diff --git a/app/Http/Controllers/Reports/AnalisaController.php b/app/Http/Controllers/Reports/AnalisaController.php index 7f9b8e1..86a4b27 100644 --- a/app/Http/Controllers/Reports/AnalisaController.php +++ b/app/Http/Controllers/Reports/AnalisaController.php @@ -402,10 +402,249 @@ public function getSummaryLaporanPelangganAktif(Request $request) } + public function getSummaryLaporanDataPelangganBycaw(Request $request) + { + $year = $request->year; + if (!$year) { + return response()->json(['error' => 'Sila pilih tahun'], 400); + } + // =============================== + // INPUT CAWANGAN (MULTIPLE) + // =============================== + $cawangan = $request->input('cawangan', []); + if (!is_array($cawangan)) { + $cawangan = [$cawangan]; + } + + $startOfYear = Carbon::create($year, 1, 1)->startOfDay(); + $endOfYear = Carbon::create($year, 12, 31)->endOfDay(); + Carbon::setLocale('ms'); + // =============================== + // 1️⃣ AMBIL PELANGGAN (FILTER CAWANGAN) + // =============================== + $pelangganQuery = Customer::whereYear('tarikhdaftar', $year); + if (!empty($cawangan)) { + $pelangganQuery->whereIn('kodcaw', $cawangan); + } + + $pelanggan = $pelangganQuery + ->select( + 'id','nama','kpbaru','kplama','t_lahir','jantina', + 'kodkerja','poskod','kodcaw','tarikhdaftar', + 'tujuangadai','nopelanggan' + ) + ->get(); + + if ($pelanggan->isEmpty()) { + return response()->json([ + 'year' => $year, + 'summary' => [ + 'total_pelanggan' => 0, + 'jumlah_cawangan' => 0, + ], + 'pelanggan' => [] + ], 200); + } + + // =============================== + // 2️⃣ CONNECTION CAWANGAN + // =============================== + $connections = $this->getActiveCawanganConnections(); + + // =============================== + // 3️⃣ MASTER DATA + // =============================== + $pekerjaanAll = Pekerjaan::pluck('keterangan', 'kodkerja'); + $poskodAll = Poskod::with('daerah')->get()->keyBy('poskod'); + + // =============================== + // 4️⃣ NOKP PELANGGAN + // =============================== + $nokps = $pelanggan + ->map(fn($p) => $p->kpbaru ?? $p->kplama) + ->filter() + ->values(); + + // =============================== + // 5️⃣ TRANSAKSI GADAI / TEBUS + // =============================== + $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) + ->whereBetween('g.t_gadai', [$startOfYear, $endOfYear]) + ->select( + 'g.nokp', + 'g.norujukan', + 'g.t_gadai', + 't.t_tebus', + 'g.pinjaman', + 'g.upah12', + 'g.tempoh', + 'l.t_lelong', + 'g.sttebus' + ) + ->get(); + + $allTransaksi = $allTransaksi->concat($data); + } + + $transGrouped = $allTransaksi->groupBy('nokp'); + + // =============================== + // 6️⃣ NORUJUKAN BAYARAN ONLINE + // =============================== + $onlineNorujukan = TransactionOnline::pluck('norujukan')->unique(); + + // =============================== + // 7️⃣ MAP DATA PELANGGAN + // =============================== + $result = $pelanggan->map(function ($row) use ( + $transGrouped, + $onlineNorujukan, + $pekerjaanAll, + $poskodAll, + $year + ) { + + $nokp = $row->kpbaru ?? $row->kplama; + + $tempohData = $transGrouped->get($nokp, collect()); + + $norujukanPelanggan = $tempohData->pluck('norujukan')->unique(); + + // Cara Bayaran + $adaOnline = $norujukanPelanggan + ->intersect($onlineNorujukan) + ->isNotEmpty(); + + $caraBayaran = $adaOnline ? 'Online' : 'Kaunter'; + + // Bilangan + $bilTransaksi = $tempohData->count(); + + $bilOutstanding = $tempohData->filter(function ($row) use ($year) { + $endOfYear = Carbon::create($year, 12, 31)->endOfDay(); + + if (empty($row->sttebus)) return true; + + return Carbon::parse($row->t_tebus)->gt($endOfYear); + })->count(); + + $bilTebus = $tempohData->whereNotNull('t_tebus')->count(); + + // Jumlah + $jumlahPinjaman = $tempohData->sum('pinjaman'); + + $jumlahUjrah = $tempohData->reduce(function ($carry, $trx) { + if (!$trx->upah12 || !$trx->tempoh) return $carry; + return $carry + ($trx->upah12 / 12 * $trx->tempoh); + }, 0); + + // Tarikh + $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(); + + // Status Aktif + $startOfYear = Carbon::create($year, 1, 1)->startOfDay(); + $endOfYear = Carbon::create($year, 12, 31)->endOfDay(); + + $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; + + return $tGadai->lte($endOfYear) && + (is_null($tTebus) || $tTebus->gte($startOfYear)); + }); + + // 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 = $row->poskod && isset($poskodAll[$row->poskod]) + ? ($poskodAll[$row->poskod]->daerah->namadaerah ?? 'Lain-lain') + : 'Lain-lain'; + + + return [ + 'cawangan' => $row->kodcaw, + 'nama' => $row->nama, + 'nopelanggan' => $row->nopelanggan, + '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_outstanding' => $bilOutstanding, + 'bil_tebus' => $bilTebus, + 'jumlah_pinjaman' => $jumlahPinjaman, + 'jumlah_ujrah' => $jumlahUjrah, + 'tujuan_gadai' => $tujuangadai, + 'cara_bayaran' => $caraBayaran, + 'status_aktif' => $statusAktif ? 'AKTIF' : 'TIDAK AKTIF', + 'tarikh_lelong' => $tarikhLelong + ? Carbon::parse($tarikhLelong)->format('d-m-Y') + : null, + ]; + }); + + $result = $result->sortBy('cawangan')->values(); + + return response()->json([ + 'year' => $year, + 'cawangan' => $cawangan, + 'summary' => [ + 'total_pelanggan' => $result->count(), + 'jumlah_cawangan' => $result->pluck('cawangan')->unique()->count(), + ], + 'pelanggan' => $result, + ], 200); + } } diff --git a/routes/report.php b/routes/report.php index 2ed721d..c202553 100644 --- a/routes/report.php +++ b/routes/report.php @@ -59,5 +59,6 @@ $router->group(['prefix' => 'api/reports'], function () use ($router) { $router->get('saringan/gadaian', ['uses' => 'SaringanGadaianController@getLaporanGadai']); $router->get('data-pelanggan', ['uses' => 'AnalisaController@getSummaryLaporanDataPelanggan']); + $router->get('data-pelanggan-bycaw', ['uses' => 'AnalisaController@getSummaryLaporanDataPelangganBycaw']); }); }); From edcc0dc0d415604613bb98e48b86558ec9ff6b32 Mon Sep 17 00:00:00 2001 From: Nur Izzati Date: Sun, 22 Feb 2026 14:13:19 +0800 Subject: [PATCH 47/80] tambah field barang kes dalam laporan outstanding --- app/Http/Controllers/Reports/OutstandingController.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/Http/Controllers/Reports/OutstandingController.php b/app/Http/Controllers/Reports/OutstandingController.php index 7b8c110..8043739 100644 --- a/app/Http/Controllers/Reports/OutstandingController.php +++ b/app/Http/Controllers/Reports/OutstandingController.php @@ -46,10 +46,17 @@ class OutstandingController extends Controller // Query outstanding summary for each branch $summary_Outstanding_data = array_map(function ($db_connection) use ($endDate) { + // SAG KES + $queryKes = Gadai::on($db_connection) + ->selectRaw('COUNT(norujukan) as total_gadaian_kes, SUM(pinjaman) as sum_pinjaman_kes') + ->where('tagbaru', 0) + ->where('tagpalsu', 1) + ->where('sttebus', ''); // SAG LAMA $queryLama = Gadai::on($db_connection) ->selectRaw('COUNT(norujukan) as total_gadaian, SUM(pinjaman) as sum_pinjaman') ->where('tagbaru', 0) + ->where('tagpalsu', 0) ->where('sttebus', ''); // SAG BARU @@ -64,12 +71,14 @@ class OutstandingController extends Controller ->where('sttebus', ''); if (!empty($endDate)) { + $queryKes->where('t_gadai', '<=', $endDate); $queryLama->where('t_gadai', '<=', $endDate); $queryBaru->where('t_gadai', '<=', $endDate); $queryAll->where('t_gadai', '<=', $endDate); } return array_merge( + $queryKes->first()->toArray(), $queryLama->first()->toArray(), $queryBaru->first()->toArray(), $queryAll->first()->toArray() From df734c2482364dcc2e24ca299495579962bb3d45 Mon Sep 17 00:00:00 2001 From: Nur Izzati Date: Sun, 22 Feb 2026 15:31:11 +0800 Subject: [PATCH 48/80] update laporan peti besi --- app/Http/Controllers/Reports/OutstandingController.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/Http/Controllers/Reports/OutstandingController.php b/app/Http/Controllers/Reports/OutstandingController.php index 8043739..7e70c3e 100644 --- a/app/Http/Controllers/Reports/OutstandingController.php +++ b/app/Http/Controllers/Reports/OutstandingController.php @@ -127,10 +127,12 @@ class OutstandingController extends Controller if (!empty($endDate)) { $queryAll->where('tarikh', '=', $endDate); } - - return array_merge( - $queryAll->first()->toArray() - ); + $record = $queryAll->first(); + + return $record + ? $record->toArray() + : ['bakieod' => 0]; + }, $active_cawangan_db_connection); // Combine data with branch info From 522727159f20b97a8dd20f09281ec464c1ff4961 Mon Sep 17 00:00:00 2001 From: Nur Izzati Date: Mon, 23 Feb 2026 15:25:29 +0800 Subject: [PATCH 49/80] tambah baik laporan stok audit keseluruhan --- .../Reports/StokAuditController.php | 72 +++++++++++++------ 1 file changed, 49 insertions(+), 23 deletions(-) diff --git a/app/Http/Controllers/Reports/StokAuditController.php b/app/Http/Controllers/Reports/StokAuditController.php index 16ad7bd..af2ff70 100644 --- a/app/Http/Controllers/Reports/StokAuditController.php +++ b/app/Http/Controllers/Reports/StokAuditController.php @@ -2,9 +2,11 @@ namespace App\Http\Controllers\Reports; use App\Cawangan; +use App\Gadai; use App\Helper; use App\Http\Controllers\Controller; use Illuminate\Http\Request; +use Carbon\Carbon; class StokAuditController extends Controller { @@ -38,6 +40,40 @@ class StokAuditController extends Controller public function getSummaryLaporanStokAudit(Request $request) { + $connections = $this->getActiveCawanganConnections(); + + // MODE 1: TARIKH SEMASA + if ($request->dateOption === 'current') { + + $today = Carbon::today(); + + $total_audit = $connections->map(function ($connection) { + + $data = Gadai::on($connection->mysql) + ->where('tagpalsu', 0) + ->where(function($q) { + $q->where('sttebus', '') + ->orWhereNull('sttebus'); + }) + ->get(); + + return [ + 'cawangan' => $connection->details_caw, + 'bilangan_pembiayaan' => $data->count(), + 'berat' => $data->sum('berat'), + 'nilai_marhun' => $data->sum('nilaimarhun'), + 'baki_pembiayaan' => $data->sum('bakipjm'), + 'pembiayaan' => $data->sum('pinjaman'), + 'upah_belum_bayar' => $data->sum('upahblmbyar'), + 'total_utg_onepercent' => 0, + 'total_ujrah' => $data->sum('ujrah'), + ]; + }); + + } + // MODE 2: BULAN TERTENTU + else { + $month = $request->month; $year = $request->year; @@ -59,34 +95,24 @@ class StokAuditController extends Controller 'total_ujrah' => $data->sum('ujrah'), ]; }); + } - $getTotalAcrossCawangan = function($property) use($total_audit) { - $total = array_reduce($total_audit->toArray(), function($carry, $subarray) use($property) { - return $carry + $subarray[$property]; - }, 0); - - return $total; - }; - - $total_all_cawangan_audit = [ + // TOTAL SEMUA CAWANGAN + $total_all = [ 'cawangan' => 'Total Semua Cawangan', - 'bilangan_pembiayaan' => $getTotalAcrossCawangan('bilangan_pembiayaan'), - 'berat' => $getTotalAcrossCawangan('berat'), - 'nilai_marhun' => $getTotalAcrossCawangan('nilai_marhun'), - 'baki_pembiayaan' => $getTotalAcrossCawangan('baki_pembiayaan'), - 'pembiayaan' => $getTotalAcrossCawangan('pembiayaan'), - 'upah_belum_bayar' => $getTotalAcrossCawangan('upah_belum_bayar'), - 'total_utg_onepercent' => $getTotalAcrossCawangan('total_utg_onepercent'), - 'total_ujrah' => $getTotalAcrossCawangan('total_ujrah'), + 'bilangan_pembiayaan' => $total_audit->sum('bilangan_pembiayaan'), + 'berat' => $total_audit->sum('berat'), + 'nilai_marhun' => $total_audit->sum('nilai_marhun'), + 'baki_pembiayaan' => $total_audit->sum('baki_pembiayaan'), + 'pembiayaan' => $total_audit->sum('pembiayaan'), + 'upah_belum_bayar' => $total_audit->sum('upah_belum_bayar'), + 'total_utg_onepercent' => $total_audit->sum('total_utg_onepercent'), + 'total_ujrah' => $total_audit->sum('total_ujrah'), ]; - $total_audit->push($total_all_cawangan_audit); + $total_audit->push($total_all); - if (sizeof($total_audit) == 0) { - return response()->json('failed', 200); - } else { - return response()->json($total_audit, 200); - } + return response()->json($total_audit, 200); } } From 00ee7be8368a5635e31b2fe92ae38cdc03a34dd9 Mon Sep 17 00:00:00 2001 From: Nisha Muhd Date: Sun, 12 Apr 2026 12:46:38 +0800 Subject: [PATCH 50/80] fixbugs-wtd-process --- app/Http/Controllers/AdminPageController.php | 4 ++-- app/Http/Controllers/LaporanController.php | 20 ++++++++++++++++---- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/app/Http/Controllers/AdminPageController.php b/app/Http/Controllers/AdminPageController.php index 55d9e2a..bb36bc1 100644 --- a/app/Http/Controllers/AdminPageController.php +++ b/app/Http/Controllers/AdminPageController.php @@ -2727,7 +2727,7 @@ class AdminPageController extends Controller 'prkod' => "01", 'teller' => "DM", 'bakipjm' => ($lel['bakipjm']) ? $lel['bakipjm'] : 0, - 'bakiupah' => $lel['bakiupah'], + 'bakiupah' => ($lel['bakiupah']) ? $lel['bakiupah'] : 0, 'cajlain' => '0.00', 'cajlelong' => $lel['cajlelong'], 'kodgl' => '', @@ -2749,7 +2749,7 @@ class AdminPageController extends Controller 't_jual' => $lel['t_jual'], 'hargajual' => $lel['hargajual'], 'pinjaman' => $lel['pinjaman'], - 'bakiupah' => $lel['bakiupah'], + 'bakiupah' => ($lel['bakiupah']) ? $lel['bakiupah'] : 0, 'cajlelong' => $lel['cajlelong'], 'gst_cl' => $lel['gst_cl'], 'baki' => $lel['baki'], diff --git a/app/Http/Controllers/LaporanController.php b/app/Http/Controllers/LaporanController.php index 82acd19..23300c9 100644 --- a/app/Http/Controllers/LaporanController.php +++ b/app/Http/Controllers/LaporanController.php @@ -974,11 +974,23 @@ $date = new Carbon($request->tarikh); $gadaiDataKaunter = Gadai::on($cawangan['mysql'])->whereIn('norujukan',$total_keuntunganansuran_data_kaunter)->whereNotNull('hargajualan')->pluck('norujukan'); + // $keuntunganansuran_kaunter_query = TransaksiKeuntungan::on('mysql7') + // ->whereIn('norujukan',$gadaiDataKaunter) + // ->whereDate('tarikh_bayaran','>=',$request->mula) + // ->whereDate('tarikh_bayaran','<=',$request->akhir); + // //new update $keuntunganansuran_kaunter_query = TransaksiKeuntungan::on('mysql7') - ->whereIn('norujukan',$gadaiDataKaunter) - ->whereDate('tarikh_bayaran','>=',$request->mula) - ->whereDate('tarikh_bayaran','<=',$request->akhir); - + ->leftJoin('transaction as trans', function($join) + { + $join->on('transaksi_keuntungan.norujukan', '=', 'trans.norujukan'); + $join->on('transaksi_keuntungan.tarikh_bayaran', '=', 'trans.created_at'); + }) + ->whereDate('trans.created_at','>=',$request->mula) + ->whereDate('trans.created_at','<=',$request->akhir) + ->where('trans.teller','<>','Online') + ->where('trans.trans_type','=','A') + ->where('trans.kodcaw',$request->kodcaw) + ->pluck('transaksi_keuntungan.norujukan'); $total_keuntunganansuran_kaunter = $keuntunganansuran_kaunter_query->sum('bayaran_keuntungan'); From ab598c12c92dedfc1c00cfd3dec2e3d8701ae9b5 Mon Sep 17 00:00:00 2001 From: Hafifie PKB Date: Wed, 4 Mar 2026 09:36:29 +0800 Subject: [PATCH 51/80] 1. added page for edit mutu 2. change from max pinjaman with a static 75% and 80% to manipulate value --- .../Controllers/MaxPinjamanController.php | 107 ++++++++++++- app/MaxMutuEmas.php | 40 +++++ bootstrap/app.php | 2 +- config/parameter.php | 5 + ...02_12_144445_create_max_mutuemas_table.php | 140 ++++++++++++++++++ routes/web.php | 2 + 6 files changed, 293 insertions(+), 3 deletions(-) create mode 100644 app/MaxMutuEmas.php create mode 100644 config/parameter.php create mode 100644 database/migrations/2026_02_12_144445_create_max_mutuemas_table.php diff --git a/app/Http/Controllers/MaxPinjamanController.php b/app/Http/Controllers/MaxPinjamanController.php index 734d04b..540abe7 100644 --- a/app/Http/Controllers/MaxPinjamanController.php +++ b/app/Http/Controllers/MaxPinjamanController.php @@ -2,14 +2,117 @@ namespace App\Http\Controllers; +use App\MaxMutuEmas; use App\MaxPinjaman; use Illuminate\Http\Request; class MaxPinjamanController extends Controller { - public function getAllMaxPinjaman(){ - $pinjaman = MaxPinjaman::on('mysql7')->get(); + public function getAllMaxPinjaman(Request $request) + { + if (config('parameter.max_mutuemas')) { + $data = MaxMutuEmas::on('mysql7')->select('karat', 'teller', 'pc', 'operasi')->get(); + $calculateMargin = $this->calculateMaxPinjamanMutu($data, $request->mutu,$request->total_nilai_marhun); + + $pinjaman = [ + [ + "user_type" => "teller", + "max" => $calculateMargin['teller'] + ], + [ + "user_type" => "khazanah", + "max" => $calculateMargin['pc'] + ], + [ + "user_type" => "operasi", + "max" => $calculateMargin['operasi'] + ] + ]; + } else { + $pinjaman = MaxPinjaman::on('mysql7')->get(); + } return response()->json($pinjaman); } + + public function calculateMaxPinjamanMutu($data, $mutu,$totalMarhun) + { + $totalMaxPC = 0; + $totalMaxTeller = 0; + $totalMaxOperasi = 0; + + if($mutu == null || $totalMarhun == 0){ + return [ + "pc" => 0, + "teller" => 0, + "operasi" => 0 + ]; + } + $mutuKarat = array_map(function($item) { + return $item[0]; + }, $mutu); + $mutuNilai = array_map(function($item) { + return $item[1]; + }, $mutu); + + foreach($mutuKarat as $index => $karat){ + $margin = $data->where('karat', $karat)->first(); + if($margin){ + $nilai = $mutuNilai[$index]; + $totalMaxPC += ($margin->pc/100) * $nilai; + $totalMaxTeller += ($margin->teller/100) * $nilai; + $totalMaxOperasi += ($margin->operasi/100) * $nilai; + } + } + $totalMaxPC = $totalMarhun > 0 ? ($totalMaxPC / $totalMarhun) * 100 : 0; + $totalMaxTeller = $totalMarhun > 0 ? ($totalMaxTeller / $totalMarhun) * 100 : 0; + $totalMaxOperasi = $totalMarhun > 0 ? ($totalMaxOperasi / $totalMarhun) * 100 : 0; + + + return [ + "pc" => round($totalMaxPC,2), + "teller" => round($totalMaxTeller,2), + "operasi" => round($totalMaxOperasi,2) + ]; + } + + + public function getAllMaxMutuEmas(Request $request) + { + $maxmutuemas = MaxMutuEmas::on('mysql7')->get(); + return response()->json($maxmutuemas); + } + + public function updateMaxMutuEmas(Request $request) + { + $recno = $request->recno; + $karat = $request->karat; + $keterangan = $request->keterangan; + $teller = $request->teller; + $pc = $request->pc; + $operasi = $request->operasi; + + $maxmutuemas = MaxMutuEmas::on('mysql7')->where('recno', $recno)->first(); + + if ($maxmutuemas) { + $maxmutuemas->karat = $karat; + $maxmutuemas->keterangan = $keterangan; + $maxmutuemas->teller = $teller; + $maxmutuemas->pc = $pc; + $maxmutuemas->operasi = $operasi; + $maxmutuemas->tarikhupdate = \Carbon\Carbon::now(); + $maxmutuemas->save(); + + return response()->json([ + 'status' => 'success', + 'message' => 'Max Mutu Emas updated successfully', + 'data' => $maxmutuemas + ]); + } else { + return response()->json([ + 'status' => 'error', + 'message' => 'Record not found' + ], 404); + } + } } \ No newline at end of file diff --git a/app/MaxMutuEmas.php b/app/MaxMutuEmas.php new file mode 100644 index 0000000..4512185 --- /dev/null +++ b/app/MaxMutuEmas.php @@ -0,0 +1,40 @@ + 'decimal:2', + 'pc' => 'decimal:2', + 'operasi' => 'decimal:2', + 'tarikhupdate' => 'datetime', + ]; + + /** + * The attributes excluded from the model's JSON form. + * + * @var array + */ + // protected $hidden = []; +} \ No newline at end of file diff --git a/bootstrap/app.php b/bootstrap/app.php index 16b5e30..d358544 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -64,7 +64,7 @@ $app->configure('tinker'); $app->configure('tennant_database'); $app->configure('report'); $app->configure('app_parameter'); - +$app->configure('parameter'); /* |-------------------------------------------------------------------------- | Register Middleware diff --git a/config/parameter.php b/config/parameter.php new file mode 100644 index 0000000..8af8857 --- /dev/null +++ b/config/parameter.php @@ -0,0 +1,5 @@ + env('MAX_MUTUEMAS', true), +]; \ No newline at end of file diff --git a/database/migrations/2026_02_12_144445_create_max_mutuemas_table.php b/database/migrations/2026_02_12_144445_create_max_mutuemas_table.php new file mode 100644 index 0000000..718a8fb --- /dev/null +++ b/database/migrations/2026_02_12_144445_create_max_mutuemas_table.php @@ -0,0 +1,140 @@ +id('recno'); + $table->string('karat'); + $table->string('keterangan'); + $table->decimal('teller', 8, 2); + $table->decimal('pc', 8, 2); + $table->decimal('operasi', 8, 2); + $table->timestamp('tarikhupdate'); + }); + + // Insert data + DB::table('max_mutuemas')->insert([ + [ + 'recno' => 1, + 'karat' => '24.0Kgb', + 'keterangan' => '999 gb', + 'teller' => 75.00000, + 'pc' => 80.00000, + 'operasi' => 80.00000, + 'tarikhupdate' => '2025-01-12 00:00:00', + ], + [ + 'recno' => 2, + 'karat' => '24.0K', + 'keterangan' => '999', + 'teller' => 75.00000, + 'pc' => 80.00000, + 'operasi' => 80.00000, + 'tarikhupdate' => '2025-01-12 00:00:00', + ], + [ + 'recno' => 3, + 'karat' => '23.0K', + 'keterangan' => '950', + 'teller' => 74.00000, + 'pc' => 80.00000, + 'operasi' => 80.00000, + 'tarikhupdate' => '2025-01-12 00:00:00', + ], + [ + 'recno' => 4, + 'karat' => '22.0K', + 'keterangan' => '916', + 'teller' => 73.66667, + 'pc' => 80.00000, + 'operasi' => 80.00000, + 'tarikhupdate' => '2025-01-12 00:00:00', + ], + [ + 'recno' => 5, + 'karat' => '21.0K', + 'keterangan' => '900', + 'teller' => 73.16667, + 'pc' => 80.00000, + 'operasi' => 80.00000, + 'tarikhupdate' => '2025-01-12 00:00:00', + ], + [ + 'recno' => 6, + 'karat' => '20.0K', + 'keterangan' => '835', + 'teller' => 72.66667, + 'pc' => 80.00000, + 'operasi' => 80.00000, + 'tarikhupdate' => '2025-01-12 00:00:00', + ], + [ + 'recno' => 7, + 'karat' => '18.0Kp', + 'keterangan' => '750', + 'teller' => 72.16667, + 'pc' => 80.00000, + 'operasi' => 80.00000, + 'tarikhupdate' => '2025-01-12 00:00:00', + ], + [ + 'recno' => 8, + 'karat' => '18.0K', + 'keterangan' => '750', + 'teller' => 71.66667, + 'pc' => 80.00000, + 'operasi' => 80.00000, + 'tarikhupdate' => '2025-01-12 00:00:00', + ], + [ + 'recno' => 21, + 'karat' => '14.0K', + 'keterangan' => '585', + 'teller' => 71.16667, + 'pc' => 80.00000, + 'operasi' => 80.00000, + 'tarikhupdate' => '2025-01-12 00:00:00', + ], + [ + 'recno' => 22, + 'karat' => '14.0Kp', + 'keterangan' => '585', + 'teller' => 70.66667, + 'pc' => 80.00000, + 'operasi' => 80.00000, + 'tarikhupdate' => '2025-01-12 00:00:00', + ], + [ + 'recno' => 23, + 'karat' => '9.0K', + 'keterangan' => '375', + 'teller' => 70.16667, + 'pc' => 80.00000, + 'operasi' => 80.00000, + 'tarikhupdate' => '2025-01-12 00:00:00', + ], + ]); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('max_mutuemas'); + } +} \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index 2c3c1be..1faced3 100644 --- a/routes/web.php +++ b/routes/web.php @@ -262,6 +262,8 @@ $router->group(['prefix'=>'api'], function () use ($router){ $router->get('maxpinjaman',['uses'=>'MaxPinjamanController@getAllMaxPinjaman']); + $router->get('maxmutuemas',['uses'=>'MaxPinjamanController@getAllMaxMutuEmas']); + $router->post('maxmutuemas/update',['uses'=>'MaxPinjamanController@updateMaxMutuEmas']); $router->get('transaksi_keuntungan/{norujukan}',['uses'=>'TransaksiKeuntunganController@getTransaksiKeuntunganByRujukan']); $router->get('transaksi_keuntungan_latest/{norujukan}',['uses'=>'TransaksiKeuntunganController@getTransaksiKeuntunganByRujukanLatest']); From 041369e04960b4ae073d49a56e6c243745713003 Mon Sep 17 00:00:00 2001 From: Hafifie PKB Date: Tue, 10 Mar 2026 09:55:08 +0800 Subject: [PATCH 52/80] add specific mutuemas API --- .../Controllers/MaxPinjamanController.php | 23 +++++++++++++++++++ routes/web.php | 1 + 2 files changed, 24 insertions(+) diff --git a/app/Http/Controllers/MaxPinjamanController.php b/app/Http/Controllers/MaxPinjamanController.php index 540abe7..5948442 100644 --- a/app/Http/Controllers/MaxPinjamanController.php +++ b/app/Http/Controllers/MaxPinjamanController.php @@ -83,6 +83,29 @@ class MaxPinjamanController extends Controller return response()->json($maxmutuemas); } + public function getSpecificMaxMutuEmas(Request $request) + { + $karat = $request->karat; + $nilaimarhun = $request->nilaimarhun; + + $nilaimarhun = preg_replace('/[^0-9.]/', '', $nilaimarhun); // Remove non-numeric characters except decimal point + $nilaimarhun = is_numeric($nilaimarhun) ? (float)$nilaimarhun : 0; + + $maxmutuemas = MaxMutuEmas::on('mysql7')->where('karat', $karat)->first(); + + if($maxmutuemas && $nilaimarhun > 0){ + $maxmutuemas->maxteller = ($maxmutuemas->teller/100) * $nilaimarhun; + $maxmutuemas->maxpc = ($maxmutuemas->pc/100) * $nilaimarhun; + $maxmutuemas->maxoperasi = ($maxmutuemas->operasi/100) * $nilaimarhun; + } else if($maxmutuemas) { + $maxmutuemas->maxteller = 0; + $maxmutuemas->maxpc = 0; + $maxmutuemas->maxoperasi = 0; + } + + return response()->json($maxmutuemas); + } + public function updateMaxMutuEmas(Request $request) { $recno = $request->recno; diff --git a/routes/web.php b/routes/web.php index 1faced3..f74c21e 100644 --- a/routes/web.php +++ b/routes/web.php @@ -263,6 +263,7 @@ $router->group(['prefix'=>'api'], function () use ($router){ $router->get('maxpinjaman',['uses'=>'MaxPinjamanController@getAllMaxPinjaman']); $router->get('maxmutuemas',['uses'=>'MaxPinjamanController@getAllMaxMutuEmas']); + $router->get('maxmutuemas/specific',['uses'=>'MaxPinjamanController@getSpecificMaxMutuEmas']); $router->post('maxmutuemas/update',['uses'=>'MaxPinjamanController@updateMaxMutuEmas']); $router->get('transaksi_keuntungan/{norujukan}',['uses'=>'TransaksiKeuntunganController@getTransaksiKeuntunganByRujukan']); From d540a3461d0208631e4d5ab4b4a597ff29917dee Mon Sep 17 00:00:00 2001 From: Hafifie PKB Date: Tue, 10 Mar 2026 10:23:07 +0800 Subject: [PATCH 53/80] add validation for editing mutu marhun --- .../Controllers/MaxPinjamanController.php | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/app/Http/Controllers/MaxPinjamanController.php b/app/Http/Controllers/MaxPinjamanController.php index 5948442..1dc0a41 100644 --- a/app/Http/Controllers/MaxPinjamanController.php +++ b/app/Http/Controllers/MaxPinjamanController.php @@ -108,6 +108,45 @@ class MaxPinjamanController extends Controller public function updateMaxMutuEmas(Request $request) { + // Validate the request manually for Lumen + $validator = \Illuminate\Support\Facades\Validator::make($request->all(), [ + 'recno' => 'required|integer', + 'karat' => 'required|string|max:10', + 'keterangan' => 'required|string|max:255', + 'teller' => 'required|numeric|min:0|max:100', + 'pc' => 'required|numeric|min:0|max:100', + 'operasi' => 'required|numeric|min:0|max:100', + ], [ + 'recno.required' => 'Nombor rekod diperlukan.', + 'recno.integer' => 'Nombor rekod mesti berupa nombor.', + 'karat.required' => 'Karat diperlukan.', + 'karat.string' => 'Karat mesti berupa teks.', + 'karat.max' => 'Karat tidak boleh lebih dari 10 aksara.', + 'keterangan.required' => 'Keterangan diperlukan.', + 'keterangan.string' => 'Keterangan mesti berupa teks.', + 'keterangan.max' => 'Keterangan tidak boleh lebih dari 255 aksara.', + 'teller.required' => 'Peratus teller diperlukan.', + 'teller.numeric' => 'Peratus teller mesti berupa nombor.', + 'teller.min' => 'Peratus teller mestilah sekurang-kurangnya 0.', + 'teller.max' => 'Peratus teller tidak boleh melebihi 100.', + 'pc.required' => 'Peratus PC diperlukan.', + 'pc.numeric' => 'Peratus PC mesti berupa nombor.', + 'pc.min' => 'Peratus PC mestilah sekurang-kurangnya 0.', + 'pc.max' => 'Peratus PC tidak boleh melebihi 100.', + 'operasi.required' => 'Peratus operasi diperlukan.', + 'operasi.numeric' => 'Peratus operasi mesti berupa nombor.', + 'operasi.min' => 'Peratus operasi mestilah sekurang-kurangnya 0.', + 'operasi.max' => 'Peratus operasi tidak boleh melebihi 100.', + ]); + + if ($validator->fails()) { + return response()->json([ + 'status' => 'error', + 'message' => 'Pengesahan gagal', + 'errors' => $validator->errors() + ], 422); + } + $recno = $request->recno; $karat = $request->karat; $keterangan = $request->keterangan; From 860b57285dbfa1b07aa4b7c7b0eb38e8e2464733 Mon Sep 17 00:00:00 2001 From: Hafifie PKB Date: Wed, 11 Mar 2026 00:55:04 +0800 Subject: [PATCH 54/80] added nilaimarhun for marign teller and pc --- .../Controllers/MaxPinjamanController.php | 47 +++++++++++-------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/app/Http/Controllers/MaxPinjamanController.php b/app/Http/Controllers/MaxPinjamanController.php index 1dc0a41..7cecc9f 100644 --- a/app/Http/Controllers/MaxPinjamanController.php +++ b/app/Http/Controllers/MaxPinjamanController.php @@ -5,7 +5,7 @@ namespace App\Http\Controllers; use App\MaxMutuEmas; use App\MaxPinjaman; use Illuminate\Http\Request; - +use Illuminate\Support\Facades\Log; class MaxPinjamanController extends Controller { public function getAllMaxPinjaman(Request $request) @@ -18,15 +18,19 @@ class MaxPinjamanController extends Controller $pinjaman = [ [ "user_type" => "teller", - "max" => $calculateMargin['teller'] + "max" => $calculateMargin['teller'], + "teller_pinjaman" => $calculateMargin['teller_pinjaman'] + ], [ "user_type" => "khazanah", - "max" => $calculateMargin['pc'] + "max" => $calculateMargin['pc'], + "pc_pinjaman" => $calculateMargin['pc_pinjaman'] ], [ "user_type" => "operasi", - "max" => $calculateMargin['operasi'] + "max" => $calculateMargin['operasi'], + "operasi_pinjaman" => $calculateMargin['operasi_pinjaman'] ] ]; } else { @@ -37,15 +41,18 @@ class MaxPinjamanController extends Controller public function calculateMaxPinjamanMutu($data, $mutu,$totalMarhun) { - $totalMaxPC = 0; - $totalMaxTeller = 0; - $totalMaxOperasi = 0; + $totalMaxMarhunPC = 0; + $totalMaxMarhunTeller = 0; + $totalMaxMarhunOperasi = 0; if($mutu == null || $totalMarhun == 0){ return [ "pc" => 0, + "pc_pinjaman" => 0, "teller" => 0, - "operasi" => 0 + "teller_pinjaman" => 0, + "operasi" => 0, + "operasi_pinjaman" => 0 ]; } $mutuKarat = array_map(function($item) { @@ -59,20 +66,22 @@ class MaxPinjamanController extends Controller $margin = $data->where('karat', $karat)->first(); if($margin){ $nilai = $mutuNilai[$index]; - $totalMaxPC += ($margin->pc/100) * $nilai; - $totalMaxTeller += ($margin->teller/100) * $nilai; - $totalMaxOperasi += ($margin->operasi/100) * $nilai; + $totalMaxMarhunPC += round(($margin->pc/100) * $nilai, 2); + $totalMaxMarhunTeller += round(($margin->teller/100) * $nilai, 2); + $totalMaxMarhunOperasi += round(($margin->operasi/100) * $nilai, 2); } } - $totalMaxPC = $totalMarhun > 0 ? ($totalMaxPC / $totalMarhun) * 100 : 0; - $totalMaxTeller = $totalMarhun > 0 ? ($totalMaxTeller / $totalMarhun) * 100 : 0; - $totalMaxOperasi = $totalMarhun > 0 ? ($totalMaxOperasi / $totalMarhun) * 100 : 0; - + $totalMaxPC = $totalMarhun > 0 ? ($totalMaxMarhunPC / $totalMarhun) * 100 : 0; + $totalMaxTeller = $totalMarhun > 0 ? ($totalMaxMarhunTeller / $totalMarhun) * 100 : 0; + $totalMaxOperasi = $totalMarhun > 0 ? ($totalMaxMarhunOperasi / $totalMarhun) * 100 : 0; return [ "pc" => round($totalMaxPC,2), + "pc_pinjaman" => round(($totalMaxPC / 100) * $totalMarhun, 2), "teller" => round($totalMaxTeller,2), - "operasi" => round($totalMaxOperasi,2) + "teller_pinjaman" => round(($totalMaxTeller / 100) * $totalMarhun, 2), + "operasi" => round($totalMaxOperasi,2), + "operasi_pinjaman" => round(($totalMaxOperasi / 100) * $totalMarhun, 2) ]; } @@ -94,9 +103,9 @@ class MaxPinjamanController extends Controller $maxmutuemas = MaxMutuEmas::on('mysql7')->where('karat', $karat)->first(); if($maxmutuemas && $nilaimarhun > 0){ - $maxmutuemas->maxteller = ($maxmutuemas->teller/100) * $nilaimarhun; - $maxmutuemas->maxpc = ($maxmutuemas->pc/100) * $nilaimarhun; - $maxmutuemas->maxoperasi = ($maxmutuemas->operasi/100) * $nilaimarhun; + $maxmutuemas->maxteller = round(($maxmutuemas->teller/100) * $nilaimarhun, 2); + $maxmutuemas->maxpc = round(($maxmutuemas->pc/100) * $nilaimarhun, 2); + $maxmutuemas->maxoperasi = round(($maxmutuemas->operasi/100) * $nilaimarhun, 2); } else if($maxmutuemas) { $maxmutuemas->maxteller = 0; $maxmutuemas->maxpc = 0; From c76fce70c3da12d359499ca916e9bdc0131fe655 Mon Sep 17 00:00:00 2001 From: Hafifie PKB Date: Wed, 11 Mar 2026 11:06:04 +0800 Subject: [PATCH 55/80] added audit logs for operasi --- app/Http/Controllers/MaxPinjamanController.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/app/Http/Controllers/MaxPinjamanController.php b/app/Http/Controllers/MaxPinjamanController.php index 7cecc9f..ed996cd 100644 --- a/app/Http/Controllers/MaxPinjamanController.php +++ b/app/Http/Controllers/MaxPinjamanController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers; +use App\Audit; use App\MaxMutuEmas; use App\MaxPinjaman; use Illuminate\Http\Request; @@ -125,6 +126,7 @@ class MaxPinjamanController extends Controller 'teller' => 'required|numeric|min:0|max:100', 'pc' => 'required|numeric|min:0|max:100', 'operasi' => 'required|numeric|min:0|max:100', + 'username' => 'required|string|max:255' ], [ 'recno.required' => 'Nombor rekod diperlukan.', 'recno.integer' => 'Nombor rekod mesti berupa nombor.', @@ -162,10 +164,15 @@ class MaxPinjamanController extends Controller $teller = $request->teller; $pc = $request->pc; $operasi = $request->operasi; + $username = $request->username; + + $current = \Carbon\Carbon::now(); $maxmutuemas = MaxMutuEmas::on('mysql7')->where('recno', $recno)->first(); if ($maxmutuemas) { + $oldmax = $maxmutuemas->toJson(); + $maxmutuemas->karat = $karat; $maxmutuemas->keterangan = $keterangan; $maxmutuemas->teller = $teller; @@ -174,6 +181,17 @@ class MaxPinjamanController extends Controller $maxmutuemas->tarikhupdate = \Carbon\Carbon::now(); $maxmutuemas->save(); + Audit::create([ + 'users' => $username, + 'actions' => 'Penukaran Mutu Margin', + 'norujukan' => '-', + 'new_data' => $maxmutuemas->toJson(), + 'old_data' => $oldmax, + 'kodcaw' => 'OPERASI', + 'created_at' => $current, + 'updated_at' => $current, + ]); + return response()->json([ 'status' => 'success', 'message' => 'Max Mutu Emas updated successfully', From 0dcf421d0efb97575806a48370fe900cc9ce249a Mon Sep 17 00:00:00 2001 From: Hafifie PKB Date: Thu, 12 Mar 2026 12:21:22 +0800 Subject: [PATCH 56/80] added laporan audit in operasi --- .../Reports/AuditTrailController.php | 78 +++++++++++++++++++ routes/report.php | 3 +- 2 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 app/Http/Controllers/Reports/AuditTrailController.php diff --git a/app/Http/Controllers/Reports/AuditTrailController.php b/app/Http/Controllers/Reports/AuditTrailController.php new file mode 100644 index 0000000..a24ff1a --- /dev/null +++ b/app/Http/Controllers/Reports/AuditTrailController.php @@ -0,0 +1,78 @@ +get('limit', 100); + + $audit_trails = Audit::query() + ->when($request->filled('norujukan'), fn($q) => $q->where('norujukan', $request->norujukan)) + ->when($request->filled('actions'), fn($q) => $q->where('actions', $request->actions)) + ->orderBy('created_at', 'desc') + ->limit($limit) + ->get(); + + return response()->json($audit_trails); + } + + public function AuditTrailOperasi(Request $request) + { + $date_first = $request->get('date', null); + $date_till = $request->get('date_till', null); + + $audit_trails = Audit::query() + ->where('kodcaw', 'operasi') + ->whereDate('created_at', '>=', $date_first) + ->whereDate('created_at', '<=', $date_till) + ->orderBy('created_at', 'asc') + ->get(); + + $audit_trails->map(function ($audit) { + // Convert from UTC to Malaysia timezone (UTC+8) + $audit->created_at = $audit->created_at->format('Y-m-d H:i:s'); + + // Get differences between old_data and new_data + $old_data = json_decode($audit->old_data, true) ?? []; + $new_data = json_decode($audit->new_data, true) ?? []; + + $differences = []; + + // Find changed fields + foreach ($new_data as $key => $new_value) { + if ($key === 'tarikhupdate') continue; + + $old_value = $old_data[$key] ?? null; + if ($old_value !== $new_value) { + $differences[$key] = [ + 'old' => $old_value, + 'new' => $new_value + ]; + } + } + + // Check for removed fields + foreach ($old_data as $key => $old_value) { + if ($key === 'tarikhupdate') continue; + + if (!array_key_exists($key, $new_data)) { + $differences[$key] = [ + 'old' => $old_value, + 'new' => null + ]; + } + } + + $audit->differences = $differences; + return $audit; + }); + + return response()->json($audit_trails); + } +} \ No newline at end of file diff --git a/routes/report.php b/routes/report.php index c202553..0046b76 100644 --- a/routes/report.php +++ b/routes/report.php @@ -55,7 +55,8 @@ $router->group(['prefix' => 'api/reports'], function () use ($router) { $router->get('gadaitebus', ['uses' => 'GadaianController@getSummaryLaporanGadaiTebus']); $router->get('gadaitebusmasa', ['uses' => 'GadaianController@getSummaryLaporanGadaiTebusMasa']); $router->get('gadaitebusmasa/{kod_cawangan}', ['uses' => 'GadaianController@getLaporanGadaiTebusMasaCawangan']); - + $router->get('audit-trail', ['uses' => 'AuditTrailController@getAuditTrail']); + $router->get('audittrail/operasi',['uses'=>'AuditTrailController@AuditTrailOperasi']); $router->get('saringan/gadaian', ['uses' => 'SaringanGadaianController@getLaporanGadai']); $router->get('data-pelanggan', ['uses' => 'AnalisaController@getSummaryLaporanDataPelanggan']); From e1878e31e416a2a5689459dc73cab80aa86adfed Mon Sep 17 00:00:00 2001 From: nurafrinaalimi16 Date: Sun, 14 Jun 2026 15:02:45 +0800 Subject: [PATCH 57/80] pdpa for koperasi --- app/Http/Controllers/CustomerController.php | 21 +++++++++++++++++++++ routes/web.php | 1 + 2 files changed, 22 insertions(+) diff --git a/app/Http/Controllers/CustomerController.php b/app/Http/Controllers/CustomerController.php index 5b93b81..18d25a2 100644 --- a/app/Http/Controllers/CustomerController.php +++ b/app/Http/Controllers/CustomerController.php @@ -1038,6 +1038,27 @@ class CustomerController extends Controller return response()->json($results); } + public function updateTagPdpa(Request $request) + { + $tarikh_cetak_pdpa = Carbon::now()->toDateString(); + + $no_ic = $request->input('no_ic'); + + $customer = Customer::where('kplama', $no_ic) + ->orWhere('kpbaru', $no_ic) + ->first(); + + if (!$customer) { + return response()->json(['error' => 'Customer not found.'], 404); + } + + $customer->tag_pdpa = $request->input('tag_pdpa'); + $customer->tarikh_cetak_pdpa = $tarikh_cetak_pdpa; + $customer->save(); + + return response()->json(['message' => 'Customer PDPA updated successfully.'], 200); + } + // public function createNotaArcc($kodcaw, Request $request) // { // $current = Carbon::now(); diff --git a/routes/web.php b/routes/web.php index 008c397..fdcefdd 100644 --- a/routes/web.php +++ b/routes/web.php @@ -62,6 +62,7 @@ $router->group(['prefix'=>'api'], function () use ($router){ $router->get('customer/anggota',['uses'=>'CustomerController@anggotaKoperasi']); $router->get('customer/eachcawangan/{ic}',['uses'=>'CustomerController@showCustomerByEachCawangan']); $router->put('customers/{noic}/assign-anggota', ['uses' => 'CustomerController@assignAnggota']); + $router->post('/customers/update-tag-pdpa', ['uses' => 'CustomerController@updateTagPdpa']); //arcc $router->get('customer/searchbyname',['uses'=>'CustomerController@searchByName']); From 237a5aa44be599c1be45dd84ed8807802ff360b9 Mon Sep 17 00:00:00 2001 From: nurafrinaalimi16 Date: Sun, 14 Jun 2026 15:05:02 +0800 Subject: [PATCH 58/80] fix figure on laporan terkumpul --- app/Http/Controllers/LaporanController.php | 38 ++++++++++++---------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/app/Http/Controllers/LaporanController.php b/app/Http/Controllers/LaporanController.php index 11b340f..2cdd162 100644 --- a/app/Http/Controllers/LaporanController.php +++ b/app/Http/Controllers/LaporanController.php @@ -804,7 +804,7 @@ $date = new Carbon($request->tarikh); $tebus = Tebus::on($cawangan['mysql']) ->join('gadai as gad','gad.norujukan','=','tebus.norujukan') - ->where([['t_tebus','>=',$request->mula],['t_tebus','<=',$request->akhir],['tebus.jenistebus','=','T']]); + ->where([['t_tebus','>=',$request->mula],['t_tebus','<=',$request->akhir]]); $ansuran = Transaction::on('mysql7')->whereDate('created_at','>=',$request->mula)->whereDate('created_at','<=',$request->akhir)->where([['trans_type','=','A'],['kodcaw','=',$request->kodcaw]]); $bayaranonlinequery = Transaction::on('mysql7')->whereDate('created_at','>=',$request->mula)->whereDate('created_at','<=',$request->akhir)->where('teller','=','Online')->where('kodcaw',$request->kodcaw); @@ -834,20 +834,22 @@ $date = new Carbon($request->tarikh); ->whereDate('trans.created_at','<=',$request->akhir) ->where('trans.trans_type','=','A') ->where('trans.kodcaw','=',$request->kodcaw) + // ->pluck('trans.norujukan'); // ->groupBy('trans.id') ->sum('bayaran_keuntungan'); - + // dd($total_keuntunganansuran); // $total_ansuran = number_format($total_ansuran,2); $total_keuntungan = floatval($total_upah) + floatval($total_keuntunganansuran) + floatval($total_keuntungantebus); - + //b $bilangan_gadai = $gadai->count(); $bilangan_tebus = $tebus->count(); // $bilangan_ansuran = $ansuran->count(); - //$bilangan_customer_baru = Customer::on($cawangan['mysql'])->where([['tarikhdaftar','>=',$request->mula],['tarikhdaftar','<=',$request->akhir]])->count(); - $bilangan_customer_baru = Customer::on('mysql7')->where([['tarikhdaftar','>=',$request->mula],['tarikhdaftar','<=',$request->akhir]])->count(); + //$bilangan_customer_baru = Customer::on('mysql7')->where([['tarikhdaftar','=',$request->tarikh],['kodcaw',$request->kodcaw]])->count() + //$bilangan_customer_baru = Customer::on('mysql7')->where([['tarikhdaftar','>=',$request->mula],['tarikhdaftar','<=',$request->akhir]])->count(); + $bilangan_customer_baru = Customer::on('mysql7')->whereBetween('tarikhdaftar', [$request->mula, $request->akhir])->where('kodcaw', $request->kodcaw)->count(); //f $data_lelong = Lelong::on($cawangan['mysql'])->where([['t_jual','>=',$request->mula],['t_jual','<=',$request->akhir]])->get(); @@ -970,21 +972,23 @@ $date = new Carbon($request->tarikh); ->whereDate('trans.created_at','<=',$request->akhir) ->where('trans.teller','<>','Online') ->where('trans.trans_type','=','A') - ->where('trans.kodcaw',$request->kodcaw) - ->pluck('transaksi_keuntungan.norujukan'); + ->where('trans.kodcaw',$request->kodcaw); + // ->pluck('transaksi_keuntungan.norujukan'); + - $gadaiDataKaunter = Gadai::on($cawangan['mysql'])->whereIn('norujukan',$total_keuntunganansuran_data_kaunter)->whereNotNull('hargajualan')->pluck('norujukan'); - - $keuntunganansuran_kaunter_query = TransaksiKeuntungan::on('mysql7') - ->whereIn('norujukan',$gadaiDataKaunter) - ->whereDate('tarikh_bayaran','>=',$request->mula) - ->whereDate('tarikh_bayaran','<=',$request->akhir); + // $gadaiDataKaunter = Gadai::on($cawangan['mysql'])->whereIn('norujukan',$total_keuntunganansuran_data_kaunter)->whereNotNull('hargajualan')->pluck('norujukan'); + // $keuntunganansuran_kaunter_query = TransaksiKeuntungan::on('mysql7') + // ->whereIn('norujukan',$gadaiDataKaunter) + // ->where('kodcaw',$request->kodcaw) + // ->whereDate('tarikh_bayaran','>=',$request->mula) + // ->whereDate('tarikh_bayaran','<=',$request->akhir); + //dd($keuntunganansuran_kaunter_query->get()->toArray()); - $total_keuntunganansuran_kaunter = $keuntunganansuran_kaunter_query->sum('bayaran_keuntungan'); - $bil_keuntunganansuran_kaunter = $keuntunganansuran_kaunter_query->count(); - + $total_keuntunganansuran_kaunter = $total_keuntunganansuran_data_kaunter->sum('bayaran_keuntungan'); + //dd($total_keuntunganansuran_kaunter); + $bil_keuntunganansuran_kaunter = $total_keuntunganansuran_data_kaunter->count(); $total_keuntunganansuran_data_online = TransaksiKeuntungan::on('mysql7') ->leftJoin('transaction as trans', function($join) { @@ -1245,7 +1249,7 @@ $date = new Carbon($request->tarikh); array_push($atarray,[ 'tarikh' => $tarikh, 'masa' => $masa, - 'users' => $at['users'], + 'users' => isset($at['users']) && $at['users'] !== '' ? $at['users'] : '-', 'pelulus' => isset($atnewdata['namapelulus']) ? $atnewdata['namapelulus'] : '-', 'actions' => $at['actions'], 'norujukan' => $at['norujukan'], From 2fa36eabf7888cbdc3ab2ee7e28e58b68d7dbfcf Mon Sep 17 00:00:00 2001 From: nurafrinaalimi16 Date: Sun, 14 Jun 2026 15:06:24 +0800 Subject: [PATCH 59/80] include kplama on report marhun --- app/Http/Controllers/MarhunController.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/MarhunController.php b/app/Http/Controllers/MarhunController.php index 8c8a7b7..d35e7f1 100644 --- a/app/Http/Controllers/MarhunController.php +++ b/app/Http/Controllers/MarhunController.php @@ -203,7 +203,10 @@ class MarhunController extends Controller $marhun = Marhun::on($cawangan['mysql']) ->select('marhun.norujukan','gadai.nokp','customer.nama','marhun.marhun','marhun.nota','marhun.berat','marhun.karat','marhun.harga','marhun.n_marhun','marhun.t_gadai','marhun.tag_permata', 'marhun.berat_batu_permata') ->rightJoin('gadai', 'gadai.norujukan', '=', 'marhun.norujukan') - ->rightJoin('online_arrahn.customer as customer', 'customer.kpbaru','=','gadai.nokp') + ->rightJoin('master_erahn.customer as customer', function($join) { + $join->on('customer.kpbaru', '=', 'gadai.nokp') + ->orOn('customer.kplama', '=', 'gadai.nokp'); + }) ->where('marhun.t_gadai','=',$tarikh) ->orderBy('marhun.t_gadai') ->get(); @@ -221,7 +224,10 @@ class MarhunController extends Controller $marhun = Marhun::on($cawangan['mysql']) ->select('marhun.norujukan','gadai.sttebus','gadai.pinjaman','gadai.nokp','customer.nama','marhun.marhun','marhun.nota','marhun.berat','marhun.karat','marhun.harga','marhun.n_marhun','marhun.t_gadai') ->rightJoin('gadai', 'gadai.norujukan', '=', 'marhun.norujukan') - ->rightJoin('online_arrahn.customer as customer', 'customer.kpbaru','=','gadai.nokp') + ->rightJoin('master_erahn.customer as customer', function($join) { + $join->on('customer.kpbaru', '=', 'gadai.nokp') + ->orOn('customer.kplama', '=', 'gadai.nokp'); + }) ->where('marhun.t_gadai','<=',$tarikh) ->whereYear('marhun.t_gadai','=',$current->year) ->where('gadai.sttebus','=','') From 0358878e8388748da10692ce0259a3a87b512ac5 Mon Sep 17 00:00:00 2001 From: nurafrinaalimi16 Date: Mon, 10 Nov 2025 18:51:01 +0800 Subject: [PATCH 60/80] models for kadar anggota koperasi --- app/Anggota.php | 18 ++++++++++++++++++ app/Customer.php | 3 ++- app/MohonAnggota.php | 15 +++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 app/Anggota.php create mode 100644 app/MohonAnggota.php diff --git a/app/Anggota.php b/app/Anggota.php new file mode 100644 index 0000000..17c19f4 --- /dev/null +++ b/app/Anggota.php @@ -0,0 +1,18 @@ + Date: Mon, 10 Nov 2025 18:55:17 +0800 Subject: [PATCH 61/80] update all controllers for kadar anggota koperasi --- app/Http/Controllers/CustomerController.php | 37 +++- app/Http/Controllers/KelulusanController.php | 182 ++++++++++++++++++- 2 files changed, 217 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/CustomerController.php b/app/Http/Controllers/CustomerController.php index 06fc48f..8efc9a6 100644 --- a/app/Http/Controllers/CustomerController.php +++ b/app/Http/Controllers/CustomerController.php @@ -15,6 +15,7 @@ use App\AuditCustomer; use Illuminate\Http\Request; use App\TuntutBaki; use Illuminate\Support\Facades\Auth; +use App\Anggota; use Carbon\Carbon; use Illuminate\Support\Facades\Log; @@ -394,12 +395,38 @@ class CustomerController extends Controller 'nota_pekerjaan'=>$request->nota_pekerjaan, // 'nota_arcc'=>$request->nota_arcc, 'telefon' => $request->telefon1, - 'telefon2' => $request->telefon2 + 'telefon2' => $request->telefon2, )); return response()->json($customer_update, 200); } + public function assignAnggota($noic, Request $request) +{ + // Semak sama ada pelanggan wujud + $customer = Customer::on('mysql7') + ->where('kpbaru', $noic) + ->orWhere('kplama', $noic) + ->first(); + + if (!$customer) { + return response()->json([ + 'success' => false, + 'message' => 'Pelanggan tidak dijumpai.' + ], 404); + } + + // Kemaskini tag_anggota + $customer->tag_anggota = 1; + $customer->save(); + + return response()->json([ + 'success' => true, + 'message' => 'Tag anggota berjaya dikemaskini.', + 'data' => $customer + ], 200); +} + public function customerUpdateKaunter($nokp,$kodcaw, Request $request){ $current = Carbon::now(); @@ -826,6 +853,14 @@ class CustomerController extends Controller return response()->json($blacklist); } + public function anggotaKoperasi(Request $request){ + + $anggota = Anggota::where('noic',$request->noic)->first(); + + return response()->json($anggota); + } + + public function showCustomerByEachCawangan($ic) { $cawangan_all = Cawangan::on('mysql7')->get(); diff --git a/app/Http/Controllers/KelulusanController.php b/app/Http/Controllers/KelulusanController.php index c663000..07ed5d7 100644 --- a/app/Http/Controllers/KelulusanController.php +++ b/app/Http/Controllers/KelulusanController.php @@ -6,6 +6,8 @@ use App\Audit; use App\Mohon; use App\Cawangan; use App\Mohonid; +use App\MohonAnggota; +use App\Customer; use Carbon\Carbon; @@ -229,6 +231,98 @@ class KelulusanController extends Controller return response()->json($kelulusan,201); } + public function updateAnggota($kodcaw, Request $request) +{ + $harini = Carbon::now(); + + // Dapatkan sambungan database cawangan + $cawangan = Cawangan::on('mysql7') + ->where('kodcaw', '=', $kodcaw) + ->first(); + + if (!$cawangan) { + return response()->json(['success' => false, 'message' => 'Kod cawangan tidak sah'], 404); + } + + $nokp = $request->nokp; + $komen = $request->komenkelulusan; + $namaoperasi = $request->namaoperasi; + $status = $request->sahkan; // 1 = Lulus, 2 = Batal + + // Debug log masuk + Log::info('UpdateKelulusanAnggota triggered', [ + 'kodcaw' => $kodcaw, + 'nokp' => $nokp, + 'status' => $status, + 'komen' => $komen, + 'namaoperasi' => $namaoperasi + ]); + + // ✅ Kalau LULUS + if ($status == 1) { + $kelulusan = MohonAnggota::on($cawangan['mysql']) + ->where('nokp', '=', $nokp) + ->update([ + 'status' => 'DILULUSKAN', + 'komen' => $komen, + 'peloperasi' => $namaoperasi, + 'datetime_pelulus' => $harini, + 'updated_at' => $harini, + ]); + + // 🟢 Update CUSTOMER di pusat (mysql7) + Customer::on('mysql7') + ->where('kpbaru', '=', $nokp) + ->update([ + 'tag_anggota' => 1, + ]); + } + // ❌ Kalau BATAL / TOLAK + else if ($status == 2) { + $kelulusan = MohonAnggota::on($cawangan['mysql']) + ->where('nokp', '=', $nokp) + ->update([ + 'status' => 'DITOLAK', + 'komen' => $komen, + 'peloperasi' => $namaoperasi, + 'datetime_pelulus' => $harini, + 'updated_at' => $harini, + ]); + } else { + return response()->json(['success' => false, 'message' => 'Status tidak sah'], 400); + } + + // 🧾 Simpan audit log + $audit = new Audit(); + $audit->users = $namaoperasi; + $audit->actions = ($status == 1) + ? "Kelulusan anggota oleh operasi (tag_anggota=1)" + : "Pembatalan / tolak anggota oleh operasi"; + $audit->new_data = json_encode([ + 'nokp' => $nokp, + 'status' => $status, + 'komen' => $komen, + ]); + $audit->kodcaw = $kodcaw; + $audit->created_at = $harini; + $audit->updated_at = $harini; + $audit->save(); + + Log::info('Kelulusan anggota dikemas kini', [ + 'nokp' => $nokp, + 'status' => $status, + 'updated_tag_anggota' => ($status == 1) ? 1 : 0 + ]); + + return response()->json([ + 'success' => true, + 'status' => ($status == 1) ? 'DILULUSKAN' : 'DITOLAK', + 'updated_rows' => $kelulusan + ], 200); +} + + + public function updatekomen($kodcaw,$norujukan,Request $request) { $harini = Carbon::now(); @@ -314,6 +408,64 @@ public function create(REQUEST $request,$kodcaw,$norujukan,$roles) return response()->json($kelulusan); } + public function createKelulusanAnggota(Request $request, $kodcaw) +{ + try { + $harini = Carbon::now(); + + // ✅ Dapatkan maklumat cawangan (database connection) + $cawangan = Cawangan::on('mysql7')->where('kodcaw', $kodcaw)->first(); + + if (!$cawangan) { + return response()->json(['success' => false, 'message' => 'Cawangan tidak dijumpai'], 404); + } + + // ✅ Simpan ke dalam model MohonAnggota + $kelulusan = new MohonAnggota(); + $kelulusan->setConnection($cawangan['mysql']); // guna connection cawangan dinamik + $kelulusan->tarikh = $harini->toDateString(); + $kelulusan->nokp = $request->nokp; + $kelulusan->nama = $request->nama ?? null; + $kelulusan->status = 'MENUNGGU OPERASI'; + $kelulusan->komen = $request->komen; + $kelulusan->teller = $request->teller; + $kelulusan->peloperasi = null; + $kelulusan->created_at = $harini; + $kelulusan->updated_at = $harini; + $kelulusan->save(); + + // ✅ Simpan audit trail + $audit = new Audit(); + $audit->users = $request->teller; + $audit->actions = 'Mohon kelulusan anggota'; + $audit->new_data = json_encode(['mohon_anggota_id' => $kelulusan->id]); + $audit->kodcaw = $kodcaw; + $audit->created_at = $harini; + $audit->updated_at = $harini; + $audit->save(); + + // ✅ Return JSON response ke frontend + return response()->json([ + 'success' => true, + 'message' => 'Permohonan kelulusan anggota berjaya dihantar kepada operasi.', + 'data' => [ + 'id' => $kelulusan->id, + 'nokp' => $kelulusan->nokp, + 'status' => $kelulusan->status, + 'komen' => $kelulusan->komen, + 'teller' => $kelulusan->teller, + ], + ], 201); + + } catch (\Throwable $th) { + Log::error('❌ createKelulusanAnggota error: ' . $th->getMessage()); + return response()->json([ + 'success' => false, + 'message' => $th->getMessage(), + ], 500); + } +} + //KEPOHONAN EDIT DAN HAPUS public function kepohonancreate(REQUEST $request,$kodcaw,$norujukan) @@ -526,7 +678,7 @@ public function create(REQUEST $request,$kodcaw,$norujukan,$roles) return response()->json($kelulusan, 200); } - public function getApprovalLaporan(Request $request){ + public function getApprovalLaporan(Request $request){ $cawangan = Cawangan::on('mysql7')->where('kodcaw','=',$request->kodcaw)->first(); $kelulusan = Mohonid::on($cawangan['mysql']) ->selectRaw('recno, benar, tarikh, onlineid, mohon, norujukan, id, katalaluan, benar, operasi, pinjaman, ansuran, nilaimarhun, berat, margin, teller ,masa, timestamp_approved_by_pc, timestamp_approved_by_operasi') @@ -540,6 +692,34 @@ public function create(REQUEST $request,$kodcaw,$norujukan,$roles) return response()->json($kelulusan, 200); } + public function listKelulusanAnggota(Request $request){ + + $harini = Carbon::now(); + $harini = new Carbon; + Log::info($request->all()); + $cawangan = Cawangan::on('mysql7')->get(); + + $array_kelulusan = []; + + foreach($cawangan as $caw){ + + $kelulusan = MohonAnggota::on($caw['mysql']) + ->where('tarikh', '=', $harini->toDateString()) + ->where('peloperasi', '=', 0) + ->orWhereNull('peloperasi') // Corrected this part + ->orderBy('id', 'desc') + ->get(); + + if(sizeof($kelulusan) != 0){ + array_push($array_kelulusan,["kelulusanall" => $kelulusan,"cawangan" => $caw['details_caw'],"cawangankod" => $caw['kodcaw']]); + } + + } + + + return response()->json($array_kelulusan,200); + } + } From a3cb756f6b1911684cc116be882f59592b778446 Mon Sep 17 00:00:00 2001 From: nurafrinaalimi16 Date: Mon, 10 Nov 2025 19:11:13 +0800 Subject: [PATCH 62/80] calculation for kadar anggota koperasi --- app/Services/OnePercentServices.php | 39 +++++++++++++++++-- app/Support/OnePercent.php | 28 ++++++++++---- app/Support/v2/Calculation.php | 59 ++++++++++++++++++++++++++--- app/Support/v2/GadaiV2.php | 37 +++++++++++++++--- 4 files changed, 141 insertions(+), 22 deletions(-) diff --git a/app/Services/OnePercentServices.php b/app/Services/OnePercentServices.php index 6e8e834..ad5b9ff 100644 --- a/app/Services/OnePercentServices.php +++ b/app/Services/OnePercentServices.php @@ -3,6 +3,7 @@ namespace App\Services; use App\KadarUpah; +use App\Customer; class OnePercentServices { @@ -79,13 +80,43 @@ class OnePercentServices return ['keuntungan' => $keuntungan,'onepercent' => $onepercent, 'ujrah' => $ujrah_sebenar]; } - public function getKadarUjrah(float $nilaimarhun = 0.0, $groupid) : Float{ +public function getKadarUjrah(float $nilaimarhun = 0.0, $groupid, $nokp = null): float +{ + //Semak status pelanggan dalam table customer + if ($nokp) { + $customer = Customer::on('mysql7') + ->select('tag_anggota') + ->where(function($q) use ($nokp) { + $q->where('kpbaru', $nokp) + ->orWhere('kplama', $nokp); + }) + ->first(); - $kadarujrah = KadarUpah::on('mysql7')->select('kadarujrah')->where([['min','<=',$nilaimarhun],['max','>=',$nilaimarhun]])->where('group_id',1)->get()->toArray(); - - return isset($kadarujrah[0]) ? $kadarujrah[0]['kadarujrah'] : 0; + // Jika anggota koperasi → kadar tetap + if ($customer && (int)$customer->tag_anggota === 1) { + return 0.16; // kadar ujrah tetap untuk anggota + } } + //Jika bukan anggota → ambil dari jadual kadar_upah + $kadar = KadarUpah::on('mysql7') + ->select('kadarujrah') + ->where([ + ['min', '<=', $nilaimarhun], + ['max', '>=', $nilaimarhun], + ]) + ->where('group_id', $groupid) + ->first(); + + //Jika jumpa kadar dalam jadual + if ($kadar && isset($kadar->kadarujrah)) { + return (float) $kadar->kadarujrah; + } + + //Default fallback + return 0.0; +} + public function getRoundedMethod(float $number = 0.0) : Float{ $number_string = number_format(floor($number * 100)/100,2); diff --git a/app/Support/OnePercent.php b/app/Support/OnePercent.php index e924fc1..941b245 100644 --- a/app/Support/OnePercent.php +++ b/app/Support/OnePercent.php @@ -9,6 +9,8 @@ use Illuminate\Http\Request as HttpRequest; use App\Support\v2\GadaiV2 as Version2Gadai; use App\Support\v2\Penebusan; +use Illuminate\Support\Facades\Log; + class OnePercent extends MasterServices { protected $kodcaw; @@ -61,18 +63,30 @@ class OnePercent extends MasterServices return $response; } - public function getKadarUjrah(HttpRequest $request){ - $cawangan = Cawangan::on('mysql7')->where('kodcaw',$request->kodcaw)->first(); - $onePercentServices = new Calculation(); - $kadarujrah = $onePercentServices->getKadarUjrah($request->nilaimarhun,$cawangan['group_id']); + public function getKadarUjrah(HttpRequest $request) +{ + Log::info('[DEBUG-CONTROLLER] Data request', [ + 'nokp' => $request->nokp, + 'kodcaw' => $request->kodcaw, + 'nilaimarhun' => $request->nilaimarhun + ]); - return $kadarujrah; - } + $cawangan = Cawangan::on('mysql7')->where('kodcaw', $request->kodcaw)->first(); + $onePercentServices = new Calculation(); + + $kadarujrah = $onePercentServices->getKadarUjrah( + $request->nilaimarhun, + $cawangan['group_id'], + $request->nokp + ); + + return $kadarujrah; +} public function getOnePercent(HttpRequest $request){ $margin = (!is_numeric($request->margin)) ? 0 : $request->margin; $onePercentServices = new Calculation(); - $keuntungan = $onePercentServices->kiraanKeuntunganSebenar($request->pembiayaan,$request->nilaimarhun,$request->kadarujrah,$margin); + $keuntungan = $onePercentServices->kiraanKeuntunganSebenar($request->pembiayaan,$request->nilaimarhun,$request->kadarujrah,$margin, $request->nokp); return $keuntungan; } diff --git a/app/Support/v2/Calculation.php b/app/Support/v2/Calculation.php index 178b275..18f31a6 100644 --- a/app/Support/v2/Calculation.php +++ b/app/Support/v2/Calculation.php @@ -3,6 +3,9 @@ namespace App\Support\v2; use App\KadarUpah; +use App\Customer; +use Illuminate\Support\Facades\Log; + use Illuminate\Http\Request; class Calculation @@ -58,7 +61,6 @@ class Calculation public function kiraanKeuntunganRebet(float $pembiayaan = 0.0,float $nilaimarhun = 0.0,float $kadarujrah = 0.0,float $margin = 0.0){ $this->one_percent = $this->getKadarUpah($nilaimarhun); - $onepercent = $this->kiraanOnePercent($pembiayaan); $ujrah_sebenar = $this->kiraanUjrahSebenar($nilaimarhun,$kadarujrah,$margin); @@ -83,13 +85,60 @@ class Calculation return ['keuntungan' => $keuntungan,'onepercent' => $onepercent, 'ujrah' => $ujrah_sebenar]; } - public function getKadarUjrah(float $nilaimarhun = 0.0, $groupid) : Float{ +public function getKadarUjrah(float $nilaimarhun = 0.0, $groupid, $nokp = null): float +{ + // 1️⃣ Semak status pelanggan dalam table customer + if ($nokp) { + $customer = Customer::on('mysql7') + ->select('tag_anggota') + ->where(function($q) use ($nokp) { + $q->where('kpbaru', $nokp) + ->orWhere('kplama', $nokp); + }) + ->first(); - $kadarujrah = KadarUpah::on('mysql7')->select('kadarujrah')->where([['min','<=',$nilaimarhun],['max','>=',$nilaimarhun]])->where('group_id',$groupid)->get()->toArray(); - - return isset($kadarujrah[0]) ? $kadarujrah[0]['kadarujrah'] : 0; + // 2️⃣ Jika anggota koperasi → kadar tetap + if ($customer && (int)$customer->tag_anggota === 1) { + Log::info('[DEBUG-UJRAH] Anggota koperasi', [ + 'nokp' => $nokp, + 'kadarujrah' => 0.16, + 'groupid' => $groupid, + 'nilaimarhun' => $nilaimarhun, + ]); + return 0.16; + } } + // 3️⃣ Jika bukan anggota → ambil dari jadual kadar_upah + $kadar = KadarUpah::on('mysql7') + ->select('kadarujrah') + ->where([ + ['min', '<=', $nilaimarhun], + ['max', '>=', $nilaimarhun], + ]) + ->where('group_id', $groupid) + ->first(); + + if ($kadar && isset($kadar->kadarujrah)) { + Log::info('[DEBUG-UJRAH] Bukan anggota - dari jadual kadar_upah', [ + 'nokp' => $nokp, + 'kadarujrah' => (float)$kadar->kadarujrah, + 'groupid' => $groupid, + 'nilaimarhun' => $nilaimarhun, + ]); + return (float) $kadar->kadarujrah; + } + + // 4️⃣ Default fallback + Log::info('[DEBUG-UJRAH] Tiada kadar ditemui', [ + 'nokp' => $nokp, + 'groupid' => $groupid, + 'nilaimarhun' => $nilaimarhun, + ]); + return 0.0; +} + + public function getKadarUpah(float $nilaimarhun = 0.0){ $kadarupah = KadarUpah::on('mysql7')->where([['min','<=',$nilaimarhun],['max','>=',$nilaimarhun]])->where('group_id',1)->first(); diff --git a/app/Support/v2/GadaiV2.php b/app/Support/v2/GadaiV2.php index dd006a5..b0af4af 100644 --- a/app/Support/v2/GadaiV2.php +++ b/app/Support/v2/GadaiV2.php @@ -4,6 +4,7 @@ namespace App\Support\v2; use App\Audit; use App\Cawangan; +use App\Customer; use App\KadarUpah; use App\Support\v2\Calculation; use Carbon\Carbon; @@ -57,6 +58,31 @@ class GadaiV2 } } + private function getKadarUpahAnggota($nokp,$total_nilai_marhun = 0,$groupid = 2) : Float{ + Log::info('DEBUG NOKP:' . $nokp); + if($nokp){ + $customer = Customer::on('mysql7') + ->select('tag_anggota') + ->where(function($q) use ($nokp) { + $q->where('kpbaru', $nokp) + ->orWhere('kplama', $nokp); + }) + ->first(); + $customer = $customer ? $customer->toArray() : []; + if(isset($customer) && $customer['tag_anggota'] == 1){ + return 0.16; + }else{ + return KadarUpah::where('min', '<=', $total_nilai_marhun) + ->where('max', '>=', $total_nilai_marhun) + ->where('group_id', $groupid) + ->value('kadarujrah'); + } + } + + return 0.0; + + } + public function createMarhun($norujukan,HttpRequest $request){ $current = Carbon::now(); $current = new Carbon(); @@ -83,14 +109,13 @@ class GadaiV2 $total_berat = Marhun::on($cawangan['mysql'])->where('norujukan','=',$norujukan)->sum('berat'); //query kadar upah baru - $kadar_raw = KadarUpah::where('min','<=',$total_nilai_marhun)->where('max','>=',$total_nilai_marhun)->where('group_id',$cawangan['group_id'])->first(); - + $kadar_raw = $this->getKadarUpahAnggota($request->nokp,$total_nilai_marhun,$cawangan['group_id']); // query kadar upah lama // $kadar_raw = KadarUpah::where('min','<=',$total_nilai_marhun)->where('max','>=',$total_nilai_marhun)->first(); $onepercentservices = new Calculation(); - $keuntungan = $onepercentservices->kiraanKeuntunganSebenar($request->pinjaman,$total_nilai_marhun,$kadar_raw['kadarujrah'],$margin_pinjam); + $keuntungan = $onepercentservices->kiraanKeuntunganSebenar($request->pinjaman,$total_nilai_marhun,$kadar_raw,$margin_pinjam); // $upah1 = $request->pinjaman * ($kadar_raw['kadarupdah']/100); // $upah6 = $upah1 * 6; // $upah12 = $upah1 * 12; @@ -102,7 +127,7 @@ class GadaiV2 $hargajualan = $request->pinjaman + $upah12; - $akrual = $this->kiraupahTawarruqStokAuditUjrahOnePercent(0.5,0,$kadar_raw['kadarujrah'],$request->pinjaman,$total_nilai_marhun,$margin_pinjam); + $akrual = $this->kiraupahTawarruqStokAuditUjrahOnePercent(0.5,0,$kadar_raw,$request->pinjaman,$total_nilai_marhun,$margin_pinjam); $gadai = Gadai::on($cawangan['mysql']) ->where('norujukan','=',$norujukan) @@ -110,7 +135,7 @@ class GadaiV2 'nilaimarhun' => $total_nilai_marhun, 'berat'=> $total_berat, 'pinjaman' => $request->pinjaman, - 'kadarupah' => $kadar_raw['kadarujrah'], + 'kadarupah' => $kadar_raw, 'marhun' => $request->marhun, 'percentpinj' => $margin_pinjam, 'teller' => $request->teller, @@ -131,7 +156,7 @@ class GadaiV2 'upahdibayar' => 0.00, 'tempohbayar' => 0.00, 'lelong_tawarruq' => 1, - 'kadarujrah' => $kadar_raw['kadarujrah'], + 'kadarujrah' => $kadar_raw, 'ujrah' => $ujrah, 'onepercent' => $onepercent, 'margin_semasa' => $margin_pinjam, From 1717035643a045749a624eea2140fdbc9331c561 Mon Sep 17 00:00:00 2001 From: nurafrinaalimi16 Date: Mon, 10 Nov 2025 19:12:26 +0800 Subject: [PATCH 63/80] database migration for kadar anggota koperasi --- ...2025_10_06_160240_create_anggota_table.php | 35 ++++++++++ ..._08_121938_add_status_to_anggota_table.php | 36 +++++++++++ ...0723_add_tag_anggota_to_customer_table.php | 32 ++++++++++ ...1_04_164447_create_mohon_anggota_table.php | 64 +++++++++++++++++++ 4 files changed, 167 insertions(+) create mode 100644 database/migrations/2025_10_06_160240_create_anggota_table.php create mode 100644 database/migrations/2025_10_08_121938_add_status_to_anggota_table.php create mode 100644 database/migrations/2025_10_13_110723_add_tag_anggota_to_customer_table.php create mode 100644 database/migrations/2025_11_04_164447_create_mohon_anggota_table.php diff --git a/database/migrations/2025_10_06_160240_create_anggota_table.php b/database/migrations/2025_10_06_160240_create_anggota_table.php new file mode 100644 index 0000000..33297f3 --- /dev/null +++ b/database/migrations/2025_10_06_160240_create_anggota_table.php @@ -0,0 +1,35 @@ +id(); + $table->string('no_anggota')->unique()->nullable(); // No keahlian + $table->string('nama'); + $table->string('noic')->unique(); // IC wajib unik + $table->string('no_tel')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('anggota'); + } +} diff --git a/database/migrations/2025_10_08_121938_add_status_to_anggota_table.php b/database/migrations/2025_10_08_121938_add_status_to_anggota_table.php new file mode 100644 index 0000000..d9afe81 --- /dev/null +++ b/database/migrations/2025_10_08_121938_add_status_to_anggota_table.php @@ -0,0 +1,36 @@ +tinyInteger('status') + ->default(1) + ->comment('1 = aktif, 0 = tidak aktif') + ->after('no_tel'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('anggota', function (Blueprint $table) { + // + $table->dropColumn('status'); + }); + } +} diff --git a/database/migrations/2025_10_13_110723_add_tag_anggota_to_customer_table.php b/database/migrations/2025_10_13_110723_add_tag_anggota_to_customer_table.php new file mode 100644 index 0000000..d2c585b --- /dev/null +++ b/database/migrations/2025_10_13_110723_add_tag_anggota_to_customer_table.php @@ -0,0 +1,32 @@ +boolean('tag_anggota')->default(0)->after('ahli'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('customer', function (Blueprint $table) { + $table->dropColumn('tag_anggota'); + }); + } +} diff --git a/database/migrations/2025_11_04_164447_create_mohon_anggota_table.php b/database/migrations/2025_11_04_164447_create_mohon_anggota_table.php new file mode 100644 index 0000000..8f9f15c --- /dev/null +++ b/database/migrations/2025_11_04_164447_create_mohon_anggota_table.php @@ -0,0 +1,64 @@ +getPdo(); + return true; + } catch (\Exception $e) { + return false; + } + }); + + return $db_connection; + } + + /** + * Jalankan migration + */ + public function up() + { + $db_connection = $this->getActiveDB(); + + foreach ($db_connection as $dbase) { + if (!Schema::connection($dbase)->hasTable('mohon_anggota')) { + Schema::connection($dbase)->create('mohon_anggota', function (Blueprint $table) { + $table->bigIncrements('id'); + $table->date('tarikh')->nullable(); + $table->string('nokp', 20)->nullable(); + $table->string('nama', 100)->nullable(); + $table->string('status', 50)->default('MENUNGGU OPERASI'); + $table->text('komen')->nullable(); + $table->string('teller', 100)->nullable(); + $table->string('peloperasi', 100)->nullable(); + $table->dateTime('datetime_pelulus')->nullable(); + $table->timestamps(); + }); + } + } + } + + /** + * Undur migration + */ + public function down() + { + $db_connection = $this->getActiveDB(); + + foreach ($db_connection as $dbase) { + Schema::connection($dbase)->dropIfExists('mohon_anggota'); + } + } +} From 15a3972ae9e1a72693dbca68026e67071af794ac Mon Sep 17 00:00:00 2001 From: nurafrinaalimi16 Date: Mon, 10 Nov 2025 19:13:29 +0800 Subject: [PATCH 64/80] route for kadar anggota --- routes/web.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/routes/web.php b/routes/web.php index f74c21e..082da17 100644 --- a/routes/web.php +++ b/routes/web.php @@ -59,7 +59,10 @@ $router->group(['prefix'=>'api'], function () use ($router){ $router->put('customers/information/update/admin', ['uses' => 'CustomerController@customerUpdateAdmin']); //blh refer sini izazi $router->get('admin/customers/nokp/search',['uses'=>'CustomerController@showOneCustomerByICAdmin']); $router->get('customer/blacklist',['uses'=>'CustomerController@blacklistCustomer']); + $router->get('customer/anggota',['uses'=>'CustomerController@anggotaKoperasi']); $router->get('customer/eachcawangan/{ic}',['uses'=>'CustomerController@showCustomerByEachCawangan']); + $router->put('customers/{noic}/assign-anggota', ['uses' => 'CustomerController@assignAnggota']); + //arcc $router->get('customer/searchbyname',['uses'=>'CustomerController@searchByName']); $router->get('customer/searchbygadai/{kodcaw}/{norujukan}',['uses'=>'CustomerController@AdminsearchGadai']); @@ -404,15 +407,20 @@ $router->group(['prefix'=>'api'], function () use ($router){ $router->get('SenaraiDahLulus/{kodcaw}/{norujukan}',['uses'=>'KelulusanController@listdahlulus']); $router->get('ListLatestLulus/{kodcaw}/{norujukan}',['uses'=>'KelulusanController@listlatestlulus']); $router->put('UpdateKelulusan/{kodcaw}/{norujukan}',['uses'=>'KelulusanController@update']); + $router->put('UpdateKelulusanAnggota/{kodcaw}',['uses'=>'KelulusanController@updateAnggota']); $router->put('UpdateKelulusanKomen/{kodcaw}/{norujukan}',['uses'=>'KelulusanController@updatekomen']); $router->post('CreateKelulusan/{kodcaw}/{norujukan}/roles/{roles}',['uses'=>'KelulusanController@create']); + $router->post('CreateKelulusanAnggota/{kodcaw}/roles/{roles}',['uses'=>'KelulusanController@createKelulusanAnggota']); $router->post('CreateLulus/{kodcaw}/{norujukan}',['uses'=>'KelulusanController@kepohonancreate']); $router->get('GetLulus/{kodcaw}/',['uses'=>'KelulusanController@kepohonangetteller']); $router->put('UpdateKelulusan/kepohonan/{kodcaw}/{norujukan}',['uses'=>'KelulusanController@updatekepohonankhazanah']); $router->get('GetLulusAll/{kodcaw}/',['uses'=>'KelulusanController@listkepohonan']); $router->get('ListOperasi/',['uses'=>'KelulusanController@listoperasi']); $router->get('ListOperasiKelulusan/',['uses'=>'KelulusanController@listoperasikelulusan']); + $router->get('list/approval/anggota',['uses'=>'KelulusanController@listKelulusanAnggota']); + + //API REQUEST TELLER From db9b17f36914cfd277a2a0f909977ad75ccefe0b Mon Sep 17 00:00:00 2001 From: nurafrinaalimi16 Date: Mon, 10 Nov 2025 19:14:29 +0800 Subject: [PATCH 65/80] import csv anggota koperasi --- app/Console/Commands/ImportCSV.php | 95 +++++++ app/Console/Kernel.php | 1 + resources/data/anggota.csv | 417 +++++++++++++++++++++++++++++ 3 files changed, 513 insertions(+) create mode 100644 app/Console/Commands/ImportCSV.php create mode 100644 resources/data/anggota.csv diff --git a/app/Console/Commands/ImportCSV.php b/app/Console/Commands/ImportCSV.php new file mode 100644 index 0000000..cc792e3 --- /dev/null +++ b/app/Console/Commands/ImportCSV.php @@ -0,0 +1,95 @@ + 'no_anggota', + 'nama' => 'nama', + 'no_kp' => 'noic', + 'telefon' => 'no_tel', + ]; + + $chunk = []; + $chunkSize = 1000; + $totalRows = 0; + + $bar = $this->output->createProgressBar(); + $bar->start(); + + try { + while (($row = fgetcsv($handle)) !== false) { + $csvData = array_combine($header, $row); + $data = []; + + foreach ($columnMap as $csvCol => $dbCol) { + $data[$dbCol] = $csvData[$csvCol] ?? null; + } + + $data['status'] = 1; + $chunk[] = $data; + + if (count($chunk) >= $chunkSize) { + DB::table('anggota')->insertOrIgnore($chunk); + $totalRows += count($chunk); + $chunk = []; + $bar->advance($chunkSize); + } + } + + if (!empty($chunk)) { + DB::table('anggota')->insertOrIgnore($chunk); + $totalRows += count($chunk); + } + + $bar->finish(); + $this->info("\n✅ Successfully imported {$totalRows} rows"); + } catch (\Exception $e) { + $this->error("\n❌ Error: " . $e->getMessage()); + } + + fclose($handle); + } +} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 9d8e527..1d236f5 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -24,6 +24,7 @@ class Kernel extends ConsoleKernel Commands\ClearCachesAll::class, Commands\RestartSupervisor::class, Commands\InsertSempornaData::class, + Commands\ImportCsv::class, ]; diff --git a/resources/data/anggota.csv b/resources/data/anggota.csv new file mode 100644 index 0000000..87b0623 --- /dev/null +++ b/resources/data/anggota.csv @@ -0,0 +1,417 @@ +id,nama,no_kp,telefon,no_anggota +9,WAN ZULKIFLY B WAN MOHAMED,680509035997,010-8995997,1 +13,HASANAH MOHAMAD,740325036196,1169670585,2 +14,HASLINA HASBULLAH,630216035760,1111473265,3 +16,NURWIDAD BINTI AZLY,891020035246,134040289,4 +19,ZULAILA BINTI CHE MAT,840313035290,1137707081,5 +25,MUHAMMAD HAFIFI BIN ABD RAHMAN,970403035003,1114884900,6 +33,FARAHAIN FATIN BINTI MOHD FAUZI,940624035560,169877154,7 +45,NURHANA BINTI FARHAN,910508125764,1137425769,8 +51,CHE FAHMI AMIRUL BIN CHE MOHAMAD ZAID,930702035381,1139239497,9 +53,KELVIN @ MOHD NAJIB BIN KEREAN,900420125525,146750406,10 +55,MUHAMMAD NAZIF BIN ABDULLAH,840830025541,166892948,11 +56,SUHAIBAH BINTI JUSOH,931212035148,199128698,12 +58,ELMA HARFAZLYANA BINTI BAHAR,990827126556,198782708,13 +59,MARINAH MAZNAH BINTI AMAT @ ABD RAHMAN,961109126102,1128686033,14 +60,SITI NUR ATHIRAH BINTI ZULKIFLI,980222036786,128108084,15 +61,MOHAMAD HAFIZUL BIN SANUAR,930619036201,149246474,16 +63,MUHAMAD MUSLIM BIN MADIRAN,970326035551,179726697,17 +64,EQA NURFITRIANA BINTI ALIMUDDIN,980202126442,1112085474,18 +65,ZULKARNAIN BIN MOHD JAMAL,980203126321,1139237021,19 +68,IRFAHANNA EMIRAH BINTI MOHD ALWI,10506031090,1110311820,20 +70,NURAIN SYAFIKA BINTI BURHAN,20828030380,179016282,21 +71,NUR FADHILAH AFIFAH BINTI MOHD NAZMI,980827035268,1117821334,22 +75,MOHD HAFIZUDDIN BIN HARUN,930822115351,134986658,23 +76,MUHAMMAD AMMAR FIRDAUS BIN RIDZUAN,970826035291,109253592,24 +77,MOHAMAD AFDHAL BIN ANWAR,890818075031,012 2017437,25 +78,NOR AIN BINTI ABDULLAH AZID,920411035470,1131590164,26 +79,SITI NOORAINI BINTI LAZIM,900617025042,1140794473,27 +82,FATIN AFIQAH BINTI MOHD SHAH,920322036084,199084590,28 +84,NUR ASIAH BINTI MUHAMMAD,950324035840,010-4152116,29 +85,AHMAD NAZRI BIN ISMAIL,700601035039,199179559,30 +86,TUAN NURHAFIZA BINTI TUAN ZULKIFLI,890624035306,133925842,31 +87,MOHAMAD NAZMI BIN MOHD SUKRI,980131035999,139245295,32 +88,AMIRUL HISHAM AIMI BIN CHE AMRAN,940515035545,139622447,33 +90,MUHAMMAD HAFIZI WAJDI BIN HASSAN,951103036043,1125509097,34 +91,NUR AMIRAH BINTI ZULKIPLI,980422036502,134863252,35 +92,WAN NOR AZIAN WAN ABDUL MANAF,740428035008,179142365,36 +94,SITI MARIAM BINTI MUHAMMAD AZHAR,800123035154,199288851,37 +95,TUAN NOR DIANA BT TUAN AZHAN,940401035870,193770187,38 +96,MOHAMMAD IZFAN BIN MAT IZANI,970805036113,137884588,39 +97,NUR IZZAH IWANI BT MOHD RAZDI,970624035146,179189543,40 +98,WAN ROZARINA BT WAN ZAIN,801210035368,129616201,41 +100,SYAHADAL AUZAEAIN BIN ZULKARNAIN,961020855069,169324952,42 +101,SYARIFAH AL QURAISYAH BT SAYED MUSTAPHA,970319035596,105750423,43 +106,MOHAMAD HAFIZ BIN CHE SOH,890905035337,199720813,44 +110,NIK NUREN SYAFIKAH BT NIK MOHAMED NAZRI,950501035164,179406274,45 +121,SITI FATIMAH SALWANI BT ROSMAN,891222035658,126209004,46 +122,AHMAD AFKAR BIN MOHD NOOR,10626030957,108847563,47 +123,MOHD THAQAFI BIN SHAMSUDDIN,920409036669,179162486,48 +124,NUR AYUNI BINTI AHMAD FAUZI,971101035686,1111433401,49 +127,NOR AZILA BT CHE SOH,751005035980,1110742242,50 +153,ALILYHAYATIE BINTI MOHAMED,840101036822,123015583,51 +162,ERNINGSIH BINTI JUNAIDI,900705125262,1139238537,52 +165,FATIN NADIA BINTI ZAIDI,920114-03-6346,199405259,53 +168,ISMAIL BIN ZAKARIA,870210035359,105681405,54 +171,KAMSAH BIN LINGGISAN,870513496697,146555718,55 +179,MOHAMAD FAIZ MOHAMED ASRI,850922035543,139938243,56 +207,RAZAKI BIN MAMAT,770215035851,199178946,57 +208,HAFEIZAH BT . AB KADIR,790918035426,129897112,58 +219,MOHD HAYYUL ILTIZAM BIN OTHMAN,851018035793,133929331,59 +232,MOHD SHAHMIN BIN SA'ARI,861130295121,196438873,60 +237,MUHAMAD FARIZ BIN ABDULLAH,871004035205,179268308,61 +245,MUHAMMAD SYAKIRIN BIN MOHD AMINUDDIN,880425065327,129077963,62 +262,MOHAMED AZMI MAHMOOD,840511035443,199731345,63 +264,MOHD RAZANI A. RAHIM,670930106593,199099713,64 +272,NOROSMINI BT. MAT NOOR,821001035984,129493588,65 +280,WAN MOHAMMAD ARMANI WAN SHARIFUDIN,870119035091,189022406,66 +312,NORALINA MOHD YUSOFF,630106035380,182269464,67 +319,NOR'AINI AH KOM BT ABDULLAH,631231675058,1112301671,68 +320,AZLY BIN OTHMAN,620809035425,199598184,69 +324,FARIDAH BT. MAMAT,600813035112,139492226,70 +325,MOHD NAIM MOHAMAD,570805035441,169214503,71 +327,NUR IZZATI HUSNA BINTI ABD RAHMAN,880417035750,194166991,72 +328,NORAZERA BINTI ADIN,930513126372,143560193,73 +343,NOR AZIAH BINTI AHMAD,770716035702,129521803,74 +354,SITI ANIZA BT HARDAH,890801125848,143751889,75 +358,RUFAIDA BINTI HAJIHIL,861221125160,178317763,76 +363,MUHAMMAD AMIN BIN RIFFIN,950626035483,132747420,77 +364,MUHAMMAD RASIHI BIN ABD KARIM,830401035435,134487279,78 +366,LIYANA FARIEHA BINTI BAKHORI,960209025136,194622615,79 +367,AFA HUSNA BINTI MD RADZI,921018025748,103737560,80 +369,NOR INTAN MARLINI BT NOR AZLAN,851124035914,139269494,81 +370,NUR AIN SOFIA BINTI ROSLI,960131035018,169409127,82 +376,MOHD FAIZUL AZAHA BIN UMANAH,840502035417,199992928,83 +378,MOHD FAIZAL BIN SAFIE,871129295529,139922275,84 +380,HASWATI BINTI KARIMIN .,820421126036,1119544351,85 +381,JURINA BINTI MADAYA,880609125224,168178634,86 +383,NURFARAHIM BT MOHD OMAR,900427035418,1126220662,87 +386,SHAZRINA BINTI AZLIND,970518125682,128373831,88 +388,HASANUDDIN BIN HUSAING,980814126339,128376008,89 +390,SITI ANNA SHAHEERA BINTI ALI,921121125026,146567467,90 +397,NUR AFRINA BINTI ALIMI,990616065714,137969408,91 +398,ABDUL HALIM BIN TALIB,901025065707,1111313873,92 +399,NUR IZZATI BINTI ZULKIFLI,890123035826,178916936,93 +400,NUR LIANA SYAFIKAH BINTI SALAM,940605035186,148478780,94 +401,AHMAD SYAHMI BIN AHMAD IZANI,870828035545,1111706484,95 +402,ROZALMI BIN RAZALI,820101035629,138973594,96 +403,SHAMSURIATI BINTI HASSAN,880826035444,133605298,97 +404,MOHD AMIRRUDDIN BIN ARZAMI,840417025943,137868197,98 +405,MOHD AZIZI BIN AB RASHID,870112295165,148983787,99 +406,SUHAIRAH BINTI SULIMAN,840615036280,139463484,100 +407,MOHD FARID BIN IBRAHIM,790406035393,199499704,101 +408,MOHD FAIZUL BIN HUSSAIN,850910035837,139090920,102 +409,MOHD KHAIDIR BIN AWANG,880606035899,139742581,103 +410,NOR AZIAH BINTI AHMAD,770716-03-5702,129521803,104 +411,FATIHA BINTI CHE ABDULLAH,950102915068,129698210,105 +412,NIK ABDULLAH BIN NIK MUHAMMAD,630411035213,148125345,106 +413,MAHNUN BINTI HUSSIN,740530035352,1155061673,107 +414,SYUKRI BIN ARIFFIN,771218715013,183416221,108 +415,ARMIN BIN MANDANGAN,981019126449,169369704,109 +416,ZAID BIN ZAKARIA,670108035479,199179138,110 +417,MOHD FIRDAUS BIN MAHAMOOD,900202035513,145075069,111 +419,NORAZANI BINTI HUSAIN,721203035204,179818808,112 +420,AZURAWATY BINTI AHMAD,840821025208,175800844,113 +421,WAN RUSLAILE BINTI WAN MOHD ZAIN,841118035644,145060899,114 +422,NOOR HAFIZI BIN MOHAMAD,890922095155,1133406383,115 +423,ISMAIL BIN ZAKARIA,870201035359,010 5681405,116 +424,MOHAMMAD FARIZ BIN MUSTAPHA,850115035969,196017695,117 +425,ABDUL HAKIM BIN AHMAD AB.NASHIR,901116025225,143464266,118 +426,AZIRIN BIN RIFFIN,730605035551,199104757,119 +427,KATHERINE RUMBANG,770421125700,1139025242,120 +428,MUHAMAD SHAHARIL BIN SIDIK,860104035049,199868018,121 +429,AMIRAH FARHAN BINTI MOHD ASRI,890711035566,136246932,122 +430,MUHAMAD HAZLAN BIN RAMLI,940225036443,148030664,123 +431,MOHD FARIS BIN RUSLEE,870812035081,179119982,124 +433,RIDHUAN BIN ABDULLAH,840612125739,1116518794,125 +434,MANIAH BINTI ASUN,840331126284,105897892,126 +435,NORFISHAH BINTI MUSTAFFA,870406026294,124478826,127 +436,NOR AZIAM BINTI JUSOH,830621035488,179627003,128 +437,HAFIZUL RAHMAN BIN MOHD FAUZI,830521035683,129397958,129 +438,NIK NOR SHAHIRAH BINTI NIK YUSOFF,950923035690,109510068,130 +439,MOHAMMED SHAZWAN BIN NORDIN,850729036165,1111683685,131 +440,MOHD REDZUAN BIN SHAARANI,870710085395,179022324,132 +441,Noor Azlan bin md noor,841201035127,199034008,133 +442,SITI RAIHAN BINTI MAT SAN,890907115154,197284647,134 +443,NIK MOHAMAD HAZIM AQMAL BIN NIK ALIM AMIRAH,920609035353,104473383,135 +445,RAJA NOR AIDAH BINTI RAJA AHMAD,901012065900,139515155,136 +447,NORLIN BINTI SAIMAN,871205235350,1160575580,137 +448,MUHAMMAD KHAIRUL BIN ALI,841212035595,179484638,138 +449,ROSLINA BINTI MOHD RAMLI,820804034326,139824757,139 +450,NUR AIN FARINA PANAI ABDULLAH,870728125228,146557037,140 +451,SUZIANA BINTI YUSOF,840822035520,104568684,141 +452,KAMSAH BIN LINGGISAN,870513 49 6697,014 655 5718,142 +453,MOHD. RAMDHAN BIN WARIMIN,890430125629,109430138,143 +454,MUHAMMAD DAUD BIN ABDULLAH,930921017159,1119526732,144 +455,NIK MUHAMMAD ARASH PUTRA BIN AZIHAN,981109036041,179003770,145 +456,MUHAMMAD IQABAL ZUEL,831202035533,149404101,146 +457,MOHD FAHMI BIN MAT LUDIN,801104115567,1121039021,147 +458,MOHD ARIFIN BIN ISMAIL,680229035095,109262869,148 +461,MOHD NOR BIN OSMAN,830601035405,129247270,149 +462,NURFARAHIAH BINTI MAT JUSOH,891028035718,199403985,150 +463,NURUL NISHA BINTI MUHAMMAD,841218035676,1110948404,151 +464,MUHAMAD IZZUWAN BIN MD SHUKRI,910607035537,179515004,152 +465,NORALINA BINTI MOHD YUSOFF,630106-03-5380,018-2269464,153 +466,NUR AININA BINTI MOHAMMAD,961010036086,1119723793,154 +467,TUAN MOHD NOR NAZRIM BIN TUAN MOHAMMAD,820527115175,122428020,155 +469,MUHAMMAD FAQIH AMRI BIN JAILANI,980917035229,166138478,156 +470,SITI NOORAAINI BINTI DAUD,761026035532,129602691,157 +471,MOHAMAD DAWAWI BIN IBRAHIM,810215035505,179415892,158 +472,RAKIAH BINTI YAACOB,590208035476,145177720,159 +473,ASMA BINTI AHMAD,871129295094,135675063,160 +474,AHMAD AZIMAN BIN CHE ALIAS,970425035485,1137999991,161 +475,MOHD SYAHMIE SYAWAL BIN MOHD BAKRI,900503036069,145144451,162 +476,MARJUNI BIN MOHD ALI,840503126521,1116027090,163 +477,AINIE HAYATIE HAMAZAH,880122115024,1116168995,164 +478,MUHAMMAD IZWAN BIN IBRAHIM,890601035127,1129079797,165 +480,FARIDAH BINTI MAMAT,600813-03-5112,139492226,166 +481,MOHD SABRI BIN ABDULLAH,530502035069,199813353,167 +482,MOHD KHALID BIN ABDUL RAHMAN,630807035295,145036476,168 +483,AZMADI B. HJ. OMAR,681028035093,199803003,169 +484,RUSMAWATI MAMAT,660827035548,104559409,170 +485,AZIMAH BT. ABDULLAH,580910035282,018770 4639,171 +486,MIHAMIDAH BT. HAMAT,680930035552,1127486160,172 +488,NOR AISAH BT. RAMELI,720723035748,1115469653,173 +490,RAZAKI B. CHE OMAR,681228035207,148131565,174 +491,SULAINI BT. JAAFAR @ MAT ZIN,740628035916,199058471,175 +492,TUAN RAZAK B. TUAN MUDA,670301035817,129695589,176 +493,AMINUDDIN MD NOR,690217035097,199975353,177 +494,ROHANA MAEL,711021035730,129249968,178 +495,WAN NOR AZIAN WAN ABDUL MANAF,720428035008,179142365,179 +496,ZAILILAH BT. HASSAN,700825035062,189163000,180 +497,NARWATI BT. LUPIN,740110035874,10416116,181 +498,CHE SOH B. HASSAN,591010035935,139070565,182 +499,MOHD EZANEE B. MOHD NOOR,610916035317,199815500,183 +500,MASTURA MUHAMMAD,761003035214,139856061,184 +501,HASSAN SHUKRI B. HUSSEIN,660604035049,139026550,185 +502,MOHD RAMLI B. YAACOB,570601035001,145091165,186 +504,NIK NOOR MASTURA BT NIK SOH,750607035174,183134464,187 +506,ROSEMALIZA BT. MUHAMAD,700224035542,199092277,188 +507,ROSHAFIZA B MAMAT,800619035051,179653635,189 +508,FATIMAH BTE MAT ZIN,821025036084,139360958,190 +509,MOHD SAHARUDIN B AB RAHMAN,810310035757,1131056099,191 +510,KAMARUL IRWAN BIN ABDUL RAZAK,780508035619,199195969,192 +511,MOHD BIN YAACOB,580925115015,129623355,193 +512,ANIS ISMAIL,720504035190,199105226,194 +513,HAFEIZAH BT. AB KADIR,790918035246,129897112,195 +514,MOHD FAIZAL B. MOHAMMAD,790118035305,139521113,196 +515,KAMRUL HISAN BIN MOHD KAMSON,650127035003,139817419,197 +516,SAFINAH BT MAHAT,620212065058,189832242,198 +517,NIK JAWAHIR BT NIK ISMAIL,700602035276,129599499,199 +518,ASMAH LAILY HUSSEIN,710328035204,139636908,200 +519,W.M. AZHARI B WAN ABDULLAH,700325035605,139821822,201 +520,WAN AZKAN BIN WAN HASSAN,660304035653,199825653,202 +521,ZAITON MAT ADAM,600821035462,179631848,203 +522,WAN MOHAMED SHARIF B WAN MUSA,540704035365,199115365,204 +523,RAMELAH BINTI DERAMAN,650629035046,196953070,205 +524,NORLY BINTI DERAMAN @ IBRAHIM,691213035190,169243019,206 +525,MUHAMAD SUKRI BIN SEMAN,740906035335,179702750,207 +526,ZAILANI YAACOB,681215035179,103346695,208 +527,AMIRIZA HAMZAH,680919035447,199806158,209 +528,MUHD NASROM SHAH B. YUSUF,720208035305,199505505,210 +529,A'SRI CHE ALI,610820035873,1111255604,211 +530,FARIDAH CHE ALI,690103035478,1139190727,212 +531,ABDUL RAHMAN ALI,701112086323,129516256,213 +532,RAMILAN ABDUL RAHMAN,650207035433,199583737,214 +533,MD AZHARI ABD RAHMAN,640406035111,139676728,215 +534,NOR FAZILLAWATI MOHAMED,830720035328,199475444,216 +535,SARINA MOHD ZAIN,700926035096,137617588,217 +536,ROSELINA MOHD MAHIDDIN,651027035588,129535394,218 +537,AMRAN MOHAMAD,720417035475,199448955,219 +538,ROZIANI BT. AHAMED KAMIL,750101039848,011 26403553,220 +539,MOHD YAMIN ISMAIL,630904035043,199602549,221 +540,AZIZAH KAMARUL ZAMAN,680615035210,179594611,222 +541,MOHD FIRDAUS JAMALUDIN,880218035387,129540047,223 +542,NOR AZLIMAH RAMLI,850708035112,179722326,224 +543,MOHD AZRUL FAIZAL ABU BAKAR,821105035735,194458020,225 +544,ABDULLAH ZAWAWI BIN MAMAT,730119035695,145042276,226 +545,AZIMAT MAMAT,650501035629,148098787,227 +546,NORHAYATI YAACOB,670110035304,179191617,228 +547,MOHD NORIKHWAN BIN SHAHIMI,850216035415,179730779,229 +548,ASHAMDI ASAARI,810910035427,173332616,230 +549,NIK NABIHAH NIK YUSOFF,880923035956,172989264,231 +550,MUHAMAD BUKHARI ABD RAHIM,820112035587,129469118,232 +551,MOHD ZANI MD ZAIN,650519035491,139972365,233 +552,NURHAIDA ABD SAMAD,821230015194,139321786,234 +553,MUHAMAD FARKIAMI AB. RAHIM,761216035621,133999602,235 +554,MOHD FAIZUL AZAHA UMANAH,840502038417,199992928,236 +555,SAIDITINA AISHAH MAHAMUD,891128065084,139278425,237 +556,MOHD HAFIZ YAHAYA,820209035567,199087605,238 +557,AHMAD KHALLIFA MOHD HANAPI,870217035167,179238977,239 +558,NUR RASHIHAH SALLEH,851117035318,139089829,240 +559,NIK FADHLINEE NIK MARWAN @ NIK FAUZI,841217035308,129578497,241 +560,ROSLINA MOHD RAMLI,820804035326,139824757,242 +561,WAN RAMLAH WAN DERAMAN,770227035840,1125712878,243 +562,MOHD ROSLAN MOHD ALI,610821035779,146455992,244 +563,ZANJABILA MOHD SALEH,851020035522,199859436,245 +564,NORAI MAT DAUD,750607035262,146060678,246 +565,MARIYANI MUDA,801209035512,129900535,247 +566,ABDULLAH HAKIM AB. ALIM,821128035885,199497979,248 +567,NOR HAFIZUDIN MOHAMED,861115296249,179274383,249 +568,NORMALA MOHD NOOR,850827035270,133267027,250 +569,SHAHILLA CHE RAZALI,830131075006,145297313,251 +570,NUR IDAYU MAT NASIR,861008295152,139019799,252 +571,MOHAMED AZMI MAHMOOD,840511-03-5443,199731345,253 +572,ABDUL RAZAK OMAR,640822035671,1111929667,254 +573,MOHD EKHWAN ZAKARIA,880422065567,1151667076,255 +574,ABDUL HAFIZ NAWAWI,870526025085,176755443,256 +575,FARAH AWANIS EDRUS,831209035296,129229523,257 +576,SADEED MUHDHAR MOHD ZAIN,870621035767,139121305,258 +577,NURUL AINI HARUN,860606296396,1137504434,259 +578,WAN MOHD RAZIS WAN SUHAIMI,831220035721,139839010,260 +579,NIK LOKMAN NIK MAN,830209035013,137440221,261 +580,MOHD SHAHRUL RIDZUAN ABDULLAH,850316035383,126865723,262 +581,WAN MOHD RIDHUAN WAN MAT LUDIN,861016296219,179717099,263 +582,MOHAMAD FAIZ MOHAMED ASRI,850922-03-5543,139347720,264 +583,MUHAMMAD FERDAUS NOOR ABAS,870119065071,179704287,265 +584,NUR FARAZLIN ROSLI,880611035172,196132336,266 +585,OTHMAN BIN DAUD,740522035889,139504781,267 +586,NOOR HAFIZI BIN MOHAMMAD,890922035155,174677645,268 +587,SITI ZALEHA HARUN,840731036042,1137550567,269 +588,FATIN FAUZANA BT. MOHD RAMLI,870615035568,1110109118,270 +589,AZID @ ABDUL AZID BIN SULAIMAN,700618035799,199271623,271 +590,MOHD SHAFIK AFFANDIE BIN MAMAT,870725035323,173550586,272 +591,HAZRUL BIN HUSSIN,831219035169,139697822,273 +592,NUR ADNIN BINTI MOHAMED,830725035298,109333696,274 +593,SAMSIANA BINTI RAHENG,840808035516,199900575,275 +594,MOHD FAIZ BIN MOHD WARDI,850817035955,1111617548,276 +595,MOHD ZAIRY BIN MOHD ROSLI,810118035503,173594115,277 +596,MOHD ASRI BIN MUKHTAR,791007035681,199721640,278 +597,NORHAPIZAH BINTI MOHAMMED @ AZIZ,871120035544,199329511,279 +598,NURUL ZATUR NAJAHAH BT YUNUS,870717065020,132128673,280 +599,MOHD EZUAN BIN ISMAIL,840324035077,137745031,281 +600,CHE RUSLI BIN MUHAMMAD,721110035459,139462647,282 +601,AHMAD AMIN BIN RASHID,850606035525,104515525,283 +602,MOHD HAFIZ BIN MOHAMMAD,840515035141,129394353,284 +603,MUZANI BIN IBRAHIM,680518035841,1140297681,285 +604,WAN AZMEER BIN WAN MAHMOOD,900114035839,133136965,286 +605,KHAIRUL ANUAR BIN YAACOB,850127035333,199618159,287 +606,AZHAN BIN MAT,870802035651,199117990,288 +607,SAKRI BIN MAT NOR,720104036207,129295955,289 +608,NASRUL HAFEZ B. MAT NASIR,831220035975,1110105975,290 +609,ARJUNAIDEY AZWAR BIN AB RAHMAN,830113035019,148284946,291 +610,MOHAMAD AZIZI BIN MOHAMED NOOR,870824295657,013 9109873,292 +611,MUHAMAD HAFIZ BIN ZAKARIA,871115035873,179156428,293 +612,MUHAMMAD ARIEZ BIN AZMAN,910504035219,179808962,294 +613,MOHAMAD RIDZWAN BIN MOHAMAD,920720035749,169357949,295 +614,ATHIRAH AZRI BINTI AZMI,870619035426,179235024,296 +615,MOHD ZULFADLI BIN IBRAHIM,860216035481,1129276057,297 +616,AIDAMARNI BINTI SALLEH,810123035890,139131328,298 +617,NORMAHWATI BT BELUDTU,840301125854,198405462,299 +618,NURHUSIN BIN APAN,831010127337,178190102,300 +619,MUHAMMAD NAFIS B ZAINUDIN,870509035089,194714564,301 +620,MOHD HAFIZUL FIKRI BIN SIDI MOHAMED NOOR,880422035149,179514823,302 +621,AHMAD ZULKHAIRI BIN ZULKFLI,890910036289,102911183,303 +622,MOHD AL-AMIN BIN YUSOFF,870516295487,1133301744,304 +623,CHE KHAIRUL AZLI CHE HASHIM,920827035829,179008827,305 +624,MOHD FIRDAUS BIN MOHAMAD,850127035237,139440200,306 +625,MOHD AYUB BIN SUHAIMI,871231675069,189650520,307 +626,MD AZWAN BIN NORDIN,900826125883,109313914,308 +627,MOHD HAFIZ FAHMI BIN SAHAK,871104125355,198955381,309 +628,SITI MASHITA BINTI MARIJIN,860930495944,019 5324767,310 +629,RIDZAN NURLINA BT MOHAMED NASIR,850119065698,189160395,311 +630,MOHAMAD FURQANUL AIZAT BIN FAUZI,900728035593,1120722721,312 +631,MUHAMMAD IZZUDDIN BIN MOKHTAR,890209035333,199011095,313 +632,MOHAMAD SHAKIR BIN ABDUL MANAN,901105035591,1110630511,314 +633,NOOR SUHAILA BINTI IBRAHIM,940423035150,104164407,315 +634,SITI NORAZNI BINTI HASSAN,900515036058,145268580,316 +635,MOHD HANIF BIN MAT ROF,811107035721,129637776,317 +636,ASMARIHAN BINTI AB GHANI,880205035150,1110970931,318 +637,HADAFI BIN MOHD ZUKIPELI,890302035071,1110104559,319 +638,MOHD SHAHLAN B. ANUAR,900728035913,179872315,320 +639,MOHD FAIZAL BIN IBRAHIM,870504295017,194178298,321 +640,MOHAMMAD KHAIRULNIZAN BIN JUSOF,910218036157,179600102,322 +641,MUHAMAD HAFIZ SHAR'E BIN HANAFI,940607035497,136749495,323 +642,ROHAYA BINTI MUHAMAD,620101038014,1117932057,324 +644,MAHARI BUKHARI BIN MAT,891115035169,145161951,325 +645,MOHAMAD AZUHAIDIE BIN AHMAD,940801035677,145116331,326 +646,MOHD ZULKIFLIE BIN MOHD ZAIN,841120035977,139559841,327 +647,IRMA SYUHADA BT IBRAHIM,840229145446,139403344,328 +648,MUHAMMAD SHAKIL BIN HAMIDIN,901226035221,179864356,329 +649,MARIATI BINTI MADAN,850919125118,198122726,330 +650,NOOR ATIQAH BT AHMAD,881228125268,102025862,331 +652,WAN MANITA BT HAMAD@ WAN MOHD,890711035662,179545432,332 +653,WAN NURHAFIZOL BIN WAN MANSOR,850127035739,179676792,333 +654,LUQMAN HAKIM BIN MOHD YAHAYA,911129035421,193458235,334 +655,MUHAMAD ASYWAM BIN A'SRI,940908036063,199016835,335 +656,MOHD HISYAM KHAIRIE BIN MOHD YUSNI,900713035689,132829323,336 +657,WAN NURUL AMIRA BINTI WAN HARON,881119035132,1110764243,337 +658,MOHD ZARIM BIN MOHD ZAMRI,930609125147,143595362,338 +659,MUHAMMAD FAIZUL HAKIMI BIN MUSTAPA,880711035225,197523023,339 +660,MOHD FAHMIE BIN ZAKARIA,910721036285,1116507469,340 +661,PG. SITI KADIZAH BINTI PG. ABDULLAH,800705125272,146510936,341 +662,SAFITERI BINTI TARNO,901121125730,168137928,342 +663,MUHAMMAD KHAIRUL AMIRIN BIN MOHD ROSLI,940425036165,129536020,343 +664,NUR FAKHIRA BINTI AHMAD KAMIL,950711035138,149693382,344 +665,MUHAMMAD HAZIM BIN MOHD ASRI,950310145475,196154087,345 +666,NURUL HIDAYAH BINTI MUSTAPA@DERAMAN,910729035308,199419472,346 +667,MOHD MUSTAKIM BIN YUSOFF,850213035911,1110814060,347 +668,NORIZAN BINTI AWANG,701017035288,1137589963,348 +669,NAZIRAH BINTI MOHAMED,911116036150,179413710,349 +670,MOHD NAWITAR BIN MOHD,780825035663,179763812,350 +671,WAN NORHISHAM BIN WAN JAAFAR,700908035391,197293648,351 +672,MOHAMAD HAMIRUL BIN HALID,901202146381,195126381,352 +673,MUNAWIR BIN MD NASIR,931019125045,198449355,353 +674,MOHD FHAEIS BIN MUHAMMAD,940413035755,187730960,354 +675,SARIP BIN SALANI,881022125297,168269145,355 +676,WAN AHMAD KAMAL BIN MOHD NOR,930530036037,173267793,356 +677,ABDUL MUHAIMIN BIN AHMAD,891218036009,136444757,357 +678,NUR ALISSYA BINTI MOHD HAZMAN,941128035232,1117806234,358 +679,DATO' DR WAN ZAWAWI BIN WAN ISMAIL,610613035547,199889217,359 +680,ABDUL MUHAIMIN BIN ABDULLAH,870129295153,1128005291,360 +681,FATIN NADIA BINTI ZAIDI,920114036346,199405259,361 +682,MOHAMMAD ASWAT BIN PATEK MOHD,850514065129,129742514,362 +683,ASMADI BIN ABDUL WAHED,900702035683,139072135,363 +684,AHMAD TARZIDIE BIN AB MANAF,851223035055,0112-6018916,364 +685,NURUL ALIA BINTI MOHAMAD KAMAL,940726035326,105705470,365 +686,JUNAIDI BIN BAKRI,890128125249,1136662466,366 +687,ASHIKIN ABDULLAH,590406035258,1111420604,367 +688,NIK NUREN SYAFIKAH BT NIK MOHAMED NAZRI,950101035164,179406274,368 +689,NOORHISHAM B. SAMAT @ MAT JURI,751016125447,139449192,369 +690,NIK MOHD NASIRUDDIN BIN NIK COB,740714036093,148007363,370 +691,AB AZIZ BIN YUNUS,600410035193,199891913,371 +692,MOHAMAD HAFIZ BIN CHE SOH,890905035331,199720813,372 +693,NIK NISREEN BT MUHAMMAD FITRI,961201855068,148471010,373 +694,FAIZAL BIN MOKTAR,920721125455,1162289550,374 +695,FATHIAH BT TAIP,921127126396,1133145854,375 +696,ABD MUHAIMIN BIN TURIDI,920126855015,184664503,376 +697,MUHAMMAD HIZHAM BIN ZAKARIA,930817035701,179442383,377 +698,ZALIHA BT MD ZAIN,870215295360,173831225,378 +699,MOHD FADZLI BIN MOHD NASRAH,950712035797,1160860255,379 +700,HASWATI BT KARIMIN,820421036036,1119544351,380 +701,NURATIKAH BINTI AJANI,940111125392,196946450,381 +702,MOHD FADILLAH BIN MATLIN,930711125549,178958563,382 +704,NAFISAH BINTI MUHAMADIN,950827125784,189602088,383 +706,WAN NUR FATIN NATASYA BT W M AZHARI,970113035574,136652264,384 +707,HAZNINA AINI BINTI HASSAN,880608295176,139973524,385 +708,MUHAMAD SHAUQI BIN SHAHAPUDIN,931013036439,148340734,386 +709,NUR FARAHIM BT MOHD OMAR,900427045418,1126220662,387 +710,NORAZRINA BINTI KAMIN,921214125834,128668241,388 +711,MOHD AMIRUDDIN BIN AZAMI,840417025942,137868197,389 +712,SRI NUR FARHANA BINTI KASIM,931114086208,010 8816543,390 +713,NOR AMYLIA EZATY BT ISMAIL,980315036312,142144227,391 +714,WAN NOR IZYAN BINTI WAN HISHAM,990415105986,1140201378,392 +715,U'WAIMAR BIN ZULHAZMI,950819885011,139984700,393 +716,MUHAMMAD AMMAR BIN ISMAIL,203030737,193517702,394 +717,AMIR THAQIF THARIY BIN SHAMSUDDIN,980822036069,1114932463,395 +718,MOHD AIZAD SALIM BIN AGUS SALIM,1126121073,136613176,396 +719,FADZLYEENA BINTI SAIREN,900204126128,149550642,397 +720,NURUL AIN IZAZI BINTI ABD AZIZ,10528030056,1112908502,398 +721,ARMAN SHARIF IBRAHIM BIN HISHAMUDIN,990624106475,129018250,399 +722,MUHAMMAD AFIQ BIN HAMZAH,910130035045,1159983870,400 +723,ZULKIFLI BIN AB HAMID,850102035679,179475958,401 +724,MUHAMAD AIMAN BIN MAZLAN,990808035309,138399913,402 +725,MOHAMAD HAFIZUDIN BIN ABDUL SATAR,910917035997,139577319,403 +726,ZULIYANA BINTI TAJUDIN,911117015992,197591920,404 +727,WAN MUHAMMAD SHAHRIL BIN WAN MOHD FADZLI,970824036039,143342577,405 +728,MUHAMMAD AIMAN HAKIM BIN MOHD RODHI,961010465075,105116144,406 +729,WAM MUHAMMAD JAMALUL'AQIL BIN WAN ZAKARIA,961117036035,169315308,407 +730,MUHAMMAD YAZID BIN OSMAN,20506040041,165276449,408 +731,PUTERI NUR AISHAH BINTI WAGIMIN,20528010740,177315254,409 +732,NURFARHANA BINTI ALIRNOR,911112065034,148160691,410 +733,AHMAD SUHAIL IRFAN BIN ZAMRI,10629030979,129607215,411 +734,NUR HUSNINA BT LUKMAN,961226035322,199652655,412 +735,CHE SOH B HASSAN,591010035395,139070565,413 +736,NUR MUZIERA SHAZRINA BINTI MUHAMAD,1024030736,172604369,414 +737,FAZILA BINTI TOMAS,951226126794,1169309126,415 +738,RIDZUAN BIN AMRAN,911118125691,1173376044,416 From 0b1c50676eca67813c1373de7d5afd1db633d2c9 Mon Sep 17 00:00:00 2001 From: nurafrinaalimi16 Date: Mon, 10 Nov 2025 23:02:30 +0800 Subject: [PATCH 66/80] comment command import csv --- app/Console/Kernel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 1d236f5..9308414 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -24,7 +24,7 @@ class Kernel extends ConsoleKernel Commands\ClearCachesAll::class, Commands\RestartSupervisor::class, Commands\InsertSempornaData::class, - Commands\ImportCsv::class, + //Commands\ImportCsv::class, ]; From e7650febfc9ea1d28fcbf3210bf4fe7dcbe8de47 Mon Sep 17 00:00:00 2001 From: nurafrinaalimi16 Date: Tue, 11 Nov 2025 00:05:33 +0800 Subject: [PATCH 67/80] fix url lelong --- app/Http/Controllers/LelongController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Controllers/LelongController.php b/app/Http/Controllers/LelongController.php index a7a867b..fe898a9 100644 --- a/app/Http/Controllers/LelongController.php +++ b/app/Http/Controllers/LelongController.php @@ -607,7 +607,7 @@ class LelongController extends Controller if(env('APP_ENV') != 'production'){ $link = 'http://niklah.arrahn.com.my/api/portalApi'; }else{ - $link = 'http://adminbid.arrahn/api/portalApi'; + $link = 'https://https://adminbid-kopkb.erahn.com.my/api/portalApi'; } $lelong = Http::withOptions(['verify' => true])->get($link,[ From c7874c15bc739461710a0eadf8d0a932378ce13e Mon Sep 17 00:00:00 2001 From: nurafrinaalimi16 Date: Tue, 11 Nov 2025 00:08:26 +0800 Subject: [PATCH 68/80] fix error url lelong --- app/Http/Controllers/LelongController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Controllers/LelongController.php b/app/Http/Controllers/LelongController.php index fe898a9..d11d76a 100644 --- a/app/Http/Controllers/LelongController.php +++ b/app/Http/Controllers/LelongController.php @@ -607,7 +607,7 @@ class LelongController extends Controller if(env('APP_ENV') != 'production'){ $link = 'http://niklah.arrahn.com.my/api/portalApi'; }else{ - $link = 'https://https://adminbid-kopkb.erahn.com.my/api/portalApi'; + $link = 'https://adminbid-kopkb.erahn.com.my/api/portalApi'; } $lelong = Http::withOptions(['verify' => true])->get($link,[ From cc11e3aed69c7ba7405bcdc3f9e0f8ade83a163f Mon Sep 17 00:00:00 2001 From: nurafrinaalimi16 Date: Tue, 11 Nov 2025 22:23:37 +0800 Subject: [PATCH 69/80] add column name on operasi approval --- app/Http/Controllers/KelulusanController.php | 64 +++++++++++++------- 1 file changed, 42 insertions(+), 22 deletions(-) diff --git a/app/Http/Controllers/KelulusanController.php b/app/Http/Controllers/KelulusanController.php index 07ed5d7..89e7647 100644 --- a/app/Http/Controllers/KelulusanController.php +++ b/app/Http/Controllers/KelulusanController.php @@ -258,7 +258,7 @@ class KelulusanController extends Controller 'namaoperasi' => $namaoperasi ]); - // ✅ Kalau LULUS + // Kalau LULUS if ($status == 1) { $kelulusan = MohonAnggota::on($cawangan['mysql']) ->where('nokp', '=', $nokp) @@ -270,14 +270,14 @@ class KelulusanController extends Controller 'updated_at' => $harini, ]); - // 🟢 Update CUSTOMER di pusat (mysql7) + // Update CUSTOMER di pusat (mysql7) Customer::on('mysql7') ->where('kpbaru', '=', $nokp) ->update([ 'tag_anggota' => 1, ]); } - // ❌ Kalau BATAL / TOLAK + // Kalau BATAL / TOLAK else if ($status == 2) { $kelulusan = MohonAnggota::on($cawangan['mysql']) ->where('nokp', '=', $nokp) @@ -692,33 +692,53 @@ public function create(REQUEST $request,$kodcaw,$norujukan,$roles) return response()->json($kelulusan, 200); } - public function listKelulusanAnggota(Request $request){ - - $harini = Carbon::now(); - $harini = new Carbon; - Log::info($request->all()); - $cawangan = Cawangan::on('mysql7')->get(); + public function listKelulusanAnggota(Request $request) +{ + $harini = Carbon::now(); + Log::info($request->all()); + $cawangan = Cawangan::on('mysql7')->get(); - $array_kelulusan = []; + $array_kelulusan = []; - foreach($cawangan as $caw){ - - $kelulusan = MohonAnggota::on($caw['mysql']) - ->where('tarikh', '=', $harini->toDateString()) - ->where('peloperasi', '=', 0) - ->orWhereNull('peloperasi') // Corrected this part + foreach ($cawangan as $caw) { + + $kelulusan = MohonAnggota::on($caw['mysql']) + ->whereDate('tarikh', $harini->toDateString()) + ->where(function ($query) { + $query->where('peloperasi', '=', 0) + ->orWhereNull('peloperasi'); + }) ->orderBy('id', 'desc') ->get(); - if(sizeof($kelulusan) != 0){ - array_push($array_kelulusan,["kelulusanall" => $kelulusan,"cawangan" => $caw['details_caw'],"cawangankod" => $caw['kodcaw']]); - } + if ($kelulusan->isNotEmpty()) { - } + // Kumpul semua nokp daripada senarai kelulusan + $nokpList = $kelulusan->pluck('nokp')->unique()->toArray(); + // Ambil semua nama daripada table customer (main DB) + $customers = Customer::whereIn('kpbaru', $nokpList) + ->pluck('nama', 'kpbaru') + ->toArray(); + + // Masukkan nama ke dalam setiap item kelulusan + $kelulusan = $kelulusan->map(function ($item) use ($customers) { + $item->nama = $customers[$item->nokp] ?? '-'; + return $item; + }); + + // Tambah ke array utama + $array_kelulusan[] = [ + "kelulusanall" => $kelulusan, + "cawangan" => $caw['details_caw'], + "cawangankod" => $caw['kodcaw'] + ]; + } + } + + return response()->json($array_kelulusan, 200); +} - return response()->json($array_kelulusan,200); - } From 39a2f9a5ef4d20e88204bf96ed159ab16e329722 Mon Sep 17 00:00:00 2001 From: nurafrinaalimi16 Date: Thu, 13 Nov 2025 23:33:11 +0800 Subject: [PATCH 70/80] fix kadar upah return 0 --- app/Services/OnePercentServices.php | 39 ++----------------- app/Support/v2/Calculation.php | 59 +++-------------------------- 2 files changed, 9 insertions(+), 89 deletions(-) diff --git a/app/Services/OnePercentServices.php b/app/Services/OnePercentServices.php index ad5b9ff..6e8e834 100644 --- a/app/Services/OnePercentServices.php +++ b/app/Services/OnePercentServices.php @@ -3,7 +3,6 @@ namespace App\Services; use App\KadarUpah; -use App\Customer; class OnePercentServices { @@ -80,43 +79,13 @@ class OnePercentServices return ['keuntungan' => $keuntungan,'onepercent' => $onepercent, 'ujrah' => $ujrah_sebenar]; } -public function getKadarUjrah(float $nilaimarhun = 0.0, $groupid, $nokp = null): float -{ - //Semak status pelanggan dalam table customer - if ($nokp) { - $customer = Customer::on('mysql7') - ->select('tag_anggota') - ->where(function($q) use ($nokp) { - $q->where('kpbaru', $nokp) - ->orWhere('kplama', $nokp); - }) - ->first(); + public function getKadarUjrah(float $nilaimarhun = 0.0, $groupid) : Float{ - // Jika anggota koperasi → kadar tetap - if ($customer && (int)$customer->tag_anggota === 1) { - return 0.16; // kadar ujrah tetap untuk anggota - } + $kadarujrah = KadarUpah::on('mysql7')->select('kadarujrah')->where([['min','<=',$nilaimarhun],['max','>=',$nilaimarhun]])->where('group_id',1)->get()->toArray(); + + return isset($kadarujrah[0]) ? $kadarujrah[0]['kadarujrah'] : 0; } - //Jika bukan anggota → ambil dari jadual kadar_upah - $kadar = KadarUpah::on('mysql7') - ->select('kadarujrah') - ->where([ - ['min', '<=', $nilaimarhun], - ['max', '>=', $nilaimarhun], - ]) - ->where('group_id', $groupid) - ->first(); - - //Jika jumpa kadar dalam jadual - if ($kadar && isset($kadar->kadarujrah)) { - return (float) $kadar->kadarujrah; - } - - //Default fallback - return 0.0; -} - public function getRoundedMethod(float $number = 0.0) : Float{ $number_string = number_format(floor($number * 100)/100,2); diff --git a/app/Support/v2/Calculation.php b/app/Support/v2/Calculation.php index 18f31a6..178b275 100644 --- a/app/Support/v2/Calculation.php +++ b/app/Support/v2/Calculation.php @@ -3,9 +3,6 @@ namespace App\Support\v2; use App\KadarUpah; -use App\Customer; -use Illuminate\Support\Facades\Log; - use Illuminate\Http\Request; class Calculation @@ -61,6 +58,7 @@ class Calculation public function kiraanKeuntunganRebet(float $pembiayaan = 0.0,float $nilaimarhun = 0.0,float $kadarujrah = 0.0,float $margin = 0.0){ $this->one_percent = $this->getKadarUpah($nilaimarhun); + $onepercent = $this->kiraanOnePercent($pembiayaan); $ujrah_sebenar = $this->kiraanUjrahSebenar($nilaimarhun,$kadarujrah,$margin); @@ -85,60 +83,13 @@ class Calculation return ['keuntungan' => $keuntungan,'onepercent' => $onepercent, 'ujrah' => $ujrah_sebenar]; } -public function getKadarUjrah(float $nilaimarhun = 0.0, $groupid, $nokp = null): float -{ - // 1️⃣ Semak status pelanggan dalam table customer - if ($nokp) { - $customer = Customer::on('mysql7') - ->select('tag_anggota') - ->where(function($q) use ($nokp) { - $q->where('kpbaru', $nokp) - ->orWhere('kplama', $nokp); - }) - ->first(); + public function getKadarUjrah(float $nilaimarhun = 0.0, $groupid) : Float{ - // 2️⃣ Jika anggota koperasi → kadar tetap - if ($customer && (int)$customer->tag_anggota === 1) { - Log::info('[DEBUG-UJRAH] Anggota koperasi', [ - 'nokp' => $nokp, - 'kadarujrah' => 0.16, - 'groupid' => $groupid, - 'nilaimarhun' => $nilaimarhun, - ]); - return 0.16; - } + $kadarujrah = KadarUpah::on('mysql7')->select('kadarujrah')->where([['min','<=',$nilaimarhun],['max','>=',$nilaimarhun]])->where('group_id',$groupid)->get()->toArray(); + + return isset($kadarujrah[0]) ? $kadarujrah[0]['kadarujrah'] : 0; } - // 3️⃣ Jika bukan anggota → ambil dari jadual kadar_upah - $kadar = KadarUpah::on('mysql7') - ->select('kadarujrah') - ->where([ - ['min', '<=', $nilaimarhun], - ['max', '>=', $nilaimarhun], - ]) - ->where('group_id', $groupid) - ->first(); - - if ($kadar && isset($kadar->kadarujrah)) { - Log::info('[DEBUG-UJRAH] Bukan anggota - dari jadual kadar_upah', [ - 'nokp' => $nokp, - 'kadarujrah' => (float)$kadar->kadarujrah, - 'groupid' => $groupid, - 'nilaimarhun' => $nilaimarhun, - ]); - return (float) $kadar->kadarujrah; - } - - // 4️⃣ Default fallback - Log::info('[DEBUG-UJRAH] Tiada kadar ditemui', [ - 'nokp' => $nokp, - 'groupid' => $groupid, - 'nilaimarhun' => $nilaimarhun, - ]); - return 0.0; -} - - public function getKadarUpah(float $nilaimarhun = 0.0){ $kadarupah = KadarUpah::on('mysql7')->where([['min','<=',$nilaimarhun],['max','>=',$nilaimarhun]])->where('group_id',1)->first(); From e8da816f35dda68131f0e50c5d7189a579ef81d0 Mon Sep 17 00:00:00 2001 From: nurafrinaalimi16 Date: Tue, 18 Nov 2025 00:30:36 +0800 Subject: [PATCH 71/80] put excpetion if kadar upah = 0 --- app/Support/v2/GadaiV2.php | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/app/Support/v2/GadaiV2.php b/app/Support/v2/GadaiV2.php index b0af4af..4dac90e 100644 --- a/app/Support/v2/GadaiV2.php +++ b/app/Support/v2/GadaiV2.php @@ -108,8 +108,19 @@ class GadaiV2 $total_nilai_marhun = Marhun::on($cawangan['mysql'])->where('norujukan','=',$norujukan)->sum('n_marhun'); $total_berat = Marhun::on($cawangan['mysql'])->where('norujukan','=',$norujukan)->sum('berat'); - //query kadar upah baru - $kadar_raw = $this->getKadarUpahAnggota($request->nokp,$total_nilai_marhun,$cawangan['group_id']); + $kadar_raw = $this->getKadarUpahAnggota($request->nokp, $total_nilai_marhun, $cawangan['group_id']); + + if (empty($kadar_raw) || $kadar_raw == 0) { + + Log::error('[BLOCKED] Kadar upah kosong / 0', [ + 'nokp' => $request->nokp, + 'total_nilai_marhun' => $total_nilai_marhun, + 'group_id' => $cawangan['group_id'], + ]); + + throw new \Exception("Kadar upah kosong / 0, transaksi dibatalkan!"); + } + // query kadar upah lama // $kadar_raw = KadarUpah::where('min','<=',$total_nilai_marhun)->where('max','>=',$total_nilai_marhun)->first(); From cd839990458bc75ca0a78da849cd42826b42fc96 Mon Sep 17 00:00:00 2001 From: nurafrinaalimi16 Date: Sun, 14 Dec 2025 10:37:29 +0800 Subject: [PATCH 72/80] disable logs kadar anggota --- app/Support/OnePercent.php | 10 +++++----- app/Support/v2/GadaiV2.php | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/Support/OnePercent.php b/app/Support/OnePercent.php index 941b245..2133931 100644 --- a/app/Support/OnePercent.php +++ b/app/Support/OnePercent.php @@ -65,11 +65,11 @@ class OnePercent extends MasterServices public function getKadarUjrah(HttpRequest $request) { - Log::info('[DEBUG-CONTROLLER] Data request', [ - 'nokp' => $request->nokp, - 'kodcaw' => $request->kodcaw, - 'nilaimarhun' => $request->nilaimarhun - ]); + // Log::info('[DEBUG-CONTROLLER] Data request', [ + // 'nokp' => $request->nokp, + // 'kodcaw' => $request->kodcaw, + // 'nilaimarhun' => $request->nilaimarhun + // ]); $cawangan = Cawangan::on('mysql7')->where('kodcaw', $request->kodcaw)->first(); $onePercentServices = new Calculation(); diff --git a/app/Support/v2/GadaiV2.php b/app/Support/v2/GadaiV2.php index 4dac90e..bab4e6e 100644 --- a/app/Support/v2/GadaiV2.php +++ b/app/Support/v2/GadaiV2.php @@ -59,7 +59,7 @@ class GadaiV2 } private function getKadarUpahAnggota($nokp,$total_nilai_marhun = 0,$groupid = 2) : Float{ - Log::info('DEBUG NOKP:' . $nokp); + //Log::info('DEBUG NOKP:' . $nokp); if($nokp){ $customer = Customer::on('mysql7') ->select('tag_anggota') From 482fbbd17e2790b965817be27ae810da6eaffab4 Mon Sep 17 00:00:00 2001 From: nurafrinaalimi16 Date: Thu, 18 Dec 2025 10:54:32 +0800 Subject: [PATCH 73/80] fix bilangan pelanggan baru on report terkumpul --- app/Http/Controllers/LaporanController.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/LaporanController.php b/app/Http/Controllers/LaporanController.php index 23300c9..815e6fe 100644 --- a/app/Http/Controllers/LaporanController.php +++ b/app/Http/Controllers/LaporanController.php @@ -846,7 +846,8 @@ $date = new Carbon($request->tarikh); $bilangan_gadai = $gadai->count(); $bilangan_tebus = $tebus->count(); // $bilangan_ansuran = $ansuran->count(); - $bilangan_customer_baru = Customer::on($cawangan['mysql'])->where([['tarikhdaftar','>=',$request->mula],['tarikhdaftar','<=',$request->akhir]])->count(); + //$bilangan_customer_baru = Customer::on($cawangan['mysql'])->where([['tarikhdaftar','>=',$request->mula],['tarikhdaftar','<=',$request->akhir]])->count(); + $bilangan_customer_baru = Customer::on('mysql7')->where([['tarikhdaftar','>=',$request->mula],['tarikhdaftar','<=',$request->akhir]])->count(); //f $data_lelong = Lelong::on($cawangan['mysql'])->where([['t_jual','>=',$request->mula],['t_jual','<=',$request->akhir]])->get(); From 696169729884f97b7b6add3b78cab06f3c4732d2 Mon Sep 17 00:00:00 2001 From: nurafrinaalimi16 Date: Tue, 23 Dec 2025 10:21:02 +0800 Subject: [PATCH 74/80] include lahad datu on report stok audit --- config/report.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/config/report.php b/config/report.php index 6a5ba4f..0aa77b7 100644 --- a/config/report.php +++ b/config/report.php @@ -1,7 +1,5 @@ [ - 'lahad datu', - ] + 'excluded_cawangan' => [] ]; From 5826f92661be402a07e032f684aa6b28bc82093e Mon Sep 17 00:00:00 2001 From: nurafrinaalimi16 Date: Sun, 14 Jun 2026 15:02:45 +0800 Subject: [PATCH 75/80] pdpa for koperasi --- app/Http/Controllers/CustomerController.php | 16 ++++++++++++++++ routes/web.php | 1 + 2 files changed, 17 insertions(+) diff --git a/app/Http/Controllers/CustomerController.php b/app/Http/Controllers/CustomerController.php index 8efc9a6..afc772f 100644 --- a/app/Http/Controllers/CustomerController.php +++ b/app/Http/Controllers/CustomerController.php @@ -1102,4 +1102,20 @@ public function AdminsearchCustomerBySAG(Request $request) return response()->json($results); } +// public function createNotaArcc($kodcaw, Request $request) +// { +// $current = Carbon::now(); + +// $customer = Customer::on('mysql7')->create([ +// 'kodcaw' => $kodcaw, +// 'tarikhdaftar' => $current->toDateString(), +// 'nota_arcc' => $request->nota_arcc, +// 'teller' => $request->teller, +// 'aktif' => 'A' +// ]); + +// return response()->json($customer, 201); +// } + + } diff --git a/routes/web.php b/routes/web.php index 082da17..8d76ddb 100644 --- a/routes/web.php +++ b/routes/web.php @@ -62,6 +62,7 @@ $router->group(['prefix'=>'api'], function () use ($router){ $router->get('customer/anggota',['uses'=>'CustomerController@anggotaKoperasi']); $router->get('customer/eachcawangan/{ic}',['uses'=>'CustomerController@showCustomerByEachCawangan']); $router->put('customers/{noic}/assign-anggota', ['uses' => 'CustomerController@assignAnggota']); + $router->post('/customers/update-tag-pdpa', ['uses' => 'CustomerController@updateTagPdpa']); //arcc $router->get('customer/searchbyname',['uses'=>'CustomerController@searchByName']); From 5bc5d286b41704504da6e454931634e955f6fbab Mon Sep 17 00:00:00 2001 From: nurafrinaalimi16 Date: Sun, 14 Jun 2026 15:05:02 +0800 Subject: [PATCH 76/80] fix figure on laporan terkumpul --- app/Http/Controllers/LaporanController.php | 41 +++++++++------------- 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/app/Http/Controllers/LaporanController.php b/app/Http/Controllers/LaporanController.php index 815e6fe..4c3320b 100644 --- a/app/Http/Controllers/LaporanController.php +++ b/app/Http/Controllers/LaporanController.php @@ -804,7 +804,7 @@ $date = new Carbon($request->tarikh); $tebus = Tebus::on($cawangan['mysql']) ->join('gadai as gad','gad.norujukan','=','tebus.norujukan') - ->where([['t_tebus','>=',$request->mula],['t_tebus','<=',$request->akhir],['tebus.jenistebus','=','T']]); + ->where([['t_tebus','>=',$request->mula],['t_tebus','<=',$request->akhir]]); $ansuran = Transaction::on('mysql7')->whereDate('created_at','>=',$request->mula)->whereDate('created_at','<=',$request->akhir)->where([['trans_type','=','A'],['kodcaw','=',$request->kodcaw]]); $bayaranonlinequery = Transaction::on('mysql7')->whereDate('created_at','>=',$request->mula)->whereDate('created_at','<=',$request->akhir)->where('teller','=','Online')->where('kodcaw',$request->kodcaw); @@ -834,20 +834,22 @@ $date = new Carbon($request->tarikh); ->whereDate('trans.created_at','<=',$request->akhir) ->where('trans.trans_type','=','A') ->where('trans.kodcaw','=',$request->kodcaw) + // ->pluck('trans.norujukan'); // ->groupBy('trans.id') ->sum('bayaran_keuntungan'); - + // dd($total_keuntunganansuran); // $total_ansuran = number_format($total_ansuran,2); $total_keuntungan = floatval($total_upah) + floatval($total_keuntunganansuran) + floatval($total_keuntungantebus); - + //b $bilangan_gadai = $gadai->count(); $bilangan_tebus = $tebus->count(); // $bilangan_ansuran = $ansuran->count(); - //$bilangan_customer_baru = Customer::on($cawangan['mysql'])->where([['tarikhdaftar','>=',$request->mula],['tarikhdaftar','<=',$request->akhir]])->count(); - $bilangan_customer_baru = Customer::on('mysql7')->where([['tarikhdaftar','>=',$request->mula],['tarikhdaftar','<=',$request->akhir]])->count(); + //$bilangan_customer_baru = Customer::on('mysql7')->where([['tarikhdaftar','=',$request->tarikh],['kodcaw',$request->kodcaw]])->count() + //$bilangan_customer_baru = Customer::on('mysql7')->where([['tarikhdaftar','>=',$request->mula],['tarikhdaftar','<=',$request->akhir]])->count(); + $bilangan_customer_baru = Customer::on('mysql7')->whereBetween('tarikhdaftar', [$request->mula, $request->akhir])->where('kodcaw', $request->kodcaw)->count(); //f $data_lelong = Lelong::on($cawangan['mysql'])->where([['t_jual','>=',$request->mula],['t_jual','<=',$request->akhir]])->get(); @@ -970,33 +972,23 @@ $date = new Carbon($request->tarikh); ->whereDate('trans.created_at','<=',$request->akhir) ->where('trans.teller','<>','Online') ->where('trans.trans_type','=','A') - ->where('trans.kodcaw',$request->kodcaw) - ->pluck('transaksi_keuntungan.norujukan'); + ->where('trans.kodcaw',$request->kodcaw); + // ->pluck('transaksi_keuntungan.norujukan'); + - $gadaiDataKaunter = Gadai::on($cawangan['mysql'])->whereIn('norujukan',$total_keuntunganansuran_data_kaunter)->whereNotNull('hargajualan')->pluck('norujukan'); + // $gadaiDataKaunter = Gadai::on($cawangan['mysql'])->whereIn('norujukan',$total_keuntunganansuran_data_kaunter)->whereNotNull('hargajualan')->pluck('norujukan'); // $keuntunganansuran_kaunter_query = TransaksiKeuntungan::on('mysql7') // ->whereIn('norujukan',$gadaiDataKaunter) + // ->where('kodcaw',$request->kodcaw) // ->whereDate('tarikh_bayaran','>=',$request->mula) // ->whereDate('tarikh_bayaran','<=',$request->akhir); - // //new update - $keuntunganansuran_kaunter_query = TransaksiKeuntungan::on('mysql7') - ->leftJoin('transaction as trans', function($join) - { - $join->on('transaksi_keuntungan.norujukan', '=', 'trans.norujukan'); - $join->on('transaksi_keuntungan.tarikh_bayaran', '=', 'trans.created_at'); - }) - ->whereDate('trans.created_at','>=',$request->mula) - ->whereDate('trans.created_at','<=',$request->akhir) - ->where('trans.teller','<>','Online') - ->where('trans.trans_type','=','A') - ->where('trans.kodcaw',$request->kodcaw) - ->pluck('transaksi_keuntungan.norujukan'); + //dd($keuntunganansuran_kaunter_query->get()->toArray()); - $total_keuntunganansuran_kaunter = $keuntunganansuran_kaunter_query->sum('bayaran_keuntungan'); - $bil_keuntunganansuran_kaunter = $keuntunganansuran_kaunter_query->count(); - + $total_keuntunganansuran_kaunter = $total_keuntunganansuran_data_kaunter->sum('bayaran_keuntungan'); + //dd($total_keuntunganansuran_kaunter); + $bil_keuntunganansuran_kaunter = $total_keuntunganansuran_data_kaunter->count(); $total_keuntunganansuran_data_online = TransaksiKeuntungan::on('mysql7') ->leftJoin('transaction as trans', function($join) { @@ -1258,6 +1250,7 @@ $date = new Carbon($request->tarikh); 'tarikh' => $tarikh, 'masa' => $masa, 'users' => isset($at['users']) && $at['users'] !== '' ? $at['users'] : '-', + 'users' => isset($at['users']) && $at['users'] !== '' ? $at['users'] : '-', 'pelulus' => isset($atnewdata['namapelulus']) ? $atnewdata['namapelulus'] : '-', 'actions' => $at['actions'], 'norujukan' => $at['norujukan'], From 9ff4393313de577c4039e6a0109604ed16c24574 Mon Sep 17 00:00:00 2001 From: nurafrinaalimi16 Date: Sun, 14 Jun 2026 15:06:24 +0800 Subject: [PATCH 77/80] include kplama on report marhun --- app/Http/Controllers/MarhunController.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/MarhunController.php b/app/Http/Controllers/MarhunController.php index 2153483..d35e7f1 100644 --- a/app/Http/Controllers/MarhunController.php +++ b/app/Http/Controllers/MarhunController.php @@ -203,7 +203,10 @@ class MarhunController extends Controller $marhun = Marhun::on($cawangan['mysql']) ->select('marhun.norujukan','gadai.nokp','customer.nama','marhun.marhun','marhun.nota','marhun.berat','marhun.karat','marhun.harga','marhun.n_marhun','marhun.t_gadai','marhun.tag_permata', 'marhun.berat_batu_permata') ->rightJoin('gadai', 'gadai.norujukan', '=', 'marhun.norujukan') - ->rightJoin(config('tennant_database.master_db') . '.customer as customer', 'customer.kpbaru','=','gadai.nokp') + ->rightJoin('master_erahn.customer as customer', function($join) { + $join->on('customer.kpbaru', '=', 'gadai.nokp') + ->orOn('customer.kplama', '=', 'gadai.nokp'); + }) ->where('marhun.t_gadai','=',$tarikh) ->orderBy('marhun.t_gadai') ->get(); @@ -221,7 +224,10 @@ class MarhunController extends Controller $marhun = Marhun::on($cawangan['mysql']) ->select('marhun.norujukan','gadai.sttebus','gadai.pinjaman','gadai.nokp','customer.nama','marhun.marhun','marhun.nota','marhun.berat','marhun.karat','marhun.harga','marhun.n_marhun','marhun.t_gadai') ->rightJoin('gadai', 'gadai.norujukan', '=', 'marhun.norujukan') - ->rightJoin(config('tennant_database.master_db') . '.customer as customer', 'customer.kpbaru','=','gadai.nokp') + ->rightJoin('master_erahn.customer as customer', function($join) { + $join->on('customer.kpbaru', '=', 'gadai.nokp') + ->orOn('customer.kplama', '=', 'gadai.nokp'); + }) ->where('marhun.t_gadai','<=',$tarikh) ->whereYear('marhun.t_gadai','=',$current->year) ->where('gadai.sttebus','=','') From 162f246acc6734d8f7ffa321cdbf09d6db8b2196 Mon Sep 17 00:00:00 2001 From: nurafrinaalimi16 Date: Mon, 3 Aug 2026 12:43:55 +0800 Subject: [PATCH 78/80] function wtd baru --- app/Http/Controllers/AdminPageController.php | 518 +++++++++---------- 1 file changed, 254 insertions(+), 264 deletions(-) diff --git a/app/Http/Controllers/AdminPageController.php b/app/Http/Controllers/AdminPageController.php index bb36bc1..64049a1 100644 --- a/app/Http/Controllers/AdminPageController.php +++ b/app/Http/Controllers/AdminPageController.php @@ -30,6 +30,7 @@ use App\Status; use App\LookupStatus; use App\ARFiles; use App\WTDDraft; +use App\WTDSimulasi; use App\SerahBaki; use App\WTD; use App\StokAudit1; @@ -62,7 +63,6 @@ use Illuminate\Pagination\LengthAwarePaginator; use Illuminate\Http\Request; use Illuminate\Support\Facades\Log; use App\Jobs\AccountCheckJob; -use App\Penyelarasan; use Illuminate\Support\Str; use Illuminate\Support\Facades\Cache; @@ -2365,7 +2365,6 @@ class AdminPageController extends Controller $cawangan = Cawangan::on('mysql7')->where('kodcaw','=',$request->kodcaw)->first(); //$latestbatch = SerahBaki::on($cawangan['mysql'])->where('norujukan','baru')->get()->toArray(); - //new added $serahBaki = SerahBaki::on($cawangan['mysql']) ->where('norujukan', 'baru') @@ -2374,28 +2373,28 @@ class AdminPageController extends Controller $allBatchNo = $serahBaki->pluck('batchno')->unique()->toArray(); $wtddraftData = WTDDraft::on('mysql7') - ->selectRaw(" - batchno_serah, - YEAR(t_jual) as tahun, - GROUP_CONCAT( - DISTINCT MONTH(t_jual) - ORDER BY MONTH(t_jual) - SEPARATOR ',' - ) as bulan - ") - ->where('kodcaw', $request->kodcaw) - ->whereIn('batchno_serah', $allBatchNo) - ->groupBy('batchno_serah', DB::raw('YEAR(t_jual)')) - ->get() - ->groupBy('batchno_serah') - ->map(function ($rows) { - return $rows->map(function ($row) { - return [ - 'tahun' => $row->tahun, - 'bulan' => $row->bulan - ]; - })->values(); - }); + ->selectRaw(" + batchno_serah, + YEAR(t_jual) as tahun, + GROUP_CONCAT( + DISTINCT MONTH(t_jual) + ORDER BY MONTH(t_jual) + SEPARATOR ',' + ) as bulan + ") + ->where('kodcaw', $request->kodcaw) + ->whereIn('batchno_serah', $allBatchNo) + ->groupBy('batchno_serah', DB::raw('YEAR(t_jual)')) + ->get() + ->groupBy('batchno_serah') + ->map(function ($rows) { + return $rows->map(function ($row) { + return [ + 'tahun' => $row->tahun, + 'bulan' => $row->bulan + ]; + })->values(); + }); $finalData = $serahBaki->map(function ($item) use ($wtddraftData) { $batchno = $item->batchno; @@ -2427,29 +2426,27 @@ class AdminPageController extends Controller $finalDataArray = $finalData->toArray(); //end new added - + $batch_old = WTDDraft::on('mysql7')->select('kodcaw')->where('batchno_serah',0)->where('kodcaw',$request->kodcaw) ->groupBy('kodcaw')->get(); $batch_old_noruj = WTDDraft::on('mysql7')->where('batchno_serah',0)->where('kodcaw',$request->kodcaw)->pluck('norujukan'); $lelong_data = Lelong::on($cawangan['mysql'])->whereIn('norujukan',$batch_old_noruj)->get(); - + foreach($batch_old as $index=>$bo) { //array_push($latestbatch,['recno' => 0,'norujukan' => 'lama','batchno' => 0,'baki' => $lelong_data->sum('baki'),'aktif' => 1]); array_push($finalDataArray,['recno' => 0,'norujukan' => 'lama','batchno' => 0,'baki' => $lelong_data->sum('baki'),'aktif' => 1]); + } //$data = $this->paginate($latestbatch,8); $data = $this->paginate($finalDataArray,8); - //dd($data); - return response()->json($data,200); } - public function rekodWTDByBatchNo($batchno,Request $request){ $cawangan = Cawangan::on('mysql7')->where('kodcaw','=',$request->kodcaw)->first(); @@ -2727,7 +2724,7 @@ class AdminPageController extends Controller 'prkod' => "01", 'teller' => "DM", 'bakipjm' => ($lel['bakipjm']) ? $lel['bakipjm'] : 0, - 'bakiupah' => ($lel['bakiupah']) ? $lel['bakiupah'] : 0, + 'bakiupah' => $lel['bakiupah'], 'cajlain' => '0.00', 'cajlelong' => $lel['cajlelong'], 'kodgl' => '', @@ -2749,7 +2746,7 @@ class AdminPageController extends Controller 't_jual' => $lel['t_jual'], 'hargajual' => $lel['hargajual'], 'pinjaman' => $lel['pinjaman'], - 'bakiupah' => ($lel['bakiupah']) ? $lel['bakiupah'] : 0, + 'bakiupah' => $lel['bakiupah'], 'cajlelong' => $lel['cajlelong'], 'gst_cl' => $lel['gst_cl'], 'baki' => $lel['baki'], @@ -2779,222 +2776,6 @@ class AdminPageController extends Controller } - public function janaSimulasiWTD(Request $request) - { - $cawangan = Cawangan::on('mysql7')->where('kodcaw', '=', $request->kodcaw)->first(); - - //listing sag belum tuntut cwgn - $sag_cwgn = collect( - Lelong::on($cawangan['mysql']) - ->selectRaw('norujukan') - ->whereYear('t_jual', $request->tahun) - ->whereNull('trkhtuntut') - ->where('baki', '>', 0) - ->pluck('norujukan') // lebih bersih - ); - - //listing sag blocked - $sag_online = collect( - WTDDraft::on('mysql7') - ->selectRaw('norujukan') - ->where('kodcaw', '=', $request->kodcaw) - ->pluck('norujukan') - ); - //dd($sag_online); - //filter sag yg tk wujud dlm wtd_draft - $filtersag = $sag_cwgn->diff($sag_online); - - //query baru - $tarikh_belum_tuntut = Lelong::on($cawangan['mysql']) - ->selectRaw(' - MONTH(t_jual) as bulan, - SUM(pinjaman) as pembiayaan, - ABS(SUM(baki)) as baki, - COUNT(DISTINCT norujukan) as jumlah_norujukan, - kodcaw - ') - ->whereIn('norujukan', $filtersag) - ->groupBy('bulan', 'kodcaw') - ->orderBy('bulan') - ->get(); - - $tarikh_belum_tuntut = $tarikh_belum_tuntut->map(function ($item) { - $item->bulan = \Carbon\Carbon::create()->month($item->bulan)->format('F'); - return $item; - }); - - return response()->json($tarikh_belum_tuntut); - } - - public function RekodSimulasiWTD(Request $request) - { - $cawangan = Cawangan::on('mysql7')->where('kodcaw', '=', $request->kodcaw)->first(); - - $rekod_simulasi = Lelong::on($cawangan['mysql']) - ->join('gadai','lelong.norujukan','=','gadai.norujukan') - ->selectRaw('ABS(lelong.baki) as baki, lelong.t_lelong, lelong.pinjaman, lelong.norujukan, gadai.nokp') - ->whereMonth('lelong.t_jual', $request->month) - ->whereYear('lelong.t_jual', $request->year) - ->whereNull('lelong.trkhtuntut') - ->where('lelong.baki', '>', 0) - ->get(); - - return response()->json($rekod_simulasi); - } - - public function prosesSimulasiWTD(Request $request) - { - $proses = $request->input; - - // dd($proses, $cawangan); - - $baki = 0; - $jumlahPembiayaan = 0; - $simulasi = WTDSimulasi::max('simulasi')+1; - - foreach ($proses as $item) { - WTDSimulasi::create([ - 'bulan' => $item['bulan'], - 'tahun' => $item['tahun'], - 'kodcaw' => $item['kodcaw'], - 'jumlah_sag' => $item['jumlah_sag'], - 'pembiayaan'=> $item['pembiayaan'], - 'baki'=> $item['baki'], - 'simulasi' => $simulasi, - ]); - $baki += $item['baki']; - $jumlahPembiayaan = $item['pembiayaan']; - } - - return response()->json(['status' => 'success','simulasi' => $simulasi,'baki' => $baki,'pinjaman' => $jumlahPembiayaan]); - } - - public function pengesahanSimulasiWTD(Request $request) - { - // Decode the JSON records from the request - $records = json_decode($request->records, true); - - // Retrieve and clean 'kodcaw' from the request - $kodcaw = $request->kodcaw; - $kodcaw_clean = str_replace('"', '', $kodcaw); - - // Get the database connection for the branch (cawangan) - $cawangan = Cawangan::where('kodcaw', $kodcaw_clean)->first(); - - // Check if 'Cawangan' exists - if (!$cawangan) { - return response()->json(['status' => 'error', 'message' => 'Invalid branch code (kodcaw).'], 404); - } - - $cawangan_connection = $cawangan->mysql; - - // Get the latest batch number and increment it - $latestBatch = SerahBaki::on($cawangan_connection)->max('batchno') + 1; - - // Initialize total variables - $totalPembiayaan = 0; - $totalBaki = 0; - - - try { - // Iterate through the records and save them to the WTDDraft table - foreach ($records as $record) { - // Check if 'bulan' and 'tahun' exist in the record - if (!isset($record['bulan']) || !isset($record['tahun'])) { - return response()->json(['status' => 'error', 'message' => 'Missing bulan or tahun in records.'], 400); - } - $month = DateTime::createFromFormat('F', $record["bulan"])->format('n'); - - - // Query norujukan records from the database - $query_norujukan = Lelong::on($cawangan_connection) - ->join('gadai', 'lelong.norujukan', '=', 'gadai.norujukan') - ->selectRaw('ABS(lelong.baki) as baki, lelong.t_lelong, lelong.pinjaman, lelong.norujukan, gadai.nokp, lelong.t_jual') - ->whereMonth('lelong.t_jual', $month) - ->whereYear('lelong.t_jual', $record["tahun"]) - ->whereNull('lelong.trkhtuntut') - ->where('lelong.baki', '>', 0) - ->get(); - - // Save each record to the WTDDraft table - foreach ($query_norujukan as $query) { - $wtddraft = new WTDDraft(); - $wtddraft->nokp = $query['nokp']; - $wtddraft->kodcaw = $kodcaw_clean; - $wtddraft->norujukan = $query['norujukan']; - $wtddraft->t_jual = $query['t_jual']; - $wtddraft->t_gadai = $query['t_gadai'] ?? null; // Optional: ensure 't_gadai' exists - $wtddraft->t_lelong = $query['t_lelong']; - $wtddraft->batchno_serah = $latestBatch; - $wtddraft->save(); - } - - // Accumulate totals - $totalPembiayaan += $record['pembiayaan'] ?? 0; - $totalBaki += $record['baki'] ?? 0; - } - - // Create a new record in the SerahBaki table - SerahBaki::on($cawangan_connection)->create([ - 'norujukan' => 'baru', - 'batchno' => $latestBatch, - 'hargajual' => 0.00, - 'pinjaman' => $totalPembiayaan, - 'upah' => 0.00, - 'cajlel' => 0.00, - 'gst_cl' => 0.00, - 'gst_hj' => 0.00, - 'baki' => $totalBaki, - 'tarikh' => Carbon::now()->toDateString(), - 't_jual' => Carbon::now()->toDateString(), - 'nopelanggan' => '', - 'aktif' => 0, - ]); - - // Return a success response with the new batch number - return response()->json(['status' => 'success', 'batchno' => $latestBatch], 200); - - } catch (\Throwable $e) { - // Log the error and return a failure response - Log::error($e->getMessage()); - Log::error($e->getLine()); - return response()->json(['status' => 'error', 'message' => $e->getMessage()], 500); - } - } - - - - public function simulasiToDraft(Request $request) - { - $bulan = $request->bulan; - - if (!$bulan || count($bulan) === 0) { - return response()->json(['error' => 'Sila pilih sekurang-kurangnya satu bulan.'], 400); - } - - $simulasi = WTDSimulasi::whereIn('bulan', $bulan)->get(); - - if ($simulasi->isEmpty()) { - return response()->json(['error' => 'Tiada data untuk bulan yang dipilih.'], 404); - } - - // foreach ($simulasi as $data) { - // WTDDraft::create([ - // 'nokp' => $data->nokp ?? null, - // 'kodcaw' => $data->kodcaw ?? null, - // 'norujukan' => $data->norujukan ?? null, - // 't_jual' => $data->t_jual ?? null, - // 't_gadai' => $data->t_gadai ?? null, - // 't_lelong' => $data->t_lelong ?? null, - // 'batchno_serah' => $data->simulasi, // Simpan sebagai rujukan - // ]); - // } - - dd($bulan, $simulasi); - - return response()->json(['message' => 'Data berjaya dipindahkan ke WTD Draft!']); - - } public function PenjanaanPC(Request $request){ $timeloni = Carbon::now(); @@ -3445,8 +3226,6 @@ class AdminPageController extends Controller return response()->json($customers); } - - public function AkruKeuntunganSebenar(Request $request){ @@ -4045,13 +3824,13 @@ class AdminPageController extends Controller $get_imbangduga = imbangdugabackup::on($cawangan['mysql'])->where('tarikh', $lastDayOfYear)->first(); $get_imbangduga = optional($get_imbangduga)->toArray() ?? []; - if(empty($get_imbangduga)){ - $requestData = new Request([ - 'tarikh' => $request->tarikh, - 'kodcaw' => $kodcaw, - ]); - $exception_case = $this->AkruKeuntunganSebenar($requestData)->getData(); - } + // if(empty($get_imbangduga)){ + // $requestData = new Request([ + // 'tarikh' => $request->tarikh, + // 'kodcaw' => $kodcaw, + // ]); + // $exception_case = $this->AkruKeuntunganSebenar($requestData); + // } $backdate_keun_sebenar += isset($get_imbangduga['keun_sebenar']) ? $get_imbangduga['keun_sebenar'] : 0; $backdate_keun_sebenar += (float) ($exception_case ?? 0); @@ -4070,14 +3849,7 @@ class AdminPageController extends Controller $total = ($utgrugilama + $lelong + $upahsimpantebus + $upahsimpanlelong + $upahsimpanansur + $gstcajlelong + $keuntungansebenar + $upahsimpankeuntungansebelumtawarruq + $available_akru + $total_keuntungan_sebenar + $akru_ujrah + $akru_1percent) + $parameter; if($kodcaw == '011229') - $total -= 45390.37; - - if($kodcaw == 'KB2') - $total -= 64.8; - - $total += Penyelarasan::on('mysql7') - ->where('kodcaw', $kodcaw) - ->sum(DB::raw('rugilelong + bakilelong + `lain-lain`')); + $total -= 45390.37; return response()->json($total,200); } @@ -4250,4 +4022,222 @@ class AdminPageController extends Controller 'result' => $status === 'completed' ? $result : null, ]); } + + //function wtd baru + public function janaSimulasiWTD(Request $request) + { + $cawangan = Cawangan::on('mysql7')->where('kodcaw', '=', $request->kodcaw)->first(); + + //listing sag belum tuntut cwgn + $sag_cwgn = collect( + Lelong::on($cawangan['mysql']) + ->selectRaw('norujukan') + ->whereYear('t_jual', $request->tahun) + ->whereNull('trkhtuntut') + ->where('baki', '>', 0) + ->pluck('norujukan') // lebih bersih + ); + + //listing sag blocked + $sag_online = collect( + WTDDraft::on('mysql7') + ->selectRaw('norujukan') + ->where('kodcaw', '=', $request->kodcaw) + ->pluck('norujukan') + ); + //dd($sag_online); + //filter sag yg tk wujud dlm wtd_draft + $filtersag = $sag_cwgn->diff($sag_online); + + //query baru + $tarikh_belum_tuntut = Lelong::on($cawangan['mysql']) + ->selectRaw(' + MONTH(t_jual) as bulan, + SUM(pinjaman) as pembiayaan, + ABS(SUM(baki)) as baki, + COUNT(DISTINCT norujukan) as jumlah_norujukan, + kodcaw + ') + ->whereIn('norujukan', $filtersag) + ->groupBy('bulan', 'kodcaw') + ->orderBy('bulan') + ->get(); + + $tarikh_belum_tuntut = $tarikh_belum_tuntut->map(function ($item) { + $item->bulan = \Carbon\Carbon::create()->month($item->bulan)->format('F'); + return $item; + }); + + return response()->json($tarikh_belum_tuntut); + } + + public function RekodSimulasiWTD(Request $request) + { + $cawangan = Cawangan::on('mysql7')->where('kodcaw', '=', $request->kodcaw)->first(); + + $rekod_simulasi = Lelong::on($cawangan['mysql']) + ->join('gadai','lelong.norujukan','=','gadai.norujukan') + ->selectRaw('ABS(lelong.baki) as baki, lelong.t_lelong, lelong.pinjaman, lelong.norujukan, gadai.nokp') + ->whereMonth('lelong.t_jual', $request->month) + ->whereYear('lelong.t_jual', $request->year) + ->whereNull('lelong.trkhtuntut') + ->where('lelong.baki', '>', 0) + ->get(); + + return response()->json($rekod_simulasi); + } + + public function prosesSimulasiWTD(Request $request) + { + $proses = $request->input; + + // dd($proses, $cawangan); + + $baki = 0; + $jumlahPembiayaan = 0; + $simulasi = WTDSimulasi::max('simulasi')+1; + + foreach ($proses as $item) { + WTDSimulasi::create([ + 'bulan' => $item['bulan'], + 'tahun' => $item['tahun'], + 'kodcaw' => $item['kodcaw'], + 'jumlah_sag' => $item['jumlah_sag'], + 'pembiayaan'=> $item['pembiayaan'], + 'baki'=> $item['baki'], + 'simulasi' => $simulasi, + ]); + $baki += $item['baki']; + $jumlahPembiayaan = $item['pembiayaan']; + } + + return response()->json(['status' => 'success','simulasi' => $simulasi,'baki' => $baki,'pinjaman' => $jumlahPembiayaan]); + } + + public function pengesahanSimulasiWTD(Request $request) + { + // Decode the JSON records from the request + $records = json_decode($request->records, true); + + // Retrieve and clean 'kodcaw' from the request + $kodcaw = $request->kodcaw; + $kodcaw_clean = str_replace('"', '', $kodcaw); + + // Get the database connection for the branch (cawangan) + $cawangan = Cawangan::where('kodcaw', $kodcaw_clean)->first(); + + // Check if 'Cawangan' exists + if (!$cawangan) { + return response()->json(['status' => 'error', 'message' => 'Invalid branch code (kodcaw).'], 404); + } + + $cawangan_connection = $cawangan->mysql; + + // Get the latest batch number and increment it + $latestBatch = SerahBaki::on($cawangan_connection)->max('batchno') + 1; + + // Initialize total variables + $totalPembiayaan = 0; + $totalBaki = 0; + + + try { + // Iterate through the records and save them to the WTDDraft table + foreach ($records as $record) { + // Check if 'bulan' and 'tahun' exist in the record + if (!isset($record['bulan']) || !isset($record['tahun'])) { + return response()->json(['status' => 'error', 'message' => 'Missing bulan or tahun in records.'], 400); + } + $month = DateTime::createFromFormat('F', $record["bulan"])->format('n'); + + + // Query norujukan records from the database + $query_norujukan = Lelong::on($cawangan_connection) + ->join('gadai', 'lelong.norujukan', '=', 'gadai.norujukan') + ->selectRaw('ABS(lelong.baki) as baki, lelong.t_lelong, lelong.pinjaman, lelong.norujukan, gadai.nokp, lelong.t_jual') + ->whereMonth('lelong.t_jual', $month) + ->whereYear('lelong.t_jual', $record["tahun"]) + ->whereNull('lelong.trkhtuntut') + ->where('lelong.baki', '>', 0) + ->get(); + + // Save each record to the WTDDraft table + foreach ($query_norujukan as $query) { + $wtddraft = new WTDDraft(); + $wtddraft->nokp = $query['nokp']; + $wtddraft->kodcaw = $kodcaw_clean; + $wtddraft->norujukan = $query['norujukan']; + $wtddraft->t_jual = $query['t_jual']; + $wtddraft->t_gadai = $query['t_gadai'] ?? null; // Optional: ensure 't_gadai' exists + $wtddraft->t_lelong = $query['t_lelong']; + $wtddraft->batchno_serah = $latestBatch; + $wtddraft->save(); + } + + // Accumulate totals + $totalPembiayaan += $record['pembiayaan'] ?? 0; + $totalBaki += $record['baki'] ?? 0; + } + + // Create a new record in the SerahBaki table + SerahBaki::on($cawangan_connection)->create([ + 'norujukan' => 'baru', + 'batchno' => $latestBatch, + 'hargajual' => 0.00, + 'pinjaman' => $totalPembiayaan, + 'upah' => 0.00, + 'cajlel' => 0.00, + 'gst_cl' => 0.00, + 'gst_hj' => 0.00, + 'baki' => $totalBaki, + 'tarikh' => Carbon::now()->toDateString(), + 't_jual' => Carbon::now()->toDateString(), + 'nopelanggan' => '', + 'aktif' => 0, + ]); + + // Return a success response with the new batch number + return response()->json(['status' => 'success', 'batchno' => $latestBatch], 200); + + } catch (\Throwable $e) { + // Log the error and return a failure response + Log::error($e->getMessage()); + Log::error($e->getLine()); + return response()->json(['status' => 'error', 'message' => $e->getMessage()], 500); + } + } + + + + public function simulasiToDraft(Request $request) + { + $bulan = $request->bulan; + + if (!$bulan || count($bulan) === 0) { + return response()->json(['error' => 'Sila pilih sekurang-kurangnya satu bulan.'], 400); + } + + $simulasi = WTDSimulasi::whereIn('bulan', $bulan)->get(); + + if ($simulasi->isEmpty()) { + return response()->json(['error' => 'Tiada data untuk bulan yang dipilih.'], 404); + } + + // foreach ($simulasi as $data) { + // WTDDraft::create([ + // 'nokp' => $data->nokp ?? null, + // 'kodcaw' => $data->kodcaw ?? null, + // 'norujukan' => $data->norujukan ?? null, + // 't_jual' => $data->t_jual ?? null, + // 't_gadai' => $data->t_gadai ?? null, + // 't_lelong' => $data->t_lelong ?? null, + // 'batchno_serah' => $data->simulasi, // Simpan sebagai rujukan + // ]); + // } + + //dd($bulan, $simulasi); + + return response()->json(['message' => 'Data berjaya dipindahkan ke WTD Draft!']); + + } } From f1618c1ffd2f1298ad6cade3511bf5fabd82ce61 Mon Sep 17 00:00:00 2001 From: afrina Date: Wed, 26 Aug 2026 11:40:55 +0800 Subject: [PATCH 79/80] Rebate anggota (#1) Co-authored-by: nurafrinaalimi16 Reviewed-on: https://git.koppkb.com/KoPKB/api_arrahn/pulls/1 --- app/Http/Controllers/LaporanController.php | 57 ++++++------------- .../Controllers/Reports/GadaianController.php | 2 +- 2 files changed, 17 insertions(+), 42 deletions(-) diff --git a/app/Http/Controllers/LaporanController.php b/app/Http/Controllers/LaporanController.php index 2b508c8..71c951f 100644 --- a/app/Http/Controllers/LaporanController.php +++ b/app/Http/Controllers/LaporanController.php @@ -804,8 +804,7 @@ $date = new Carbon($request->tarikh); $tebus = Tebus::on($cawangan['mysql']) ->join('gadai as gad','gad.norujukan','=','tebus.norujukan') - ->where([['t_tebus','>=',$request->mula],['t_tebus','<=',$request->akhir]]); - ->where([['t_tebus','>=',$request->mula],['t_tebus','<=',$request->akhir]]); + ->where([['t_tebus','>=',$request->mula],['t_tebus','<=',$request->akhir],['tebus.jenistebus','=','T']]); $ansuran = Transaction::on('mysql7')->whereDate('created_at','>=',$request->mula)->whereDate('created_at','<=',$request->akhir)->where([['trans_type','=','A'],['kodcaw','=',$request->kodcaw]]); $bayaranonlinequery = Transaction::on('mysql7')->whereDate('created_at','>=',$request->mula)->whereDate('created_at','<=',$request->akhir)->where('teller','=','Online')->where('kodcaw',$request->kodcaw); @@ -835,27 +834,19 @@ $date = new Carbon($request->tarikh); ->whereDate('trans.created_at','<=',$request->akhir) ->where('trans.trans_type','=','A') ->where('trans.kodcaw','=',$request->kodcaw) - // ->pluck('trans.norujukan'); - // ->pluck('trans.norujukan'); // ->groupBy('trans.id') ->sum('bayaran_keuntungan'); - // dd($total_keuntunganansuran); - // dd($total_keuntunganansuran); + // $total_ansuran = number_format($total_ansuran,2); $total_keuntungan = floatval($total_upah) + floatval($total_keuntunganansuran) + floatval($total_keuntungantebus); - - + //b $bilangan_gadai = $gadai->count(); $bilangan_tebus = $tebus->count(); // $bilangan_ansuran = $ansuran->count(); - //$bilangan_customer_baru = Customer::on('mysql7')->where([['tarikhdaftar','=',$request->tarikh],['kodcaw',$request->kodcaw]])->count() - //$bilangan_customer_baru = Customer::on('mysql7')->where([['tarikhdaftar','>=',$request->mula],['tarikhdaftar','<=',$request->akhir]])->count(); - $bilangan_customer_baru = Customer::on('mysql7')->whereBetween('tarikhdaftar', [$request->mula, $request->akhir])->where('kodcaw', $request->kodcaw)->count(); - //$bilangan_customer_baru = Customer::on('mysql7')->where([['tarikhdaftar','=',$request->tarikh],['kodcaw',$request->kodcaw]])->count() - //$bilangan_customer_baru = Customer::on('mysql7')->where([['tarikhdaftar','>=',$request->mula],['tarikhdaftar','<=',$request->akhir]])->count(); + //$bilangan_customer_baru = Customer::on($cawangan['mysql'])->where([['tarikhdaftar','>=',$request->mula],['tarikhdaftar','<=',$request->akhir]])->count(); $bilangan_customer_baru = Customer::on('mysql7')->whereBetween('tarikhdaftar', [$request->mula, $request->akhir])->where('kodcaw', $request->kodcaw)->count(); //f @@ -979,36 +970,21 @@ $date = new Carbon($request->tarikh); ->whereDate('trans.created_at','<=',$request->akhir) ->where('trans.teller','<>','Online') ->where('trans.trans_type','=','A') - ->where('trans.kodcaw',$request->kodcaw); - // ->pluck('transaksi_keuntungan.norujukan'); - - ->where('trans.kodcaw',$request->kodcaw); - // ->pluck('transaksi_keuntungan.norujukan'); - + ->where('trans.kodcaw',$request->kodcaw) + ->pluck('transaksi_keuntungan.norujukan'); - // $gadaiDataKaunter = Gadai::on($cawangan['mysql'])->whereIn('norujukan',$total_keuntunganansuran_data_kaunter)->whereNotNull('hargajualan')->pluck('norujukan'); - // $gadaiDataKaunter = Gadai::on($cawangan['mysql'])->whereIn('norujukan',$total_keuntunganansuran_data_kaunter)->whereNotNull('hargajualan')->pluck('norujukan'); + $gadaiDataKaunter = Gadai::on($cawangan['mysql'])->whereIn('norujukan',$total_keuntunganansuran_data_kaunter)->whereNotNull('hargajualan')->pluck('norujukan'); + + $keuntunganansuran_kaunter_query = TransaksiKeuntungan::on('mysql7') + ->whereIn('norujukan',$gadaiDataKaunter) + ->whereDate('tarikh_bayaran','>=',$request->mula) + ->whereDate('tarikh_bayaran','<=',$request->akhir); - // $keuntunganansuran_kaunter_query = TransaksiKeuntungan::on('mysql7') - // ->whereIn('norujukan',$gadaiDataKaunter) - // ->where('kodcaw',$request->kodcaw) - // ->whereDate('tarikh_bayaran','>=',$request->mula) - // ->whereDate('tarikh_bayaran','<=',$request->akhir); - //dd($keuntunganansuran_kaunter_query->get()->toArray()); - // $keuntunganansuran_kaunter_query = TransaksiKeuntungan::on('mysql7') - // ->whereIn('norujukan',$gadaiDataKaunter) - // ->where('kodcaw',$request->kodcaw) - // ->whereDate('tarikh_bayaran','>=',$request->mula) - // ->whereDate('tarikh_bayaran','<=',$request->akhir); - //dd($keuntunganansuran_kaunter_query->get()->toArray()); - $total_keuntunganansuran_kaunter = $total_keuntunganansuran_data_kaunter->sum('bayaran_keuntungan'); - //dd($total_keuntunganansuran_kaunter); - $bil_keuntunganansuran_kaunter = $total_keuntunganansuran_data_kaunter->count(); - $total_keuntunganansuran_kaunter = $total_keuntunganansuran_data_kaunter->sum('bayaran_keuntungan'); - //dd($total_keuntunganansuran_kaunter); - $bil_keuntunganansuran_kaunter = $total_keuntunganansuran_data_kaunter->count(); + $total_keuntunganansuran_kaunter = $keuntunganansuran_kaunter_query->sum('bayaran_keuntungan'); + $bil_keuntunganansuran_kaunter = $keuntunganansuran_kaunter_query->count(); + $total_keuntunganansuran_data_online = TransaksiKeuntungan::on('mysql7') ->leftJoin('transaction as trans', function($join) { @@ -1269,8 +1245,7 @@ $date = new Carbon($request->tarikh); array_push($atarray,[ 'tarikh' => $tarikh, 'masa' => $masa, - 'users' => isset($at['users']) && $at['users'] !== '' ? $at['users'] : '-', - 'users' => isset($at['users']) && $at['users'] !== '' ? $at['users'] : '-', + 'users' => $at['users'], 'pelulus' => isset($atnewdata['namapelulus']) ? $atnewdata['namapelulus'] : '-', 'actions' => $at['actions'], 'norujukan' => $at['norujukan'], diff --git a/app/Http/Controllers/Reports/GadaianController.php b/app/Http/Controllers/Reports/GadaianController.php index 301905f..abc8104 100644 --- a/app/Http/Controllers/Reports/GadaianController.php +++ b/app/Http/Controllers/Reports/GadaianController.php @@ -48,7 +48,7 @@ class GadaianController extends Controller $summary_gadaian_data = array_map(function ($db_connection) use ($request) { $query = Gadai::on($db_connection); - $query->select(DB::raw('count(norujukan) as total_gadaian, sum(berat) as sum_berat, sum(nilaimarhun) as sum_nilai_marhun, sum(pinjaman) as sum_pinjaman')); + $query->select(DB::raw('count(norujukan) as total_gadaian, sum(berat) as sum_berat, sum(nilaimarhun) as sum_nilai_marhun, sum(pinjaman) as sum_pinjaman, sum(upah12) as sum_upah_12')); $query->when($request->filled('startDate') and $request->filled('endDate'), function ($q) use ($request) { return $q->where('t_gadai', '>=', $request->startDate) From 51860cea37c7d62d11e4d26e25c8dbf1960f8545 Mon Sep 17 00:00:00 2001 From: ismailmasseran Date: Wed, 26 Aug 2026 12:03:29 +0800 Subject: [PATCH 80/80] DONE: add cicd for api_arrahn (#2) Co-authored-by: ISMAIL MASSERAN Reviewed-on: https://git.koppkb.com/KoPKB/api_arrahn/pulls/2 --- .dockerignore | 16 +++ .env.staging | 84 +++++++++++++++ .gitea/workflows/build.yml | 49 +++++++++ .gitea/workflows/deploy-staging.yml | 122 ++++++++++++++++++++++ bootstrap/.gitignore | 1 + docker-compose.staging.yml | 77 ++++++++++++++ docker-compose.yml | 40 +++++++ docker/mysql/init/01-create-databases.sql | 7 ++ docker/nginx/default.conf | 36 +++++++ docker/php/Dockerfile | 51 +++++++++ docker/php/entrypoint.sh | 30 ++++++ docker/php/php.ini | 4 + docker/php/zz-clear-env.conf | 3 + routes/web.php | 4 + storage/.gitignore | 2 + 15 files changed, 526 insertions(+) create mode 100644 .dockerignore create mode 100644 .env.staging create mode 100644 .gitea/workflows/build.yml create mode 100644 .gitea/workflows/deploy-staging.yml create mode 100644 bootstrap/.gitignore create mode 100644 docker-compose.staging.yml create mode 100644 docker-compose.yml create mode 100644 docker/mysql/init/01-create-databases.sql create mode 100644 docker/nginx/default.conf create mode 100644 docker/php/Dockerfile create mode 100644 docker/php/entrypoint.sh create mode 100644 docker/php/php.ini create mode 100644 docker/php/zz-clear-env.conf create mode 100644 storage/.gitignore diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..32264f9 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,16 @@ +.git +.gitea +node_modules +vendor +.env +.env.* +!.env.example +storage/logs +storage/framework/cache +storage/framework/sessions +storage/framework/views +storage/debugbar +npm-debug.log +Dockerfile +docker-compose.yml +docker-compose.staging.yml diff --git a/.env.staging b/.env.staging new file mode 100644 index 0000000..4f366ca --- /dev/null +++ b/.env.staging @@ -0,0 +1,84 @@ +APP_NAME=Lumen +APP_ENV=staging +APP_KEY=WbPGkYNmXZ6ZQplGlvl0iZ7zyW1b09xa +APP_DEBUG=true +APP_URL=http://127.0.0.1:8090 +APP_TIMEZONE=Asia/Kuala_Lumpur + +# Unique host ports — change these if they collide with other containers on the server. +# Host nginx should proxy the staging domain to 127.0.0.1:${HTTP_PORT} +HTTP_PORT=8090 +MYSQL_PUBLISH_PORT=3308 + +LOG_CHANNEL=stack +LOG_LEVEL=debug +LOG_SLACK_WEBHOOK_URL= + +DB_CONNECTION=mysql +DB_HOST=mysql +DB_PORT=3306 +DB_DATABASE=erahn_xtra +DB_USERNAME=root +DB_PASSWORD=root + +DB_CONNECTION_7=mysql +DB_HOST_7=mysql +DB_PORT_7=3306 +DB_DATABASE_7=master_erahn +DB_USERNAME_7=root +DB_PASSWORD_7=root + +DB_CONNECTION_2=mysql +DB_HOST_2=mysql +DB_PORT_2=3306 +DB_DATABASE_2=erahn_xtra +DB_USERNAME_2=root +DB_PASSWORD_2=root + +DB_CONNECTION_3=mysql +DB_HOST_3=mysql +DB_PORT_3=3306 +DB_DATABASE_3=erahn_baling +DB_USERNAME_3=root +DB_PASSWORD_3=root + +DB_CONNECTION_4=mysql +DB_HOST_4=mysql +DB_PORT_4=3306 +DB_DATABASE_4=arrahn_ld +DB_USERNAME_4=root +DB_PASSWORD_4=root + +DB_CONNECTION_5=mysql +DB_HOST_5=mysql +DB_PORT_5=3306 +DB_DATABASE_5=erahn_segamat +DB_USERNAME_5=root +DB_PASSWORD_5=root + +DB_CONNECTION_7=mysql +DB_HOST_7=mysql +DB_PORT_7=3306 +DB_DATABASE_7=master_erahn +DB_USERNAME_7=root +DB_PASSWORD_7=root + +DB_CONNECTION_6=mysql +DB_HOST_6=mysql +DB_PORT_6=3306 +DB_DATABASE_6=erahn_test +DB_USERNAME_6=root +DB_PASSWORD_6=root + +# DB_CONNECTION_8=mysql +# DB_HOST_8=mysql +# DB_PORT_8=3306 +# DB_DATABASE_8=arrahn_klanas +# DB_USERNAME_8=spider +# DB_PASSWORD_8=G0dz!ll42020 + +TENNANT_MASTER_DB=master_erahn +TENNANT_KAUNTER_DB=kaunter_erahn + +CACHE_DRIVER=file +QUEUE_CONNECTION=sync \ No newline at end of file diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml new file mode 100644 index 0000000..dc3a55e --- /dev/null +++ b/.gitea/workflows/build.yml @@ -0,0 +1,49 @@ +name: Build Docker Image + +on: + push: + branches: + - staging + tags: + - "v*" + workflow_dispatch: + +jobs: + build-backend: + runs-on: docker + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Login to Docker registry + run: | + echo "${{ secrets.REGISTRY_PASSWORD }}" | \ + docker login git.koppkb.com \ + -u "${{ secrets.REGISTRY_USERNAME }}" \ + --password-stdin + + - name: Build & push backend image + run: | + set -e + + IMAGE="git.koppkb.com/kopkb/api_arrahn" + TAGS="-t ${IMAGE}:${{ gitea.sha }}" + + if [ "${{ gitea.ref_type }}" = "tag" ] && echo "${{ gitea.ref_name }}" | grep -q '^v'; then + TAGS="${TAGS} -t ${IMAGE}:${{ gitea.ref_name }}" + fi + + if [ "${{ gitea.ref_name }}" = "staging" ]; then + TAGS="${TAGS} -t ${IMAGE}:staging" + fi + + echo "Building and pushing backend: ${TAGS}" + docker buildx build \ + --target staging \ + --platform linux/amd64 \ + --cache-from type=registry,ref=${IMAGE}:buildcache,ignore-error=true \ + --cache-to type=registry,ref=${IMAGE}:buildcache,mode=max \ + -f docker/php/Dockerfile \ + ${TAGS} \ + --push . diff --git a/.gitea/workflows/deploy-staging.yml b/.gitea/workflows/deploy-staging.yml new file mode 100644 index 0000000..8fd6daa --- /dev/null +++ b/.gitea/workflows/deploy-staging.yml @@ -0,0 +1,122 @@ +name: Deploy to Staging + +on: + workflow_dispatch: + inputs: + image_tag: + description: "Docker image tag to deploy (commit SHA, staging, or v*)" + required: true + default: "staging" + type: string + +env: + APP_IMAGE: git.koppkb.com/kopkb/api_arrahn + DEPLOY_DIR: /home/arrahn/Project/api_arrahn + +jobs: + deploy: + runs-on: host + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + ref: ${{ inputs.image_tag }} + + - name: Login to Docker registry + run: | + echo "${{ secrets.REGISTRY_PASSWORD }}" | \ + docker login git.koppkb.com \ + -u "${{ secrets.REGISTRY_USERNAME }}" \ + --password-stdin + + - name: Verify image exists in registry + run: | + set -e + IMAGE_TAG="${{ inputs.image_tag }}" + IMAGE="${APP_IMAGE}:${IMAGE_TAG}" + + echo "Checking if image exists: ${IMAGE}" + if ! docker manifest inspect "${IMAGE}" > /dev/null 2>&1; then + echo "ERROR: Image ${IMAGE} does not exist in registry!" + echo "Run the Build Docker Image workflow first." + exit 1 + fi + echo "✓ ${IMAGE} found" + + - name: Pull Docker image + run: | + set -e + IMAGE_TAG="${{ inputs.image_tag }}" + docker pull "${APP_IMAGE}:${IMAGE_TAG}" + echo "✓ Image pulled successfully" + + - name: Sync compose file and deploy + run: | + set -e + IMAGE_TAG="${{ inputs.image_tag }}" + + mkdir -p "${DEPLOY_DIR}/docker/nginx" "${DEPLOY_DIR}/docker/mysql" + cp docker-compose.staging.yml "${DEPLOY_DIR}/docker-compose.yml" + cp docker/nginx/default.conf "${DEPLOY_DIR}/docker/nginx/default.conf" + cp -R docker/mysql/init "${DEPLOY_DIR}/docker/mysql/" + + if [ ! -f "${DEPLOY_DIR}/.env.staging" ]; then + if [ -f .env.staging ]; then + cp .env.staging "${DEPLOY_DIR}/.env.staging" + echo "Copied .env.staging from repo (first deploy). Edit ${DEPLOY_DIR}/.env.staging on the server if needed." + else + echo "ERROR: ${DEPLOY_DIR}/.env.staging is missing on the server" + exit 1 + fi + fi + + cd "${DEPLOY_DIR}" + + export APP_IMAGE + export IMAGE_TAG + + docker compose --env-file .env.staging -f docker-compose.yml pull app + docker compose --env-file .env.staging -f docker-compose.yml up -d --no-build --remove-orphans + + echo "✓ Deployed IMAGE_TAG=${IMAGE_TAG}" + + - name: Verify deployment + run: | + set -e + cd "${DEPLOY_DIR}" + + echo "Waiting for services to start..." + sleep 10 + + for SERVICE in app web mysql; do + STATUS=$(docker compose --env-file .env.staging -f docker-compose.yml ps --status running --format '{{.Name}}' "$SERVICE" 2>/dev/null || true) + if [ -z "$STATUS" ]; then + echo "ERROR: ${SERVICE} is not running" + docker compose --env-file .env.staging -f docker-compose.yml ps + docker compose --env-file .env.staging -f docker-compose.yml logs --tail=50 "$SERVICE" || true + exit 1 + fi + echo "✓ ${SERVICE} is running (${STATUS})" + done + + HTTP_PORT=$(grep -E '^HTTP_PORT=' .env.staging 2>/dev/null | cut -d= -f2- | tr -d '"' || true) + HTTP_PORT=${HTTP_PORT:-8090} + + check_health() { + NAME=$1 + URL=$2 + for i in 1 2 3 4 5 6; do + if curl -sf "$URL" > /dev/null; then + echo "✓ ${NAME} health check passed (${URL})" + return 0 + fi + echo "Waiting for ${NAME}... attempt ${i}/6" + sleep 5 + done + echo "ERROR: ${NAME} health check failed (${URL})" + docker compose --env-file .env.staging -f docker-compose.yml logs --tail=50 app web || true + return 1 + } + + check_health "api" "http://127.0.0.1:${HTTP_PORT}/health" diff --git a/bootstrap/.gitignore b/bootstrap/.gitignore new file mode 100644 index 0000000..b49a22a --- /dev/null +++ b/bootstrap/.gitignore @@ -0,0 +1 @@ +/cache \ No newline at end of file diff --git a/docker-compose.staging.yml b/docker-compose.staging.yml new file mode 100644 index 0000000..13b6aac --- /dev/null +++ b/docker-compose.staging.yml @@ -0,0 +1,77 @@ +# Staging stack — isolated from local docker-compose.yml (8080 / 3306) +# and from other apps on the server (unique project name + host ports). +# +# Local: +# docker compose --env-file .env.staging -f docker-compose.staging.yml up -d --build +# +# CI (image already in registry): +# APP_IMAGE=git.koppkb.com/KoPKB/api_arrahn IMAGE_TAG= \ +# docker compose --env-file .env.staging -f docker-compose.staging.yml up -d --no-build +# +# Host nginx reverse-proxies the public domain to 127.0.0.1:${HTTP_PORT}. +# See docker/nginx/host-proxy.example.conf +# +# If 8090 or 3308 is already taken, set HTTP_PORT / MYSQL_PUBLISH_PORT in .env.staging. + +name: api_arrahn_staging + +services: + app: + image: ${APP_IMAGE:-api_arrahn}:${IMAGE_TAG:-staging} + build: + context: . + dockerfile: docker/php/Dockerfile + target: staging + container_name: api_arrahn_staging_app + working_dir: /var/www/html + volumes: + - storage_staging:/var/www/html/storage + - ./.env.staging:/var/www/html/.env.staging:ro + env_file: + - .env.staging + environment: + APP_ENV: staging + USE_STAGING_ENV: "true" + extra_hosts: + - "host.docker.internal:host-gateway" + depends_on: + mysql: + condition: service_healthy + restart: unless-stopped + + web: + image: nginx:1.25-alpine + container_name: api_arrahn_staging_web + ports: + - "${HTTP_PORT:-8090}:80" + volumes: + - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro + depends_on: + - app + restart: unless-stopped + + mysql: + image: mysql:8.0 + container_name: api_arrahn_staging_mysql + command: --default-authentication-plugin=mysql_native_password + ports: + - "127.0.0.1:${MYSQL_PUBLISH_PORT:-3308}:3306" + environment: + MYSQL_DATABASE: erahn_xtra + MYSQL_USER: xtrauser + MYSQL_PASSWORD: password + MYSQL_ROOT_PASSWORD: root + volumes: + - mysql_staging_data:/var/lib/mysql + - ./docker/mysql/init:/docker-entrypoint-initdb.d:ro + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-uroot", "-proot"] + interval: 5s + timeout: 5s + retries: 30 + start_period: 20s + restart: unless-stopped + +volumes: + mysql_staging_data: + storage_staging: diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..2cab859 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,40 @@ +services: + app: + build: + context: . + dockerfile: docker/php/Dockerfile + target: development + working_dir: /var/www/html + volumes: + - ./:/var/www/html:cached + environment: + APP_ENV: local + APP_DEBUG: "true" + depends_on: + - mysql + + web: + image: nginx:1.25-alpine + ports: + - "8080:80" + volumes: + - ./:/var/www/html:cached + - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro + depends_on: + - app + + mysql: + image: mysql:8.0 + command: --default-authentication-plugin=mysql_native_password + ports: + - "3306:3306" + environment: + MYSQL_DATABASE: erahn_xtra + MYSQL_USER: xtrauser + MYSQL_PASSWORD: password + MYSQL_ROOT_PASSWORD: root + volumes: + - mysql_data:/var/lib/mysql + +volumes: + mysql_data: diff --git a/docker/mysql/init/01-create-databases.sql b/docker/mysql/init/01-create-databases.sql new file mode 100644 index 0000000..9b47955 --- /dev/null +++ b/docker/mysql/init/01-create-databases.sql @@ -0,0 +1,7 @@ +CREATE DATABASE IF NOT EXISTS master_erahn; +CREATE DATABASE IF NOT EXISTS kaunter_erahn; + +GRANT ALL PRIVILEGES ON master_erahn.* TO 'xtrauser'@'%'; +GRANT ALL PRIVILEGES ON kaunter_erahn.* TO 'xtrauser'@'%'; +GRANT ALL PRIVILEGES ON erahn_xtra.* TO 'xtrauser'@'%'; +FLUSH PRIVILEGES; diff --git a/docker/nginx/default.conf b/docker/nginx/default.conf new file mode 100644 index 0000000..223a96c --- /dev/null +++ b/docker/nginx/default.conf @@ -0,0 +1,36 @@ +server { + listen 80; + server_name _; + + root /var/www/html/public; + index index.php index.html; + + charset utf-8; + client_max_body_size 50M; + + location / { + try_files $uri $uri/ @php; + } + + location @php { + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME /var/www/html/public/index.php; + fastcgi_param PATH_INFO $fastcgi_path_info; + fastcgi_pass app:9000; + fastcgi_index index.php; + fastcgi_read_timeout 120s; + } + + location ~ \.php$ { + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param PATH_INFO $fastcgi_path_info; + fastcgi_pass app:9000; + fastcgi_index index.php; + fastcgi_read_timeout 120s; + } + + location ~ /\.(?!well-known).* { + deny all; + } +} diff --git a/docker/php/Dockerfile b/docker/php/Dockerfile new file mode 100644 index 0000000..172df1c --- /dev/null +++ b/docker/php/Dockerfile @@ -0,0 +1,51 @@ +FROM php:7.4-fpm AS base + +WORKDIR /var/www/html + +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + git \ + pkg-config \ + unzip \ + libonig-dev \ + libzip-dev \ + libpng-dev \ + libjpeg62-turbo-dev \ + libfreetype6-dev \ + && docker-php-ext-configure gd --with-freetype --with-jpeg \ + && docker-php-ext-install -j"$(nproc)" \ + pdo_mysql \ + mbstring \ + bcmath \ + zip \ + exif \ + gd \ + && rm -rf /var/lib/apt/lists/* + +COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer + +COPY docker/php/php.ini /usr/local/etc/php/conf.d/app.ini +COPY docker/php/zz-clear-env.conf /usr/local/etc/php-fpm.d/zz-clear-env.conf +COPY docker/php/entrypoint.sh /usr/local/bin/app-entrypoint.sh + +RUN chmod +x /usr/local/bin/app-entrypoint.sh \ + && usermod -u 1000 www-data && groupmod -g 1000 www-data + +ENTRYPOINT ["app-entrypoint.sh"] +CMD ["php-fpm"] + +FROM base AS staging + +COPY --chown=www-data:www-data . /var/www/html + +RUN composer install --no-interaction --prefer-dist --no-dev --optimize-autoloader \ + && mkdir -p \ + storage/logs \ + storage/framework/cache/data \ + storage/framework/views \ + storage/framework/sessions \ + storage/app/public \ + bootstrap/cache \ + && chown -R www-data:www-data storage bootstrap/cache vendor + +FROM base AS development diff --git a/docker/php/entrypoint.sh b/docker/php/entrypoint.sh new file mode 100644 index 0000000..a9951a7 --- /dev/null +++ b/docker/php/entrypoint.sh @@ -0,0 +1,30 @@ +#!/bin/sh +set -e + +cd /var/www/html + +if [ "${USE_STAGING_ENV:-false}" = "true" ] && [ -f .env.staging ]; then + cp .env.staging .env +fi + +if [ -f composer.json ]; then + if [ -f vendor/autoload.php ] && [ "${USE_STAGING_ENV:-false}" = "true" ]; then + : # vendor is baked into the staging image + elif [ "${USE_STAGING_ENV:-false}" = "true" ]; then + composer install --no-interaction --prefer-dist --no-dev --optimize-autoloader + else + composer install --no-interaction --prefer-dist + fi +fi + +mkdir -p \ + storage/logs \ + storage/framework/cache/data \ + storage/framework/views \ + storage/framework/sessions \ + storage/app/public \ + bootstrap/cache + +chown -R www-data:www-data storage bootstrap/cache + +exec docker-php-entrypoint "$@" diff --git a/docker/php/php.ini b/docker/php/php.ini new file mode 100644 index 0000000..3e9df60 --- /dev/null +++ b/docker/php/php.ini @@ -0,0 +1,4 @@ +memory_limit=512M +upload_max_filesize=50M +post_max_size=50M +max_execution_time=120 diff --git a/docker/php/zz-clear-env.conf b/docker/php/zz-clear-env.conf new file mode 100644 index 0000000..edbfb22 --- /dev/null +++ b/docker/php/zz-clear-env.conf @@ -0,0 +1,3 @@ +[www] +; Pass container env vars (from compose env_file) through to PHP workers. +clear_env = no diff --git a/routes/web.php b/routes/web.php index 8d76ddb..a239c1d 100644 --- a/routes/web.php +++ b/routes/web.php @@ -21,6 +21,10 @@ use App\Http\Controllers\TransactionOnlineTrailController; use App\Http\Controllers\Reports\RingkasanHarianController; use App\Transaction; +$router->get('/health', function () { + return response()->json(['status' => 'ok']); +}); + $router->group(['namespace' => '\Rap2hpoutre\LaravelLogViewer'], function() use ($router) { $router->get('logs', 'LogViewerController@index'); }); diff --git a/storage/.gitignore b/storage/.gitignore new file mode 100644 index 0000000..ca5c069 --- /dev/null +++ b/storage/.gitignore @@ -0,0 +1,2 @@ +/debugbar +/framework/sessions \ No newline at end of file