initializeErrorLog(); // Path ke file csv $filePath = realpath(__DIR__ . '/csv/detail-dokumen/mig_detail_dokumen.csv'); if (!$filePath) { Log::error('File csv tidak ditemukan: ' . __DIR__ . '/csv/detail-dokumen/mig_detail_dokumen.csv'); $this->command->error('File csv tidak ditemukan.'); return; } if (($handle = fopen($filePath, 'r')) === false) { Log::error('Gagal membuka file CSV: ' . $filePath); $this->command->error('Gagal membuka file CSV.'); return; } $header = fgetcsv($handle, 0, '~'); $rows = []; $batchSize = 1000; // Ukuran batch $permohonanCache = []; $jenisJaminanCache = []; $dokumenJaminanCache = []; $provinceCache = []; $cityCache = []; $districtCache = []; $subdistrictCache = []; $totalData = 0; $errorCount = 0; $errorDebitureIds = []; $hubunganPemilikCache = []; // Menghitung total data di file CSV while (($data = fgetcsv($handle, 0, '~')) !== false) { $totalData++; } rewind($handle); // Reset pointer ke awal file fgetcsv($handle, 0, '~'); // Skip header $batchCount = 0; $currentRow = 0; // Membaca setiap baris dalam CSV while (($data = fgetcsv($handle, 0, '~')) !== false) { if (count($data) != count($header)) { Log::warning('Baris CSV memiliki jumlah kolom yang tidak sesuai: ' . json_encode($data)); $errorCount++; $errorDebitureIds[] = $data[0] ?? 'ID tidak valid'; // Menyimpan ID yang error continue; } $rows[] = array_combine($header, $data); $currentRow++; // print_r($rows); if (count($rows) >= $batchSize) { $errorDebitureIds[] = $data[0] ?? 'ID tidak valid'; // Menyimpan ID yang error $this->processBatch($rows, $permohonanCache, $jenisJaminanCache, $dokumenJaminanCache, $batchCount, $currentRow, $totalData, $errorCount, $errorDebitureIds); $rows = []; } } // print_r($rows[0]); if (!empty($rows)) { $this->processBatch($rows, $permohonanCache, $jenisJaminanCache, $dokumenJaminanCache, $batchCount, $currentRow, $totalData, $errorCount, $errorDebitureIds); } fclose($handle); $this->command->info('Data debiture berhasil dimigrasikan.'); } private function processBatch( array $rows, array &$permohonanCache, array &$jenisJaminanCache, array &$dokumenJaminanCache, int $batchCount, int $currentRow, int $totalData, int &$errorCount, array &$errorDebitureIds ) { foreach ($rows as $index => $row) { try { // Pastikan field penting tersedia if (!isset($row['mig_grp_keterangan'], $row['mig_key_keterangan'], $row['mig_nilai'])) { throw new \Exception('Field wajib tidak ditemukan'); } $debiturId = $row['mig_kd_debitur_seq'] ?? null; $jaminanGroup = $row['mig_grp_keterangan']; $keyName = $row['mig_key_keterangan']; $value = $row['mig_nilai']; $urlFile = $row['mig_url_file'] ?? null; // Inisialisasi struktur jika belum ada if (!isset($this->result[$jaminanGroup])) { $this->result[$jaminanGroup] = [ 'group' => $jaminanGroup, 'details' => [], 'documents' => [] ]; } // Gabungkan detail $detailItem = [$keyName => $value]; if (!empty($this->result[$jaminanGroup]['details'])) { $existingDetails = $this->result[$jaminanGroup]['details'][0]; $detailItem = array_merge($existingDetails, $detailItem); } $this->result[$jaminanGroup]['details'] = [$detailItem]; // Tambahkan dokumen jika ada if ($urlFile && !in_array($urlFile, $this->result[$jaminanGroup]['documents'])) { $this->result[$jaminanGroup]['documents'][] = $urlFile; } // Jika sudah akhir group atau baris terakhir, simpan ke DB if ($index === count($rows) - 1 || $row['mig_grp_keterangan'] !== $rows[$index + 1]['mig_grp_keterangan']) { // Ambil ID dokumen jaminan $dokumenJaminanId = $this->getDokumenJaminanId($debiturId, $dokumenJaminanCache); if (!$dokumenJaminanId) { throw new \Exception('Dokumen jaminan tidak ditemukan'); } // Ambil ID legalitas jaminan $legalitasJaminanId = $this->getLegalitasJaminanId($jaminanGroup, $jenisJaminanCache); if (!$legalitasJaminanId) { throw new \Exception('Legalitas jaminan tidak ditemukan'); } // Encode hasil sementara $jsonResult = json_encode($this->result[$jaminanGroup], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); $dataJsonDecode = json_decode($jsonResult); // Simpan ke database DetailDokumenJaminan::create([ 'name' => $jaminanGroup, 'dokumen_jaminan_id' => $dokumenJaminanId, 'details' => isset($dataJsonDecode->details) ? json_encode($dataJsonDecode->details) : null, 'jenis_legalitas_jaminan_id' => $legalitasJaminanId, 'dokumen_jaminan' => !empty($dataJsonDecode->documents) ? json_encode($dataJsonDecode->documents) : null, 'dokumen_nomor' => $row['dokumen_nomor'] ?? null, 'keterangan' => $row['mig_deskripsi_file'] ?? null, ]); // Hapus dari result set agar tidak duplikat unset($this->result[$jaminanGroup]); // Info progress $this->command->info('Proses data detail dokumen (' . ($index + 1) . '/' . count($rows) . ', batch ke: ' . $batchCount . ', total dari: ' . $currentRow . '/' . $totalData . ')'); } } catch (\Exception $e) { Log::error('Error pada baris: ' . json_encode($row) . '. Pesan: ' . $e->getMessage()); // Catat error ke file CSV $this->logError($debiturId ?? '-', $e->getMessage()); $errorDebitureIds[] = $debiturId ?? '-'; continue; } } // Reset result set setelah batch selesai $this->result = []; } private function getDokumenJaminanId(string $code, array &$dokumenJaminanCache) { if (isset($dokumenJaminanCache[$code])) { return $dokumenJaminanCache[$code]; } $dokumen = DokumenJaminan::where('mig_kd_debitur_seq', $code)->first(); if ($dokumen) { $dokumenJaminanCache[$code] = $dokumen->id; return $dokumen->id; } } private function getLegalitasJaminanId(string $code, array &$legalitasJaminanCache) { if (isset($legalitasJaminanCache[$code])) { return $legalitasJaminanCache[$code]; } $legalitas = JenisLegalitasJaminan::whereRaw('LOWER(name) = ?', [strtolower($code)])->first(); if ($legalitas) { $legalitasJaminanCache[$code] = $legalitas->id; return $legalitas->id; } return null; } private function initializeErrorLog() { $file = $this->errorLogFile; if (file_exists($file)) { unlink($file); // Hapus file lama } $handle = fopen($file, 'w'); fputcsv($handle, ['mig_kd_debitur_seq', 'Error']); fclose($handle); } private function logError(string $kode, string $message) { Log::error("Error migrasi dokumen jaminan [$kode]: $message"); $handle = fopen($this->errorLogFile, 'a'); fputcsv($handle, [$kode, $message]); fclose($handle); } }