feat(shoraka): defer gadai persistence until commodity confirmation and add simulation support
This commit is contained in:
@@ -10,12 +10,13 @@ use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Throwable;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
class ShorakaFinancingService
|
||||
{
|
||||
public function ensureReady(): void
|
||||
{
|
||||
// Check local migration before any registration side effect.
|
||||
// Check the configured financing database before any registration side effect.
|
||||
ShorakaFinancing::where('kodcaw', Auth::user()->cawangan)->exists();
|
||||
$response = $this->api()->get(rtrim(config('api.url'), '/') . '/api/shoraka/readiness')->throw()->json();
|
||||
abort_unless(!empty($response['ready']), 503, 'Shoraka belum dikonfigurasi. Pembiayaan baharu ditahan.');
|
||||
@@ -42,15 +43,25 @@ class ShorakaFinancingService
|
||||
public function hold(Request $request, string $reference, string $action, array $extra = [])
|
||||
{
|
||||
$user = Auth::user();
|
||||
$context = array_merge($request->except(['_token', 'password']), $extra);
|
||||
if (!empty($extra['temporary_gadai'])) {
|
||||
$key = 'shoraka:payout:' . hash('sha256', $user->cawangan . ':' . $reference);
|
||||
$temporaryContext = $context;
|
||||
$context = ['temporary_gadai' => true, 'pinjaman' => $extra['pinjaman']];
|
||||
}
|
||||
$record = ShorakaFinancing::firstOrCreate(
|
||||
['kodcaw' => $user->cawangan, 'norujukan' => $reference],
|
||||
[
|
||||
'teller' => $user->name, 'action' => $action, 'state' => 'WAITING',
|
||||
'context' => array_merge($request->except(['_token', 'password']), $extra),
|
||||
'context' => $context,
|
||||
]
|
||||
);
|
||||
// A duplicate request only opens the saved workflow; it never replays registration.
|
||||
if ($record->wasRecentlyCreated) {
|
||||
if (isset($temporaryContext) && !Cache::store('file')->put($key, $temporaryContext, 604800)) {
|
||||
$record->update(['state' => 'REVIEW']);
|
||||
abort(503, 'Maklumat pembiayaan sementara tidak dapat disimpan.');
|
||||
}
|
||||
try {
|
||||
$this->api()->post($this->url($reference, '/submit'));
|
||||
} catch (Throwable $exception) {
|
||||
@@ -91,11 +102,17 @@ class ShorakaFinancingService
|
||||
409, 'Amaun pembiayaan berubah. Semakan operasi diperlukan sebelum bayaran.'
|
||||
);
|
||||
|
||||
$context = $record->context;
|
||||
if (!empty($context['temporary_gadai'])) {
|
||||
$context = Cache::store('file')->get('shoraka:payout:' . hash('sha256', $record->kodcaw . ':' . $reference));
|
||||
abort_unless(is_array($context), 409, 'Maklumat sementara tamat. Semakan operasi diperlukan sebelum bayaran.');
|
||||
}
|
||||
|
||||
$claimed = ShorakaFinancing::where('id', $record->id)->where('state', 'WAITING')
|
||||
->update(['state' => 'PROCESSING', 'updated_at' => now()]);
|
||||
abort_unless($claimed === 1, 409, 'Penyelesaian sedang diproses.');
|
||||
|
||||
$saved = new Request($record->context);
|
||||
$saved = new Request($context);
|
||||
$saved->setLaravelSession($request->session());
|
||||
try {
|
||||
if ($record->action === 'gadai') {
|
||||
@@ -119,6 +136,9 @@ class ShorakaFinancingService
|
||||
$result = redirect()->route('shoraka.show', ['norujukan' => $reference]);
|
||||
}
|
||||
$record->update(['state' => 'DONE', 'context' => []]);
|
||||
if (!empty($context['temporary_gadai'])) {
|
||||
Cache::store('file')->forget('shoraka:payout:' . hash('sha256', $record->kodcaw . ':' . $reference));
|
||||
}
|
||||
return $result;
|
||||
} catch (Throwable $exception) {
|
||||
// A failed remote payment response can be ambiguous. Never retry automatically.
|
||||
|
||||
Reference in New Issue
Block a user