info('Memulai Proses Sinkronisasi: Memindahkan data update dari [expense-old] ke [expense]...'); // Daftar tabel yang akan disinkronkan (Nama tabel diasumsikan sama pada kedua versi) $tablesToMigrate = [ 'form_up_country' => 'form_up_country', 'form_vehicle_running_cost' => 'form_vehicle_running_cost', 'form_entertainment_presentation' => 'form_entertainment_presentation', 'form_meeting_seminar' => 'form_meeting_seminar', 'form_others' => 'form_others', ]; foreach ($tablesToMigrate as $oldTable => $newTable) { $this->comment("--------------------------------------------------"); $this->comment("Memproses Tabel Target: {$newTable}"); // 1. Validasi eksistensi tabel di database tujuan (expense) if (!Schema::hasTable($newTable)) { $this->error("Tabel [{$newTable}] tidak ditemukan di database 'expense'. Melewati tabel ini."); continue; } // 2. Ambil list kolom lengkap yang ada di database tujuan (expense) $destinationColumns = Schema::getColumnListing($newTable); // 3. Ambil data transaksional paling update dari database lama (expense-old) $oldData = DB::connection('mysql_lama')->table($oldTable)->get(); $insertedCount = 0; $skippedCount = 0; foreach ($oldData as $row) { // 4. PROTEKSI ANTI-OVERWRITE: Cek apakah data sudah ada di database 'expense' $isExists = DB::table($newTable) ->where('expense_number', $row->expense_number) ->exists(); if (!$isExists) { $insertData = []; // 5. MAPPING DATA SECARA DINAMIS foreach ($destinationColumns as $column) { // KUNCI PENYEMPURNAAN: Jangan bawa ID lama agar tidak tabrakan dengan Auto-Increment di DB baru if ($column === 'id') { continue; } // Jika kolom dari database baru tersedia di data 'expense-old', ambil nilainya if (property_exists($row, $column) && !is_null($row->$column)) { $insertData[$column] = $row->$column; } else { // Jika kolom baru versi 2.0 tidak ada di database lama / bernilai NULL, isi dengan nilai default aman $insertData[$column] = $this->getDefaultValueForColumn($newTable, $column); } } // 6. Jalankan amunisi Insert ke database utama (expense) DB::table($newTable)->insert($insertData); $insertedCount++; } else { $skippedCount++; } } $this->info("Tabel [{$newTable}] Selesai: Masuk {$insertedCount} data baru. Diabaikan (Sudah ada) {$skippedCount} data."); } $this->info('=================================================='); $this->info('Sukses! Seluruh data dari [expense-old] telah bermigrasi ke [expense] dengan aman.'); } /** * Fallback Nilai Default untuk Kolom Baru Struktur Aplikasi 2.0 */ private function getDefaultValueForColumn($tableName, $columnName) { // POINT 1: Solusi otomatisasi penanganan cabang_id yang NULL pada tabel entertainment if ($tableName === 'form_entertainment_presentation' && $columnName === 'cabang_id') { return 1; // Ganti angka 1 dengan ID Cabang default existing Anda } // Pengondisian khusus untuk kolom-kolom baru krusial di versi 2.0 Anda if ($columnName === 'account_number') { return '-'; } if ($columnName === 'approved_total') { return 0; } if ($columnName === 'approved_at' || $columnName === 'approved2_at' || $columnName === 'final_approved_at') { return null; } // Nilai bawaan jika tidak masuk kategori spesifik di atas return null; } }