From 823ccf0fe74a4f8064eb829c2284ad5033896136 Mon Sep 17 00:00:00 2001 From: Daeng Deni Mardaeni Date: Mon, 12 May 2025 18:28:34 +0700 Subject: [PATCH] refactor(webstatement): improve ATM card sync logic and error handling - Update filter untuk query dengan kondisi tambahan pada `crsts` dan pengecualian jenis kartu tertentu. - Refactor metode `scheduleUpdateBranchCurrencyJobs`: - Tambahkan batch process untuk penghematan memori. - Log tambahan untuk melacak progres yang lebih jelas. - Perbaikan logika penjadwalan job dengan penundaan (delay) dinamis. - Penanganan error yang lebih detail dan log pendukung untuk debugging. - Perbaikan pada controller `KartuAtmController`: - Amankan akses properti menggunakan null-safe operator pada data biaya kartu. Signed-off-by: Daeng Deni Mardaeni --- app/Http/Controllers/KartuAtmController.php | 2 +- app/Jobs/BiayaKartu.php | 112 +++++++++++++++----- 2 files changed, 87 insertions(+), 27 deletions(-) diff --git a/app/Http/Controllers/KartuAtmController.php b/app/Http/Controllers/KartuAtmController.php index 3369e76..7be2fab 100644 --- a/app/Http/Controllers/KartuAtmController.php +++ b/app/Http/Controllers/KartuAtmController.php @@ -86,7 +86,7 @@ $currentPage = $request->get('page') ?: 1; $data = $data->map(function ($item) { - $item->fee = $item->biaya->biaya; + $item->fee = $item->biaya?->biaya; return $item; }); diff --git a/app/Jobs/BiayaKartu.php b/app/Jobs/BiayaKartu.php index 5cc0fcb..046ae1c 100644 --- a/app/Jobs/BiayaKartu.php +++ b/app/Jobs/BiayaKartu.php @@ -182,7 +182,8 @@ ->table(self::DB_TABLE) ->select('CRDNO', 'ACCFLAG', 'CRACC1', 'CRACC2', 'CRACC3', 'CRACC4', 'CRACC5', 'CRACCNAM1', 'CRACCNAM2', 'CRACCNAM3', 'CRACCNAM4', 'CRACCNAM5', 'CRSTS', 'CTTYPE', 'CTDESC', 'CRDATE', 'LASTUPDATE') ->join('IST77.CMS_VCARDTYP', 'IST77.CMS_VCARD.CRTYPE', '=', 'IST77.CMS_VCARDTYP.CTTYPE') - ->where('crsts', 1) + ->where('crsts', '!=',2) + ->whereNotIn('cttype',['2','3','6']) ->whereNotNull('ACCFLAG') ->where('ACCFLAG', '>', 0) ->skip($offset) @@ -252,46 +253,105 @@ * * @return void */ - private function scheduleUpdateBranchCurrencyJobs() - : void + /** + * 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(); + // Process cards in chunks to avoid memory issues + $batchSize = 1000; // Process 1000 cards at a time + $totalProcessed = 0; + $batchNumber = 0; - $totalCards = $cards->count(); - Log::info("Menjadwalkan {$totalCards} job pembaruan branch dan currency"); + // Get total count first (without loading all records) + $totalCards = Atmcard::where('crsts', 1) + ->whereNotNull('accflag') + ->where('accflag', '!=', '') + ->where(function ($query) { + $query->whereNull('branch') + ->orWhere('branch', '') + ->orWhereNull('currency') + ->orWhere('currency', ''); + }) + ->count(); + + Log::info("Total {$totalCards} cards need branch and currency update"); // Update log $this->syncLog->update([ - 'sync_notes' => $this->syncLog->sync_notes . "\nMenjadwalkan {$totalCards} job pembaruan branch dan currency" + 'sync_notes' => $this->syncLog->sync_notes . "\nTotal {$totalCards} cards need branch and currency update" ]); - foreach ($cards as $card) { - foreach ($cards as $index => $card) { - UpdateAtmCardBranchCurrencyJob::dispatch($card, $this->syncLog->id) - ->delay(now()->addSeconds(1 * ($index + 1))); - } - } + // Process in batches + do { + // Get a batch of cards + $cards = Atmcard::where('crsts', 1) + ->whereNotNull('accflag') + ->where('accflag', '!=', '') + ->where(function ($query) { + $query->whereNull('branch') + ->orWhere('branch', '') + ->orWhereNull('currency') + ->orWhere('currency', ''); + }) + ->skip($batchNumber * $batchSize) + ->take($batchSize) + ->get(); + + $currentBatchCount = $cards->count(); + $totalProcessed += $currentBatchCount; + + if ($currentBatchCount > 0) { + Log::info("Processing batch #{$batchNumber}: {$currentBatchCount} cards (Total processed: {$totalProcessed}/{$totalCards})"); + + // Schedule jobs for this batch with increasing delay + foreach ($cards as $index => $card) { + // Calculate delay based on batch number and index to spread out job execution + $delay = ($batchNumber * $batchSize + $index) % 300; // Spread over 5 minutes (300 seconds) + + // Dispatch job with the card ID instead of the full object to save memory + UpdateAtmCardBranchCurrencyJob::dispatch($card, $this->syncLog->id) + ->delay(now()->addSeconds($delay)); + } + + // Update progress in log every 10 batches + if ($batchNumber % 10 === 0) { + $this->syncLog->update([ + 'sync_notes' => $this->syncLog->sync_notes . "\nProcessed {$totalProcessed} of {$totalCards} cards for branch and currency update" + ]); + } + } + + $batchNumber++; + + // Free up memory + unset($cards); + + // Force garbage collection if PHP version supports it + if (function_exists('gc_collect_cycles')) { + gc_collect_cycles(); + } + + } while ($currentBatchCount > 0); + + Log::info("All {$totalProcessed} branch and currency update jobs have been scheduled"); + + // Final update to log + $this->syncLog->update([ + 'sync_notes' => $this->syncLog->sync_notes . "\nAll {$totalProcessed} branch and currency update jobs have been scheduled" + ]); - Log::info('Semua job pembaruan branch dan currency telah dijadwalkan'); } catch (Exception $e) { - Log::error('Gagal menjadwalkan job pembaruan branch dan currency: ' . $e->getMessage(), [ + Log::error('Failed to schedule branch and currency update jobs: ' . $e->getMessage(), [ 'file' => $e->getFile(), 'line' => $e->getLine() ]); $this->syncLog->update([ - 'sync_notes' => $this->syncLog->sync_notes . "\nError: Gagal menjadwalkan job pembaruan branch dan currency: " . $e->getMessage() + 'sync_notes' => $this->syncLog->sync_notes . "\nError: Failed to schedule branch and currency update jobs: " . $e->getMessage() ]); } }