refactor(jobs): optimasi query GenerateClosingBalanceReportJob dengan distinct trans_reference dan amount_lcy
Melakukan refactoring pada GenerateClosingBalanceReportJob untuk meningkatkan performa dan akurasi: - Menghapus eager loading yang kompleks pada relasi 'ft' dan 'dc' untuk menyederhanakan query - Menambahkan distinct(['trans_reference', 'amount_lcy']) pada level query untuk mencegah duplikasi data langsung dari database - Menambahkan orderBy untuk trans_reference dan amount_lcy sebelum orderBy existing untuk konsistensi hasil - Memperbaiki kondisi pada getTableNameByGroup() dari '===' menjadi '!==' untuk logika yang benar - Menghapus method getSelectFields() yang tidak lagi digunakan setelah simplifikasi query - Memperbarui log message untuk mencerminkan penggunaan distinct pada kombinasi trans_reference dan amount_lcy - Meningkatkan efisiensi dengan mengurangi kompleksitas query dan menghindari pemrosesan data duplikat di level aplikasi - Memastikan akurasi perhitungan running balance dengan mengeliminasi entri duplikat sejak awal Perubahan ini menggantikan pendekatan sebelumnya yang menggunakan array $processedTransactions untuk skip duplikat di level aplikasi dengan solusi yang lebih efisien di level database.
This commit is contained in:
@@ -177,40 +177,8 @@ class GenerateClosingBalanceReportJob implements ShouldQueue
|
|||||||
// Tentukan model berdasarkan group name
|
// Tentukan model berdasarkan group name
|
||||||
$modelClass = $this->getModelByGroup();
|
$modelClass = $this->getModelByGroup();
|
||||||
|
|
||||||
// Build query menggunakan pure Eloquent dengan eager loading
|
// Build query menggunakan pure Eloquent dengan distinct pada kombinasi trans_reference dan amount_lcy
|
||||||
$query = $modelClass::with([
|
$query = $modelClass::select([
|
||||||
'ft' => function($query) {
|
|
||||||
$query->select([
|
|
||||||
'_id',
|
|
||||||
'ref_no',
|
|
||||||
'debit_acct_no',
|
|
||||||
'debit_value_date',
|
|
||||||
'credit_acct_no',
|
|
||||||
'bif_rcv_acct',
|
|
||||||
'bif_rcv_name',
|
|
||||||
'credit_value_date',
|
|
||||||
'at_unique_id',
|
|
||||||
'bif_ref_no',
|
|
||||||
'atm_order_id',
|
|
||||||
'recipt_no',
|
|
||||||
'api_iss_acct',
|
|
||||||
'api_benff_acct',
|
|
||||||
'authoriser',
|
|
||||||
'remarks',
|
|
||||||
'payment_details',
|
|
||||||
'merchant_id',
|
|
||||||
'term_id',
|
|
||||||
'date_time'
|
|
||||||
]);
|
|
||||||
},
|
|
||||||
'dc' => function($query) {
|
|
||||||
$query->select([
|
|
||||||
'id',
|
|
||||||
'date_time'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
])
|
|
||||||
->select([
|
|
||||||
'id',
|
'id',
|
||||||
'trans_reference',
|
'trans_reference',
|
||||||
'booking_date',
|
'booking_date',
|
||||||
@@ -219,10 +187,13 @@ class GenerateClosingBalanceReportJob implements ShouldQueue
|
|||||||
])
|
])
|
||||||
->where('account_number', $this->accountNumber)
|
->where('account_number', $this->accountNumber)
|
||||||
->where('booking_date', $this->period)
|
->where('booking_date', $this->period)
|
||||||
|
->distinct(['trans_reference', 'amount_lcy']) // Distinct pada kombinasi trans_reference dan amount_lcy
|
||||||
|
->orderBy('trans_reference')
|
||||||
|
->orderBy('amount_lcy')
|
||||||
->orderBy('booking_date')
|
->orderBy('booking_date')
|
||||||
->orderBy('date_time');
|
->orderBy('date_time');
|
||||||
|
|
||||||
Log::info('Transaction query built successfully using pure Eloquent', [
|
Log::info('Transaction query built successfully using pure Eloquent with distinct trans_reference and amount_lcy', [
|
||||||
'model_class' => $modelClass,
|
'model_class' => $modelClass,
|
||||||
'account_number' => $this->accountNumber,
|
'account_number' => $this->accountNumber,
|
||||||
'period' => $this->period
|
'period' => $this->period
|
||||||
@@ -400,41 +371,7 @@ class GenerateClosingBalanceReportJob implements ShouldQueue
|
|||||||
*/
|
*/
|
||||||
private function getTableNameByGroup(): string
|
private function getTableNameByGroup(): string
|
||||||
{
|
{
|
||||||
return $this->groupName === 'QRIS' ? 'stmt_entry' : 'stmt_entry_details';
|
return $this->groupName !== 'QRIS' ? 'stmt_entry' : 'stmt_entry_details';
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get select fields for the query
|
|
||||||
* Mendapatkan field select untuk query
|
|
||||||
*/
|
|
||||||
private function getSelectFields(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
's.trans_reference',
|
|
||||||
's.booking_date',
|
|
||||||
's.amount_lcy',
|
|
||||||
'ft.debit_acct_no',
|
|
||||||
'ft.debit_value_date',
|
|
||||||
DB::raw('CASE WHEN s.amount_lcy::numeric < 0 THEN s.amount_lcy::numeric ELSE NULL END AS debit_amount'),
|
|
||||||
'ft.credit_acct_no',
|
|
||||||
'ft.bif_rcv_acct',
|
|
||||||
'ft.bif_rcv_name',
|
|
||||||
'ft.credit_value_date',
|
|
||||||
DB::raw('CASE WHEN s.amount_lcy::numeric > 0 THEN s.amount_lcy::numeric ELSE NULL END AS credit_amount'),
|
|
||||||
'ft.at_unique_id',
|
|
||||||
'ft.bif_ref_no',
|
|
||||||
'ft.atm_order_id',
|
|
||||||
'ft.recipt_no',
|
|
||||||
'ft.api_iss_acct',
|
|
||||||
'ft.api_benff_acct',
|
|
||||||
DB::raw('COALESCE(ft.date_time, dc.date_time, s.date_time) AS date_time'),
|
|
||||||
'ft.authoriser',
|
|
||||||
'ft.remarks',
|
|
||||||
'ft.payment_details',
|
|
||||||
'ft.ref_no',
|
|
||||||
'ft.merchant_id',
|
|
||||||
'ft.term_id'
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user