DONE: bsas integration first stage

This commit is contained in:
2026-10-18 11:46:48 +08:00
parent 1138e193ae
commit 060f7a22cd
20 changed files with 1371 additions and 262 deletions
+75 -17
View File
@@ -298,7 +298,7 @@ class GadaianController extends Controller
}
if ($caraTerima === 'ONLINE' && !$this->hasMatchingBorangOnlinePrint($request)) {
return redirect()->back()->with('error', 'Sila cetak borang pengesahan pelanggan sebelum tekan Terima.');
return $this->gadaiStoreResult($request, false, 'Sila cetak borang pengesahan pelanggan sebelum tekan Terima.');
}
//$total_nilai_marhun = $request->total_nilai_marhun;
@@ -320,6 +320,27 @@ class GadaianController extends Controller
$keuntungan12bulan = $keuntungan_sebln * 12;
$hargajualan = $request->pinjaman + $keuntungan12bulan;
// BSAS commodity order must succeed before finalizing gadai.
$bsas = Http::withOptions(['verify' => config('app.api_verify')])
->timeout(60)
->post(config('api.url') . '/api/komuditi/bsas/order', [
'norujukan' => $request->norujukan_gadai,
'kodcaw' => $auth_user['cawangan'],
'pinjaman' => round((float) $request->pinjaman, 2),
'hargajualan' => round((float) $hargajualan, 2),
'nama_pelanggan' => $request->nama_pelanggan ?: $request->nama_akaun,
'teller' => $auth_user['name'],
]);
if (!$bsas->successful()) {
$body = $bsas->json();
$msg = is_array($body) && isset($body['message'])
? $body['message']
: 'Gagal pembelian komoditi BSAS. Sila cuba lagi.';
return $this->gadaiStoreResult($request, false, $msg);
}
//Log::info('DEBUG NOKP:' . $request->nokp);
$gadai = Http::withOptions(['verify' => config('app.api_verify')])->put(config('api.url') . '/api/gadai/norujukan/' . $auth_user['cawangan'] . '/' . $request->norujukan_gadai, [
'kodcaw' => $auth_user['cawangan'],
@@ -344,14 +365,6 @@ class GadaianController extends Controller
'rebate' => $this->parseMoney($request->rebate),
])->json();
$komuditi = Http::withOptions(['verify' => config('app.api_verify')])->put(config('api.url') . '/api/komuditi/transaksi', [
'unit_komuditi' => round($request->pinjaman, 2),
'norujukan' => $request->norujukan_gadai,
'kodcaw' => $auth_user['cawangan'],
'teller' => $auth_user['name']
]);
if ($caraTerima === 'ONLINE') {
$online = Http::withOptions(['verify' => config('app.api_verify')])
->asForm()
@@ -374,7 +387,7 @@ class GadaianController extends Controller
$msg = is_array($body) && isset($body['message'])
? $body['message']
: 'Gagal daftar pembiayaan online. Sila cuba lagi.';
return redirect()->back()->with('error', $msg);
return $this->gadaiStoreResult($request, false, $msg);
}
$this->notifyPcPembiayaanOnlinePending($auth_user, $request, $pinjamanAmt);
@@ -392,6 +405,33 @@ class GadaianController extends Controller
$request->session()->flash('message', 'Gadai berjaya. Pembiayaan online menunggu semakan PC.');
}
return $this->gadaiStoreResult($request, true);
}
/**
* JSON for AJAX Terima (BSAS progress UI); normal redirect otherwise.
*/
protected function gadaiStoreResult(Request $request, bool $ok, string $message = null)
{
if ($request->ajax() || $request->wantsJson()) {
if (!$ok) {
return response()->json([
'ok' => false,
'message' => $message ?: 'Gadai tidak berjaya.',
], 422);
}
return response()->json([
'ok' => true,
'message' => $message ?: 'Gadai berjaya.',
'redirect' => route('customer_info'),
]);
}
if (!$ok) {
return redirect()->back()->with('error', $message ?: 'Gadai tidak berjaya.');
}
return redirect()->route('customer_info');
}
@@ -671,13 +711,31 @@ class GadaianController extends Controller
// $pembayaran_segera = "https://spare.arrahn.com.my/pembayaransegera";
$pembayaran_segera = "https://pay.arrahn.com.my";
$komoditi = Http::withOptions(['verify' => config('app.api_verify')])
->get($api_url . '/api/komuditi/check')
->json();
$product = Http::withOptions(['verify' => config('app.api_verify')])
->get($api_url . '/api/komuditi/description', ['kodproduk' => $komoditi['kodproduct']])
->json();
$kuantiti = $gadai_detail['pinjaman'] / $komoditi['nilai'];
$bsasSag = Http::withOptions(['verify' => config('app.api_verify')])
->get($api_url . '/api/komuditi/bsas/order/norujukan/' . urlencode($norujukan));
$komoditi = [];
$product = [];
$kuantiti = 0;
if ($bsasSag->successful() && is_array($bsasSag->json())) {
$bsasPayload = $bsasSag->json();
$komoditi = $bsasPayload['komoditi'] ?? [];
$product = $bsasPayload['product'] ?? [];
$kuantiti = (float) ($bsasPayload['kuantiti'] ?? 0);
}
if (!is_array($komoditi)) {
$komoditi = [];
}
if (!is_array($product)) {
$product = [
'product_code' => $komoditi['kodproduct'] ?? '',
'kodproduk' => $komoditi['kodproduct'] ?? '',
'description' => '',
'unit' => 'TAN',
];
}
if ($gadai_detail['tagbaru'] == 1) {
$cawangan_info = Http::withOptions(['verify' => config('app.api_verify')])
+118
View File
@@ -55,4 +55,122 @@ class KomuditiController extends Controller
return redirect()->route('komuditi');
}
/**
* Dummy BSAS eCert layout preview (2-page A4).
*/
public function previewBsasEcert()
{
$cert = [
'ecert_no' => 'CPO13OCT26-0000136-025',
'seller' => 'KOPERASI PERMODALAN KELANTAN BERHAD',
'buyer' => 'WAN MOHAMAD AIMAN',
'bid_no' => '1',
'report_time' => '13:39:23.751',
'report_date' => '13 OCTOBER 2026',
'value_date' => '13 OCTOBER 2026',
'product' => 'CPO-MSIA-09',
'unit' => 'Tonnage',
'volume' => '.72562358',
'currency' => 'MYR',
'price' => '5,256.72',
'price_myr' => '5,256.72',
'value' => '3,200.00',
'txn_type' => '-',
'murabaha' => '3,814.40',
'lines' => [
[
'supplier' => 'POA RESOURCES BERHAD',
'volume' => '.72562358',
],
],
];
return view('print.bsas_ecert', [
'cert' => $cert,
'isDummy' => true,
]);
}
/**
* Live BSAS eCert from stored bsas_orders.ecert_response.
*/
public function showBsasEcert($uuid)
{
$response = Http::withOptions(['verify' => config('app.api_verify')])
->get(config('api.url') . '/api/komuditi/bsas/order/' . urlencode($uuid) . '/ecert');
if ($response->status() === 404) {
abort(404, $response->json('message') ?: 'eCert tidak dijumpai.');
}
if (!$response->successful()) {
abort(502, 'Gagal memuatkan eCert BSAS.');
}
$payload = $response->json();
$ecert = $payload['ecert'] ?? null;
if (!is_array($ecert) || empty($ecert)) {
abort(404, 'eCert belum tersedia untuk order ini.');
}
return view('print.bsas_ecert', [
'cert' => $this->mapBsasEcertToView($ecert, $payload),
'isDummy' => false,
]);
}
/**
* Map stored otcXML / eCert JSON into print view fields.
*/
protected function mapBsasEcertToView(array $ecert, array $orderMeta = []): array
{
$reporting = trim((string) ($ecert['REPORTINGTIMEDATE'] ?? ''));
$reportTime = '-';
$reportDate = '-';
if ($reporting !== '') {
$parts = explode(' ', $reporting, 2);
$reportTime = $parts[0] ?? '-';
$reportDate = isset($parts[1]) ? strtoupper($parts[1]) : '-';
}
$lines = [];
foreach (($ecert['LINE'] ?? []) as $line) {
if (!is_array($line)) {
continue;
}
$lines[] = [
'supplier' => $line['SUPPLIER'] ?? '-',
'volume' => $line['VOLUME'] ?? ($ecert['PVOLUME'] ?? '-'),
];
}
if (empty($lines)) {
$lines[] = [
'supplier' => '-',
'volume' => $ecert['PVOLUME'] ?? '-',
];
}
return [
'ecert_no' => $ecert['ECERTNO'] ?? ($orderMeta['e_cert_no'] ?? '-'),
'seller' => $ecert['SELLER'] ?? 'KOPERASI PERMODALAN KELANTAN BERHAD',
'buyer' => $ecert['BUYER'] ?? ($orderMeta['otc_counter_party'] ?? '-'),
'bid_no' => $orderMeta['serial_number'] ?? '1',
'report_time' => $reportTime,
'report_date' => $reportDate,
'value_date' => isset($ecert['VALUEDATE']) ? strtoupper((string) $ecert['VALUEDATE']) : '-',
'product' => $ecert['PNAME'] ?? ($orderMeta['product_code'] ?? '-'),
'unit' => 'Tonnage',
'volume' => $ecert['PVOLUME'] ?? '-',
'currency' => $ecert['CURRENCY'] ?? 'MYR',
'price' => $ecert['PRICE'] ?? '-',
'price_myr' => $ecert['PRICE_MYR_EQUIVALENT'] ?? ($ecert['PRICE'] ?? '-'),
'value' => $ecert['TOTALVALUE'] ?? '-',
'txn_type' => '-',
'murabaha' => $ecert['MURABAHAVALUE'] ?? ($orderMeta['otc_murabaha_value'] ?? '-'),
'lines' => $lines,
];
}
}
@@ -585,15 +585,37 @@ class PembiayaanOnlineController extends Controller
$pembayaran_segera = 'https://pay.arrahn.com.my';
$komoditi = $this->api()->get($api_url . '/api/komuditi/check')->json();
$product = $this->api()
->get($api_url . '/api/komuditi/description', [
'kodproduk' => is_array($komoditi) ? ($komoditi['kodproduct'] ?? '') : '',
])
->json();
// Prefer per-Terima BSAS order; fall back to legacy daily KomuditiPurchase.
$bsasSag = $this->api()
->get($api_url . '/api/komuditi/bsas/order/norujukan/' . urlencode($norujukan));
$nilai = is_array($komoditi) ? (float) ($komoditi['nilai'] ?? 0) : 0;
$kuantiti = $nilai > 0 ? ((float) ($gadai_detail['pinjaman'] ?? 0) / $nilai) : 0;
if ($bsasSag->successful() && is_array($bsasSag->json())) {
$bsasPayload = $bsasSag->json();
$komoditi = $bsasPayload['komoditi'] ?? [];
$product = $bsasPayload['product'] ?? [];
$kuantiti = (float) ($bsasPayload['kuantiti'] ?? 0);
} else {
$komoditi = $this->api()->get($api_url . '/api/komuditi/check')->json();
$product = $this->api()
->get($api_url . '/api/komuditi/description', [
'kodproduk' => is_array($komoditi) ? ($komoditi['kodproduct'] ?? '') : '',
])
->json();
$nilai = is_array($komoditi) ? (float) ($komoditi['nilai'] ?? 0) : 0;
$kuantiti = $nilai > 0 ? ((float) ($gadai_detail['pinjaman'] ?? 0) / $nilai) : 0;
}
if (!is_array($komoditi)) {
$komoditi = [];
}
if (!is_array($product)) {
$product = [
'kodproduk' => $komoditi['kodproduct'] ?? '',
'description' => '',
'unit' => 'TAN',
];
}
if (($gadai_detail['tagbaru'] ?? 0) == 1) {
$cawangan_info = $this->api()