feat(shoraka): integrate transactions with Shoraka API
This commit is contained in:
@@ -229,6 +229,9 @@ class GadaiController extends Controller
|
||||
|
||||
|
||||
public function daftarGadaiMarhun($norujukan,Request $request){
|
||||
if (\App\ShorakaTransaction::where('norujukan', $request->norujukan)->exists()) {
|
||||
abort(409, 'Kontrak telah dihantar ke Shoraka dan tidak boleh diubah.');
|
||||
}
|
||||
// dd("ggwp");
|
||||
$master = new MasterServices($request->kodcaw);
|
||||
$response = $master->createMarhunGadai($request->norujukan,$request);
|
||||
@@ -406,6 +409,11 @@ class GadaiController extends Controller
|
||||
}
|
||||
|
||||
public function pembelianKomuditi($kodcaw,$norujukan){
|
||||
if (\App\ShorakaTransaction::where('norujukan', $norujukan)->exists()
|
||||
|| !\App\KomuditiTransaksi::on('mysql7')->where('norujukan', $norujukan)->exists()) {
|
||||
app(\App\Services\ShorakaGadaiService::class)->assertCompleted($kodcaw, $norujukan);
|
||||
}
|
||||
|
||||
$cawangan = Cawangan::on('mysql7')->where('kodcaw','=',$kodcaw)->first();
|
||||
|
||||
$gadai = Gadai::on($cawangan['mysql'])
|
||||
@@ -418,6 +426,10 @@ class GadaiController extends Controller
|
||||
}
|
||||
|
||||
public function cetakSAG($kodcaw,$norujukan,Request $request){
|
||||
if (\App\ShorakaTransaction::where('norujukan', $norujukan)->exists()) {
|
||||
app(\App\Services\ShorakaGadaiService::class)->assertCompleted($kodcaw, $norujukan);
|
||||
}
|
||||
|
||||
$harini = Carbon::now();
|
||||
|
||||
$cawangan = Cawangan::on('mysql7')->where('kodcaw','=',$kodcaw)->first();
|
||||
@@ -442,6 +454,10 @@ class GadaiController extends Controller
|
||||
}
|
||||
|
||||
public function serahMarhun($kodcaw,$norujukan){
|
||||
if (\App\ShorakaTransaction::where('norujukan', $norujukan)->exists()) {
|
||||
app(\App\Services\ShorakaGadaiService::class)->assertCompleted($kodcaw, $norujukan);
|
||||
}
|
||||
|
||||
$cawangan = Cawangan::on('mysql7')->where('kodcaw','=',$kodcaw)->first();
|
||||
$gadai = Gadai::on($cawangan['mysql'])
|
||||
->where('norujukan','=',$norujukan)
|
||||
|
||||
@@ -117,6 +117,9 @@ class KomuditiController extends Controller
|
||||
}
|
||||
|
||||
public function updateKomuditi(Request $request){
|
||||
if (\App\ShorakaTransaction::where('norujukan', $request->norujukan)->exists()) {
|
||||
abort(409, 'Transaksi Shoraka memerlukan semakan operasi; stok lama tidak boleh diubah.');
|
||||
}
|
||||
$current = Carbon::now();
|
||||
$current = new Carbon();
|
||||
|
||||
@@ -138,37 +141,20 @@ class KomuditiController extends Controller
|
||||
return response()->json($komuditi_transaksi);
|
||||
}
|
||||
|
||||
public function transaksiKomuditi(Request $request){
|
||||
$current = Carbon::now();
|
||||
$current = new Carbon();
|
||||
|
||||
$komuditi_current = KomuditiPurchase::on('mysql7')->where('date_purchase','=',$current->toDateString())->orderBy('created_at','desc')->first();
|
||||
|
||||
$unit_current = $komuditi_current['unit_komuditi'];
|
||||
$update_unit = $unit_current - $request->unit_komuditi;
|
||||
|
||||
$unit_current = round((float) $komuditi_current['unit_komuditi'], 2);
|
||||
$unit_komuditi = round((float) $request->unit_komuditi, 2);
|
||||
$update_unit = round($unit_current - $unit_komuditi, 2);
|
||||
|
||||
$update_komuditi = KomuditiPurchase::on('mysql7')->where('id','=',$komuditi_current['id'])->update([
|
||||
'unit_komuditi' => $update_unit
|
||||
]);
|
||||
|
||||
$komuditi_transaksi = KomuditiTransaksi::on('mysql7')->create([
|
||||
'unit_komuditi' => $unit_komuditi,
|
||||
'nosijil'=>$komuditi_current['no_sijil'],
|
||||
'norujukan' => $request->norujukan,
|
||||
'kodcaw' => $request->kodcaw ,
|
||||
'teller' => $request->teller ,
|
||||
'masa' => $current->toTimeString(),
|
||||
'tarikh' => $current->toDateString()
|
||||
]);
|
||||
|
||||
return response()->json($komuditi_transaksi);
|
||||
public function transaksiKomuditi(Request $request)
|
||||
{
|
||||
$this->validate($request, ['kodcaw' => 'required|string', 'norujukan' => 'required|string']);
|
||||
return app(ShorakaGadaiController::class)->submitGadai(
|
||||
$request->kodcaw, $request->norujukan,
|
||||
app(\App\Services\ShorakaGadaiService::class),
|
||||
app(\App\Services\ShorakaService::class)
|
||||
);
|
||||
}
|
||||
|
||||
public function batalKomuditi(Request $request){
|
||||
if (\App\ShorakaTransaction::where('norujukan', $request->norujukan)->exists()) {
|
||||
abort(409, 'Transaksi Shoraka memerlukan semakan operasi; stok lama tidak boleh diubah.');
|
||||
}
|
||||
|
||||
$komuditi_current = KomuditiPurchase::on('mysql7')->orderBy('created_at','desc')->first();
|
||||
|
||||
|
||||
@@ -5,299 +5,228 @@ namespace App\Http\Controllers;
|
||||
use App\ShorakaTransaction;
|
||||
use App\Services\ShorakaService;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use RuntimeException;
|
||||
use Throwable;
|
||||
|
||||
class ShorakaController extends Controller
|
||||
{
|
||||
/**
|
||||
* Hantar transaksi pembiayaan pelanggan ke Shoraka.
|
||||
*/
|
||||
public function submit(
|
||||
Request $request,
|
||||
ShorakaService $shoraka
|
||||
) {
|
||||
/*
|
||||
* Validation untuk Lumen 7.
|
||||
*/
|
||||
public function submit(Request $request, ShorakaService $shoraka)
|
||||
{
|
||||
$validated = $this->validate($request, [
|
||||
'norujukan' =>
|
||||
'required|string',
|
||||
|
||||
'ownership' =>
|
||||
'required|string',
|
||||
|
||||
'order_amount' =>
|
||||
'required|numeric|min:0.01',
|
||||
|
||||
'murabaha_amount' =>
|
||||
'required|numeric|min:0.01',
|
||||
|
||||
'tenor_other' =>
|
||||
'required|integer|min:1',
|
||||
'norujukan' => 'required|string|max:255',
|
||||
'ownership' => 'required|string|max:255',
|
||||
'order_amount' => 'required|numeric|min:0.01|max:9999999999999.99',
|
||||
'murabaha_amount' => 'required|numeric|min:0.01|max:9999999999999.99',
|
||||
'tenor_other' => 'required|integer|min:1',
|
||||
]);
|
||||
|
||||
/*
|
||||
* Jangan hubungi Shoraka selagi credentials
|
||||
* belum diterima atau belum dimasukkan.
|
||||
*/
|
||||
if (
|
||||
empty(config('services.shoraka.api_id')) ||
|
||||
empty(config('services.shoraka.secret_key'))
|
||||
) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' =>
|
||||
'API ID dan Secret Key Shoraka belum dikonfigurasi.',
|
||||
], 503);
|
||||
if (!$shoraka->configured()) {
|
||||
return $this->unconfigured();
|
||||
}
|
||||
|
||||
/*
|
||||
* Semak sama ada nombor rujukan yang sama
|
||||
* sudah pernah berjaya dihantar.
|
||||
*/
|
||||
$existing = ShorakaTransaction::where(
|
||||
'norujukan',
|
||||
$validated['norujukan']
|
||||
)->first();
|
||||
|
||||
if (
|
||||
$existing &&
|
||||
!empty($existing->order_id)
|
||||
) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' =>
|
||||
'Transaksi ini telah dihantar ke Shoraka sebelum ini.',
|
||||
'data' => [
|
||||
'norujukan' =>
|
||||
$existing->norujukan,
|
||||
|
||||
'order_id' =>
|
||||
$existing->order_id,
|
||||
|
||||
'status' =>
|
||||
$existing->status,
|
||||
],
|
||||
], 409);
|
||||
$existing = ShorakaTransaction::where('norujukan', $validated['norujukan'])->first();
|
||||
if ($existing) {
|
||||
return $this->duplicate($existing);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sediakan data mengikut format Shoraka.
|
||||
*/
|
||||
$payload = [
|
||||
'product_type' =>
|
||||
'FINANCING',
|
||||
|
||||
/*
|
||||
* Kod komoditi perlu disahkan
|
||||
* dengan pihak Shoraka.
|
||||
*/
|
||||
'commodity_type' =>
|
||||
'000-COPPER',
|
||||
|
||||
/*
|
||||
* Nama pelanggan.
|
||||
*/
|
||||
'ownership' =>
|
||||
$validated['ownership'],
|
||||
|
||||
/*
|
||||
* Nombor rujukan pembiayaan eRahn.
|
||||
*/
|
||||
'ownership_doc_no' =>
|
||||
$validated['norujukan'],
|
||||
|
||||
/*
|
||||
* Format yang diminta Shoraka:
|
||||
* DD/MM/YYYY
|
||||
*/
|
||||
'value_date' =>
|
||||
Carbon::now()->format('d/m/Y'),
|
||||
|
||||
'order_currency' =>
|
||||
'MYR',
|
||||
|
||||
'order_amount' =>
|
||||
$validated['order_amount'],
|
||||
|
||||
'murabaha_amount' =>
|
||||
$validated['murabaha_amount'],
|
||||
|
||||
/*
|
||||
* Sila sahkan dengan Shoraka sama ada
|
||||
* nilai sebenar ialah OTHER atau OTHERS.
|
||||
*/
|
||||
'tenor' =>
|
||||
'OTHERS',
|
||||
|
||||
'tenor_other' =>
|
||||
$validated['tenor_other'],
|
||||
|
||||
'tenor_other_unit' =>
|
||||
'MONTH',
|
||||
|
||||
'order_type' =>
|
||||
'Buy & Sell',
|
||||
'product_type' => 'FINANCING',
|
||||
'commodity_type' => '000-COPPER',
|
||||
'ownership' => $validated['ownership'],
|
||||
'ownership_doc_no' => $validated['norujukan'],
|
||||
'value_date' => Carbon::now()->format('d/m/Y'),
|
||||
'order_currency' => 'MYR',
|
||||
'order_amount' => number_format((float) $validated['order_amount'], 2, '.', ''),
|
||||
'murabaha_amount' => number_format((float) $validated['murabaha_amount'], 2, '.', ''),
|
||||
// Appendix codes in v1.5: OTHERS and MONTH.
|
||||
'tenor' => 'OTHERS',
|
||||
'tenor_other' => $validated['tenor_other'],
|
||||
'tenor_other_unit' => 'MONTH',
|
||||
'order_type' => 'Buy & Sell',
|
||||
];
|
||||
|
||||
/*
|
||||
* Simpan rekod awal sebelum request dihantar.
|
||||
*/
|
||||
$transaction = ShorakaTransaction::updateOrCreate(
|
||||
[
|
||||
'norujukan' =>
|
||||
$validated['norujukan'],
|
||||
],
|
||||
[
|
||||
'status' =>
|
||||
'PENDING',
|
||||
|
||||
'product_type' =>
|
||||
$payload['product_type'],
|
||||
|
||||
'commodity_type' =>
|
||||
$payload['commodity_type'],
|
||||
|
||||
'ownership_name' =>
|
||||
$payload['ownership'],
|
||||
|
||||
'ownership_doc_no' =>
|
||||
$payload['ownership_doc_no'],
|
||||
|
||||
'order_amount' =>
|
||||
$payload['order_amount'],
|
||||
|
||||
'murabaha_amount' =>
|
||||
$payload['murabaha_amount'],
|
||||
|
||||
'request_payload' =>
|
||||
$payload,
|
||||
|
||||
'error_message' =>
|
||||
null,
|
||||
]
|
||||
);
|
||||
try {
|
||||
// The unique norujukan index is the atomic claim for concurrent submissions.
|
||||
$transaction = ShorakaTransaction::create([
|
||||
'norujukan' => $validated['norujukan'],
|
||||
'kodcaw' => $request->attributes->get('shoraka_kodcaw'),
|
||||
'status' => 'PENDING',
|
||||
'product_type' => $payload['product_type'],
|
||||
'commodity_type' => $payload['commodity_type'],
|
||||
'ownership_name' => $payload['ownership'],
|
||||
'ownership_doc_no' => $payload['ownership_doc_no'],
|
||||
'order_amount' => $payload['order_amount'],
|
||||
'murabaha_amount' => $payload['murabaha_amount'],
|
||||
'request_payload' => $payload,
|
||||
'attempt_count' => 1,
|
||||
]);
|
||||
} catch (QueryException $exception) {
|
||||
$existing = ShorakaTransaction::where('norujukan', $validated['norujukan'])->first();
|
||||
if ($existing) {
|
||||
return $this->duplicate($existing);
|
||||
}
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
try {
|
||||
/*
|
||||
* Tambah bilangan percubaan request.
|
||||
*/
|
||||
$transaction->increment(
|
||||
'attempt_count'
|
||||
);
|
||||
|
||||
/*
|
||||
* Hantar order kepada API Shoraka.
|
||||
*/
|
||||
$response = $shoraka->submitOrder(
|
||||
$payload
|
||||
);
|
||||
|
||||
/*
|
||||
* Shoraka mesti memberikan orderId.
|
||||
*/
|
||||
if (empty($response['orderId'])) {
|
||||
throw new RuntimeException(
|
||||
'Shoraka tidak memberikan orderId.'
|
||||
);
|
||||
}
|
||||
|
||||
$status = isset($response['status'])
|
||||
? $response['status']
|
||||
: 'SUBMITTED';
|
||||
|
||||
/*
|
||||
* Simpan respons Shoraka.
|
||||
*/
|
||||
$transaction->update([
|
||||
'order_id' =>
|
||||
$response['orderId'],
|
||||
|
||||
'status' =>
|
||||
$status,
|
||||
|
||||
'certificate_url' =>
|
||||
isset($response['certificateUrl'])
|
||||
? $response['certificateUrl']
|
||||
: null,
|
||||
|
||||
'response_payload' =>
|
||||
$response,
|
||||
|
||||
'submitted_at' =>
|
||||
Carbon::now(),
|
||||
|
||||
'completed_at' =>
|
||||
$status === 'Completed'
|
||||
? Carbon::now()
|
||||
: null,
|
||||
|
||||
'error_message' =>
|
||||
null,
|
||||
]);
|
||||
$response = $shoraka->submitOrder($payload);
|
||||
$this->saveOrder($transaction, $response);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
|
||||
'message' =>
|
||||
'Order berjaya dihantar ke Shoraka.',
|
||||
|
||||
'data' => [
|
||||
'norujukan' =>
|
||||
$transaction->norujukan,
|
||||
|
||||
'order_id' =>
|
||||
$transaction->order_id,
|
||||
|
||||
'status' =>
|
||||
$transaction->status,
|
||||
|
||||
'certificate_url' =>
|
||||
$transaction->certificate_url,
|
||||
],
|
||||
], 200);
|
||||
'message' => 'Order berjaya dihantar ke Shoraka.',
|
||||
'data' => $this->orderData($transaction),
|
||||
]);
|
||||
} catch (Throwable $exception) {
|
||||
/*
|
||||
* Simpan status gagal.
|
||||
*/
|
||||
// A timeout or invalid response does not prove the remote trade failed.
|
||||
// Block resubmission until this reference has been reconciled with Shoraka.
|
||||
$transaction->update([
|
||||
'status' =>
|
||||
'FAILED',
|
||||
|
||||
'error_message' =>
|
||||
$exception->getMessage(),
|
||||
'status' => $transaction->order_id ? $transaction->status : 'UNKNOWN',
|
||||
'error_message' => 'Submission outcome requires reconciliation with Shoraka.',
|
||||
]);
|
||||
|
||||
/*
|
||||
* Rekodkan ralat tanpa API Secret Key.
|
||||
*/
|
||||
Log::error(
|
||||
'Shoraka order submission failed',
|
||||
[
|
||||
'norujukan' =>
|
||||
$validated['norujukan'],
|
||||
|
||||
'message' =>
|
||||
$exception->getMessage(),
|
||||
]
|
||||
);
|
||||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
|
||||
'message' =>
|
||||
'Order gagal dihantar ke Shoraka.',
|
||||
|
||||
/*
|
||||
* Paparkan error untuk UAT sahaja.
|
||||
* Buang field ini semasa production.
|
||||
*/
|
||||
'error' =>
|
||||
$exception->getMessage(),
|
||||
], 502);
|
||||
return $this->upstreamError('submit', $transaction, $exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function refresh(string $norujukan, ShorakaService $shoraka)
|
||||
{
|
||||
if (!$shoraka->configured()) {
|
||||
return $this->unconfigured();
|
||||
}
|
||||
$transaction = ShorakaTransaction::where('norujukan', $norujukan)->firstOrFail();
|
||||
if (!$transaction->order_id) {
|
||||
return $this->missingOrderId();
|
||||
}
|
||||
|
||||
try {
|
||||
$response = $shoraka->orderStatus($transaction->order_id);
|
||||
$this->saveOrder($transaction, $response);
|
||||
|
||||
return response()->json(['success' => true, 'data' => $this->orderData($transaction)]);
|
||||
} catch (Throwable $exception) {
|
||||
return $this->upstreamError('status', $transaction, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
public function certificate(string $norujukan, ShorakaService $shoraka)
|
||||
{
|
||||
if (!$shoraka->configured()) {
|
||||
return $this->unconfigured();
|
||||
}
|
||||
$transaction = ShorakaTransaction::where('norujukan', $norujukan)->firstOrFail();
|
||||
if (!$transaction->order_id) {
|
||||
return $this->missingOrderId();
|
||||
}
|
||||
|
||||
try {
|
||||
$pdf = $shoraka->certificate($transaction->order_id);
|
||||
|
||||
return response($pdf, 200, [
|
||||
'Content-Type' => 'application/pdf',
|
||||
'Content-Disposition' => 'attachment; filename="shoraka-' . $transaction->id . '.pdf"',
|
||||
'Cache-Control' => 'private, no-store',
|
||||
]);
|
||||
} catch (Throwable $exception) {
|
||||
return $this->upstreamError('certificate', $transaction, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
public function callback(Request $request, ShorakaService $shoraka)
|
||||
{
|
||||
if (!$shoraka->configured()) {
|
||||
return $this->unconfigured();
|
||||
}
|
||||
$payload = $request->json()->all();
|
||||
if (!$shoraka->validCallback($payload)) {
|
||||
return response()->json(['success' => false, 'message' => 'Invalid callback signature.'], 401);
|
||||
}
|
||||
|
||||
// ownershipDocNo and certificateUrl are NOT signed. Never use them to link
|
||||
// a callback to a local record or download a file.
|
||||
$transaction = ShorakaTransaction::where('order_id', $payload['orderId'])->first();
|
||||
if (!$transaction) {
|
||||
return response()->json(['success' => false, 'message' => 'Order not found.'], 404);
|
||||
}
|
||||
|
||||
try {
|
||||
// There is no signed callback timestamp. Query the current order so a
|
||||
// delayed/replayed callback cannot directly restore an old status.
|
||||
$response = $shoraka->orderStatus($transaction->order_id);
|
||||
unset($payload['signature']);
|
||||
$this->saveOrder($transaction, $response, ['callback_payload' => $payload]);
|
||||
|
||||
// Exact acknowledgement required by section 6.
|
||||
return response('OK', 200, ['Content-Type' => 'text/plain']);
|
||||
} catch (Throwable $exception) {
|
||||
return $this->upstreamError('callback', $transaction, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
protected function saveOrder(ShorakaTransaction $transaction, array $response, array $extra = []): void
|
||||
{
|
||||
$transaction->update(array_merge([
|
||||
'order_id' => (string) $response['orderId'],
|
||||
'status' => $response['status'],
|
||||
'certificate_url' => $response['certificateUrl'] ?? null,
|
||||
'response_payload' => $response,
|
||||
'submitted_at' => $transaction->submitted_at ?: Carbon::now(),
|
||||
'completed_at' => $response['status'] === 'Completed'
|
||||
? ($transaction->completed_at ?: Carbon::now()) : $transaction->completed_at,
|
||||
'error_message' => null,
|
||||
], $extra));
|
||||
app(\App\Services\ShorakaGadaiService::class)->sync($transaction);
|
||||
}
|
||||
|
||||
protected function orderData(ShorakaTransaction $transaction): array
|
||||
{
|
||||
return [
|
||||
'norujukan' => $transaction->norujukan,
|
||||
'kodcaw' => $transaction->kodcaw,
|
||||
'order_id' => $transaction->order_id,
|
||||
'status' => $transaction->status,
|
||||
'certificate_url' => $transaction->certificate_url,
|
||||
];
|
||||
}
|
||||
|
||||
protected function duplicate(ShorakaTransaction $transaction)
|
||||
{
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Transaksi telah direkodkan. Semak status dengan Shoraka sebelum penghantaran semula.',
|
||||
'data' => $this->orderData($transaction),
|
||||
], 409);
|
||||
}
|
||||
|
||||
protected function missingOrderId()
|
||||
{
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Order ID belum tersedia. Semakan dengan Shoraka diperlukan.',
|
||||
], 409);
|
||||
}
|
||||
|
||||
protected function unconfigured()
|
||||
{
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'API ID dan Secret Key Shoraka belum dikonfigurasi.',
|
||||
], 503);
|
||||
}
|
||||
|
||||
protected function upstreamError(string $operation, ShorakaTransaction $transaction, Throwable $exception)
|
||||
{
|
||||
// Connection exceptions may include request details; log only the class.
|
||||
Log::error('Shoraka request failed', [
|
||||
'operation' => $operation,
|
||||
'transaction_id' => $transaction->id,
|
||||
'exception_type' => get_class($exception),
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Permintaan Shoraka gagal. Semak status transaksi sebelum mencuba semula.',
|
||||
], 502);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\KomuditiTransaksi;
|
||||
use App\Services\ShorakaGadaiService;
|
||||
use App\Services\ShorakaService;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ShorakaGadaiController extends ShorakaController
|
||||
{
|
||||
public function readiness(ShorakaService $shoraka)
|
||||
{
|
||||
return response()->json(['provider' => 'shoraka', 'ready' => $shoraka->configured()]);
|
||||
}
|
||||
|
||||
public function showGadai(string $kodcaw, string $norujukan, ShorakaGadaiService $gadaiService)
|
||||
{
|
||||
$gadai = $gadaiService->gadai($kodcaw, $norujukan);
|
||||
$order = $gadaiService->transaction($kodcaw, $norujukan);
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => [
|
||||
'norujukan' => $norujukan, 'kodcaw' => $kodcaw,
|
||||
'order_amount' => $gadai->pinjaman, 'murabaha_amount' => $gadai->hargajualan,
|
||||
'order' => $order ? $this->orderData($order) : null,
|
||||
'details' => $order ? $order->response_payload : null,
|
||||
'can_complete' => $order && $order->status === 'Completed'
|
||||
&& number_format((float) $gadai->pinjaman, 2, '.', '') === $order->order_amount
|
||||
&& number_format((float) $gadai->hargajualan, 2, '.', '') === $order->murabaha_amount,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function submitGadai(string $kodcaw, string $norujukan, ShorakaGadaiService $gadaiService, ShorakaService $shoraka)
|
||||
{
|
||||
$gadai = $gadaiService->gadai($kodcaw, $norujukan);
|
||||
$existing = $gadaiService->transaction($kodcaw, $norujukan);
|
||||
if ($existing) {
|
||||
return $this->duplicate($existing);
|
||||
}
|
||||
// Historical commodity purchases must never be traded again.
|
||||
if (KomuditiTransaksi::on('mysql7')->where('norujukan', $norujukan)->exists()
|
||||
|| $gadai->cetak || $gadai->sttebus) {
|
||||
abort(409, 'Gadaian lama atau telah selesai tidak boleh dihantar sebagai order baharu.');
|
||||
}
|
||||
$request = new Request($gadaiService->payload($gadai));
|
||||
$request->attributes->set('shoraka_kodcaw', $kodcaw);
|
||||
return $this->submit($request, $shoraka);
|
||||
}
|
||||
|
||||
public function refreshGadai(string $kodcaw, string $norujukan, ShorakaGadaiService $gadaiService, ShorakaService $shoraka)
|
||||
{
|
||||
$gadaiService->gadai($kodcaw, $norujukan);
|
||||
$gadaiService->transaction($kodcaw, $norujukan);
|
||||
return $this->refresh($norujukan, $shoraka);
|
||||
}
|
||||
|
||||
public function certificateGadai(string $kodcaw, string $norujukan, ShorakaGadaiService $gadaiService, ShorakaService $shoraka)
|
||||
{
|
||||
$gadaiService->assertCompleted($kodcaw, $norujukan);
|
||||
return $this->certificate($norujukan, $shoraka);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user