Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 350b14492b | |||
| 406044b847 | |||
| adab98701f | |||
| ac96050ed0 | |||
| e989f053c4 |
@@ -77,7 +77,7 @@ jobs:
|
||||
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 --force-recreate --remove-orphans app web
|
||||
docker compose --env-file .env.staging -f docker-compose.yml up -d --no-build --remove-orphans
|
||||
|
||||
echo "✓ Deployed IMAGE_TAG=${IMAGE_TAG}"
|
||||
|
||||
|
||||
@@ -14,11 +14,4 @@ FLUSH PRIVILEGES;
|
||||
```
|
||||
|
||||
Gadai=Pembiayaan
|
||||
Tebus=penyelesaian penuh/ansuran
|
||||
|
||||
## Load db dump without using docker
|
||||
```bash
|
||||
docker exec -i api_arrahn_staging_mysql mysql -uroot -proot erahn_test < erahn_test.sql
|
||||
```
|
||||
|
||||
## Disable the cawangan in arrahn_master_db
|
||||
Tebus=penyelesaian penuh/ansuran
|
||||
+1
-2
@@ -62,8 +62,7 @@ class Customer extends Model
|
||||
'telefon2',
|
||||
'nota_pekerjaan',
|
||||
'tagpelanggan',
|
||||
'tag_anggota',
|
||||
'gambar_mykad'
|
||||
'tag_anggota'
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,7 +5,6 @@ namespace App\Http\Controllers;
|
||||
use App\Audit;
|
||||
use App\Marhun;
|
||||
use App\BankMaster;
|
||||
use App\ARFiles;
|
||||
use App\Customer;
|
||||
use App\Gadai;
|
||||
use App\Lelong;
|
||||
@@ -65,7 +64,7 @@ class CustomerController extends Controller
|
||||
->orWhere('kpbaru','=',$ic)
|
||||
->first();
|
||||
|
||||
return response()->json($this->withMykadPhoto($customer));
|
||||
return response()->json($customer);
|
||||
}
|
||||
|
||||
public function showOneCustomerByICAdmin(Request $request){
|
||||
@@ -75,7 +74,7 @@ class CustomerController extends Controller
|
||||
->orWhere('kpbaru','=',$request->ic)
|
||||
->first();
|
||||
|
||||
return response()->json($this->withMykadPhoto($customer));
|
||||
return response()->json($customer);
|
||||
}
|
||||
|
||||
public function showOneCustomerByICMobile($ic){
|
||||
@@ -369,8 +368,6 @@ class CustomerController extends Controller
|
||||
'tujuangadai'=>$request->tujuangadai
|
||||
]);
|
||||
|
||||
$this->attachMykadPhoto($customer, $request);
|
||||
|
||||
$audit = new Audit();
|
||||
$audit->users = $request->teller;
|
||||
$audit->actions = "Daftar Pelanggan Baru";
|
||||
@@ -380,7 +377,7 @@ class CustomerController extends Controller
|
||||
$audit->updated_at = $current;
|
||||
$audit->save();
|
||||
|
||||
return response()->json($this->withMykadPhoto($customer), 201);
|
||||
return response()->json($customer, 201);
|
||||
}
|
||||
|
||||
public function customerUpdate($nokp,Request $request){
|
||||
@@ -1127,114 +1124,6 @@ public function AdminsearchCustomerBySAG(Request $request)
|
||||
return response()->json(['message' => 'Customer PDPA updated successfully.'], 200);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save MyKad photo into arrahn_files and link it on customer.gambar_mykad.
|
||||
*/
|
||||
protected function attachMykadPhoto($customer, Request $request)
|
||||
{
|
||||
if (!$customer) {
|
||||
return;
|
||||
}
|
||||
|
||||
$raw = $this->photoBase64FromRequest($request);
|
||||
if ($raw === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$fileId = $this->storeMykadPhoto($raw, $request->input('photo_mime', $request->json('photo_mime')), $customer);
|
||||
if (!$fileId) {
|
||||
return;
|
||||
}
|
||||
|
||||
Customer::on('mysql7')
|
||||
->where('kpbaru', $customer->kpbaru)
|
||||
->where('kplama', $customer->kplama)
|
||||
->update(['gambar_mykad' => $fileId]);
|
||||
|
||||
$customer->gambar_mykad = $fileId;
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Failed to attach MyKad photo: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
protected function photoBase64FromRequest(Request $request)
|
||||
{
|
||||
$raw = $request->input('photo_base64');
|
||||
if ($raw === null || $raw === '') {
|
||||
$raw = $request->json('photo_base64');
|
||||
}
|
||||
|
||||
return is_string($raw) ? $raw : '';
|
||||
}
|
||||
|
||||
protected function storeMykadPhoto($raw, $mime, $customer)
|
||||
{
|
||||
$commaPos = strpos($raw, ',');
|
||||
if ($commaPos !== false) {
|
||||
$raw = substr($raw, $commaPos + 1);
|
||||
}
|
||||
$raw = preg_replace('/\s+/', '', $raw);
|
||||
|
||||
if ($raw === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$decoded = base64_decode($raw, true);
|
||||
if ($decoded === false) {
|
||||
$decoded = base64_decode($raw);
|
||||
}
|
||||
if ($decoded === false || $decoded === '') {
|
||||
Log::warning('MyKad photo skipped: invalid base64');
|
||||
return null;
|
||||
}
|
||||
|
||||
if (strlen($raw) > 400000) {
|
||||
Log::warning('MyKad photo skipped: payload too large');
|
||||
return null;
|
||||
}
|
||||
|
||||
$mime = strtolower((string) ($mime ?: 'image/jpeg'));
|
||||
if (!in_array($mime, ['image/jpeg', 'image/jpg', 'image/png'], true)) {
|
||||
$mime = 'image/jpeg';
|
||||
}
|
||||
|
||||
$nric = preg_replace('/[^0-9A-Za-z]/', '', (string) ($customer->kpbaru ?: ''));
|
||||
$ext = $mime === 'image/png' ? 'png' : 'jpg';
|
||||
|
||||
$file = new ARFiles();
|
||||
$file->data = $raw;
|
||||
$file->filename = ($nric !== '' ? $nric : 'mykad') . '.' . $ext;
|
||||
$file->type = $mime;
|
||||
$file->tarikhmasa = Carbon::now()->toDateTimeString();
|
||||
$file->save();
|
||||
|
||||
return $file->id;
|
||||
}
|
||||
|
||||
protected function withMykadPhoto($customer)
|
||||
{
|
||||
if (!$customer) {
|
||||
return $customer;
|
||||
}
|
||||
|
||||
$payload = $customer->toArray();
|
||||
$payload['photo_base64'] = null;
|
||||
$payload['photo_mime'] = null;
|
||||
|
||||
if (empty($customer->gambar_mykad)) {
|
||||
return $payload;
|
||||
}
|
||||
|
||||
$file = ARFiles::on('mysql7')->where('id', $customer->gambar_mykad)->first();
|
||||
if ($file && $file->data) {
|
||||
$payload['photo_base64'] = $file->data;
|
||||
$payload['photo_mime'] = $file->type ?: 'image/jpeg';
|
||||
}
|
||||
|
||||
return $payload;
|
||||
}
|
||||
|
||||
// public function createNotaArcc($kodcaw, Request $request)
|
||||
// {
|
||||
// $current = Carbon::now();
|
||||
|
||||
@@ -605,7 +605,7 @@ class LelongController extends Controller
|
||||
|
||||
if($cawangan['tagarrahnbid'] == 1){
|
||||
if(env('APP_ENV') != 'production'){
|
||||
$link = 'https://adminbid-kopkb.erahn.com.my/api/portalApi';
|
||||
$link = 'http://niklah.arrahn.com.my/api/portalApi';
|
||||
}else{
|
||||
$link = 'https://adminbid-kopkb.erahn.com.my/api/portalApi';
|
||||
}
|
||||
|
||||
@@ -593,14 +593,20 @@ class PembiayaanOnlineService
|
||||
}
|
||||
}
|
||||
|
||||
list($batch, $appended) = $this->findOrCreateSlotBatch(
|
||||
$mysql,
|
||||
$kodcaw,
|
||||
$tarikh,
|
||||
$slot,
|
||||
$pcBy,
|
||||
$now
|
||||
);
|
||||
$batchNo = $this->nextBatchNo($mysql, $kodcaw, $tarikh, $slot);
|
||||
$jumlah = round((float) $lines->sum('pinjaman'), 2);
|
||||
|
||||
$batch = BatchPembiayaanOnline::on($mysql)->create([
|
||||
'batch_no' => $batchNo,
|
||||
'kodcaw' => $kodcaw,
|
||||
'tarikh' => $tarikh,
|
||||
'slot' => $slot,
|
||||
'bilangan' => $lines->count(),
|
||||
'jumlah_keseluruhan' => $jumlah,
|
||||
'status' => 'SUBMITTED',
|
||||
'pc_submitted_by' => $pcBy,
|
||||
'submitted_at' => $now,
|
||||
]);
|
||||
|
||||
foreach ($lines as $line) {
|
||||
PembiayaanOnline::on($mysql)->where('id', $line->id)->update([
|
||||
@@ -613,14 +619,6 @@ class PembiayaanOnlineService
|
||||
]);
|
||||
}
|
||||
|
||||
if ($appended) {
|
||||
BatchPembiayaanOnline::on($mysql)->where('id', $batch->id)->update([
|
||||
'submitted_at' => $now,
|
||||
]);
|
||||
}
|
||||
|
||||
$batch = $this->refreshBatchStatus($mysql, $batch->id);
|
||||
|
||||
$freshLines = PembiayaanOnline::on($mysql)
|
||||
->where('batch_id', $batch->id)
|
||||
->orderBy('id', 'asc')
|
||||
@@ -628,12 +626,11 @@ class PembiayaanOnlineService
|
||||
|
||||
return [
|
||||
'ok' => true,
|
||||
'status' => $appended ? 200 : 201,
|
||||
'status' => 201,
|
||||
'payload' => [
|
||||
'batch' => $batch,
|
||||
'lines' => $freshLines,
|
||||
'slot_info' => $slotInfo,
|
||||
'appended' => $appended,
|
||||
],
|
||||
];
|
||||
});
|
||||
@@ -1538,45 +1535,24 @@ class PembiayaanOnlineService
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* One batch per branch / day / slot (B1-001 or B2-001). Later submits append.
|
||||
*
|
||||
* @return array{0:\App\BatchPembiayaanOnline,1:bool} [batch, appended]
|
||||
*/
|
||||
protected function findOrCreateSlotBatch($mysql, $kodcaw, $tarikh, $slot, $pcBy, $now)
|
||||
{
|
||||
$batch = BatchPembiayaanOnline::on($mysql)
|
||||
->where('kodcaw', $kodcaw)
|
||||
->where('tarikh', $tarikh)
|
||||
->where('slot', $slot)
|
||||
->orderBy('id', 'asc')
|
||||
->lockForUpdate()
|
||||
->first();
|
||||
|
||||
if ($batch) {
|
||||
return [$batch, true];
|
||||
}
|
||||
|
||||
$batch = BatchPembiayaanOnline::on($mysql)->create([
|
||||
'batch_no' => $this->slotBatchNo($kodcaw, $tarikh, $slot),
|
||||
'kodcaw' => $kodcaw,
|
||||
'tarikh' => $tarikh,
|
||||
'slot' => $slot,
|
||||
'bilangan' => 0,
|
||||
'jumlah_keseluruhan' => 0,
|
||||
'status' => 'SUBMITTED',
|
||||
'pc_submitted_by' => $pcBy,
|
||||
'submitted_at' => $now,
|
||||
]);
|
||||
|
||||
return [$batch, false];
|
||||
}
|
||||
|
||||
protected function slotBatchNo($kodcaw, $tarikh, $slot)
|
||||
protected function nextBatchNo($mysql, $kodcaw, $tarikh, $slot)
|
||||
{
|
||||
$slotTag = $slot === 'BATCH1' ? 'B1' : 'B2';
|
||||
$ymd = Carbon::parse($tarikh)->format('Ymd');
|
||||
$prefix = strtoupper($kodcaw) . '-PO-' . $ymd . '-' . $slotTag . '-';
|
||||
|
||||
return strtoupper($kodcaw) . '-PO-' . $ymd . '-' . $slotTag . '-001';
|
||||
$last = BatchPembiayaanOnline::on($mysql)
|
||||
->where('kodcaw', $kodcaw)
|
||||
->where('tarikh', $tarikh)
|
||||
->where('slot', $slot)
|
||||
->orderBy('id', 'desc')
|
||||
->first();
|
||||
|
||||
$seq = 1;
|
||||
if ($last && preg_match('/-(\d+)$/', $last->batch_no, $m)) {
|
||||
$seq = ((int) $m[1]) + 1;
|
||||
}
|
||||
|
||||
return $prefix . str_pad((string) $seq, 3, '0', STR_PAD_LEFT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -398,7 +398,7 @@ class OnePercentService
|
||||
$t_gadai = Carbon::parse($gadai->t_gadai);
|
||||
$t_bayaran = Carbon::parse($trans->tarikh_bayaran);
|
||||
|
||||
if (($t_gadai->month == $t_bayaran->month) && ($t_gadai->year == $t_bayaran->year)) {
|
||||
if ($t_gadai->month === $t_bayaran->month && $t_gadai->year === $t_bayaran->year) {
|
||||
return false;
|
||||
}else{
|
||||
return true;
|
||||
|
||||
+34
-36
@@ -58,34 +58,31 @@ class GadaiV2
|
||||
}
|
||||
}
|
||||
|
||||
private function getKadarUpahAnggota($nokp, $total_nilai_marhun = 0, $groupid = 2): ?float
|
||||
{
|
||||
if (!$nokp) {
|
||||
return null; // tiada nokp = tak boleh tentukan kadar
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
$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['tag_anggota']) && $customer['tag_anggota'] == 1) {
|
||||
return 0.00; // ahli — kadar 0.00 memang sah
|
||||
}
|
||||
|
||||
$kadar = KadarUpah::where('min', '<=', $total_nilai_marhun)
|
||||
->where('max', '>=', $total_nilai_marhun)
|
||||
->where('group_id', $groupid)
|
||||
->value('kadarujrah');
|
||||
|
||||
return is_null($kadar) ? null : (float) $kadar; // tak jumpa row = null (block)
|
||||
}
|
||||
|
||||
public function createMarhun($norujukan,HttpRequest $request){
|
||||
$current = Carbon::now();
|
||||
$current = new Carbon();
|
||||
@@ -111,18 +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');
|
||||
|
||||
$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 (is_null($kadar_raw)) {
|
||||
Log::error('[BLOCKED] Kadar upah tidak dijumpai', [
|
||||
'nokp' => $request->nokp,
|
||||
'total_nilai_marhun' => $total_nilai_marhun,
|
||||
'group_id' => $cawangan['group_id'],
|
||||
]);
|
||||
throw new \Exception("Kadar upah tidak dijumpai, transaksi dibatalkan!");
|
||||
}
|
||||
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!");
|
||||
}
|
||||
|
||||
// $kadar_raw = 0.00 (ahli) akan lepas ke sini dan diteruskan
|
||||
|
||||
// query kadar upah lama
|
||||
// $kadar_raw = KadarUpah::where('min','<=',$total_nilai_marhun)->where('max','>=',$total_nilai_marhun)->first();
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddGambarMykadToCustomerTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Master DB (mysql7) — stores arrahn_files.id for the MyKad photo.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
if (
|
||||
Schema::connection('mysql7')->hasTable('customer')
|
||||
&& !Schema::connection('mysql7')->hasColumn('customer', 'gambar_mykad')
|
||||
) {
|
||||
Schema::connection('mysql7')->table('customer', function (Blueprint $table) {
|
||||
if (Schema::connection('mysql7')->hasColumn('customer', 'tag_anggota')) {
|
||||
$table->unsignedBigInteger('gambar_mykad')->nullable()->after('tag_anggota');
|
||||
} else {
|
||||
$table->unsignedBigInteger('gambar_mykad')->nullable();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
if (
|
||||
Schema::connection('mysql7')->hasTable('customer')
|
||||
&& Schema::connection('mysql7')->hasColumn('customer', 'gambar_mykad')
|
||||
) {
|
||||
Schema::connection('mysql7')->table('customer', function (Blueprint $table) {
|
||||
$table->dropColumn('gambar_mykad');
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
# CI (image already in registry):
|
||||
# APP_IMAGE=git.koppkb.com/KoPKB/api_arrahn IMAGE_TAG=<sha> \
|
||||
# docker compose --env-file .env.staging -f docker-compose.staging.yml up -d --no-build --force-recreate app web
|
||||
# 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
|
||||
|
||||
@@ -9,7 +9,6 @@ server {
|
||||
client_max_body_size 50M;
|
||||
|
||||
location / {
|
||||
rewrite ^/(.*)/$ /$1 last;
|
||||
try_files $uri @php;
|
||||
}
|
||||
|
||||
|
||||
+4
-1
@@ -371,9 +371,11 @@ $router->group(['prefix'=>'api'], function () use ($router){
|
||||
$router->get('GetCurrentTunai/{kodcaw}',['uses' =>'TunaiController@getCurrentTunai']);
|
||||
$router->get('getPastTunai/{kodcaw}',['uses' =>'TunaiController@getTunaiPast']);
|
||||
$router->get('GetLatestTunai/{kodcaw}',['uses' =>'TunaiController@getLatestTunai']);
|
||||
$router->get('getAddTunai/{kodcaw}/kodlaluan',['uses' =>'TunaiController@getAddTunaibyKodlaluan']);
|
||||
$router->get('getAddTunai/{kodcaw}/kodlaluan/',['uses' =>'TunaiController@getAddTunaibyKodlaluan']);
|
||||
$router->get('getAddTunai/{kodcaw}',['uses' =>'TunaiController@getAddTunai']);
|
||||
$router->get('getAddTunai/{kodcaw}/',['uses' =>'TunaiController@getAddTunai']);
|
||||
$router->get('getAddTunaiDate/{kodcaw}/',['uses' =>'TunaiController@getAddTunaiDate']);
|
||||
$router->get('getAddTunai/{kodcaw}/kodlaluan/',['uses' =>'TunaiController@getAddTunaibyKodlaluan']);
|
||||
$router->get('getAddTunaiLatest/{kodcaw}',['uses' =>'TunaiController@getAddTunaibyKodlaluanLatest']);
|
||||
$router->put('gadai/hapus/{kodcaw}/{norujukan}', ['uses' => 'GadaiController@GadaiHapus']);
|
||||
$router->put('tebus/hapus/{kodcaw}/{norujukan}', ['uses' => 'GadaiController@TebusHapus']);
|
||||
@@ -516,6 +518,7 @@ $router->group(['prefix'=>'api'], function () use ($router){
|
||||
$router->get('TuntutBaki/{kodcaw}',['uses'=>'LelongController@showTuntutBaki']);
|
||||
$router->get('TuntutBakiRangeDate/{kodcaw}',['uses'=>'LelongController@showTuntutBakiRangeDate']);
|
||||
$router->get('TuntutBaki/{kodcaw}/teller',['uses'=>'LelongController@showTuntutBakiTeller']);
|
||||
$router->get('TuntutBaki/{kodcaw}/teller/',['uses'=>'LelongController@showTuntutBakiTeller']);
|
||||
$router->get('TuntutBaki/resit/{kodcaw}/{norujukan}',['uses'=>'LelongController@resitLelong']);
|
||||
$router->post('Tuntutbakisimpan/{kodcaw}',['uses'=>'LelongController@simpantuntutbaki']);
|
||||
$router->put('tuntutbakiupdate/{kodcaw}/{norujukan}',['uses'=>'LelongController@updatetagtbaki']);
|
||||
|
||||
Reference in New Issue
Block a user