diff --git a/app/Jobs/ExportStatementJob.php b/app/Jobs/ExportStatementJob.php index b0b5d30..93861e3 100644 --- a/app/Jobs/ExportStatementJob.php +++ b/app/Jobs/ExportStatementJob.php @@ -55,15 +55,7 @@ try { Log::info("Starting export statement job for account: {$this->account_number}, period: {$this->period}"); - // Cek apakah data sudah diproses sebelumnya - $existingData = ProcessedStatement::where('account_number', $this->account_number) - ->where('period', $this->period) - ->exists(); - - if (!$existingData) { - // Jika belum ada data yang diproses, lakukan pemrosesan - $this->processStatementData(); - } + $this->processStatementData(); // Export data yang sudah diproses ke CSV $this->exportToCsv(); @@ -75,77 +67,119 @@ } } - /** - * Process statement data and save to database - */ - private function processStatementData() - : void + private function processStatementData(): void { - // Hapus data yang mungkin sudah ada untuk kombinasi account dan period yang sama - ProcessedStatement::where('account_number', $this->account_number) - ->where('period', $this->period) - ->delete(); + $accountQuery = [ + 'account_number' => $this->account_number, + 'period' => $this->period + ]; + $totalCount = $this->getTotalEntryCount($accountQuery); + $existingDataCount = $this->getExistingProcessedCount($accountQuery); + + // Hanya proses jika data belum lengkap diproses + if ($existingDataCount !== $totalCount) { + $this->deleteExistingProcessedData($accountQuery); + $this->processAndSaveStatementEntries($totalCount); + } + } + + private function getTotalEntryCount(array $criteria): int + { + return StmtEntry::where('account_number', $criteria['account_number']) + ->where('booking_date', $criteria['period']) + ->count(); + } + + private function getExistingProcessedCount(array $criteria): int + { + return ProcessedStatement::where('account_number', $criteria['account_number']) + ->where('period', $criteria['period']) + ->count(); + } + + private function deleteExistingProcessedData(array $criteria): void + { + ProcessedStatement::where('account_number', $criteria['account_number']) + ->where('period', $criteria['period']) + ->delete(); + } + + private function processAndSaveStatementEntries(int $totalCount): void + { $runningBalance = (float) $this->saldo; - $totalCount = StmtEntry::where('account_number', $this->account_number) - ->where('booking_date', $this->period) - ->count(); + $globalSequence = 0; Log::info("Processing {$totalCount} statement entries for account: {$this->account_number}"); - // Track the global sequence number across chunks - $globalSequence = 0; - - // Proses data dalam chunk untuk mengurangi penggunaan memori StmtEntry::with(['ft', 'transaction']) - ->where('account_number', $this->account_number) - ->where('booking_date', $this->period) - ->orderBy('date_time', 'ASC') - ->orderBy('trans_reference', 'ASC') - ->chunk($this->chunkSize, function ($entries) use (&$runningBalance, &$globalSequence) { - $processedData = []; + ->where('account_number', $this->account_number) + ->where('booking_date', $this->period) + ->orderBy('date_time', 'ASC') + ->orderBy('trans_reference', 'ASC') + ->chunk($this->chunkSize, function ($entries) use (&$runningBalance, &$globalSequence) { + $processedData = $this->prepareProcessedData($entries, $runningBalance, $globalSequence); - foreach ($entries as $item) { - $globalSequence++; // Increment the global sequence counter - $runningBalance += (float) $item->amount_lcy; + if (!empty($processedData)) { + DB::table('processed_statements')->insert($processedData); + } + }); + } - try { - $transactionDate = Carbon::createFromFormat('YmdHi', $item->booking_date . substr($item->ft?->date_time ?? '0000000000', 6, 4)) - ->format('d/m/Y H:i'); - } catch (Exception $e) { - $transactionDate = Carbon::now()->format('d/m/Y H:i'); - Log::warning("Error formatting transaction date: " . $e->getMessage()); - } + private function prepareProcessedData($entries, &$runningBalance, &$globalSequence): array + { + $processedData = []; - try { - $actualDate = Carbon::createFromFormat('ymdHi', $item->ft?->date_time ?? '2505120000') - ->format('d/m/Y H:i'); - } catch (Exception $e) { - $actualDate = Carbon::now()->format('d/m/Y H:i'); - Log::warning("Error formatting actual date: " . $e->getMessage()); - } + foreach ($entries as $item) { + $globalSequence++; + $runningBalance += (float) $item->amount_lcy; - $processedData[] = [ - 'account_number' => $this->account_number, - 'period' => $this->period, - 'sequence_no' => $globalSequence, - 'transaction_date' => $transactionDate, - 'reference_number' => $item->trans_reference, - 'transaction_amount' => $item->amount_lcy, - 'transaction_type' => $item->amount_lcy < 0 ? 'D' : 'C', - 'description' => $this->generateNarrative($item), - 'end_balance' => $runningBalance, - 'actual_date' => $actualDate, - 'created_at' => now(), - 'updated_at' => now(), - ]; - } - // var_dump($processedData); - // Simpan data dalam batch untuk kinerja yang lebih baik - if (!empty($processedData)) { - DB::table('processed_statements')->insert($processedData); - } - }); + $transactionDate = $this->formatTransactionDate($item); + $actualDate = $this->formatActualDate($item); + + $processedData[] = [ + 'account_number' => $this->account_number, + 'period' => $this->period, + 'sequence_no' => $globalSequence, + 'transaction_date' => $transactionDate, + 'reference_number' => $item->trans_reference, + 'transaction_amount' => $item->amount_lcy, + 'transaction_type' => $item->amount_lcy < 0 ? 'D' : 'C', + 'description' => $this->generateNarrative($item), + 'end_balance' => $runningBalance, + 'actual_date' => $actualDate, + 'created_at' => now(), + 'updated_at' => now(), + ]; + } + + return $processedData; + } + + private function formatTransactionDate($item): string + { + try { + return Carbon::createFromFormat( + 'YmdHi', + $item->booking_date . substr($item->ft?->date_time ?? '0000000000', 6, 4) + )->format('d/m/Y H:i'); + } catch (Exception $e) { + Log::warning("Error formatting transaction date: " . $e->getMessage()); + return Carbon::now()->format('d/m/Y H:i'); + } + } + + private function formatActualDate($item): string + { + try { + return Carbon::createFromFormat( + 'ymdHi', + $item->ft?->date_time ?? '2505120000' + )->format('d/m/Y H:i'); + } catch (Exception $e) { + Log::warning("Error formatting actual date: " . $e->getMessage()); + return Carbon::now()->format('d/m/Y H:i'); + } } /**