Feature/bsas integration (#24)

Reviewed-on: #24
Co-authored-by: ISMAIL MASSERAN <ismail@koppkb.com>
Co-committed-by: ISMAIL MASSERAN <ismail@koppkb.com>
This commit was merged in pull request #24.
This commit is contained in:
2026-10-26 15:35:48 +08:00
committed by ismailmasseran
parent 2786b3be0c
commit 0451ad3dbe
10 changed files with 900 additions and 2 deletions
+194
View File
@@ -3,15 +3,18 @@
namespace App\Http\Controllers;
use App\Audit;
use App\BsasOrder;
use App\Komuditi;
use App\KomuditiPurchase;
use App\KomuditiTransaksi;
use App\KomuditiProduk;
use App\Cawangan;
use App\Services\Bsas\BsasOrderService;
use DB;
use Illuminate\Http\Request;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
class KomuditiController extends Controller
{
@@ -338,4 +341,195 @@ class KomuditiController extends Controller
return response()->json($rekodkomoditi);
}
/**
* List BSAS commodity orders for operasi rekod view.
*/
public function listBsasOrders(Request $request)
{
$query = BsasOrder::on('mysql7')
->select([
'id',
'uuid',
'norujukan',
'kodcaw',
'serial_number',
'product_code',
'bid_value',
'otc_murabaha_value',
'otc_counter_party',
'status',
'status_code',
'status_message',
'e_cert_no',
'bid_ecert_response',
'otc_ecert_response',
'stb_ecert_response',
'created_by',
'created_at',
'updated_at',
])
->orderBy('created_at', 'desc')
->orderBy('id', 'desc');
if ($request->filled('status')) {
$query->where('status', $request->input('status'));
}
if ($request->filled('kodcaw')) {
$query->where('kodcaw', $request->input('kodcaw'));
}
if ($request->filled('limit_view')) {
$query->limit((int) $request->input('limit_view'));
}
$rows = $query->get()->map(function (BsasOrder $order) {
$payload = $order->toArray();
$payload['has_bid_ecert'] = !empty($order->bid_ecert_response);
$payload['has_otc_ecert'] = !empty($order->otc_ecert_response);
$payload['has_stb_ecert'] = !empty($order->stb_ecert_response);
unset($payload['bid_ecert_response'], $payload['otc_ecert_response'], $payload['stb_ecert_response']);
return $payload;
});
return response()->json($rows);
}
/**
* SAG-ready komoditi/product payload from confirmed BSAS order for a norujukan.
* Replaces daily KomuditiPurchase lookup for per-Terima BSAS purchases.
*/
public function getBsasOrderByNorujukan($norujukan)
{
$order = BsasOrder::on('mysql7')
->where('norujukan', $norujukan)
->where('status', 'confirmed')
->orderBy('id', 'desc')
->first();
if (!$order) {
return response()->json(['message' => 'BSAS order tidak dijumpai untuk norujukan ini.'], 404);
}
$otc = is_array($order->otc_ecert_response) ? $order->otc_ecert_response : [];
$productCode = (string) ($order->product_code ?: config('bsas.product_code'));
$description = trim((string) ($otc['PNAME'] ?? ''));
if ($description === '') {
$produk = KomuditiProduk::on('mysql7')->where('kodproduk', $productCode)->first();
$description = $produk ? (string) $produk->description : $productCode;
}
$price = (float) ($otc['PRICE_MYR_EQUIVALENT'] ?? $otc['PRICE'] ?? 0);
$volume = (float) ($otc['PVOLUME'] ?? 0);
$pinjaman = (float) $order->bid_value;
if ($volume <= 0 && $price > 0 && $pinjaman > 0) {
$volume = round($pinjaman / $price, 4);
}
return response()->json([
'source' => 'bsas',
'uuid' => $order->uuid,
'komoditi' => [
'no_sijil' => $order->e_cert_no ?: $order->uuid,
'kodproduct' => $productCode,
'nilai' => $price > 0 ? $price : null,
],
'product' => [
'product_code' => $productCode,
'kodproduk' => $productCode,
'description' => $description,
'unit' => 'TAN',
],
'kuantiti' => $volume,
]);
}
/**
* Return stored BSAS eCert payload only (no live BSAS refresh).
*/
public function getBsasOrderEcert($uuid)
{
$order = BsasOrder::on('mysql7')->where('uuid', $uuid)->first();
if (!$order) {
return response()->json(['message' => 'BSAS order tidak dijumpai.'], 404);
}
if (empty($order->bid_ecert_response) && empty($order->otc_ecert_response) && empty($order->stb_ecert_response)) {
return response()->json(['message' => 'eCert belum tersedia untuk order ini.'], 404);
}
return response()->json([
'uuid' => $order->uuid,
'norujukan' => $order->norujukan,
'e_cert_no' => $order->e_cert_no,
'serial_number' => $order->serial_number,
'product_code' => $order->product_code,
'bid_value' => $order->bid_value,
'otc_murabaha_value' => $order->otc_murabaha_value,
'otc_counter_party' => $order->otc_counter_party,
'bid_ecert' => $order->bid_ecert_response,
'otc_ecert' => $order->otc_ecert_response,
'stb_ecert' => $order->stb_ecert_response,
]);
}
/**
* Place BSAS commodity order for a gadai Terima, long-poll result, fetch eCert.
*/
public function placeBsasOrder(Request $request)
{
try {
$service = new BsasOrderService();
$order = $service->placeAndConfirm([
'norujukan' => $request->input('norujukan'),
'kodcaw' => $request->input('kodcaw'),
'pinjaman' => $request->input('pinjaman'),
'hargajualan' => $request->input('hargajualan'),
'nama_pelanggan' => $request->input('nama_pelanggan'),
'teller' => $request->input('teller'),
]);
return response()->json([
'message' => 'BSAS order confirmed',
'order' => $order,
], 200);
} catch (\Throwable $e) {
Log::error('BSAS place order failed', [
'norujukan' => $request->input('norujukan'),
'error' => $e->getMessage(),
]);
return response()->json([
'message' => $e->getMessage() ?: 'Gagal pembelian komoditi BSAS.',
], 422);
}
}
/**
* Re-query BSAS orderResult / retry eCert by stored uuid.
*/
public function getBsasOrder($uuid)
{
try {
$service = new BsasOrderService();
$order = $service->refreshByUuid($uuid);
return response()->json([
'message' => 'OK',
'order' => $order,
], 200);
} catch (\Throwable $e) {
Log::error('BSAS refresh order failed', [
'uuid' => $uuid,
'error' => $e->getMessage(),
]);
return response()->json([
'message' => $e->getMessage() ?: 'Gagal semak status BSAS.',
], 422);
}
}
}