diff --git a/.env.docker.example b/.env.docker.example index 3468ee4..d0aa137 100644 --- a/.env.docker.example +++ b/.env.docker.example @@ -1,10 +1,12 @@ APP_NAME=Laravel APP_ENV=local -APP_KEY=base64:Her7qzZ/iDiuEBFfMZVnN8fMDOJvOZ8mmg2quO+L2ck= +APP_KEY=base64:42429JS6yzOce6gW3d+c59GBL9cJw6D5vqhWv9h7nx8= APP_DEBUG=true -APP_URL=http://localhost -API_URL=http://host.docker.internal:8874 -API_LELONG_URL=http://host.docker.internal:8096 +APP_URL=http://pay.localhost +API_URL=http://apiv2.localhost +API_URL_KOOP=http://apiv3.localhost +API_LELONG_URL=http://lelong.localhost +API_VERIFY=false LOG_CHANNEL=stack LOG_LEVEL=debug @@ -51,3 +53,15 @@ PUSHER_APP_CLUSTER=mt1 MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" + +BILLPLZ_PRODUCTION_API_KEY="f3e82fe1-a422-4660-97f0-65cc59ff6c47" +BILLPLZ_PRODUCTION_X_SIGNATURE="S-alZUbzmD2_TF3vmrRqgehQ" +BILLPLZ_PRODUCTION_COLLECTION_ID="5aosv2dg" + +BILLPLZ_SANDBOX_API_KEY="abecfd0c-98d8-4635-abc2-2fcba8c60c11" +BILLPLZ_SANDBOX_X_SIGNATURE="S-GWr7z03XjAhqPsFfu_H5nQ" +BILLPLZ_SANDBOX_COLLECTION_ID="z0r4kjhi" + +BILLPLZ_SANDBOX_KOPKB_API_KEY="abecfd0c-98d8-4635-abc2-2fcba8c60c11" +BILLPLZ_SANDBOX_KOPKB_X_SIGNATURE="S-GWr7z03XjAhqPsFfu_H5nQ" +BILLPLZ_SANDBOX_KOPKB_COLLECTION_ID="uae40muk" diff --git a/.env.example b/.env.example index a42d7e0..4b8cd08 100644 --- a/.env.example +++ b/.env.example @@ -4,6 +4,7 @@ APP_KEY= APP_DEBUG=true APP_URL=http://localhost API_URL=http://api_arrahn.test +API_URL_KOOP=http://api_arrahn_v3.test API_LELONG_URL=https://niklah.arrahn.com.my LOG_CHANNEL=stack @@ -51,3 +52,15 @@ PUSHER_APP_CLUSTER=mt1 MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" + +BILLPLZ_PRODUCTION_API_KEY="f3e82fe1-a422-4660-97f0-65cc59ff6c47" +BILLPLZ_PRODUCTION_X_SIGNATURE="S-alZUbzmD2_TF3vmrRqgehQ" +BILLPLZ_PRODUCTION_COLLECTION_ID="5aosv2dg" + +BILLPLZ_SANDBOX_API_KEY="abecfd0c-98d8-4635-abc2-2fcba8c60c11" +BILLPLZ_SANDBOX_X_SIGNATURE="S-GWr7z03XjAhqPsFfu_H5nQ" +BILLPLZ_SANDBOX_COLLECTION_ID="z0r4kjhi" + +BILLPLZ_SANDBOX_KOPKB_API_KEY="abecfd0c-98d8-4635-abc2-2fcba8c60c11" +BILLPLZ_SANDBOX_KOPKB_X_SIGNATURE="S-GWr7z03XjAhqPsFfu_H5nQ" +BILLPLZ_SANDBOX_KOPKB_COLLECTION_ID="uae40muk" diff --git a/app/Console/Commands/DeleteCarts.php b/app/Console/Commands/DeleteCarts.php new file mode 100644 index 0000000..f80ffe5 --- /dev/null +++ b/app/Console/Commands/DeleteCarts.php @@ -0,0 +1,54 @@ +delete(); + Log::info("$deleted carts have been deleted."); + $this->info("$deleted carts have been deleted."); + }catch(\Exception $e){ + Log::error('Error deleting carts: ' . $e->getMessage()); + $this->error('Error deleting carts: ' . $e->getMessage()); + return 1; + } + + } +} diff --git a/app/Console/Commands/DeleteCartsHourly.php b/app/Console/Commands/DeleteCartsHourly.php new file mode 100644 index 0000000..44c4dc5 --- /dev/null +++ b/app/Console/Commands/DeleteCartsHourly.php @@ -0,0 +1,55 @@ +subHour(); + $deleted = PersonalCarts::where('created_at', '<', $oneHourAgo)->delete(); + Log::info('carts hourly have been deleted.'); + $this->info('carts have been deleted.'); + }catch(\Exception $e){ + Log::error('Error deleting hourly carts: ' . $e->getMessage()); + $this->error('Error deleting hourly carts: ' . $e->getMessage()); + return 1; + } + + } +} diff --git a/app/Console/Commands/UpdateTransactionMaster.php b/app/Console/Commands/UpdateTransactionMaster.php index 37866db..1d84f4d 100644 --- a/app/Console/Commands/UpdateTransactionMaster.php +++ b/app/Console/Commands/UpdateTransactionMaster.php @@ -40,11 +40,18 @@ class UpdateTransactionMaster extends Command public function handle() { $updateOnline = Http::arrahn()->get('/api/transaction/online/update')->json(); - + $updateOnline_Koop = Http::arrahn_koop()->get('/api/transaction/online/update')->json(); + if($updateOnline == 'success'){ return 0; }else{ - Log::error('Update transaction master failed'); + Log::error('PKB::Update transaction master failed'); + } + + if($updateOnline_Koop == 'success'){ + return 0; + }else{ + Log::error('KOOP::Update transaction master failed'); } } } diff --git a/app/Console/Commands/updateUnsuccess.php b/app/Console/Commands/updateUnsuccess.php index e2dd207..33ef2f0 100644 --- a/app/Console/Commands/updateUnsuccess.php +++ b/app/Console/Commands/updateUnsuccess.php @@ -2,9 +2,11 @@ namespace App\Console\Commands; +use App\Models\CompanyStatus; use App\Models\TransactionOnlineStatus; use App\Services\BillplzService; use App\Services\OnlineTransactionLoggerService; +use Billplz\Base\Bill; use Illuminate\Support\Facades\Http; use Illuminate\Console\Command; @@ -15,8 +17,7 @@ class UpdateUnsuccess extends Command * * @var string */ - protected $signature = 'update:unsuccess'; - + protected $signature = 'update:unsuccess {--type=1}'; /** * The console command description. * @@ -29,18 +30,36 @@ class UpdateUnsuccess extends Command * * @return int */ - public function handle(BillplzService $billplzService) + public function handle() { - - $getFailedOnlineTransaction = fn() => Http::arrahn()->get('/api/transaction/online/unsuccessful')->json(); - - $FailedBillplzID = array_map(fn($x) => $x['billplz_id'], $getFailedOnlineTransaction()); + $type = $this->option('type'); + + if($type == '1'){ + $getFailedOnlineTransaction = fn() => Http::arrahn()->get('/api/transaction/online/unsuccessful')->json(); + $FailedBillplzID = array_map(fn($x) => $x['billplz_id'], $getFailedOnlineTransaction()); + $this->resolve_payment($FailedBillplzID,CompanyStatus::COM_PKB); + }else{ + $getFailedOnlineTransaction_Koop = fn() => Http::arrahn_koop()->get('/api/transaction/online/unsuccessful')->json(); + $FailedBillplzID_Koop = array_map(fn($x) => $x['billplz_id'], $getFailedOnlineTransaction_Koop()); + $this->resolve_payment($FailedBillplzID_Koop,CompanyStatus::COM_KOOPPKB); + } + + } + public function resolve_payment($FailedBillplzID,$company) + { + $billplzService = new BillplzService($company); if(sizeof($FailedBillplzID) < 0){ return; } + + if($company == CompanyStatus::COM_PKB){ + $companyID = 'PKB'; + }else{ + $companyID = 'KOPKB'; + } - $billplzUpdatedTransactionStatus = array_map(fn($x) => $billplzService->getTransactionByBillId($x), $FailedBillplzID); + $billplzUpdatedTransactionStatus = array_map(fn($x) => $billplzService->getTransactionByBillId($x,$companyID), $FailedBillplzID); $getCompletedBillplzTransaction = function() use($billplzUpdatedTransactionStatus){ @@ -59,7 +78,13 @@ class UpdateUnsuccess extends Command ]; try { - $response = Http::arrahn()->put('/api/transaction/online/unsuccesfull/update', $transactionData); + + $CallableHttp = $company == CompanyStatus::COM_PKB + ? Http::arrahn() + : Http::arrahn_koop(); + + $response = $CallableHttp->put('/api/transaction/online/unsuccesfull/update', $transactionData); + OnlineTransactionLoggerService::logs($transaction['bill_id'], $transactionData, $response, TransactionOnlineStatus::UPDATE_UNSUCCESSFUL_TRANSACTION ); } catch (\Exception $e) { diff --git a/app/Http/Controllers/BayaranController.php b/app/Http/Controllers/BayaranController.php index 6c4557e..0cb5e2a 100644 --- a/app/Http/Controllers/BayaranController.php +++ b/app/Http/Controllers/BayaranController.php @@ -3,6 +3,8 @@ namespace App\Http\Controllers; use App\Http\Requests\PaymentRequest; +use App\Models\CompanyStatus; +use App\Models\PersonalCarts; use App\Models\TransactionOnlineStatus; use App\Services\BillplzService; use Carbon\Carbon; @@ -13,25 +15,86 @@ use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Log; use Money\Money; use App\Services\OnlineTransactionLoggerService; +use Illuminate\Support\Facades\Session; +use PDF; class BayaranController extends Controller { + public $CallableHttp; + public function PembayaranAction(PaymentRequest $request) { - $request->validated(); + + $exist_carts = $this->checkCarts(); + $exist_carts = optional($exist_carts)->toArray(); + + if($exist_carts){ + /* Do Have Carts. */ + $list_pkb = json_decode($exist_carts['list_pkb'],true); + $list_koop = json_decode($exist_carts['list_koop'],true); - $arraybayar = $this->setUpahTawarruq($request->getPembiayaanFromNorujukan()); + if($this->checkSAG($list_pkb, 'PKB')){ + $this->removeCartsInternal(); + return redirect()->route('buffer'); + } - return view('includes.bayaran.pembayaransag', compact('arraybayar')); + if($this->checkSAG($list_koop, 'KOPKB')){ + $this->removeCartsInternal(); + return redirect()->route('buffer'); + } + + if($exist_carts['status_pkb'] == 'PENDING') $list_pkb = ($list_pkb) ? $this->setUpahTawarruq($list_pkb) : []; else $list_pkb = []; + if($exist_carts['status_koop'] == 'PENDING') $list_koop = ($list_koop) ? $this->setUpahTawarruq($list_koop) : []; else $list_koop = []; + + if (empty($list_pkb) && empty($list_koop)) { + $this->removeCartsInternal(); + return redirect()->route('buffer'); + } + + }else{ + /* Doesn't Have Carts. First Timer */ + $request->validated(); + + if(isset($request->redirect_trolley)){ + return redirect()->route('buffer'); + } + + $arraybayar = $this->setUpahTawarruq($request->getPembiayaanFromNorujukan()); + + $list_pkb = array_filter(array_map(function ($x){ + return ($x['tag_syarikat'] == CompanyStatus::COM_PKB) ? $x : null; + },$arraybayar)); + + $list_koop = array_filter(array_map(function ($x){ + return ($x['tag_syarikat'] == CompanyStatus::COM_KOOPPKB) ? $x : null; + },$arraybayar)); + + $personal_carts = new PersonalCarts(); + $personal_carts->ic_no = Auth::user()->icno; + $personal_carts->list_koop = json_encode($list_koop); + $personal_carts->list_pkb = json_encode($list_pkb); + $personal_carts->status_pkb = ($list_pkb) ? 'PENDING' : 'NONE'; + $personal_carts->status_koop = ($list_koop) ? 'PENDING' : 'NONE'; + $personal_carts->user_id = Auth::user()->id; + $personal_carts->save(); + } + + return view('includes.bayaran.pembayaransag', compact('list_pkb','list_koop')); } - public function PembayaranEngine(Request $request, BillplzService $billplzService) + public function PembayaranEngine(Request $request) { ['email' => $customerEmail, 'notel' => $customerPhoneNumber, 'name' => $customerName, 'icno' => $customerIcno] = auth()->user()->toArray(); + + #Validate the request + $error = $this->validateRequest($request); + if ($error) { + return redirect()->route('buffer')->with(['errorvalidate' => $error]); + } $bayaranArrahn = array_filter($request->txtjenisbayaran, fn($x) => $x == 'arrahn'); $bayaranOthers = array_filter($request->txtjenisbayaran, fn($x) => $x != 'arrahn'); - + $bayaranArrahnArray = array_map(function ($x) use ($customerName, $customerIcno, $request) { return [ 'customer_name' => $customerName, @@ -62,9 +125,14 @@ class BayaranController extends Controller return Money::MYR($sum())->add($billPlzTransactionFee); }; - $bill = $billplzService->createBill([$customerEmail, $customerPhoneNumber, $customerName, $getPaymentSum()]); + $company = strtoupper($request->txtcompany); + $billplzService = new BillplzService($company); + $bill = $billplzService->createBill([$customerEmail, $customerPhoneNumber, $customerName, $getPaymentSum()],$company); + + Session::put('company', $company); + $this->serviceCallHttp($company); - $isRecordTransactionSuccess = $this->recordTransaction($paymentArray, $bill); + $isRecordTransactionSuccess = $this->recordTransaction($paymentArray, $bill,$company); if ($isRecordTransactionSuccess) { session([ @@ -76,12 +144,12 @@ class BayaranController extends Controller } } - public function recordTransaction($paymentArray, $bill) + public function recordTransaction($paymentArray, $bill,$company = 'PKB') { ['name' => $customerName, 'icno' => $customerIcno] = auth()->user()->toArray(); $getlatestNoSiri = function () { - $previous_siri = Http::arrahn()->get('/api/online/transaction')->json(); + $previous_siri = $this->CallableHttp->get('/api/online/transaction')->json(); if ($previous_siri) { return $previous_siri['nosiri'] + 1; } else { @@ -95,10 +163,13 @@ class BayaranController extends Controller return 'APKB' . $day . $month . $year . sprintf('%08d', $getlatestNoSiri()); }; + $serviceCallable = $company == 'PKB' + ? fn(Pool $pool) => $pool->arrahn() + : fn(Pool $pool) => $pool->arrahn_koop(); try { Http::pool( fn(Pool $pool) => collect($paymentArray)->map( - fn($payment) => $pool->arrahn()->post('/api/online/transaction', [ + fn($payment) => $serviceCallable($pool)->post('/api/online/transaction', [ 'nokp' => $customerIcno, 'reference_no' => $generateTransactionReferenceNumber(), 'nosiri' => $getlatestNoSiri(), @@ -122,7 +193,7 @@ class BayaranController extends Controller } try { - $response = Http::arrahn() + $response = $this->CallableHttp ->put('/api/transaction/online/tagportal', [ 'billplz_id' => $bill['id'], ]) @@ -142,11 +213,12 @@ class BayaranController extends Controller public function ResitBayaran(Request $request) { + $this->serviceCallHttp(Session::get('company')); $payment_details = $request->payment; $kpbaru = Auth::User()->icno; - $customer = Http::arrahn() + $customer = $this->CallableHttp ->get('/api/customers/' . $kpbaru) ->json(); $customer_details = $customer; @@ -155,31 +227,77 @@ class BayaranController extends Controller $current = new Carbon(); $date = $current->toDateTimeString(); - $cawangan_info = Http::arrahn() + $cawangan_info = $this->CallableHttp ->get('/api/cawangan/' . $payment_details['kodcaw']) ->json(); - $cawangan = Http::arrahn() + $cawangan = $this->CallableHttp ->get('/api/cawangan/detail/' . $payment_details['kodcaw']) ->json(); $cawangan_detail = $cawangan[0]; $nama_cawangan = $cawangan_info['details_caw']; - $gadai_details = Http::arrahn() + $gadai_details = $this->CallableHttp ->get('/api/gadai/norujukan/' . $payment_details['norujukan']) ->json(); $gadai = $gadai_details[0][0]; - return view('pembayaran.resit.resitportal', compact('customer_details', 'payment_details', 'cawangan_detail', 'nama_cawangan', 'gadai')); + $company = Session::get('company'); + + return view('pembayaran.resit.resitportal', compact('customer_details', 'payment_details', 'cawangan_detail', 'nama_cawangan', 'gadai','company')); } - public function callback(Request $request, BillplzService $billplzService) + public function generateResit(Request $request) { + $this->serviceCallHttp($request->company); + + $kpbaru = Auth::User()->icno; + + $customer = $this->CallableHttp + ->get('/api/customers/' . $kpbaru) + ->json(); + $customer_details = $customer; + + $current = Carbon::now(); + $current = new Carbon(); + $date = $current->toDateTimeString(); + + $payment_details = $this->CallableHttp + ->get('/api/transaction/online/express', ['billplz_id' => $request->billplzid,'norujukan' => $request->norujukan]) + ->json(); + + $cawangan_info = $this->CallableHttp + ->get('/api/cawangan/' . $payment_details['kodcaw']) + ->json(); + $cawangan = $this->CallableHttp + ->get('/api/cawangan/detail/' . $payment_details['kodcaw']) + ->json(); + $cawangan_detail = $cawangan[0]; + $nama_cawangan = $cawangan_info['details_caw']; + + $gadai_details = $this->CallableHttp + ->get('/api/gadai/norujukan/' . $payment_details['norujukan']) + ->json(); + $gadai = $gadai_details[0][0]; + + // Load a view and pass data to it + if($request->jenis == 'pdf'){ + $pdf = PDF::loadView('pembayaran.resit.resitpdf', compact('customer_details', 'payment_details', 'cawangan_detail', 'nama_cawangan', 'gadai')); + return $pdf->stream('resit_pembayaran.pdf'); + }else{ + return view('pembayaran.resit.resitpdf', compact('customer_details', 'payment_details', 'cawangan_detail', 'nama_cawangan', 'gadai')); + } + + } + + public function callback(Request $request) + { + $billplzService = new BillplzService(Session::get('company')); $data = $billplzService->webhook($request->toArray()); $isBillUnpaid = $data['paid'] !== true; if ($isBillUnpaid) { - Http::arrahn()->put('/api/online/transaction', [ + $this->CallableHttp->put('/api/online/transaction', [ 'billplz_id' => $data['id'], 'status' => 'UNSUCCESSFUL', 'paid_at' => null, @@ -188,29 +306,43 @@ class BayaranController extends Controller return response(200); } - Http::arrahn()->put('/api/online/transaction', [ + $this->CallableHttp->put('/api/online/transaction', [ 'billplz_id' => $data['id'], 'status' => 'PAID', 'paid_at' => $data['paid_at']->format('Y-m-d H:i:s'), ]); + $column_updated = (Session::get('company') == 'PKB') ? 'status_pkb' : 'status_koop'; + $value_paid = 'PAID'; + + $exist_carts = PersonalCarts::where('ic_no', Auth::user()->icno) + ->where('user_id', Auth::user()->id) + ->where(function ($query) { + $query->where('status_pkb', 'PENDING') + ->orWhere('status_koop', 'PENDING'); + }) + ->update([ + $column_updated => $value_paid, + ]); + return response(200); } - public function response(Request $request, BillplzService $billplzService) + public function response(Request $request) { + $billplzService = new BillplzService(Session::get('company')); $data = $billplzService->redirect($request->toArray()); - + $this->serviceCallHttp($billplzService->company); $isBillUnpaid = $data['paid'] !== true; if ($isBillUnpaid) { - Http::arrahn()->put('/api/online/transaction', [ + $this->CallableHttp->put('/api/online/transaction', [ 'billplz_id' => $data['id'], - 'status' => 'UNSUCCESSFUL', + 'status' => 'NOT PAID', 'paid_at' => null, ]); - $transactionOnline = Http::arrahn() + $transactionOnline = $this->CallableHttp ->get('/api/transaction/online/login', [ 'billplz_id' => $data['id'], ]) @@ -219,18 +351,33 @@ class BayaranController extends Controller return redirect()->route('pay.failed'); } - Http::arrahn()->put('/api/online/transaction', [ + $this->CallableHttp->put('/api/online/transaction', [ 'billplz_id' => $data['id'], 'status' => 'PAID', 'paid_at' => $data['paid_at']->format('Y-m-d H:i:s'), ]); - $transactionOnline = Http::arrahn() + $column_updated = (Session::get('company') == 'PKB') ? 'status_pkb' : 'status_koop'; + $value_paid = 'PAID'; + $column_payment_updated = (Session::get('company') == 'PKB') ? 'payment_pkb' : 'payment_koop'; + + $transactionOnline = $this->CallableHttp ->get('/api/transaction/online/login', [ 'billplz_id' => $data['id'], ]) ->json(); + $exist_carts = PersonalCarts::where('ic_no', Auth::user()->icno) + ->where('user_id', Auth::user()->id) + ->where(function ($query) { + $query->where('status_pkb', 'PENDING') + ->orWhere('status_koop', 'PENDING'); + }) + ->update([ + $column_updated => $value_paid, + $column_payment_updated => json_encode($transactionOnline) + ]); + return redirect()->route('pay.success', [ 'transactionOnline' => $transactionOnline, ]); @@ -238,23 +385,76 @@ class BayaranController extends Controller public function successPayment(Request $request) { + $this->serviceCallHttp(Session::get('company')); $transactionOnline = $request->transactionOnline; + $exist_carts = PersonalCarts::where('ic_no', Auth::user()->icno) + ->where('user_id', Auth::user()->id) + ->where(function ($query) { + $query->where('status_pkb', 'PENDING') + ->orWhere('status_koop', 'PENDING'); + }) + ->first(); + + $exist_carts = optional($exist_carts)->toArray(); + + if(!$exist_carts){ + $paid_carts = PersonalCarts::where('ic_no', Auth::user()->icno) + ->where('user_id', Auth::user()->id) + ->where(function ($query) { + $query->where('status_pkb', 'PAID') + ->where('status_koop', 'PAID'); + }) + ->first(); + $paid_carts = optional($paid_carts)->toArray(); + if($paid_carts){ + + $trans_pkb = json_decode($paid_carts['payment_pkb'],true); + $trans_koop = json_decode($paid_carts['payment_koop'],true); + + $trans_pkb = array_map(function ($item) { + $item['tag_syarikat'] = CompanyStatus::COM_PKB; + return $item; + }, $trans_pkb); + + $trans_koop = array_map(function ($item) { + $item['tag_syarikat'] = CompanyStatus::COM_KOOPPKB; + return $item; + }, $trans_koop); + + $transactionOnline = array_merge($trans_pkb,$trans_koop); + + $arraycawangan = array_map( + fn($x) => $x['tag_syarikat'] == CompanyStatus::COM_PKB + ? Http::arrahn() + ->get('/api/cawangan/detail/' . $x['kodcaw']) + ->json()[0] + : Http::arrahn_koop() + ->get('/api/cawangan/detail/' . $x['kodcaw']) + ->json()[0], + $transactionOnline + ); + + + return view('pembayaran.result.berjayaportal', compact('transactionOnline', 'arraycawangan','exist_carts')); + } + } + $arraygadai = array_map( - fn($x) => Http::arrahn() + fn($x) => $this->CallableHttp ->get('/api/gadai/norujukan/' . $x['norujukan']) ->json()[0][0], $transactionOnline, ); $arraycawangan = array_map( - fn($x) => Http::arrahn() + fn($x) => $this->CallableHttp ->get('/api/cawangan/detail/' . $x['kodcaw']) ->json()[0], $transactionOnline, ); - return view('pembayaran.result.berjayaportal', compact('transactionOnline', 'arraycawangan', 'arraygadai')); + return view('pembayaran.result.berjayaportal', compact('transactionOnline', 'arraycawangan', 'arraygadai','exist_carts')); } public function failedPayment() @@ -270,7 +470,7 @@ class BayaranController extends Controller $auth_user = Auth::user(); - $belum_tebus = Http::arrahn() + $belum_tebus = $this->CallableHttp ->get('/api/customers/' . $auth_user['icno'] . '/gadai/' . 'belum_tebus') ->json(); @@ -302,7 +502,11 @@ class BayaranController extends Controller $getUpahTawarruqPerPembiayaan = function ($x) use ($getJenisKeuntungan) { $jenisKeuntungan = $getJenisKeuntungan($x); - $upahTawarruq = Http::arrahn() + $CallableHttp = $x['tag_syarikat'] == CompanyStatus::COM_PKB + ? Http::arrahn() + : Http::arrahn_koop(); + + $upahTawarruq = $CallableHttp ->get('/api/upahtawarruq/' . $x['kodcaw'] . '/' . $x['norujukan'], ['jeniskeuntungan' => $jenisKeuntungan]) ->json(); @@ -319,4 +523,180 @@ class BayaranController extends Controller return array_map($getUpahTawarruqPerPembiayaan, $pembiayaan); } + + public function checkCarts(){ + $exist_carts = PersonalCarts::where('ic_no', Auth::user()->icno) + ->where('user_id', Auth::user()->id) + ->where(function ($query) { + $query->where('status_pkb', 'PENDING') + ->orWhere('status_koop', 'PENDING'); + }) + ->first(); + + return $exist_carts; + } + + public function UserCheckCarts(Request $request){ + if($request->ajax() || $request->expectsJson()){ + $exist_carts = PersonalCarts::where('ic_no', Auth::user()->icno) + ->where('user_id', Auth::user()->id) + ->where(function ($query) { + $query->where('status_pkb', 'PENDING') + ->orWhere('status_koop', 'PENDING'); + }) + ->first(); + + return response()->json($exist_carts); + }else{ + return redirect()->route('buffer'); + } + + + } + + public function removeCarts(Request $request){ + if($request->ajax() || $request->expectsJson()){ + $exist_carts = PersonalCarts::where('ic_no', Auth::user()->icno) + ->where('user_id', Auth::user()->id) + ->first(); + + if ($exist_carts) { + $exist_carts->delete(); + } + + return response()->json($exist_carts); + }else{ + return redirect()->route('buffer'); + } + } + + public function serviceCallHttp($company){ + $this->CallableHttp = $company == 'PKB' + ? Http::arrahn() + : Http::arrahn_koop(); + + } + + private function checkSAG($list_sag, $company) + { + $CallableHttp = $company == 'PKB' + ? Http::arrahn() + : Http::arrahn_koop(); + + foreach ($list_sag as $x) { + $array_lelong = Http::withOptions(['verify' => config('app.api_verify')]) + ->get(config('api-lelong.url') . '/api/portalApi', ['norujukan' => $x['norujukan']]) + ->json(); + + $array_gadai = $CallableHttp->get('/api/gadai/norujukan/' . $x['norujukan'])->json(); + $isdisabled = $CallableHttp->get('/portal/searchsagonline/', ['norujukan' => $x['norujukan']])->json(); + + if ($array_lelong['lelong'] != null) { + return true; + } + + if ($isdisabled) { + return true; + } + + if (sizeof($array_gadai) != 0) { + $array_gadai = $array_gadai[0][0]; + if ($array_gadai['sttebus'] == 'T' || $array_gadai['sttebus'] == 'L') { + return true; + } + } + } + + return false; + } + + private function removeCartsInternal(){ + $exist_carts = PersonalCarts::where('ic_no', Auth::user()->icno) + ->where('user_id', Auth::user()->id) + ->first(); + + if ($exist_carts) { + $exist_carts->delete(); + } + + return $exist_carts; + } + + private function validateRequest($request) + { + $CallableHttp = $request->txtcompany == 'pkb' + ? Http::arrahn() + : Http::arrahn_koop(); + + if ( + !is_array($request->txtnorujukanhidden) || + !is_array($request->txtbayaranhidden) || + !is_array($request->txtkodcawhidden) || + count($request->txtnorujukanhidden) !== count($request->txtbayaranhidden) || + count($request->txtnorujukanhidden) !== count($request->txtkodcawhidden) + ) { + Log::error('Jumlah bayaran, norujukan dan kod cawangan tidak sepadan.', [ + 'txtnorujukanhidden' => $request->txtnorujukanhidden, + 'txtbayaranhidden' => $request->txtbayaranhidden, + 'txtkodcawhidden' => $request->txtkodcawhidden, + ]); + return 'Sila Pilih Sekali Lagi.'; + } + + foreach ($request->txtnorujukanhidden as $index => $x) { + $array_gadai = $CallableHttp->get('/api/gadai/norujukan/' . $request->txtkodcawhidden[$index] . '/' . $x)->json(); + + if (empty($array_gadai)) { + Log::error('norujukan tidak dijumpai.', [ + 'norujukan' => $x, + 'kodcaw' => $request->txtkodcawhidden[$index], + ]); + + return 'Sila Pilih Sekali lagi. Dan pastikan salah satu sahaja dipilih untuk ruangan PKB dan KOPKB.'; + } + + $array_gadai = $array_gadai[0]; + if (in_array($array_gadai['sttebus'], ['T', 'L'])) { + Log::error('Norujukan sudah ditebus.', [ + 'norujukan' => $x, + 'kodcaw' => $request->txtkodcawhidden[$index], + ]); + return 'Norujukan' . $x . ' sudah ditebus.'; + }else{ + $payment = (float) $request->txtbayaranhidden[$index]; + $remain_loan = (float) $array_gadai['bakipjm']; + $nm = (float) $array_gadai['nilaimarhun']; + $profit = 0; + + $jenisKeuntungan = $array_gadai['tagbaru'] == '1' ? 'onepercent' : 'asal'; + + $upahTawarruq = $CallableHttp + ->get('/api/upahtawarruq/' . $array_gadai['kodcaw'] . '/' . $array_gadai['norujukan'], ['jeniskeuntungan' => $jenisKeuntungan]) + ->json(); + + if ($jenisKeuntungan == 'onepercent') { + $profit = $upahTawarruq['keuntungan'] + $upahTawarruq['ujrah']; + } + + if ($jenisKeuntungan == 'asal') { + $profit = $upahTawarruq; + } + + $item = ($remain_loan - ($nm * 0.1) + $profit); + + if ($payment > $item) { + return 'Baki Pembiayaan tidak boleh kurang 10% daripada Nilai Marhun!'; + } else if ($payment < $profit && $profit !== 0.00) { + return 'Bayaran tidak boleh kurang daripada keuntungan semasa!'; + } + else if ($payment == 0.00 && $profit == 0.00) { + return 'Bayaran tidak boleh dalam nilai 0.00'; + } + + } + } + + return null; + } + } diff --git a/app/Http/Controllers/BillplzController.php b/app/Http/Controllers/BillplzController.php index 0949e85..8a154cf 100644 --- a/app/Http/Controllers/BillplzController.php +++ b/app/Http/Controllers/BillplzController.php @@ -2,15 +2,39 @@ namespace App\Http\Controllers; +use App\Models\CompanyStatus; use App\Services\BillplzService; use Carbon\Carbon; use Illuminate\Http\Request; class BillplzController extends Controller { - public function __invoke(Request $request, BillplzService $billplzService) + public function __invoke(Request $request) { - $billIdArray = json_decode($request->bill_ids); - return $billplzService->getBills($billIdArray); + + $billplz_ids = json_decode($request->bill_ids, true); + + $account_own_by_PKB = array_filter($billplz_ids, fn($x) => $x['account_own_by'] == 'PKB'); + $account_own_by_KOPKB = array_filter($billplz_ids, fn($x) => $x['account_own_by'] == 'KOOP'); + + $bill_ids_PKB = array_map(fn($x) => $x['bill_id'], $account_own_by_PKB); + $bill_ids_PKB = array_values($bill_ids_PKB); + + $bill_ids_KOPKB = array_map(fn($x) => $x['bill_id'], $account_own_by_KOPKB); + $bill_ids_KOPKB = array_values($bill_ids_KOPKB); + + $getBillDetailFromBillplz = function($company_code, $bill_ids) { + $billplzService = new BillplzService($company_code); + return $billplzService->getBills($bill_ids); + }; + + $billDetailsKOPKB = $getBillDetailFromBillplz('KOPKB', $bill_ids_KOPKB); + $billDetailsPKB = $getBillDetailFromBillplz('PKB', $bill_ids_PKB); + + return [ + 'KOPKB' => $billDetailsKOPKB, + 'PKB' => $billDetailsPKB, + ]; + } } diff --git a/app/Http/Controllers/BillplzTransactionReviewController.php b/app/Http/Controllers/BillplzTransactionReviewController.php index 2817731..5160b32 100644 --- a/app/Http/Controllers/BillplzTransactionReviewController.php +++ b/app/Http/Controllers/BillplzTransactionReviewController.php @@ -2,26 +2,41 @@ namespace App\Http\Controllers; +use App\Models\CompanyStatus; use App\Services\BillplzService; use Carbon\Carbon; use Illuminate\Http\Request; class BillplzTransactionReviewController extends Controller { - public function index(Request $request, BillplzService $billplzService) + public function index(Request $request) { $date = $request->date ?? Carbon::now()->toDateString(); - $billplzTransactionReview = $billplzService->getBillplzTransactionReview($date); + $companyMapping = [ + 'PKB', + 'KOPKB', + ]; - return response()->json($billplzTransactionReview, 200); + $billplzTransactionReview = array_map(function($company_code) use($date){ + $billplzService = new BillplzService($company_code); + return $billplzService->getBillplzTransactionReview($date)->toArray(); + }, $companyMapping); + + return response()->json(array_merge(...$billplzTransactionReview), 200); } - public function show(Request $request, BillplzService $billplzService) + public function show(Request $request) { - $date = $request->date ?? Carbon::now()->toDateString(); - - $billplzTransactionReview = $billplzService->getBillplzTransactionReviewByBillId($request->bill_id); + $companyMapping = [ + 'PKB', + 'KOPKB', + ]; + + $billplzTransactionReview = array_map(function($company_code) use($request){ + $billplzService = new BillplzService($company_code); + return $billplzService->getBillplzTransactionReviewByBillId($request->bill_id)->toArray(); + }, $companyMapping); return response()->json($billplzTransactionReview, 200); } diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index ca3e5a2..b423b7b 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -30,12 +30,31 @@ class HomeController extends Controller { $homeUrl = route('home'); $authUser = Auth::user(); - $customerInfo = Http::withOptions(['verify' => config('app.api_verify')]) - ->get(config('api.url') . '/portal/customer/info', ['ic' => $authUser['icno']]) - ->json(); - ['gadai' => $customer_gadai, 'lelong' => $customer_lelong] = $customerInfo; + $responses = Http::pool(fn ($pool) => [ + $pool->withOptions(['verify' => config('app.api_verify')]) + ->get(config('api.url') . '/portal/customer/info', ['ic' => $authUser['icno']]), + + $pool->withOptions(['verify' => config('app.api_verify')]) + ->get(config('api.url_koop') . '/portal/customer/info', ['ic' => $authUser['icno']]), + ]); + $customer_pkb = $responses[0]->json(); + $customer_koop = $responses[1]->json(); + + $customerLelong = $this->getCustomerInfoLelong($authUser['icno']); + + // ['gadai' => $customer_gadai, 'lelong' => $customer_lelong] = $customerInfo; + $customer_gadai = array_merge( + $customer_pkb['gadai'] ?? [], + $customer_koop['gadai'] ?? [] + ); + + $customer_lelong = array_merge( + $customer_pkb['lelong'] ?? [], + $customer_koop['lelong'] ?? [] + ); + // only get lelong that is harga jualan that is not null or 0 $customer_lelong = array_filter($customer_lelong, fn($x) => $x['hargajualan'] != null && $x['hargajualan'] != 0); @@ -49,7 +68,7 @@ class HomeController extends Controller $bilangan = sizeof($customer_gadai) + sizeOf($customer_lelong); - return view('includes.buffer', compact('bilangan', 'sixMonths', 'total', 'bilanganLelong', 'homeUrl')); + return view('includes.buffer', compact('bilangan', 'sixMonths', 'total', 'bilanganLelong', 'homeUrl','customerLelong')); } /** @@ -62,12 +81,32 @@ class HomeController extends Controller $pembiayaan = $this->pembiayaanService->getPembiayaan($request->filter); $authUser = Auth::user(); - $customerInfo = Http::withOptions(['verify' => config('app.api_verify')]) - ->get(config('api.url') . '/portal/customer/info', ['ic' => $authUser['icno']]) - ->json(); - ['gadai' => $customer_gadai, 'lelong' => $customer_lelong] = $customerInfo; + $responses = Http::pool(fn ($pool) => [ + $pool->withOptions(['verify' => config('app.api_verify')]) + ->get(config('api.url') . '/portal/customer/info', ['ic' => $authUser['icno']]), + + $pool->withOptions(['verify' => config('app.api_verify')]) + ->get(config('api.url_koop') . '/portal/customer/info', ['ic' => $authUser['icno']]), + ]); + + $customer_pkb = $responses[0]->json(); + $customer_koop = $responses[1]->json(); + + + $customerLelong = $this->getCustomerInfoLelong($authUser['icno']); + // ['gadai' => $customer_gadai, 'lelong' => $customer_lelong] = $customerInfo; + + $customer_gadai = array_merge( + $customer_pkb['gadai'] ?? [], + $customer_koop['gadai'] ?? [] + ); + $customer_lelong = array_merge( + $customer_pkb['lelong'] ?? [], + $customer_koop['lelong'] ?? [] + ); + // only get lelong that is harga jualan that is not null or 0 $customer_lelong = array_filter($customer_lelong, fn($x) => $x['hargajualan'] != null && $x['hargajualan'] != 0); @@ -81,6 +120,33 @@ class HomeController extends Controller $bilangan = sizeof($customer_gadai) + sizeOf($customer_lelong); - return view('includes.home', compact('bilangan', 'sixMonths', 'total', 'bilanganLelong', 'pembiayaan')); + return view('includes.home', compact('bilangan', 'sixMonths', 'total', 'bilanganLelong', 'pembiayaan','customerLelong')); + } + + private function getCustomerInfoLelong($icno){ + $customerLelong = Http::withOptions(['verify' => config('app.api_verify')]) + ->get(config('api.url') . '/portal/customer/info/lelong', ['ic' => $icno]) + ->json(); + + $customerLelongKoop = Http::withOptions(['verify' => config('app.api_verify')]) + ->get(config('api.url_koop') . '/portal/customer/info/lelong', ['ic' => $icno]) + ->json(); + + // Extract data with null safety + $bakiLelong = isset($customerLelong['success']) && $customerLelong['success'] + ? ($customerLelong['data']['bakilelong'] ?? 0) : 0; + $rugiLelong = isset($customerLelong['success']) && $customerLelong['success'] + ? ($customerLelong['data']['rugilelong'] ?? 0) : 0; + + $bakiKoop = isset($customerLelongKoop['success']) && $customerLelongKoop['success'] + ? ($customerLelongKoop['data']['bakilelong'] ?? 0) : 0; + $rugiKoop = isset($customerLelongKoop['success']) && $customerLelongKoop['success'] + ? ($customerLelongKoop['data']['rugilelong'] ?? 0) : 0; + + // Calculate totals + $totalBakiLelong = $bakiLelong + $bakiKoop; + $totalRugiLelong = $rugiLelong + $rugiKoop; + + return ['rugilelong' => $totalRugiLelong, 'bakilelong' => $totalBakiLelong]; } } diff --git a/app/Http/Controllers/InformationController.php b/app/Http/Controllers/InformationController.php index ba8b16a..08e3f6d 100644 --- a/app/Http/Controllers/InformationController.php +++ b/app/Http/Controllers/InformationController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers; +use App\Models\CompanyStatus; use App\Models\LelongBid; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; @@ -30,17 +31,29 @@ class InformationController extends Controller { $auth_user = Auth::User(); - $CustomerInfo = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') .'/portal/customer/info',['ic' => $auth_user['icno']])->json(); + $customer_pkb = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') .'/portal/customer/info',['ic' => $auth_user['icno']])->json(); + $customer_koop = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url_koop') .'/portal/customer/info',['ic' => $auth_user['icno']])->json(); $pembiayaansemasa = []; - if(isset($CustomerInfo['gadai'])) - { - $pembiayaansemasa = $CustomerInfo['gadai']; + if(isset($customer_pkb['gadai'])){ + $pembiayaansemasa = array_map(function ($pkb) { + $pkb['tag_syarikat'] = CompanyStatus::COM_PKB; + return $pkb; + }, $customer_pkb['gadai']); } - if(isset($CustomerInfo['lelong'])){ - if(sizeof($CustomerInfo['lelong']) > 0){ - foreach($CustomerInfo['lelong'] as $index=>$lelong){ + if(isset($customer_koop['gadai'])){ + $array_koop = array_map(function ($koop) { + $koop['tag_syarikat'] = CompanyStatus::COM_KOOPPKB; + return $koop; + }, $customer_koop['gadai']); + $pembiayaansemasa = array_merge($pembiayaansemasa,$array_koop); + } + + if(isset($customer_pkb['lelong'])){ + if(sizeof($customer_pkb['lelong']) > 0){ + foreach($customer_pkb['lelong'] as $index=>$lelong){ + $customer_pkb['lelong'][$index]['tag_syarikat'] = CompanyStatus::COM_KOOPPKB; $array_lelong = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api-lelong.url') . '/api/portalApi',['norujukan' => $lelong['norujukan']])->json(); if($array_lelong === null){ @@ -48,13 +61,35 @@ class InformationController extends Controller } if($array_lelong['lelong'] !== null){ - $CustomerInfo['lelong'][$index] = collect($lelong)->merge($array_lelong['lelong'])->toArray(); + $array_lelong['lelong']['tag_syarikat'] = CompanyStatus::COM_PKB; + $customer_pkb['lelong'][$index] = collect($lelong)->merge($array_lelong['lelong'])->toArray(); } } - $pembiayaansemasa = collect($pembiayaansemasa)->merge($CustomerInfo['lelong']); - $pembiayaansemasa = $pembiayaansemasa->toArray(); + $pembiayaansemasa = collect($pembiayaansemasa)->merge($customer_pkb['lelong']); + $pembiayaansemasa = $pembiayaansemasa->toArray(); } } + + if(isset($customer_koop['lelong'])){ + if(sizeof($customer_koop['lelong']) > 0){ + foreach($customer_koop['lelong'] as $index=>$lelong){ + $customer_koop['lelong'][$index]['tag_syarikat'] = CompanyStatus::COM_KOOPPKB; + $array_lelong = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api-lelong.url_koop') . '/api/portalApi',['norujukan' => $lelong['norujukan']])->json(); + + if($array_lelong === null){ + continue; + } + + if($array_lelong['lelong'] !== null){ + $array_lelong['lelong']['tag_syarikat'] = CompanyStatus::COM_KOOPPKB; + $customer_koop['lelong'][$index] = collect($lelong)->merge($array_lelong['lelong'])->toArray(); + } + } + $pembiayaansemasa = collect($pembiayaansemasa)->merge($customer_koop['lelong']); + $pembiayaansemasa = $pembiayaansemasa->toArray(); + } + } + return response()->json($pembiayaansemasa,200); // return view('includes.information.pembiayaanaktif',compact('pembiayaansemasa')); } @@ -63,14 +98,16 @@ class InformationController extends Controller { $auth_user = Auth::User(); - $CustomerInfo = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') .'/portal/customer/info',['ic' => $auth_user['icno']])->json(); + $customer_pkb = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') .'/portal/customer/info',['ic' => $auth_user['icno']])->json(); + $customer_koop = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url_koop') .'/portal/customer/info',['ic' => $auth_user['icno']])->json(); $melebihi6bulan = []; - if(isset($CustomerInfo['gadai'])) + if(isset($customer_pkb['gadai'])) { - foreach($CustomerInfo['gadai'] as $index=>$gadai) + foreach($customer_pkb['gadai'] as $index=>$gadai) { + $gadai['tag_syarikat'] = CompanyStatus::COM_PKB; if($gadai['tempoh'] >= 6) { array_push($melebihi6bulan,$gadai); @@ -78,6 +115,21 @@ class InformationController extends Controller } } + if(isset($customer_koop['gadai'])) + { + foreach($customer_koop['gadai'] as $index=>$gadai) + { + $gadai['tag_syarikat'] = CompanyStatus::COM_KOOPPKB; + + if($gadai['tempoh'] >= 6) + { + array_push($melebihi6bulan,$gadai); + } + } + } + + + return response()->json($melebihi6bulan,200); // return view('includes.information.melebihi6bulan',compact('melebihi6bulan')); } @@ -86,12 +138,13 @@ class InformationController extends Controller { $auth_user = Auth::User(); - $CustomerInfo = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') .'/portal/customer/info',['ic' => $auth_user['icno']])->json(); + $customer_pkb = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') .'/portal/customer/info',['ic' => $auth_user['icno']])->json(); + $customer_koop = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url_koop') .'/portal/customer/info',['ic' => $auth_user['icno']])->json(); $lelong = []; - if(isset($CustomerInfo['lelong'])){ - if(sizeof($CustomerInfo['lelong']) > 0){ - foreach($CustomerInfo['lelong'] as $index=>$lel){ + if(isset($customer_pkb['lelong'])){ + if(sizeof($customer_pkb['lelong']) > 0){ + foreach($customer_pkb['lelong'] as $index=>$lel){ $array_lelong = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api-lelong.url') . '/api/portalApi',['norujukan' => $lel['norujukan']])->json(); if($array_lelong === null){ @@ -99,11 +152,31 @@ class InformationController extends Controller } if($array_lelong['lelong'] !== null){ - $CustomerInfo['lelong'][$index] = collect($lel)->merge($array_lelong['lelong'])->toArray(); + $array_lelong['lelong']['tag_syarikat'] = CompanyStatus::COM_PKB; + $customer_pkb['lelong'][$index] = collect($lel)->merge($array_lelong['lelong'])->toArray(); } } - $lelong = collect($lelong)->merge($CustomerInfo['lelong']); - $lelong = $lelong->toArray(); + $lelong = collect($lelong)->merge($customer_pkb['lelong']); + $lelong = $lelong->toArray(); + } + } + + if(isset($customer_koop['lelong'])){ + if(sizeof($customer_koop['lelong']) > 0){ + foreach($customer_koop['lelong'] as $index=>$lel){ + $array_lelong = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api-lelong.url') . '/api/portalApi',['norujukan' => $lel['norujukan']])->json(); + + if($array_lelong === null){ + continue; + } + + if($array_lelong['lelong'] !== null){ + $array_lelong['lelong']['tag_syarikat'] = CompanyStatus::COM_KOOPPKB; + $customer_koop['lelong'][$index] = collect($lel)->merge($array_lelong['lelong'])->toArray(); + } + } + $lelong = collect($lelong)->merge($customer_koop['lelong']); + $lelong = $lelong->toArray(); } } diff --git a/app/Http/Controllers/SemakController.php b/app/Http/Controllers/SemakController.php index e08c346..eeeda6f 100644 --- a/app/Http/Controllers/SemakController.php +++ b/app/Http/Controllers/SemakController.php @@ -154,22 +154,31 @@ class SemakController extends Controller return view('resit.resittebus',compact('transaction','gadai','cawangan_info','customers_info','penebusan','wakil','totaltransaction','totalBayaranAnsuran')); } - public function resit($id) + public function resit($id,$company) { + $setapi = $company == 1 + ? config('api.url') + : config('api.url_koop'); + $totaltransaction = 0; - $transaction = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') . '/api/transaction/id/'. $id)->json(); + $transaction = Http::withOptions(['verify' => config('app.api_verify')])->get($setapi . '/api/transaction/id/'. $id)->json(); if(sizeof($transaction) != 0) $transaction = $transaction[0]; - $gadai = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') . '/api/gadai/norujukan/'. $transaction['norujukan'])->json(); + if($transaction['nokp'] != Auth::user()->icno) + { + return response('not allowed', 403); + } + + $gadai = Http::withOptions(['verify' => config('app.api_verify')])->get($setapi . '/api/gadai/norujukan/'. $transaction['norujukan'])->json(); if(sizeof($gadai) != 0) $gadai = $gadai[0][0]; - $customers_info = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') . '/api/customers/'. $gadai['nokp'])->json(); + $customers_info = Http::withOptions(['verify' => config('app.api_verify')])->get($setapi . '/api/customers/'. $gadai['nokp'])->json(); // if(sizeof($customers_info) != 0) // $customers_info = $customers_info[0]; diff --git a/app/Http/Controllers/TacController.php b/app/Http/Controllers/TacController.php index 7555861..503d4c7 100644 --- a/app/Http/Controllers/TacController.php +++ b/app/Http/Controllers/TacController.php @@ -16,12 +16,9 @@ class TacController extends Controller $tac = tacportal::where([['icno',$request->icno],['tac_no',$request->tac]])->get()->toArray(); if($tac){ - $CustomerInfo = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') .'/api/customers/' . $request->icno)->json(); - $poskod = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') . '/api/poskod/' . $CustomerInfo['poskod'])->json(); - $daerah = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') .'/api/daerah/' . $poskod['koddaerah'])->json(); - $negeri =Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') .'/api/negeri/' . $poskod['kodnegeri'])->json(); - - return response(['status' => 1, 'customerinfo' => $CustomerInfo,'namadaerah' => $daerah['namadaerah'],'namanegeri' => $negeri['negeri']]); + $request->session()->put('registerlog_tac_entered', true); + $DetailsCustomer = $this->getCustomerData($request->icno, true); + return response(['status' => 1, 'customerinfo' => $DetailsCustomer['customerinfo'],'namadaerah' => $DetailsCustomer['daerah']['namadaerah'],'namanegeri' => $DetailsCustomer['negeri']['negeri']]); }else{ return response(['status' => 0]); } @@ -64,8 +61,8 @@ class TacController extends Controller return response(['message' => true]); } - $CustomerInfo = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') .'/api/customers/' . $request->icno)->json(); - + $CustomerInfo = $this->getCustomerData($request->icno, false); + if($CustomerInfo) { $generatestatus = $this->generateTAC($CustomerInfo); @@ -98,7 +95,7 @@ class TacController extends Controller } - $CustomerInfo = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') .'/api/customers/' . $request->icno)->json(); + $CustomerInfo = $this->getCustomerData($request->icno, false); if($CustomerInfo) { @@ -174,6 +171,33 @@ class TacController extends Controller return implode('',$num); } + + private function getCustomerData($icno,$details = false){ + $CustomerInfo_PKB = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') .'/api/customers/' . $icno)->json(); + $CustomerInfo_KOOPKB = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url_koop') .'/api/customers/' . $icno)->json(); + + if($CustomerInfo_KOOPKB){ + if($details == true){ + $poskod = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') . '/api/poskod/' . $CustomerInfo_KOOPKB['poskod'])->json(); + $daerah = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') .'/api/daerah/' . $poskod['koddaerah'])->json(); + $negeri =Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') .'/api/negeri/' . $poskod['kodnegeri'])->json(); + return ['customerinfo' => $CustomerInfo_KOOPKB,'poskod' => $poskod,'daerah' => $daerah,'negeri' => $negeri]; + } + $CustomerInfo = $CustomerInfo_KOOPKB; + }else if($CustomerInfo_PKB){ + if($details == true){ + $poskod = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url_koop') . '/api/poskod/' . $CustomerInfo_PKB['poskod'])->json(); + $daerah = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url_koop') .'/api/daerah/' . $poskod['koddaerah'])->json(); + $negeri =Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url_koop') .'/api/negeri/' . $poskod['kodnegeri'])->json(); + return ['customerinfo' => $CustomerInfo_PKB,'poskod' => $poskod,'daerah' => $daerah,'negeri' => $negeri]; + } + $CustomerInfo = $CustomerInfo_PKB; + }else{ + $CustomerInfo = null; + } + + return $CustomerInfo; + } } diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 30020a5..3f1d4d7 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -4,6 +4,7 @@ namespace App\Http; use Illuminate\Foundation\Http\Kernel as HttpKernel; + class Kernel extends HttpKernel { /** @@ -62,5 +63,8 @@ class Kernel extends HttpKernel 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, + 'logauth' => \App\Http\Middleware\LogViewerPassword::class, + 'registerauth' => \App\Http\Middleware\RegisterLog::class, + ]; } diff --git a/app/Http/Middleware/LogViewerPassword.php b/app/Http/Middleware/LogViewerPassword.php new file mode 100644 index 0000000..d4e59ee --- /dev/null +++ b/app/Http/Middleware/LogViewerPassword.php @@ -0,0 +1,33 @@ +session()->get('logviewer_authenticated'); + $authenticatedAt = $request->session()->get('logviewer_authenticated_at'); + + if (!$isAuthenticated) { + return redirect()->route('log-login'); + } + + if(now()->diffInMinutes($authenticatedAt) > env('LOGVIEWER_SESSION_MINUTES', 10)) { + $request->session()->forget(['logviewer_authenticated', 'logviewer_authenticated_at']); + return redirect()->route('log-login')->with('error', 'Session expired. Please log in again.'); + } + + return $next($request); + } +} diff --git a/app/Http/Middleware/RegisterLog.php b/app/Http/Middleware/RegisterLog.php new file mode 100644 index 0000000..79f86b5 --- /dev/null +++ b/app/Http/Middleware/RegisterLog.php @@ -0,0 +1,30 @@ +all(); + $isAuthenticated = $request->session()->pull('registerlog_tac_entered'); + + $sizeofData = count($isEntered); + + if($isAuthenticated == false || $sizeofData == 0) { + return redirect()->route('login'); + } + + return $next($request); + } +} diff --git a/app/Http/Middleware/VerifyCsrfToken.php b/app/Http/Middleware/VerifyCsrfToken.php index b98b02e..af67ef1 100644 --- a/app/Http/Middleware/VerifyCsrfToken.php +++ b/app/Http/Middleware/VerifyCsrfToken.php @@ -3,6 +3,7 @@ namespace App\Http\Middleware; use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware; +use Illuminate\Session\TokenMismatchException; class VerifyCsrfToken extends Middleware { @@ -11,7 +12,19 @@ class VerifyCsrfToken extends Middleware * * @var array */ - protected $except = [ + + protected $except = [ '/pembayaran/backend' ]; + + public function handle($request, \Closure $next) + { + try { + return parent::handle($request, $next); + } catch (TokenMismatchException $e) { + // Redirect to login page if CSRF token is invalid + return redirect()->route('login')->with('logsemula', 'Sesi anda telah tamat. Sila log masuk semula.'); + } + } + } diff --git a/app/Http/Requests/PaymentRequest.php b/app/Http/Requests/PaymentRequest.php index ff4fed0..a0cf18a 100644 --- a/app/Http/Requests/PaymentRequest.php +++ b/app/Http/Requests/PaymentRequest.php @@ -3,6 +3,7 @@ namespace App\Http\Requests; use App\Http\Controllers\InformationController; +use App\Models\CompanyStatus; use App\Rules\PaymentRules\CawanganPermitUjrahPayment; use App\Rules\PaymentRules\NorujukanBukanFasa2; use App\Rules\PaymentRules\NorujukanContractNotExceed12Month; @@ -53,9 +54,33 @@ class PaymentRequest extends FormRequest public function getPembiayaanFromNorujukan() { + if(null !== $this->input('redirect_trolley') && $this->input('redirect_trolley') == 'trolley'){ + return []; + } + $norujukanList = json_decode($this->totalSagInCartInput); + $syarikatList = json_decode($this->listSyarikatinCartInput); - return array_map(fn($x) => Http::arrahn()->get('/api/gadai/norujukan/' . $x)->json()[0][0], $norujukanList); + $filterByStatus = function ($status) use ($norujukanList, $syarikatList) { + return array_filter( + array_map(function ($sag, $index) use ($syarikatList, $status) { + if (isset($syarikatList[$index]) && $syarikatList[$index] == $status) { + $HttpRequest = $status == CompanyStatus::COM_PKB ? Http::arrahn() : Http::arrahn_koop(); + $array_temp = $HttpRequest->get('/api/gadai/norujukan/' . $sag)->json()[0][0] ?? null; + $array_temp['tag_syarikat'] = $status; + return $array_temp; + } + return null; + }, $norujukanList, array_keys($norujukanList)) + ); + }; + + $list_pkb = $filterByStatus(CompanyStatus::COM_PKB); + $list_koop = $filterByStatus(CompanyStatus::COM_KOOPPKB); + + $array_merged_list = array_merge($list_pkb,$list_koop); + return $array_merged_list; + // return array_map(fn($x) => Http::arrahn()->get('/api/gadai/norujukan/' . $x)->json()[0][0], $norujukanList); } public function getPembiayaanAkanDilelong() diff --git a/app/Models/CompanyStatus.php b/app/Models/CompanyStatus.php new file mode 100644 index 0000000..ad1d728 --- /dev/null +++ b/app/Models/CompanyStatus.php @@ -0,0 +1,11 @@ + 'array', + 'list_koop' => 'array', + ]; + + protected $guarded = [ + 'id', + 'ic_no', + 'list_pkb', + 'list_koop', + 'status_pkb', + 'status_koop', + 'payment_pkb', + 'payment_koop', + 'user_id', + 'created_at', + 'updated_at' + ]; + + public $timestamps = true; +} diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index c94b6e1..93bb34e 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -28,11 +28,21 @@ class AppServiceProvider extends ServiceProvider Http::macro('arrahn', function () { return Http::withOptions(['verify' => config('app.api_verify')])->baseUrl(config('api.url')); }); + + Http::macro('arrahn_koop', function () { + return Http::withOptions(['verify' => config('app.api_verify')])->baseUrl(config('api.url_koop')); + }); PendingRequest::macro('arrahn', function () { $this->options['verify'] = config('app.api_verify'); $this->baseUrl(config('api.url')); return $this; }); + + PendingRequest::macro('arrahn_koop', function () { + $this->options['verify'] = config('app.api_verify'); + $this->baseUrl(config('api.url_koop')); + return $this; + }); } } diff --git a/app/Rules/PaymentRules/NorujukanTidakAkanDilelong.php b/app/Rules/PaymentRules/NorujukanTidakAkanDilelong.php index 5fa9d95..a521e6f 100644 --- a/app/Rules/PaymentRules/NorujukanTidakAkanDilelong.php +++ b/app/Rules/PaymentRules/NorujukanTidakAkanDilelong.php @@ -36,7 +36,7 @@ class NorujukanTidakAkanDilelong implements Rule $tarikhLelong = Carbon::parse($x->t_lelong); $currentDate = Carbon::now(); - if ($currentDate->gte($tarikhLelong->subDays(3))) { + if ($currentDate->gte($tarikhLelong->subDays(2))) { return true; } diff --git a/app/Services/BayaranHistoryService.php b/app/Services/BayaranHistoryService.php index 7dddd15..b1c86ff 100644 --- a/app/Services/BayaranHistoryService.php +++ b/app/Services/BayaranHistoryService.php @@ -2,6 +2,7 @@ namespace App\Services; +use App\Models\CompanyStatus; use Illuminate\Http\Client\Pool; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Http; @@ -14,17 +15,21 @@ class BayaranHistoryService $this->norujukan = $norujukan; } - public function getBayaranHistory() + public function getBayaranHistory($tagsyarikat) { - $bayaranHistory = Http::arrahn()->get('/api/transaction/'. $this->norujukan)->json(); + $CallableHttp = $tagsyarikat == CompanyStatus::COM_PKB + ? Http::arrahn() + : Http::arrahn_koop(); - $formatBayaranHistoryData = function ($x) { + $bayaranHistory = $CallableHttp->get('/api/transaction/'. $this->norujukan)->json(); + + $formatBayaranHistoryData = function ($x) use($tagsyarikat) { if (sizeof($x) === 0) { return $x; } $formatDate = fn($x) => Carbon::parse($x)->format('d/m/Y'); - $setResitAnsuranLink = fn($x) => route("resit.ansuran", $x); + $setResitAnsuranLink = fn($x) => route("resit.ansuran", ['id' => $x, 'company' => $tagsyarikat]); return array_map(function ($y) use ($formatDate, $setResitAnsuranLink) { $y['created_at'] = $formatDate($y['created_at']); diff --git a/app/Services/BillplzService.php b/app/Services/BillplzService.php index ae853f9..ae2ed79 100644 --- a/app/Services/BillplzService.php +++ b/app/Services/BillplzService.php @@ -6,6 +6,8 @@ use App\Models\TransactionOnlineStatus; use Billplz\Client; use Carbon\Carbon; use Illuminate\Support\Facades\Http; +use Illuminate\Support\Facades\Log; +use Illuminate\Support\Facades\Session; class BillplzService { @@ -14,24 +16,14 @@ class BillplzService public $callbackUrl; public $paymentTitle; public $redirectUrl; + public $company; - public function __construct() + public function __construct(string $company) { - $appEnvironment = config('app.env'); - $billplzConfig = $appEnvironment == 'production' ? config('services.billplz.production') : config('services.billplz.sandbox'); - - $client = Client::make($billplzConfig['api_key'], $billplzConfig['x_signature']); - $client->useVersion('v4'); - - if ($appEnvironment != 'production') { - $client->useSandbox(); - } - - $this->callbackUrl = route('pay.callback'); - $this->redirectUrl = ['redirect_url' => route('pay.paymentStatus')]; - $this->paymentTitle = "Pembayaran Ansuran"; - $this->config = $billplzConfig; - $this->client = $client; + $this->company = $company; + $this->setupBillplzClient($company); + $this->setupUrls(); + $this->paymentTitle = config('services.billplz.paymentTitle'); } public function getCollections() @@ -39,8 +31,9 @@ class BillplzService return $this->client->collection()->all()->toArray(); } - public function createBill(array $data) + public function createBill(array $data,string $company) { + $composed_data = [ $this->config['collection_id'], ...$data, @@ -94,6 +87,8 @@ class BillplzService public function webhook($request) { + // $this->setCompany(Session::get('company')); + // $this->setupBillplzClient($this->company); try { $response = $this->client->webhook($request); @@ -114,7 +109,14 @@ class BillplzService $billplzID = collect($arrahnTransactions)->pluck('billplz_id')->unique()->values(); $billplzTransactions = collect($billplzID)->map(function ($billId) { - return $this->client->transaction()->get($billId)->toArray(); + try { + return $this->client->transaction()->get($billId)->toArray(); + } catch (\Exception $e) { + return []; + } + }) + ->filter(function ($transaction) { + return $transaction !== []; }) ->map(function ($data) { $latestTransaction = reset($data['transactions']) == false ? [] : reset($data['transactions']); @@ -131,7 +133,14 @@ class BillplzService $billplzID = collect([$billId]); $billplzTransactions = collect($billplzID)->map(function ($billId) { - return $this->client->transaction()->get($billId)->toArray(); + try { + return $this->client->transaction()->get($billId)->toArray(); + } catch (\Exception $e) { + return []; + } + }) + ->filter(function ($transaction) { + return $transaction !== []; }) ->map(function ($data) { $latestTransaction = reset($data['transactions']) == false ? [] : reset($data['transactions']); @@ -145,13 +154,21 @@ class BillplzService public function getArrahnTransactions($queryData) { + $query_all = []; + if(isset($queryData['date'])){ - return Http::arrahn()->get('/api/transaction/online/query', ['date' => $queryData['date']])->json(); + $pkb_query = Http::arrahn()->get('/api/transaction/online/query', ['date' => $queryData['date']])->json(); + $koop_query = Http::arrahn_koop()->get('/api/transaction/online/query', ['date' => $queryData['date']])->json(); + $query_all = array_merge($pkb_query,$koop_query); } if(isset($queryData['billId'])){ - return Http::arrahn()->get('/api/transaction/online/query', ['billId' => $queryData['billId']])->json(); + $pkb_query = Http::arrahn()->get('/api/transaction/online/query', ['billId' => $queryData['billId']])->json(); + $koop_query = Http::arrahn_koop()->get('/api/transaction/online/query', ['billId' => $queryData['billId']])->json(); + $query_all = array_merge($pkb_query,$koop_query); } + + return $query_all; } public function getBillplzTransactionReview($date) @@ -194,6 +211,15 @@ class BillplzService return $data; }); + + $summarizedBillplzTransactions = $summarizedBillplzTransactions + ->filter(function($x){ + return $x['billplz_latest_transaction'] !== null; + }) + ->filter(function($x){ + return array_key_exists('completed_at', $x['billplz_latest_transaction']); + }); + return $summarizedBillplzTransactions; } @@ -237,10 +263,24 @@ class BillplzService return $summarizedBillplzTransactions; } - public function getTransactionByBillId($billId) + public function getTransactionByBillId($billId,$company) { + $appEnvironment = config('app.env'); + + $billplzEnvironments = [ + 'PKB' => ($appEnvironment === 'production') ? config('services.billplz.production') : config('services.billplz.sandbox'), + 'KOPKB' => ($appEnvironment === 'production') ? config('services.billplz.production_kopkb') : config('services.billplz.sandbox_kopkb'), + ]; + + $billplzConfig = $appEnvironment === 'production' + ? ($billplzEnvironments[$company] ?? config('services.billplz.production')) + : ($billplzEnvironments[$company] ?? config('services.billplz.sandbox')); + + $client = Client::make($billplzConfig['api_key'], ($this->isBase64($billplzConfig['x_signature'])) ? $billplzConfig['x_signature'] : base64_encode($billplzConfig['x_signature'])); + $client->useVersion('v4'); + try { - return $this->client->bill()->transaction($billId)->toArray(); + return $client->bill()->transaction($billId)->toArray(); } catch (\Throwable $th) { logger()->error('Error when querying billplz id : ' . $billId); logger()->error($th->getMessage()); @@ -250,6 +290,69 @@ class BillplzService public function getBills($billIds) { - return array_map(fn($x) => $this->client->bill()->get($x)->toArray(), $billIds); + return array_map(function($x){ + try{ + return $this->client->bill()->get($x)->toArray(); + }catch(\Exception $e){ + return []; + } + }, $billIds); + } + + protected function setupBillplzClient($company) + { + $appEnvironment = config('app.env'); + + $billplzEnvironments = [ + 'PKB' => ($appEnvironment === 'production') ? config('services.billplz.production') : config('services.billplz.sandbox'), + 'KOPKB' => ($appEnvironment === 'production') ? config('services.billplz.production_kopkb') : config('services.billplz.sandbox_kopkb'), + ]; + + $billplzConfig = $appEnvironment === 'production' + ? ($billplzEnvironments[$company] ?? config('services.billplz.production')) + : ($billplzEnvironments[$company] ?? config('services.billplz.sandbox')); + + $client = Client::make($billplzConfig['api_key'], ($this->isBase64($billplzConfig['x_signature'])) ? $billplzConfig['x_signature'] : base64_encode($billplzConfig['x_signature'])); + $client->useVersion('v4'); + + if ($appEnvironment !== 'production') { + $client->useSandbox(); + } + + $this->config = $billplzConfig; + $this->client = $client; + } + + protected function setupUrls() + { + $this->callbackUrl = route('pay.callback'); + $this->redirectUrl = ['redirect_url' => route('pay.paymentStatus')]; + } + + protected function isBase64($string) { + if($this->isBase64UrlSafe($string)){ + return true; + } + + if (preg_match('/^[A-Za-z0-9+\/=]+$/', $string)) { + return base64_encode(base64_decode($string, true)) === $string; + } + return false; + } + + protected function isBase64UrlSafe($string) { + // Convert URL-safe Base64 to standard Base64 + $standardBase64 = str_replace(['-', '_'], ['+', '/'], $string); + + // Add padding if necessary + $remainder = strlen($standardBase64) % 4; + if ($remainder > 0) { + $standardBase64 .= str_repeat('=', 4 - $remainder); + } + + // Attempt to decode the string + $decoded = base64_decode($standardBase64, true); + + return $decoded !== false; // Return true if it successfully decodes } } diff --git a/app/Services/MarhunService.php b/app/Services/MarhunService.php index 6a7d99c..f154ab1 100644 --- a/app/Services/MarhunService.php +++ b/app/Services/MarhunService.php @@ -2,6 +2,7 @@ namespace App\Services; +use App\Models\CompanyStatus; use Illuminate\Support\Facades\Http; class MarhunService @@ -12,14 +13,18 @@ class MarhunService $this->norujukan = $norujukan; } - public function getMarhunDetails() + public function getMarhunDetails($tagsyarikat) { - $getMarhunDetails = function ($x) { - return Http::arrahn()->get('/api/marhun/' . $x)->json(); + $CallableHttp = $tagsyarikat == CompanyStatus::COM_PKB + ? Http::arrahn() + : Http::arrahn_koop(); + + $getMarhunDetails = function ($x) use($CallableHttp) { + return $CallableHttp->get('/api/marhun/' . $x)->json(); }; - $getMarhunTypeFullName = function ($code) { - return Http::arrahn()->get('/api/jemas/nama_marhun', ['marhun' => $code['marhun']])->json()['descpt']; + $getMarhunTypeFullName = function ($code) use($CallableHttp) { + return $CallableHttp->get('/api/jemas/nama_marhun', ['marhun' => $code['marhun']])->json()['descpt']; }; $formatMarhunDetailData = function ($x) use($getMarhunTypeFullName) { diff --git a/app/Services/PembiayaanService.php b/app/Services/PembiayaanService.php index 610bfcd..d434697 100644 --- a/app/Services/PembiayaanService.php +++ b/app/Services/PembiayaanService.php @@ -3,9 +3,11 @@ namespace App\Services; use App\Http\Controllers\InformationController; +use App\Models\CompanyStatus; use Illuminate\Http\Client\Pool; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Http; +use Illuminate\Support\Facades\Log; class PembiayaanService { @@ -23,6 +25,9 @@ class PembiayaanService } $pembiayaan = array_filter($getPembiayaan(), fn($x) => $x->hargajualan != null || $x->hargajualan != 0); + // $pembiayaan_filter = array_filter($getPembiayaan(),fn($x) => $x->tag_syarikat == CompanyStatus::COM_PKB); + // $pembiayaan_koop = array_filter($getPembiayaan(),fn($x) => $x->tag_syarikat == CompanyStatus::COM_PKB); + $pembiayaan = $this->setUpahTawarruq($pembiayaan); $pembiayaan = $this->formatPembiayaanData($pembiayaan); $pembiayaan = $this->checkPembiayaanPaymentDisabled($pembiayaan); @@ -44,7 +49,12 @@ class PembiayaanService $getUpahTawarruqPerPembiayaan = function ($x) use ($getJenisKeuntungan) { $jenisKeuntungan = $getJenisKeuntungan($x); - $upahTawarruq = Http::arrahn()->get('/api/upahtawarruq/' . $x->kodcaw . '/' . $x->norujukan, ['jeniskeuntungan' => $jenisKeuntungan])->json(); + + $CallableHttp = $x->tag_syarikat == CompanyStatus::COM_PKB + ? Http::arrahn() + : Http::arrahn_koop(); + + $upahTawarruq = $CallableHttp->get('/api/upahtawarruq/' . $x->kodcaw . '/' . $x->norujukan, ['jeniskeuntungan' => $jenisKeuntungan])->json(); if ($jenisKeuntungan == 'onepercent') { $x->upah_tawarruq = $upahTawarruq['keuntungan'] + $upahTawarruq['ujrah']; @@ -62,7 +72,10 @@ class PembiayaanService private function formatPembiayaanData($pembiayaan) { - $allCawangan = Http::arrahn()->get('/api/cawangan')->json(); + $arrahnCawangan = Http::arrahn()->get('/api/cawangan')->json(); + $arrahnKoopCawangan = Http::arrahn_koop()->get('/api/cawangan')->json(); + + $allCawangan = array_merge($arrahnCawangan, $arrahnKoopCawangan); $setCawanganFullName = function ($pembiayaan) use ($allCawangan) { $cawangan = array_filter($allCawangan, fn($x) => $x['kodcaw'] === $pembiayaan->kodcaw); @@ -100,36 +113,51 @@ class PembiayaanService return $formatted; } - public function getMarhunModalData($norujukan) + public function getMarhunModalData($norujukan,$tagsyarikat) { - $gadaianDetails = Http::arrahn()->get('/api/gadai/norujukan/' . $norujukan)->json()[0][0]; - - $attachCawanganName = function ($x) use ($gadaianDetails) { - $x['cawangan_name'] = Http::arrahn()->get('/api/cawangan/detail/' . $gadaianDetails['kodcaw'])->json()[0]['cawangan']; - return $x; - }; - - $gadaianDetails = $attachCawanganName($gadaianDetails); - - $marhunDetails = MarhunService::from($norujukan)->getMarhunDetails(); - - $bayaranHistoryDetails = BayaranHistoryService::from($norujukan)->getBayaranHistory(); - - - return [ - 'gadaianDetails' => $gadaianDetails, - 'marhunDetails' => $marhunDetails, - 'bayaranHistoryDetails' => $bayaranHistoryDetails, - ]; + try{ + $CallableHttp = $tagsyarikat == CompanyStatus::COM_PKB + ? Http::arrahn() + : Http::arrahn_koop(); + + $gadaianDetails = $CallableHttp->get('/api/gadai/norujukan/' . $norujukan)->json()[0][0]; + + $attachCawanganName = function ($x) use ($gadaianDetails,$CallableHttp) { + $x['cawangan_name'] = $CallableHttp->get('/api/cawangan/detail/' . $gadaianDetails['kodcaw'])->json()[0]['cawangan']; + return $x; + }; + + $gadaianDetails = $attachCawanganName($gadaianDetails); + + $marhunDetails = MarhunService::from($norujukan)->getMarhunDetails($tagsyarikat); + + $bayaranHistoryDetails = BayaranHistoryService::from($norujukan)->getBayaranHistory($tagsyarikat); + + + return [ + 'gadaianDetails' => $gadaianDetails, + 'marhunDetails' => $marhunDetails, + 'bayaranHistoryDetails' => $bayaranHistoryDetails, + ]; + }catch(\Exception $e){ + Log::debug('norujukan:' . $norujukan); + Log::debug('tagsyarikat:' . $tagsyarikat); + Log::debug('error message:' . $e->getMessage()); + return [ + 'gadaianDetails' => [], + 'marhunDetails' => [], + 'bayaranHistoryDetails' => [], + ]; + } } private function getNorujukanRecentlyAttemptPayment($norujukanList) { $getRecentlyAttemptPayment = function () use ($norujukanList) { return Http::pool(function (Pool $pool) use ($norujukanList) { - foreach ($norujukanList as $norujukan) { - $pool->get(config('api.url') . '/portal/searchsagonline/', ['norujukan' => $norujukan]); + foreach ($norujukanList as $list) { + $pool->get(($list['tag_syarikat'] == CompanyStatus::COM_PKB ? config('api.url') : config('api.url_koop')) . '/portal/searchsagonline/', ['norujukan' => $list['norujukan']]); } }); }; @@ -150,18 +178,21 @@ class PembiayaanService } private function checkPembiayaanPaymentDisabled($pembiayaan) - { - $norujukanList = array_map(fn($x) => $x->norujukan, $pembiayaan); + { + $norujukanList = array_map(fn($x) => [ + 'tag_syarikat' => $x->tag_syarikat, + 'norujukan' => $x->norujukan, + ], $pembiayaan); $norujukanRecentlyAttemptPayment = $this->getNorujukanRecentlyAttemptPayment($norujukanList); $getPembiayaanAkanDilelong = fn() => (new InformationController())->pembiayaanakandilelong()->getData(); - $isCurrentDateGreaterThanEqual3DaysBeforeLelong = function ($x) { + $isCurrentDateGreaterThanEqual2DaysBeforeLelong = function ($x) { $tarikhLelong = Carbon::parse($x->t_lelong); $currentDate = Carbon::now(); - if ($currentDate->gte($tarikhLelong->subDays(3))) { + if ($currentDate->gte($tarikhLelong->subDays(2))) { return true; } @@ -169,7 +200,7 @@ class PembiayaanService }; - $pembiayaanAkanDilelong = array_filter($getPembiayaanAkanDilelong(), $isCurrentDateGreaterThanEqual3DaysBeforeLelong); + $pembiayaanAkanDilelong = array_filter($getPembiayaanAkanDilelong(), $isCurrentDateGreaterThanEqual2DaysBeforeLelong); $norujukanAkanDilelong = array_map(fn($x) => $x->norujukan, $pembiayaanAkanDilelong); @@ -189,6 +220,7 @@ class PembiayaanService $kodCawanganBranchesNotPermitPaymentUjrah = array_map(fn($x) => $x['kodcaw'], $branchesNotPermitPaymentUjrah); $isNorujukanPaymentRecentlyAttempted = function ($x) use ($norujukanRecentlyAttemptPayment) { + $norujukanRecentlyAttemptPayment = array_column($norujukanRecentlyAttemptPayment, 'norujukan'); return in_array($x->norujukan, $norujukanRecentlyAttemptPayment); }; @@ -240,7 +272,15 @@ class PembiayaanService return in_array($x->norujukan, $norujukanExcludeList); }; - return array_map(function ($x) use ($isNorujukanPaymentRecentlyAttempted, $isNorujukanAkanDilelong, $isNorujukanIsInFasa2, $isCawanganNotPermitUjrahPayment, $checkExcludePaymentList) { + $isCawanganVersion2 = function ($x){ + + if($x->tag_syarikat == 1 && $x->kodcaw != 'KB1'){ + return true; + } + return false; + }; + + return array_map(function ($x) use ($isNorujukanPaymentRecentlyAttempted, $isNorujukanAkanDilelong, $isNorujukanIsInFasa2, $isCawanganNotPermitUjrahPayment, $checkExcludePaymentList,$isCawanganVersion2) { $x->disabled_payment = false; @@ -250,6 +290,7 @@ class PembiayaanService || $isNorujukanPaymentRecentlyAttempted($x) || $isCawanganNotPermitUjrahPayment($x) || $checkExcludePaymentList($x) + || $isCawanganVersion2($x) ) { $x->disabled_payment = true; } diff --git a/composer.json b/composer.json index 531e898..7832b11 100644 --- a/composer.json +++ b/composer.json @@ -6,6 +6,7 @@ "license": "MIT", "require": { "php": "^7.3|^8.0", + "barryvdh/laravel-dompdf": "*", "fideloper/proxy": "^4.4", "fruitcake/laravel-cors": "^2.0", "guzzlehttp/guzzle": "^7.0.1", @@ -15,6 +16,7 @@ "laravel/framework": "^8.40", "laravel/tinker": "^2.5", "laravel/ui": "^3.3", + "milon/barcode": "^12.0", "php-http/discovery": "^1.19", "php-http/guzzle7-adapter": "^1.0", "php-http/message": "^1.16", diff --git a/config/api-lelong.php b/config/api-lelong.php index 6114358..6ee436d 100644 --- a/config/api-lelong.php +++ b/config/api-lelong.php @@ -1,4 +1,5 @@ env('API_LELONG_URL', 'https://niklah.arrahn.com.my') + 'url' => env('API_LELONG_URL', 'https://niklah.arrahn.com.my'), + 'url_koop' => env('API_LELONG_URL_KOOP', 'https://niklah.arrahn.com.my') ]; diff --git a/config/api.php b/config/api.php index a64a030..4004da8 100644 --- a/config/api.php +++ b/config/api.php @@ -1,4 +1,5 @@ env('API_URL'), + 'url' => env('API_URL', 'https://api2.arrahn.com.my'), + 'url_koop' => env('API_URL_KOOP', 'https://api3.arrahn.com.my'), ]; diff --git a/config/app.php b/config/app.php index ed9f19b..232fe12 100644 --- a/config/app.php +++ b/config/app.php @@ -161,6 +161,7 @@ return [ Illuminate\Translation\TranslationServiceProvider::class, Illuminate\Validation\ValidationServiceProvider::class, Illuminate\View\ViewServiceProvider::class, + Milon\Barcode\BarcodeServiceProvider::class, /* * Package Service Providers... @@ -229,9 +230,12 @@ return [ 'URL' => Illuminate\Support\Facades\URL::class, 'Validator' => Illuminate\Support\Facades\Validator::class, 'View' => Illuminate\Support\Facades\View::class, + 'DNS1D' => Milon\Barcode\Facades\DNS1DFacade::class, + 'DNS2D' => Milon\Barcode\Facades\DNS2DFacade::class, ], 'api_verify' => env('API_VERIFY',true), + ]; diff --git a/config/logging.php b/config/logging.php index 1aa06aa..e09aae6 100644 --- a/config/logging.php +++ b/config/logging.php @@ -17,7 +17,7 @@ return [ | */ - 'default' => env('LOG_CHANNEL', 'stack'), + 'default' => env('LOG_CHANNEL', 'daily'), /* |-------------------------------------------------------------------------- diff --git a/config/services.php b/config/services.php index 833feeb..9b31e32 100644 --- a/config/services.php +++ b/config/services.php @@ -31,15 +31,26 @@ return [ ], 'billplz' => [ + 'paymentTitle' => 'Pembayaran Ansuran', 'production' => [ 'api_key' => env('BILLPLZ_PRODUCTION_API_KEY', 'f3e82fe1-a422-4660-97f0-65cc59ff6c47'), 'x_signature' => env('BILLPLZ_PRODUCTION_X_SIGNATURE', 'S-alZUbzmD2_TF3vmrRqgehQ'), - 'collection_id' => env('BILLPLZ_SANDBOX_COLLECTION_ID', '5aosv2dg'), + 'collection_id' => env('BILLPLZ_PRODUCTION_COLLECTION_ID', '5aosv2dg'), + ], + 'production_kopkb' => [ + 'api_key' => env('BILLPLZ_PRODUCTION_KOPKB_API_KEY', 'fb81e895-f307-4c9c-b43d-0b55033ee479'), + 'x_signature' => env('BILLPLZ_PRODUCTION_KOPKB_X_SIGNATURE', 'afdb4035f1fe7f53cfdf3668765235f2714ee2ad6211c287a6ee52d170cb52b9b9e87d795213a9b4ede2de14076cdf2ced351343692194a28b0c23adfe3087bb'), + 'collection_id' => env('BILLPLZ_PRODUCTION_KOPKB_COLLECTION_ID', '93mzsttm'), ], 'sandbox' => [ 'api_key' => env('BILLPLZ_SANDBOX_API_KEY', 'abecfd0c-98d8-4635-abc2-2fcba8c60c11'), 'x_signature' => env('BILLPLZ_SANDBOX_X_SIGNATURE', 'S-GWr7z03XjAhqPsFfu_H5nQ'), - 'collection_id' => env('BILLPLZ_PRODUCTION_COLLECTION_ID', 'z0r4kjhi'), + 'collection_id' => env('BILLPLZ_SANDBOX_COLLECTION_ID', 'z0r4kjhi'), + ], + 'sandbox_kopkb' => [ + 'api_key' => env('BILLPLZ_SANDBOX_KOPKB_API_KEY', '4b9218fd-04fb-4338-a067-982e6730d160'), + 'x_signature' => env('BILLPLZ_SANDBOX_KOPKB_X_SIGNATURE', '0ac6e5438cf729754bb819860ed7de6d87d79b0d183212bf10581fca39a4c2d992697b605a706118032af37d31a85fed6637ff1233c56e6d2421bc22cca9d710'), + 'collection_id' => env('BILLPLZ_SANDBOX_KOPKB_COLLECTION_ID', 'uae40muk'), ], ], diff --git a/database/migrations/2024_12_07_012607_create_carts_table.php b/database/migrations/2024_12_07_012607_create_carts_table.php new file mode 100644 index 0000000..287f1cc --- /dev/null +++ b/database/migrations/2024_12_07_012607_create_carts_table.php @@ -0,0 +1,42 @@ +id(); + $table->string('ic_no'); + $table->json('list_pkb'); + $table->json('list_koop'); + $table->json('payment_pkb')->nullable(); + $table->json('payment_koop')->nullable(); + $table->enum('status_pkb', ['PENDING', 'PAID','NONE']); + $table->enum('status_koop', ['PENDING', 'PAID','NONE']); + $table->softDeletes(); + $table->unsignedBigInteger('user_id'); + $table->timestamps(); + + $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('personal_carts'); + } +} diff --git a/public/argon/js/main.js b/public/argon/js/main.js index 17f7d79..2b94b44 100644 --- a/public/argon/js/main.js +++ b/public/argon/js/main.js @@ -1,4 +1,6 @@ function loadingbtn(){ + const loader = document.getElementById('load-arrahn'); + loader.classList.remove('d-none'); $.notifyClose(); // $(this).unbind("click"); $('#background').css('display', 'block'); diff --git a/public/js/miscellaneous/cart.js b/public/js/miscellaneous/cart.js new file mode 100644 index 0000000..84b8704 --- /dev/null +++ b/public/js/miscellaneous/cart.js @@ -0,0 +1,134 @@ +// let checked_rad = () =>{ + function checked_rad(){ + const radios = document.querySelectorAll('input[name="radpembayaran"]'); + // let rad_payment = document.getElementById('radpembayaran'); + let btn_payment = document.getElementById('bayarsbmt'); + let btn_payment_phone = document.getElementById('bayarsbmt-phone'); + + + if(radios.checked){ + btn_payment.disabled = false; + btn_payment_phone.disabled = false; + }else{ + /* Make default checked */ + let radpkb = document.getElementById('pkb'); + let radkopkb = document.getElementById('kopkb'); + + if (radpkb && !radpkb.checked) { + selected_radiopkb(radpkb); + return; + } + + if(radkopkb && !radkopkb.checked){ + selected_radiokopkb(radkopkb); + return; + } + + btn_payment.disabled = true; + btn_payment_phone.disabled = true; + } +} + + +let selected_radiopkb = (radpkb) => { + radpkb.setAttribute('checked', 'checked'); + radpkb.dispatchEvent(new Event('change')); + radpkb.focus(); +} + +let selected_radiokopkb = (radkopkb) => { + radkopkb.setAttribute('checked', 'checked'); + radkopkb.dispatchEvent(new Event('change')); + radkopkb.focus(); +} + +const radios = document.querySelectorAll('input[name="radpembayaran"]'); + +radios.forEach((radio) => { + radio.addEventListener('change', function () { + let btn_payment = document.getElementById('bayarsbmt'); + let btn_payment_phone = document.getElementById('bayarsbmt-phone'); + let content1 = document.getElementById('divpkb'); + let content2 = document.getElementById('divkopkb'); + let whole_total = document.getElementById('spanjumlah'); + let whole_total_phone = document.getElementById('spanjumlah-phone'); + let inputs = document.querySelectorAll(`#div${this.value} input[type="number"]`); + let values = Array.from(inputs).map(input => parseFloat(input.value) || 0).reduce((sum,value) => sum + value, 0); + + if (this.checked) { + if(this.value == 'kopkb'){ + let inputsdisabled = document.querySelectorAll(`#divpkb input:not([type="radio"])`); + let inputenabled = document.querySelectorAll(`#divkopkb input`); + inputsdisabled.forEach(input => { + input.disabled = true; + }); + inputenabled.forEach(input =>{ + input.disabled = false; + }); + content1?.classList.add('blurred'); + content2?.classList.remove('blurred'); + + if(values != 0){ + btn_payment.disabled = false; + btn_payment_phone.disabled = false; + + }else{ + btn_payment.disabled = true; + btn_payment_phone.disabled = true; + } + whole_total.innerHTML = formatter.format(values + 1); + whole_total_phone.innerHTML = formatter.format(values + 1); + + + }else{ + let inputsdisabled = document.querySelectorAll(`#divkopkb input:not([type="radio"])`); + let inputenabled = document.querySelectorAll(`#divpkb input`); + + inputsdisabled.forEach(input => { + input.disabled = true; + }); + inputenabled.forEach(input =>{ + input.disabled = false; + }); + content2?.classList.add('blurred'); + content1?.classList.remove('blurred'); + + if(values != 0){ + btn_payment.disabled = false; + btn_payment_phone.disabled = false; + }else{ + btn_payment.disabled = true; + btn_payment_phone.disabled = true; + } + whole_total.innerHTML = formatter.format(values + 1); + whole_total_phone.innerHTML = formatter.format(values + 1); + } + } + + }); +}); + +let deleteCarts = () => { + const loader = document.getElementById('load-arrahn'); + if(loader) + loader.classList.remove('d-none'); + + fetch('/deletecarts', {method: 'GET', headers: {'Content-Type': 'application/json','Accept': 'application/json'}}) + .then(response => { + if (!response.ok) { + throw new Error('HTTP error ' + response.status); + } + return response.json(); + }) + .then(data => { + if (data) { + redirect_home(); + } + }) + .catch(error => console.error(error)); +} + +let redirect_home = () => { + window.location.href = redirect_home_var; +} + diff --git a/public/js/miscellaneous/navigation-trolley.js b/public/js/miscellaneous/navigation-trolley.js new file mode 100644 index 0000000..6116d88 --- /dev/null +++ b/public/js/miscellaneous/navigation-trolley.js @@ -0,0 +1,73 @@ +async function fetchCartCount() { + try { + const response = await fetch('/showcarts-available', { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + }, + }); + + if (!response.ok) { + throw new Error('Failed to fetch cart count'); + } + + const data = await response.json(); + + let totalcount = 0; + totalcount += (data.status_koop === 'PENDING') ? 1 : 0; + totalcount += (data.status_pkb === 'PENDING') ? 1 : 0; + const cartCount = totalcount || 0; + + updateCartCount(cartCount); + } catch (error) { + console.error('Error fetching cart count:', error); + updateCartCount(0); + } +} + +function updateCartCount(itemCount) { + const cartCountElement = document.getElementById('cart-count'); + const ahrefRedirect = document.getElementById('a-redirect'); + + if (itemCount > 0) { + cartCountElement.textContent = itemCount; + cartCountElement.classList.remove('d-none'); + } else { + cartCountElement.textContent = ''; + cartCountElement.classList.add('d-none'); + + } +} + +function redirectTrolley() { + const cartCountElement = document.getElementById('cart-count'); + if(cartCountElement.textContent == 0){ + return false; + } + + let form = document.createElement('form'); + form.method = 'POST'; + form.action = routetrolley; + + let csrfInput = document.createElement('input'); + csrfInput.type = 'hidden'; + csrfInput.name = '_token'; + csrfInput.value = csrftoken; + form.appendChild(csrfInput); + + let redirectInput = document.createElement('input'); + redirectInput.type = 'hidden'; + redirectInput.name = 'redirect_trolley'; + redirectInput.value = 'trolley'; + form.appendChild(redirectInput); + document.body.appendChild(form); + + + const loader = document.getElementById('load-arrahn'); + loader.classList.remove('d-none'); + + form.submit(); +} + +fetchCartCount(); \ No newline at end of file diff --git a/resources/views/auth/forgotemail2.blade.php b/resources/views/auth/forgotemail2.blade.php index 591f0c2..ae2420d 100644 --- a/resources/views/auth/forgotemail2.blade.php +++ b/resources/views/auth/forgotemail2.blade.php @@ -155,7 +155,7 @@
Pertama Kali diff --git a/resources/views/auth/login.blade.php b/resources/views/auth/login.blade.php index d24e5a1..935cb2f 100644 --- a/resources/views/auth/login.blade.php +++ b/resources/views/auth/login.blade.php @@ -24,8 +24,20 @@ @endif
@@ -141,4 +141,4 @@ $(function() { }); -@endsection \ No newline at end of file +@endsection diff --git a/resources/views/auth/passwords/reset.blade.php b/resources/views/auth/passwords/reset.blade.php index cbcd2d2..f698af2 100644 --- a/resources/views/auth/passwords/reset.blade.php +++ b/resources/views/auth/passwords/reset.blade.php @@ -19,8 +19,20 @@ @endif -
+ | No Rujukan |
+ No Rujukan | Tarikh Akhir | Bayaran | -Baki Pembiayaan |
-
-
+ Baki Pembiayaan |
|---|---|---|---|---|---|
| {{ $bayar['norujukan'] }} | @@ -96,38 +168,17 @@ } @endphp - -+ | + | - - - |
| No Rujukan |
+ Tarikh Akhir | +Bayaran | +Baki Pembiayaan |
+
|---|---|---|---|
| + {{ $bayar['norujukan'] }} + | + @php + + $t_matang = strtotime($bayar['t_matang']); + $t_akhir = date("d/m/Y", $t_matang); + + if($bayar['lelong_tawarruq'] == 0) + { + $t_matang = strtotime($bayar['t_matang1']); + $t_akhir = date("d/m/Y", $t_matang); + } + @endphp ++ {{ $t_akhir }} + | + @php + $upahtawarruq = $bayar['upah_tawarruq']; + $upahtawarruq = floatval(str_replace(',','',$upahtawarruq)); + + $totalupahasal = $totalupahasal + $upahtawarruq; + + + if(floatval($upahtawarruq) == 0){ + $errorcount++; + } + + @endphp ++ + + + + + + | + ++ + | +
+
+ diff --git a/resources/views/pembayaran/checkout.blade.php b/resources/views/pembayaran/checkout.blade.php index 5e38b18..705aaf3 100644 --- a/resources/views/pembayaran/checkout.blade.php +++ b/resources/views/pembayaran/checkout.blade.php @@ -158,7 +158,7 @@
diff --git a/resources/views/pembayaran/resit/resitpdf.blade.php b/resources/views/pembayaran/resit/resitpdf.blade.php new file mode 100644 index 0000000..8ea0c0c --- /dev/null +++ b/resources/views/pembayaran/resit/resitpdf.blade.php @@ -0,0 +1,99 @@ + + +
+ + +
+ + + + + + + + + + +
+