initializeErrorLog(); // Path ke file csv $filePath = realpath(__DIR__ . '/csv/inspeksi/foto_20251014.csv'); if (!$filePath) { Log::error('File csv tidak ditemukan: ' . __DIR__ . '/csv/inspeksi/foto_20251014.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 = 500; $userData = []; $branchCache = []; // <-- Gunakan sebagai cache $totalData = 0; while (($data = fgetcsv($handle, 0, ',')) !== false) { $totalData++; } rewind($handle); fgetcsv($handle, 0, ','); // Skip header $batchCount = 0; $currentRow = 0; $errorCount = 0; $errorDebitureIds = []; while (($data = fgetcsv($handle, 0, ',')) !== false) { if (count($data) != count($header)) { Log::warning('Baris CSV memiliki jumlah kolom yang tidak sesuai: ' . json_encode($data)); continue; } $rows[] = array_combine($header, $data); $currentRow++; if (count($rows) >= $batchSize) { $batchCount++; $this->command->info("Memproses batch ke-{$batchCount} ({$currentRow}/{$totalData})"); $this->processBatch($rows, $branchCache, $userData, $errorCount, $errorDebitureIds, $totalData, $batchCount, $currentRow); $rows = []; } } // info_harga_laporan_202505021522.csv // print_r($rows[0]); if (!empty($rows)) { $batchCount++; $this->command->info("Memproses batch ke-{$batchCount} ({$currentRow}/{$totalData})"); $this->processBatch($rows, $branchCache, $userData, $errorCount, $errorDebitureIds, $totalData, $batchCount, $currentRow); } fclose($handle); $this->command->info("Data debiture berhasil dimigrasikan. Total data: {$totalData}, Total batch: {$batchCount}"); } private function processBatch(array $rows, array &$branchCache, array &$userData, int &$errorCount, array &$errorDebitureIds, int $totalData, int $batchCount, int $currentRow) { // Kelompokkan berdasarkan mig_nomor_jaminan $groupedRows = $this->groupRowsByJaminan($rows); foreach ($groupedRows as $nomorJaminan => $groupRows) { try { // Ambil informasi permohonan dan dokument_id $nomorRegis = $this->getNomorRegistrasiPermohonan($nomorJaminan, $branchCache); if (!$nomorRegis) { Log::warning("Nomor registrasi tidak ditemukan untuk nomor jaminan: {$nomorJaminan}"); $errorCount++; $errorDebitureIds[] = $nomorJaminan; continue; } // Bangun JSON foto_form $fotoJson = $this->checkFoto($groupRows); Inspeksi::updateOrCreate( [ 'permohonan_id' => $nomorRegis['id'], 'dokument_id' => $nomorRegis['dokument_id'] ], [ 'foto_form' => $fotoJson, 'updated_at' => now() ] ); $this->command->info("Berhasil update foto_form untuk nomor jaminan: {$nomorJaminan}"); } catch (\Exception $e) { Log::error("Error pada nomor jaminan {$nomorJaminan}: " . $e->getMessage()); $errorCount++; $errorDebitureIds[] = $nomorJaminan; continue; } } } private function groupRowsByJaminan(array $rows): array { $grouped = []; foreach ($rows as $row) { $nomorJaminan = $row['mig_nomor_jaminan'] ?? null; if (!empty($nomorJaminan)) { $grouped[$nomorJaminan][] = $row; } } return $grouped; } private function checkFoto(array $rows) { // Inisialisasi kelompok untuk tiap kategori $kategoriPrioritas = [ 'PETA LOKASI' => [], 'GAMBAR SITUASI / SURAT UKUR' => [], 'FOTO JAMINAN' => [], 'MAK' => [], 'lainnya' => [] ]; foreach ($rows as $row) { // Ambil kolom penting $namaFoto = trim($row['mig_nama_gambar'] ?? ''); $pathFoto = trim($row['mig_url_gambar'] ?? ''); $kategori = trim($row['mig_kategori'] ?? 'lainnya'); $urutan = (int)($row['mig_urutan_gambar'] ?? 999); $tgl = trim($row['mig_tgl'] ?? ''); $nomorLpj = trim($row['mig_nomor_laporan'] ?? ''); if (empty($pathFoto) || empty($tgl)) { continue; // Lewati jika tidak lengkap } try { $tanggal = \Carbon\Carbon::createFromFormat('d/m/Y H:i:s', $tgl)->startOfDay(); if (!$tanggal) { throw new \Exception("Tanggal tidak valid"); } } catch (\Exception $e) { continue; // Lewati jika tanggal tidak valid } $tahun = $tanggal->format('Y'); $bulanAngka = $tanggal->format('n'); $bulanNama = [ 1 => 'JANUARI', 2 => 'FEBRUARI', 3 => 'MARET', 4 => 'APRIL', 5 => 'MEI', 6 => 'JUNI', 7 => 'JULI', 8 => 'AGUSTUS', 9 => 'SEPTEMBER', 10 => 'OKTOBER', 11 => 'NOVEMBER', 12 => 'DESEMBER' ][(int)$bulanAngka] ?? 'UNKNOWN'; $tanggalFormat = $tanggal->format('dmY'); if (empty($namaFoto)) { $namaFoto = basename($pathFoto) ?: 'image.jpg'; } // Gunakan '/' sebagai separator path $finalPath = "surveyor/{$tahun}/{$bulanNama}/{$tanggalFormat}/{$nomorLpj}/{$pathFoto}"; $fotoItem = [ 'urutan' => $urutan, 'name' => $namaFoto, 'path' => $finalPath, 'category' => $kategori, 'sub' => null, 'description' => '', 'created_by' => null, 'created_at' => null ]; // Masukkan ke dalam kelompok kategori if (isset($kategoriPrioritas[$kategori])) { $kategoriPrioritas[$kategori][] = $fotoItem; } else { $kategoriPrioritas['lainnya'][] = $fotoItem; } } // Urutkan masing-masing kategori berdasarkan urutan foreach ($kategoriPrioritas as &$kelompok) { usort($kelompok, function ($a, $b) { return $a['urutan'] <=> $b['urutan']; }); } // Gabungkan dengan urutan prioritas: PETA LOKASI -> GAMBAR SITUASI -> FOTO JAMINAN -> lainnya $finalFotos = array_merge( $kategoriPrioritas['PETA LOKASI'], $kategoriPrioritas['GAMBAR SITUASI / SURAT UKUR'], $kategoriPrioritas['FOTO JAMINAN'], $kategoriPrioritas['lainnya'] ); // Hapus indeks 'urutan' $finalFotos = array_map(function ($foto) { unset($foto['urutan']); return $foto; }, $finalFotos); return json_encode([ 'upload_foto' => $finalFotos ], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); } private function getNomorRegistrasiPermohonan($nomor_jaminan_id, array &$cache) { // Cek apakah sudah ada di cache if (isset($cache[$nomor_jaminan_id])) { return $cache[$nomor_jaminan_id]; } // Cari di tabel Permohonan berdasarkan nomor registrasi $permohonan = Permohonan::where('nomor_registrasi', $nomor_jaminan_id)->first(); if (!$permohonan) { // Tidak ditemukan $cache[$nomor_jaminan_id] = null; return null; } // Cari dokument jaminan terkait $dokumenJaminan = DokumenJaminan::where('permohonan_id', $permohonan->id)->first(); // Simpan hasil ke cache $result = [ 'id' => $permohonan->id, 'dokument_id' => $dokumenJaminan ? $dokumenJaminan->id : null ]; $cache[$nomor_jaminan_id] = $result; return $result; } 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); } }