From df097a279ff635bb5a1fb7804bccf61f998fc7b6 Mon Sep 17 00:00:00 2001 From: Daeng Deni Mardaeni Date: Fri, 9 May 2025 15:42:18 +0700 Subject: [PATCH] refactor(webstatement): optimalkan sinkronisasi dan pembaruan data kartu ATM - Menghapus dependensi yang tidak digunakan untuk memperingkas kode. - Memisahkan logika pembaruan branch dan currency menjadi job terpisah `UpdateAtmCardBranchCurrencyJob`. - Menambahkan penjadwalan job untuk pembaruan branch dan currency setelah sinkronisasi kartu selesai. - Mengubah query database untuk sinkronisasi kartu menjadi lebih sederhana. - Menambahkan binding `UpdateAtmCardBranchCurrencyJob` di service provider. Refactor ini meningkatkan readability dan modularitas kode dengan memisahkan tanggung jawab tiap proses. Signed-off-by: Daeng Deni Mardaeni --- app/Jobs/BiayaKartu.php | 362 ++++++++---------- app/Jobs/UpdateAtmCardBranchCurrencyJob.php | 117 ++++++ app/Providers/WebstatementServiceProvider.php | 3 +- 3 files changed, 277 insertions(+), 205 deletions(-) create mode 100644 app/Jobs/UpdateAtmCardBranchCurrencyJob.php diff --git a/app/Jobs/BiayaKartu.php b/app/Jobs/BiayaKartu.php index c0e653a..7cc8444 100644 --- a/app/Jobs/BiayaKartu.php +++ b/app/Jobs/BiayaKartu.php @@ -1,217 +1,171 @@ syncAtmCards(); - /** - * API dan database constants - */ - private const API_BASE_PATH = '/restgateway/services/IGATEToCoreBankingServices'; - private const API_INQUIRY_PATH = '/InquiryBalanceService'; - private const DB_TABLE = 'IST77.CMS_VCARD'; - private const BATCH_SIZE = 100; - private const MAX_EXECUTION_TIME = 86400; // 24 jam dalam detik + // Setelah sync selesai, jadwalkan job untuk memperbarui branch dan currency + $this->scheduleUpdateBranchCurrencyJobs(); + } - /** - * Execute the job. - */ - public function handle() - : void - { - set_time_limit(self::MAX_EXECUTION_TIME); - $this->syncAtmCards(); - } + /** + * Synchronize ATM cards data from Oracle database + * + * @return void + */ + private function syncAtmCards(): void + { + try { + $offset = 0; + $hasMoreRecords = true; - /** - * Synchronize ATM cards data from Oracle database - * - * @return void - */ - private function syncAtmCards() - : void - { - try { - $offset = 0; - $hasMoreRecords = true; + while ($hasMoreRecords) { + $cards = $this->fetchCardBatch($offset); + $this->processCardBatch($cards); - while ($hasMoreRecords) { - $cards = $this->fetchCardBatch($offset); - $this->processCardBatch($cards); - - $hasMoreRecords = count($cards) === self::BATCH_SIZE; - $offset += self::BATCH_SIZE; - } - - Log::info('Sinkronisasi kartu ATM berhasil diselesaikan'); - } catch (Exception $e) { - Log::error('BiayaKartu: syncAtmCards: ' . $e->getMessage(), [ - 'file' => $e->getFile(), - 'line' => $e->getLine() - ]); + $hasMoreRecords = count($cards) === self::BATCH_SIZE; + $offset += self::BATCH_SIZE; } - } - /** - * Fetch a batch of ATM cards from the database - * - * @param int $offset - * - * @return \Illuminate\Support\Collection - */ - private function fetchCardBatch(int $offset) - { - return DB::connection('oracle') - ->table(self::DB_TABLE) - ->select('CRDNO','ACCFLAG','CRACC1','CRACC2','CRACC3','CRACC4','CRACC5','CRSTS','CRACCNAM1','CRACCNAM2','CRACCNAM3','CRACCNAM4','CRACCNAM5','CTTYPE','CTDESC','CRDATE','LASTUPDATE') - ->join('IST77.CMS_VCARDTYP','IST77.CMS_VCARD.CRTYPE','=','IST77.CMS_VCARDTYP.CTTYPE') - ->where('crsts', 1) - ->whereNotNull('ACCFLAG') - ->where('ACCFLAG', '>', 0) - ->skip($offset) - ->take(self::BATCH_SIZE) - ->get(); - } - - /** - * Process a batch of ATM cards - * - * @param \Illuminate\Support\Collection $cards - * - * @return void - */ - private function processCardBatch($cards) - : void - { - foreach ($cards as $card) { - try { - // Perbarui data kartu dasar - $cardData = $this->getCardBaseData($card); - - Atmcard::updateOrCreate(['crdno' => $card->crdno], $cardData); - $existingCard = $this->getExistingCard($card->crdno); - // Periksa jika perlu memperbarui branch dan currency - if ($this->needBranchAndCurrencyUpdate($existingCard)) { - $accountInfo = $this->getAccountInfo($card->accflag); - if($accountInfo['responseCode'] === '00') { - $this->updateBranchAndCurrency($card->crdno, $accountInfo); - } - } - } catch (Exception $e) { - Log::warning("Gagal memproses kartu {$card->crdno}: " . $e->getMessage()); - } - } - } - - /** - * Get existing card from database if exists - * - * @param string $cardNumber - * - * @return Atmcard|null - */ - private function getExistingCard(string $cardNumber) - : ?Atmcard - { - return Atmcard::where('crdno', $cardNumber)->first(); - } - - /** - * Get base data for card update - * - * @param object $card - * - * @return array - */ - private function getCardBaseData(object $card) - : array - { - return [ - 'accflag' => $card->accflag, - 'cracc1' => $card->cracc1, - 'cracc2' => $card->cracc2, - 'cracc3' => $card->cracc3, - 'cracc4' => $card->cracc4, - 'cracc5' => $card->cracc5, - 'craccnam1' => $card->craccnam1, - 'craccnam2' => $card->craccnam2, - 'craccnam3' => $card->craccnam3, - 'craccnam4' => $card->craccnam4, - 'craccnam5' => $card->craccnam5, - 'crsts' => $card->crsts, - 'cttype' => $card->cttype, - 'ctdesc' => $card->ctdesc, - 'crdate' => $card->crdate, - 'last_update' => $card->lastupdate, - ]; - } - - /** - * Check if branch and currency update is needed - * - * @param Atmcard|null $card - * - * @return bool - */ - private function needBranchAndCurrencyUpdate(?Atmcard $card) - : bool - { - // Jika kartu belum ada atau branch/currency belum terisi - return $card === null || empty($card->branch) || empty($card->currency); - } - - /** - * Get account information from the API - * - * @param string $accountNumber - * - * @return array - */ - private function getAccountInfo(string $accountNumber) - : array - { - $url = env('FIORANO_URL') . self::API_BASE_PATH; - $path = self::API_INQUIRY_PATH; - $data = [ - 'accountNo' => $accountNumber - ]; - - $response = Http::post($url . $path, $data); - - return $response->json(); - } - - /** - * Update branch and currency information for a card - * - * @param string $cardNumber - * @param array $accountInfo - * - * @return void - */ - private function updateBranchAndCurrency(string $cardNumber, array $accountInfo) - : void - { - $cardData = [ - 'branch' => !empty($accountInfo['acctCompany']) ? $accountInfo['acctCompany'] : null, - 'currency' => !empty($accountInfo['acctCurrency']) ? $accountInfo['acctCurrency'] : null, - ]; - - Atmcard::where('crdno', $cardNumber)->update($cardData); - - Log::info("Berhasil memperbarui branch dan currency untuk kartu {$cardNumber}"); + Log::info('Sinkronisasi kartu ATM berhasil diselesaikan'); + } catch (Exception $e) { + Log::error('BiayaKartu: syncAtmCards: ' . $e->getMessage(), [ + 'file' => $e->getFile(), + 'line' => $e->getLine() + ]); } } + + /** + * Fetch a batch of ATM cards from the database + * + * @param int $offset + * + * @return \Illuminate\Support\Collection + */ + private function fetchCardBatch(int $offset) + { + return DB::connection('oracle') + ->table(self::DB_TABLE) + ->where('crsts', 1) + ->whereNotNull('ACCFLAG') + ->where('ACCFLAG', '>', 0) + ->skip($offset) + ->take(self::BATCH_SIZE) + ->get(); + } + + /** + * Process a batch of ATM cards + * + * @param \Illuminate\Support\Collection $cards + * + * @return void + */ + private function processCardBatch($cards): void + { + foreach ($cards as $card) { + try { + // Perbarui data kartu dasar + $cardData = $this->getCardBaseData($card); + Atmcard::updateOrCreate(['crdno' => $card->crdno], $cardData); + } catch (Exception $e) { + Log::warning("Gagal memproses kartu {$card->crdno}: " . $e->getMessage()); + } + } + } + + /** + * Schedule update branch and currency jobs for cards that need update + * + * @return void + */ + private function scheduleUpdateBranchCurrencyJobs(): void + { + try { + // Ambil semua kartu yang perlu diperbarui branch dan currency + $cards = Atmcard::where('crsts', 1) + ->whereNotNull('accflag') + ->where('accflag', '!=', '') + ->where(function($query) { + $query->whereNull('branch') + ->orWhere('branch', '') + ->orWhereNull('currency') + ->orWhere('currency', ''); + }) + ->get(); + + $totalCards = $cards->count(); + Log::info("Menjadwalkan {$totalCards} job pembaruan branch dan currency"); + + foreach ($cards as $card) { + // Jadwalkan job dengan delay untuk menghindari terlalu banyak request bersamaan + UpdateAtmCardBranchCurrencyJob::dispatch($card) + ->delay(now()->addSeconds(rand(1, 300))); // Random delay antara 1-300 detik + } + + Log::info('Semua job pembaruan branch dan currency telah dijadwalkan'); + } catch (Exception $e) { + Log::error('Gagal menjadwalkan job pembaruan branch dan currency: ' . $e->getMessage(), [ + 'file' => $e->getFile(), + 'line' => $e->getLine() + ]); + } + } + + /** + * Get base data for card update + * + * @param object $card + * + * @return array + */ + private function getCardBaseData(object $card): array + { + return [ + 'accflag' => $card->accflag, + 'cracc1' => $card->cracc1, + 'cracc2' => $card->cracc2, + 'cracc3' => $card->cracc3, + 'cracc4' => $card->cracc4, + 'cracc5' => $card->cracc5, + 'craccnam1' => $card->craccnam1, + 'craccnam2' => $card->craccnam2, + 'craccnam3' => $card->craccnam3, + 'craccnam4' => $card->craccnam4, + 'craccnam5' => $card->craccnam5, + 'crsts' => $card->crsts, + 'cttype' => $card->cttype, + 'ctdesc' => $card->ctdesc, + 'crdate' => $card->crdate, + 'last_update' => $card->lastupdate, + ]; + } +} diff --git a/app/Jobs/UpdateAtmCardBranchCurrencyJob.php b/app/Jobs/UpdateAtmCardBranchCurrencyJob.php new file mode 100644 index 0000000..90829d8 --- /dev/null +++ b/app/Jobs/UpdateAtmCardBranchCurrencyJob.php @@ -0,0 +1,117 @@ +card = $card; + } + + /** + * Execute the job. + * + * @return void + */ + public function handle(): void + { + try { + if ($this->needBranchAndCurrencyUpdate()) { + $accountInfo = $this->getAccountInfo($this->card->accflag); + if ($accountInfo && isset($accountInfo['responseCode']) && $accountInfo['responseCode'] === '00') { + $this->updateBranchAndCurrency($accountInfo); + Log::info("Berhasil memperbarui branch dan currency untuk kartu {$this->card->crdno}"); + } else { + Log::warning("Gagal mendapatkan informasi akun untuk kartu {$this->card->crdno}. Response: " . + json_encode($accountInfo ?? ['error' => 'No response'])); + } + } + } catch (Exception $e) { + Log::error("Error saat memperbarui branch dan currency untuk kartu {$this->card->crdno}: " . $e->getMessage(), [ + 'file' => $e->getFile(), + 'line' => $e->getLine() + ]); + } + } + + /** + * Check if branch and currency update is needed + * + * @return bool + */ + private function needBranchAndCurrencyUpdate(): bool + { + return empty($this->card->branch) || empty($this->card->currency); + } + + /** + * Get account information from the API + * + * @param string $accountNumber + * @return array|null + */ + private function getAccountInfo(string $accountNumber): ?array + { + try { + $url = env('FIORANO_URL') . self::API_BASE_PATH; + $path = self::API_INQUIRY_PATH; + $data = [ + 'accountNo' => $accountNumber + ]; + + $response = Http::post($url . $path, $data); + return $response->json(); + } catch (Exception $e) { + Log::error("Gagal mendapatkan informasi akun: " . $e->getMessage()); + return null; + } + } + + /** + * Update branch and currency information for the card + * + * @param array $accountInfo + * @return void + */ + private function updateBranchAndCurrency(array $accountInfo): void + { + $cardData = [ + 'branch' => !empty($accountInfo['acctCompany']) ? $accountInfo['acctCompany'] : null, + 'currency' => !empty($accountInfo['acctCurrency']) ? $accountInfo['acctCurrency'] : null, + ]; + + $this->card->update($cardData); + } +} diff --git a/app/Providers/WebstatementServiceProvider.php b/app/Providers/WebstatementServiceProvider.php index 8074c98..3223524 100644 --- a/app/Providers/WebstatementServiceProvider.php +++ b/app/Providers/WebstatementServiceProvider.php @@ -7,6 +7,7 @@ use Illuminate\Support\Facades\Blade; use Illuminate\Support\ServiceProvider; use Modules\Webstatement\Console\GenerateBiayakartuCommand; use Modules\Webstatement\Console\GenerateBiayaKartuCsvCommand; +use Modules\Webstatement\Jobs\UpdateAtmCardBranchCurrencyJob; use Nwidart\Modules\Traits\PathNamespace; class WebstatementServiceProvider extends ServiceProvider @@ -41,6 +42,7 @@ class WebstatementServiceProvider extends ServiceProvider { $this->app->register(EventServiceProvider::class); $this->app->register(RouteServiceProvider::class); + $this->app->bind(UpdateAtmCardBranchCurrencyJob::class); } /** @@ -51,7 +53,6 @@ class WebstatementServiceProvider extends ServiceProvider $this->commands([ GenerateBiayakartuCommand::class, GenerateBiayaKartuCsvCommand::class - ]); }