Files
lpj/database/seeders/MigrationDetailDokumenJaminanSeeder.php
Daeng Deni Mardaeni 70dda16699 feat(lpj-seeders): Inisialisasi master referensi, migrasi MIG, dan SQL seeding
- Menata LpjDatabaseSeeder untuk orkestrasi batch, aktifkan MigrationGambarInspeksiSeeder .
- Migrasi domain MIG → LPJ lengkap dengan parseTimestamp , initializeErrorLog , logError .
- Tambah seeders MIG eksternal & tim penilai; normalisasi mapping checkTujuanPenilaian .
- Perluasan master: JFK009–JFK014, TP0007–TP00010, hubungan pemilik, KJPP; TeamsSeeder via SQL.
- MasterDataSurveyorSeeder eksekusi SQL referensi (20+ tabel) via DB::unprepared .
- Tambah puluhan SQL referensi (jenis, kondisi, sarana, posisi, spek, dll).
- Normalisasi data inspeksi (duplikasi key dinamis), serialisasi JSON rapi.
- Logging seragam ke app log + CSV error untuk audit trail.
2025-11-10 21:06:03 +07:00

357 lines
12 KiB
PHP

<?php
namespace Modules\Lpj\Database\Seeders;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Modules\Lpj\Models\Debiture;
use Modules\Location\Models\City;
use Modules\Location\Models\District;
use Modules\Location\Models\Province;
use Modules\Location\Models\Village;
use Modules\Lpj\Models\DokumenJaminan;
use Modules\Lpj\Models\Permohonan;
use Modules\Lpj\Models\JenisJaminan;
use Modules\Lpj\Models\JenisLegalitasJaminan;
use Modules\Lpj\Models\PemilikJaminan;
use Modules\Lpj\Models\DetailDokumenJaminan;
use Illuminate\Support\Facades\Log;
class MigrationDetailDokumenJaminanSeeder extends Seeder
{
protected $errorLogFile = __DIR__ . '/csv/detail.dokumen.jaminan_20251016_error.csv';
/**
* Run the database seeds.
*/
public function run()
{
$this->initializeErrorLog();
// Path ke file csv
$filePath = realpath(__DIR__ . '/csv/detail.dokumen.jaminan_20251016.csv');
if (!$filePath) {
Log::error('File csv tidak ditemukan: ' . __DIR__ . '/csv/detail.dokumen.jaminan_20251016.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
) {
$groupedRows = $this->groupRowsByNomorLaporanAndKeterangan($rows);
// print_r($groupedRows);
foreach ($groupedRows as $nomorLaporan => $dataPerGrup) {
// print_r($dataPerGrup);
try {
// Ambil salah satu baris untuk referensi (misal baris pertama dari grup)
$firstRow = reset($dataPerGrup)['details'] ? reset($dataPerGrup) : reset($dataPerGrup);
$debiturId = null;
$nomorJaminan = null;
// Cari debitur ID dari salah satu field
foreach ($rows as $row) {
if ($row['mig_nomor_laporan'] == $nomorLaporan) {
$debiturId = $row['mig_kd_debitur_seq'] ?? null;
$nomorJaminan = $row['mig_nomor_jaminan'] ?? null;
break;
}
}
if (!$debiturId) {
throw new \Exception('Debitur ID tidak ditemukan');
}
// Ambil ID dokumen jaminan
$dokumenJaminanId = $this->getDokumenJaminanId($debiturId,$nomorJaminan, $dokumenJaminanCache);
if (!$dokumenJaminanId) {
throw new \Exception('Dokumen jaminan tidak ditemukan');
}
//dd($debiturId,$nomorJaminan);
foreach ($dataPerGrup as $groupKey => $rowData) {
// Ambil legalitas jaminan ID berdasarkan grup keterangan
$legalitasJaminanId = $this->getLegalitasJaminanId($groupKey, $jenisJaminanCache);
if (!$legalitasJaminanId) {
throw new \Exception("Legalitas jaminan tidak ditemukan untuk grup: {$groupKey}");
}
// Simpan ke database
$detail =DetailDokumenJaminan::updateOrCreate(
[
'name' => $groupKey,
'dokumen_jaminan_id' => $dokumenJaminanId,
],
[
'details' => json_encode($rowData['details']),
'jenis_legalitas_jaminan_id' => $legalitasJaminanId,
'dokumen_jaminan' => !empty($rowData['documents']) ? json_encode($rowData['documents']) : null,
'dokumen_nomor' => $nomorLaporan,
'keterangan' => $groupKey,
]
);
if($nomorJaminan=='253339'){
//dd($debiturId,$nomorJaminan,$legalitasJaminanId, $detail, $dokumenJaminanId);
}
}
// Info progress
$this->command->info("Proses data detail dokumen (Nomor Laporan: {$nomorLaporan}, batch ke: {$batchCount}, total dari: {$currentRow}/{$totalData})");
} catch (\Exception $e) {
Log::error("Error pada nomor laporan {$nomorLaporan}: " . $e->getMessage());
$this->logError($debiturId ?? '-', $e->getMessage());
$errorDebitureIds[] = $debiturId ?? '-';
$errorCount++;
}
}
}
private function groupRowsByNomorLaporann(array $rows): array
{
$grouped = [];
foreach ($rows as $row) {
$nomorJaminan = $row['mig_nomor_laporan'] ?? null;
if (!empty($nomorJaminan)) {
$grouped[$nomorJaminan][] = $row;
}
}
return $grouped;
}
// private function groupRowsByNomorLaporanAndKeterangan(array $rows): array
// {
// $groupedByNomorLaporan = $this->groupRowsByNomorLaporann($rows);
// $finalGrouped = [];
// foreach ($groupedByNomorLaporan as $nomorLaporan => $rowList) {
// $groupedByGrpKeterangan = [];
// // Urutkan berdasarkan mig_urutan_sub (ascending)
// usort($rowList, function ($a, $b) {
// return $a['mig_urutan_sub'] <=> $b['mig_urutan_sub'];
// });
// foreach ($rowList as $row) {
// $grpKeterangan = $row['mig_grp_keterangan'] ?? 'UNKNOWN_GROUP';
// if (!isset($groupedByGrpKeterangan[$grpKeterangan])) {
// $groupedByGrpKeterangan[$grpKeterangan] = [
// 'details' => [],
// 'documents' => []
// ];
// }
// $keyKeterangan = $row['mig_key_keterangan'] ?? 'UNKNOWN_KEY';
// $value = $row['mig_nilai'] ?? null;
// // Jika belum ada detail, inisialisasi sebagai array asosiatif
// if (empty($groupedByGrpKeterangan[$grpKeterangan]['details'])) {
// $groupedByGrpKeterangan[$grpKeterangan]['details'][] = [];
// }
// // Masukkan ke dalam object tunggal (bukan item baru)
// if ($value !== null) {
// $lastIndex = count($groupedByGrpKeterangan[$grpKeterangan]['details']) - 1;
// $groupedByGrpKeterangan[$grpKeterangan]['details'][$lastIndex][$keyKeterangan] = $value;
// }
// // Tambahkan dokumen jika ada
// $urlFile = $row['mig_url_file'] ?? null;
// if (!empty($urlFile)) {
// $groupedByGrpKeterangan[$grpKeterangan]['documents'][] = $urlFile;
// }
// }
// $finalGrouped[$nomorLaporan] = $groupedByGrpKeterangan;
// }
// // print_r($finalGrouped);
// return $finalGrouped;
// }
private function groupRowsByNomorLaporanAndKeterangan(array $rows): array
{
$groupedByNomorLaporan = $this->groupRowsByNomorLaporann($rows);
$finalGrouped = [];
foreach ($groupedByNomorLaporan as $nomorLaporan => $rowList) {
$groupedByGrpKeterangan = [];
// Urutkan berdasarkan mig_urutan_sub
usort($rowList, function ($a, $b) {
return $a['mig_urutan_sub'] <=> $b['mig_urutan_sub'];
});
foreach ($rowList as $row) {
$grpKeterangan = $row['mig_grp_keterangan'] ?? 'UNKNOWN_GROUP';
$keyKeterangan = $row['mig_key_keterangan'] ?? 'UNKNOWN_KEY';
$value = $row['mig_nilai'] ?? null;
if (!isset($groupedByGrpKeterangan[$grpKeterangan])) {
$groupedByGrpKeterangan[$grpKeterangan] = [
'details' => [],
'documents' => []
];
}
// Masukkan sebagai object baru ke dalam details
if ($value !== null) {
$groupedByGrpKeterangan[$grpKeterangan]['details'][] = [
$keyKeterangan => $value
];
}
// Dokumen tetap masuk sebagai array string
$urlFile = $row['mig_url_file'] ?? null;
if (!empty($urlFile)) {
$groupedByGrpKeterangan[$grpKeterangan]['documents'][] = $urlFile;
}
}
$finalGrouped[$nomorLaporan] = $groupedByGrpKeterangan;
}
return $finalGrouped;
}
private function getDokumenJaminanId(string $code,string $nomorLaporan, array &$dokumenJaminanCache)
{
$dokumen = DokumenJaminan::where('mig_kd_debitur_seq', $code)
->where('nomor_lpj', $nomorLaporan)
->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);
}
}