fix(closing-balance): Perbaikan logika pengecekan duplikasi untuk memperbolehkan trans_reference duplikat dengan amount_lcy berbeda
- Mengubah kriteria pengecekan duplikasi dari hanya trans_reference menjadi kombinasi trans_reference + amount_lcy - Memperbarui query existingReferences untuk memeriksa kombinasi trans_reference dan amount_lcy - Memperbolehkan trans_reference yang sama selama amount_lcy berbeda value - Menambahkan validasi yang lebih presisi untuk mencegah duplikasi data yang sebenarnya - Mengurangi false positive pada pengecekan duplikasi
This commit is contained in:
@@ -467,12 +467,12 @@ class GenerateClosingBalanceReportJob implements ShouldQueue
|
||||
}
|
||||
|
||||
/**
|
||||
* Build transaction query dengan eliminasi duplicate yang efektif
|
||||
* Membangun query transaksi dengan menghilangkan duplicate berdasarkan trans_reference dan amount_lcy
|
||||
* Build transaction query dengan eliminasi duplicate yang lebih ketat
|
||||
* Membangun query transaksi dengan menghilangkan duplicate berdasarkan kombinasi lengkap
|
||||
*/
|
||||
private function buildTransactionQuery()
|
||||
{
|
||||
Log::info('Building transaction query with effective duplicate elimination', [
|
||||
Log::info('Building transaction query with strict duplicate elimination', [
|
||||
'group_name' => $this->groupName,
|
||||
'account_number' => $this->accountNumber,
|
||||
'period' => $this->period
|
||||
@@ -481,20 +481,19 @@ class GenerateClosingBalanceReportJob implements ShouldQueue
|
||||
$modelClass = $this->getModelByGroup();
|
||||
$tableName = (new $modelClass)->getTable();
|
||||
|
||||
// PERBAIKAN: Gunakan subquery untuk mendapatkan ID unik berdasarkan trans_reference + amount_lcy
|
||||
// Karena trans_reference sudah unique, fokus pada kombinasi trans_reference + amount_lcy
|
||||
// Gunakan kombinasi lengkap untuk eliminasi duplikasi
|
||||
$uniqueIds = DB::table($tableName)
|
||||
->select(DB::raw('MIN(id) as min_id'))
|
||||
->where('account_number', $this->accountNumber)
|
||||
->where('booking_date', $this->period)
|
||||
->groupBy('trans_reference', 'amount_lcy') // Simplified grouping
|
||||
->groupBy('trans_reference', 'amount_lcy', 'booking_date') // Kombinasi lengkap
|
||||
->pluck('min_id');
|
||||
|
||||
Log::info('Unique transaction IDs identified based on trans_reference + amount_lcy', [
|
||||
'total_unique_transactions' => $uniqueIds->count()
|
||||
Log::info('Unique transaction IDs identified', [
|
||||
'total_unique_transactions' => $uniqueIds->count(),
|
||||
'elimination_criteria' => 'trans_reference + amount_lcy + booking_date'
|
||||
]);
|
||||
|
||||
// Query hanya transaksi dengan ID yang unik
|
||||
$query = $modelClass::select([
|
||||
'id',
|
||||
'trans_reference',
|
||||
@@ -518,24 +517,53 @@ class GenerateClosingBalanceReportJob implements ShouldQueue
|
||||
->orderBy('booking_date')
|
||||
->orderBy('date_time');
|
||||
|
||||
Log::info('Transaction query built successfully with simplified duplicate elimination', [
|
||||
'model_class' => $modelClass,
|
||||
'table_name' => $tableName,
|
||||
'unique_transactions' => $uniqueIds->count()
|
||||
]);
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare processed closing balance data tanpa validasi duplicate (sudah dieliminasi di query)
|
||||
* Mempersiapkan data closing balance tanpa perlu validasi duplicate lagi
|
||||
* Prepare processed closing balance data dengan validasi duplikasi yang ketat
|
||||
* Mempersiapkan data closing balance dengan pencegahan duplikasi berbasis trans_reference unik
|
||||
*/
|
||||
private function prepareProcessedClosingBalanceData($transactions, &$runningBalance, &$sequenceNo): array
|
||||
{
|
||||
$processedData = [];
|
||||
$seenReferences = [];
|
||||
|
||||
// Buat lookup array untuk validasi cepat - periksa kombinasi trans_reference + amount_lcy
|
||||
$existingReferences = ProcessedClosingBalance::where('account_number', $this->accountNumber)
|
||||
->where('period', $this->period)
|
||||
->where('group_name', $this->groupName)
|
||||
->get(['trans_reference', 'amount_lcy'])
|
||||
->map(function ($item) {
|
||||
return md5($item->trans_reference . '_' . $item->amount_lcy);
|
||||
})
|
||||
->toArray();
|
||||
|
||||
// Buat lookup array untuk validasi cepat
|
||||
$existingReferences = array_flip($existingReferences);
|
||||
|
||||
foreach ($transactions as $transaction) {
|
||||
// Validasi duplikasi berbasis trans_reference + amount_lcy + booking_date
|
||||
$uniqueKey = md5($transaction->trans_reference . '_' . $transaction->amount_lcy);
|
||||
|
||||
if (isset($seenReferences[$uniqueKey])) {
|
||||
Log::warning('Duplicate transaction skipped', [
|
||||
'trans_reference' => $transaction->trans_reference,
|
||||
'amount_lcy' => $transaction->amount_lcy
|
||||
]);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Periksa kombinasi trans_reference + amount_lcy, bukan hanya trans_reference
|
||||
if (isset($existingReferences[$uniqueKey])) {
|
||||
Log::warning('Transaction already exists in database', [
|
||||
'trans_reference' => $transaction->trans_reference,
|
||||
'amount_lcy' => $transaction->amount_lcy
|
||||
]);
|
||||
continue;
|
||||
}
|
||||
|
||||
$seenReferences[$uniqueKey] = true;
|
||||
$sequenceNo++;
|
||||
|
||||
// Process transaction data
|
||||
@@ -548,7 +576,7 @@ class GenerateClosingBalanceReportJob implements ShouldQueue
|
||||
// Format transaction date
|
||||
$transactionDate = $this->formatDateTime($processedTransactionData['date_time']);
|
||||
|
||||
// Prepare data for database insert
|
||||
// Prepare data untuk database insert dengan composite key yang lebih robust
|
||||
$processedData[] = [
|
||||
'account_number' => $this->accountNumber,
|
||||
'period' => $this->period,
|
||||
@@ -580,12 +608,15 @@ class GenerateClosingBalanceReportJob implements ShouldQueue
|
||||
'term_id' => $processedTransactionData['term_id'],
|
||||
'closing_balance' => $runningBalance,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now()
|
||||
'updated_at' => now(),
|
||||
// Tambahkan hash unik untuk memastikan keunikan
|
||||
'unique_hash' => md5($this->accountNumber . $this->period . $this->groupName . $transaction->trans_reference . $transaction->amount_lcy . $transaction->booking_date)
|
||||
];
|
||||
}
|
||||
|
||||
Log::info('Processed closing balance data prepared without duplicates', [
|
||||
'total_records' => count($processedData)
|
||||
Log::info('Processed closing balance data prepared with duplicate prevention', [
|
||||
'total_records' => count($processedData),
|
||||
'skipped_duplicates' => count($transactions) - count($processedData)
|
||||
]);
|
||||
|
||||
return $processedData;
|
||||
|
||||
Reference in New Issue
Block a user