feat(webstatement): fallback stmt_entry_id menggunakan field id pada CSV
Menambahkan dukungan fallback untuk nilai `stmt_entry_id` yang kosong/null dengan menggunakan field `id` dari CSV (jika tersedia di akhir file). Perubahan yang dilakukan: - Menambahkan 'id' sebagai bagian dari expected CSV headers - Mengimplementasikan handleStmtEntryIdFallback() untuk logika pengganti - Menggunakan field 'id' sebagai stmt_entry_id jika nilainya kosong atau null - Menyesuaikan validasi jumlah kolom terhadap struktur CSV terbaru - Melakukan pembersihan field 'id' sebelum data disimpan ke database - Memperkuat validasi di addToBatch() agar stmt_entry_id selalu valid - Menambahkan logging untuk proses fallback dan debugging - Meningkatkan error handling untuk kasus data tidak valid - Menjamin kompatibilitas dengan struktur model StmtEntryDetail - Optimasi batch insert melalui pengecekan dan pembersihan data lebih ketat
This commit is contained in:
@@ -114,6 +114,12 @@
|
||||
],
|
||||
'SWADAYA_PANDU' => [
|
||||
'0081272689',
|
||||
],
|
||||
"AWAN_LINTANG_SOLUSI"=> [
|
||||
"1084269430"
|
||||
],
|
||||
"MONETA"=> [
|
||||
"1085667890"
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
@@ -162,17 +162,20 @@ class ProcessStmtEntryDetailDataJob implements ShouldQueue
|
||||
}
|
||||
|
||||
$headers = (new StmtEntryDetail())->getFillable();
|
||||
// Tambahkan field 'id' ke headers untuk menangani kolom tambahan di akhir CSV
|
||||
$expectedHeaders = array_merge($headers, ['id']);
|
||||
$rowCount = 0;
|
||||
$chunkCount = 0;
|
||||
|
||||
Log::info('Memulai proses file', [
|
||||
'file_path' => $filePath,
|
||||
'headers_count' => count($headers)
|
||||
'headers_count' => count($headers),
|
||||
'expected_headers_count' => count($expectedHeaders)
|
||||
]);
|
||||
|
||||
while (($row = fgetcsv($handle, 0, self::CSV_DELIMITER)) !== false) {
|
||||
$rowCount++;
|
||||
$this->processRow($row, $headers, $rowCount, $filePath);
|
||||
$this->processRow($row, $expectedHeaders, $rowCount, $filePath);
|
||||
|
||||
// Process in chunks to avoid memory issues
|
||||
if (count($this->entryBatch) >= self::CHUNK_SIZE) {
|
||||
@@ -192,39 +195,67 @@ class ProcessStmtEntryDetailDataJob implements ShouldQueue
|
||||
}
|
||||
|
||||
/**
|
||||
* Proses setiap baris data
|
||||
* Proses setiap baris data dengan penanganan field id tambahan
|
||||
*
|
||||
* @param array $row Data baris
|
||||
* @param array $headers Header kolom
|
||||
* @param array $expectedHeaders Header kolom yang diharapkan (termasuk id)
|
||||
* @param int $rowCount Nomor baris
|
||||
* @param string $filePath Path file
|
||||
* @return void
|
||||
*/
|
||||
private function processRow(array $row, array $headers, int $rowCount, string $filePath): void
|
||||
private function processRow(array $row, array $expectedHeaders, int $rowCount, string $filePath): void
|
||||
{
|
||||
if (count($headers) !== count($row)) {
|
||||
// Validasi jumlah kolom - sekarang menggunakan expectedHeaders yang sudah include field 'id'
|
||||
if (count($expectedHeaders) !== count($row)) {
|
||||
Log::warning("Row $rowCount in $filePath has incorrect column count. Expected: " .
|
||||
count($headers) . ", Got: " . count($row));
|
||||
count($expectedHeaders) . ", Got: " . count($row));
|
||||
$this->errorCount++;
|
||||
return;
|
||||
}
|
||||
|
||||
$data = array_combine($headers, $row);
|
||||
// Kombinasikan data dengan headers
|
||||
$data = array_combine($expectedHeaders, $row);
|
||||
|
||||
// Log untuk debugging struktur data
|
||||
Log::debug('Processing row data', [
|
||||
'row_count' => $rowCount,
|
||||
'stmt_entry_id' => $data['stmt_entry_id'] ?? 'not_set',
|
||||
'id' => $data['id'] ?? 'not_set'
|
||||
]);
|
||||
|
||||
// Logika untuk menggunakan field 'id' sebagai fallback jika stmt_entry_id kosong
|
||||
$this->handleStmtEntryIdFallback($data);
|
||||
|
||||
// Hapus field 'id' dari data sebelum disimpan karena tidak ada di fillable model
|
||||
unset($data['id']);
|
||||
|
||||
$this->cleanTransReference($data);
|
||||
$this->addToBatch($data, $rowCount, $filePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bersihkan trans_reference dari karakter tidak diinginkan
|
||||
* Menangani logika fallback untuk stmt_entry_id menggunakan field id
|
||||
*
|
||||
* @param array $data Data yang akan dibersihkan
|
||||
* @param array $data Data yang akan diproses
|
||||
* @return void
|
||||
*/
|
||||
private function cleanTransReference(array &$data): void
|
||||
private function handleStmtEntryIdFallback(array &$data): void
|
||||
{
|
||||
if (isset($data['trans_reference'])) {
|
||||
// Clean trans_reference from \\BNK if present
|
||||
$data['trans_reference'] = preg_replace('/\\\\.*$/', '', $data['trans_reference']);
|
||||
Log::debug('Trans reference cleaned', ['original' => $data['trans_reference']]);
|
||||
// Jika stmt_entry_id kosong atau null, gunakan value dari field 'id'
|
||||
if (empty($data['stmt_entry_id']) || $data['stmt_entry_id'] === '' || $data['stmt_entry_id'] === null) {
|
||||
if (isset($data['id']) && !empty($data['id'])) {
|
||||
$data['stmt_entry_id'] = $data['id'];
|
||||
|
||||
Log::info('Using id as stmt_entry_id fallback', [
|
||||
'original_stmt_entry_id' => $data['stmt_entry_id'] ?? 'empty',
|
||||
'fallback_id' => $data['id']
|
||||
]);
|
||||
} else {
|
||||
Log::warning('Both stmt_entry_id and id are empty', [
|
||||
'stmt_entry_id' => $data['stmt_entry_id'] ?? 'not_set',
|
||||
'id' => $data['id'] ?? 'not_set'
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,7 +270,11 @@ class ProcessStmtEntryDetailDataJob implements ShouldQueue
|
||||
private function addToBatch(array $data, int $rowCount, string $filePath): void
|
||||
{
|
||||
try {
|
||||
if (isset($data['stmt_entry_id']) && $data['stmt_entry_id'] !== 'stmt_entry_id') {
|
||||
// Validasi bahwa stmt_entry_id tidak kosong dan bukan header
|
||||
if (isset($data['stmt_entry_id']) &&
|
||||
$data['stmt_entry_id'] !== 'stmt_entry_id' &&
|
||||
!empty($data['stmt_entry_id'])) {
|
||||
|
||||
// Add timestamp fields
|
||||
$now = now();
|
||||
$data['created_at'] = $now;
|
||||
@@ -249,7 +284,16 @@ class ProcessStmtEntryDetailDataJob implements ShouldQueue
|
||||
$this->entryBatch[] = $data;
|
||||
$this->processedCount++;
|
||||
|
||||
Log::debug('Record added to batch', ['row' => $rowCount, 'stmt_entry_id' => $data['stmt_entry_id']]);
|
||||
Log::debug('Record added to batch', [
|
||||
'row' => $rowCount,
|
||||
'stmt_entry_id' => $data['stmt_entry_id']
|
||||
]);
|
||||
} else {
|
||||
Log::warning('Skipping row due to invalid stmt_entry_id', [
|
||||
'row' => $rowCount,
|
||||
'stmt_entry_id' => $data['stmt_entry_id'] ?? 'not_set'
|
||||
]);
|
||||
$this->errorCount++;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$this->errorCount++;
|
||||
@@ -257,6 +301,21 @@ class ProcessStmtEntryDetailDataJob implements ShouldQueue
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bersihkan trans_reference dari karakter tidak diinginkan
|
||||
*
|
||||
* @param array $data Data yang akan dibersihkan
|
||||
* @return void
|
||||
*/
|
||||
private function cleanTransReference(array &$data): void
|
||||
{
|
||||
if (isset($data['trans_reference'])) {
|
||||
// Clean trans_reference from \\BNK if present
|
||||
$data['trans_reference'] = preg_replace('/\\\\.*$/', '', $data['trans_reference']);
|
||||
Log::debug('Trans reference cleaned', ['original' => $data['trans_reference']]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Simpan batch data ke database menggunakan updateOrCreate
|
||||
* untuk menghindari error unique constraint
|
||||
|
||||
Reference in New Issue
Block a user