Compare commits
51 Commits
6d137ad51c
...
lpj-db-mig
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
45cebcf325 | ||
|
|
a442f879b7 | ||
|
|
796cb89d21 | ||
|
|
fb22d370b5 | ||
|
|
478c0c8079 | ||
|
|
73d0d238c0 | ||
|
|
d6d0ed28b9 | ||
|
|
ee828455a9 | ||
|
|
a6481dd482 | ||
|
|
cbf54353f4 | ||
|
|
a701e78982 | ||
|
|
6305f93f0f | ||
|
|
6ed4e8ba41 | ||
|
|
6b0022deed | ||
|
|
ae5a9ce5b7 | ||
|
|
c8b5fcc9d1 | ||
|
|
2937add646 | ||
|
|
b83920d8aa | ||
|
|
c6596cdea0 | ||
|
|
c981237663 | ||
|
|
291811b74a | ||
|
|
2d8bddff42 | ||
|
|
be41a815f7 | ||
|
|
c459d1be70 | ||
|
|
142257d18d | ||
|
|
32eab5f089 | ||
|
|
84933206ee | ||
|
|
1338085481 | ||
|
|
3f57d361f9 | ||
|
|
027c698a11 | ||
|
|
05f87f4767 | ||
|
|
6bb13dbcaf | ||
|
|
02d2e42621 | ||
|
|
fd7f5fb9c2 | ||
|
|
dbb930557b | ||
|
|
7aeab00535 | ||
|
|
22e9e6b6a9 | ||
|
|
e27a34d52f | ||
|
|
db3ffacebe | ||
|
|
daed7c5e48 | ||
|
|
4405760df4 | ||
|
|
7ddcc14167 | ||
|
|
f69128e18e | ||
|
|
39424b5df5 | ||
|
|
ec22e5f632 | ||
|
|
f81cdbb50d | ||
|
|
d1ce5f2d55 | ||
|
|
2cb68b6d94 | ||
|
|
d2b4e380b5 | ||
|
|
3853b5d6eb | ||
|
|
bf7e6275e3 |
@@ -1,21 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Exports;
|
||||
namespace Modules\Lpj\Exports;
|
||||
|
||||
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||
use Maatwebsite\Excel\Concerns\WithTitle;
|
||||
use Maatwebsite\Excel\Concerns\WithCustomStartCell;
|
||||
use Maatwebsite\Excel\Concerns\WithEvents;
|
||||
use Maatwebsite\Excel\Events\AfterSheet;
|
||||
use Modules\Lpj\Models\Permohonan;
|
||||
use Modules\Lpj\Models\Branch;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Carbon\Carbon;
|
||||
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||
use Maatwebsite\Excel\Concerns\WithTitle;
|
||||
use Maatwebsite\Excel\Concerns\WithCustomStartCell;
|
||||
use Maatwebsite\Excel\Concerns\WithEvents;
|
||||
use Maatwebsite\Excel\Events\AfterSheet;
|
||||
use Modules\Lpj\Models\Permohonan;
|
||||
use Modules\Lpj\Models\Branch;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class LaporanHasilPenilaianJaminanInternalExternalExport implements FromCollection, WithHeadings, WithMapping, WithTitle, WithCustomStartCell, WithEvents
|
||||
{
|
||||
class LaporanHasilPenilaianJaminanInternalExternalExport implements FromCollection, WithHeadings, WithMapping, WithTitle, WithCustomStartCell, WithEvents
|
||||
{
|
||||
protected $request;
|
||||
|
||||
public function __construct($request)
|
||||
@@ -30,10 +31,20 @@
|
||||
|
||||
// Apply date range filter if provided
|
||||
if ($this->request->has('start_date') || $this->request->has('end_date')) {
|
||||
$query->whereBetween('tanggal_permohonan', [
|
||||
$this->request->start_date ?? '1900-01-01',
|
||||
$this->request->end_date ?? now()->toDateString()
|
||||
]);
|
||||
$startDate = $this->request->start_date ?? '1900-01-01';
|
||||
$endDate = $this->request->end_date ?? now()->toDateString();
|
||||
|
||||
$query->where(function ($q) use ($startDate, $endDate) {
|
||||
|
||||
$q->whereHas('penilaian', function ($q2) use ($startDate, $endDate) {
|
||||
$q2->whereBetween('tanggal_kunjungan', [$startDate, $endDate]);
|
||||
});
|
||||
|
||||
// OR check if has penawaran with date in range
|
||||
$q->orWhereHas('penawaran', function ($q3) use ($startDate, $endDate) {
|
||||
$q3->whereBetween('tanggal_penilaian_sebelumnya', [$startDate, $endDate]);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Apply branch filter if provided
|
||||
@@ -43,7 +54,7 @@
|
||||
|
||||
if ($this->request->has('penilai_id') && !empty($this->request->penilai_id)) {
|
||||
$request = $this->request; // Store in a local variable
|
||||
$query->whereHas('penilaian._user_penilai.userPenilaiTeam', function($q) use ($request) {
|
||||
$query->whereHas('penilaian._user_penilai.userPenilaiTeam', function ($q) use ($request) {
|
||||
$q->where('user_id', $request->penilai_id);
|
||||
});
|
||||
}
|
||||
@@ -56,6 +67,8 @@
|
||||
$q->orWhere('tanggal_permohonan', 'LIKE', '%' . $search . '%');
|
||||
$q->orWhereRelation('user', 'name', 'LIKE', '%' . $search . '%');
|
||||
$q->orWhereRelation('tujuanPenilaian', 'name', 'LIKE', '%' . $search . '%');
|
||||
$q->orWhereRelation('debiture', DB::raw('LOWER(name)'), 'LIKE', '%' . strtolower($search) . '%');
|
||||
|
||||
$q->orWhereRelation('branch', 'name', 'LIKE', '%' . $search . '%');
|
||||
$q->orWhereRelation('jenisFasilitasKredit', 'name', 'LIKE', '%' . $search . '%');
|
||||
$q->orWhereRelation('jenisPenilaian', 'name', 'LIKE', '%' . $search . '%');
|
||||
@@ -95,13 +108,13 @@
|
||||
return [
|
||||
$this->rowNumber,
|
||||
$permohonan->nomor_registrasi,
|
||||
$permohonan->tanggal_permohonan,
|
||||
$permohonan->debiture->branch->name,
|
||||
$permohonan->creator->name,
|
||||
$permohonan->debiture->cif,
|
||||
$permohonan->debiture->name,
|
||||
$permohonan->jenisPenilaian->name,
|
||||
$permohonan->tanggal_permohonan ?? '',
|
||||
$permohonan->debiture->branch->name ?? '',
|
||||
$permohonan->user->name ?? $permohonan->mig_nama_ao ?? '',
|
||||
$permohonan->debiture->cif ?? '',
|
||||
$permohonan->debiture->name ?? '',
|
||||
$permohonan->tujuanPenilaian->name,
|
||||
$permohonan->jenisPenilaian->name ?? '',
|
||||
$permohonan->jenisFasilitasKredit->name,
|
||||
$permohonan->documents->pluck('jenisJaminan.name')->unique()->implode(', '),
|
||||
$permohonan->documents->map(function ($document) {
|
||||
@@ -128,14 +141,18 @@
|
||||
'', // tanggal_spk
|
||||
'', // nomor_spk
|
||||
'', // tanggal_rencana_kunjungan
|
||||
$permohonan->penilaian->tanggal_kunjungan ? formatTanggalIndonesia($permohonan->penilaian->tanggal_kunjungan) : '',
|
||||
$permohonan->penilaian && $permohonan->penilaian->tanggal_kunjungan
|
||||
? formatTanggalIndonesia($permohonan->penilaian->tanggal_kunjungan)
|
||||
: '',
|
||||
'', // tanggal_delivered
|
||||
'', // jangka_waktu_sla
|
||||
($permohonan->approval_dd_at || $permohonan->approval_eo_at) ?
|
||||
formatTanggalIndonesia($permohonan->approval_dd_at ?? $permohonan->approval_eo_at) : '',
|
||||
$permohonan->penilaian->tanggal_kunjungan ? formatTanggalIndonesia($permohonan->penilaian->tanggal_kunjungan) : '',
|
||||
$permohonan->penilaian && $permohonan->penilaian->tanggal_kunjungan
|
||||
? formatTanggalIndonesia($permohonan->penilaian->tanggal_kunjungan)
|
||||
: '',
|
||||
$permohonan->penilaian->_user_penilai->userPenilaiTeam->name ?? '',
|
||||
$permohonan->penilaian->teams ?? '',
|
||||
$permohonan->approveSo->name ?? '',
|
||||
'', // saran
|
||||
'' // catatan
|
||||
];
|
||||
@@ -203,7 +220,7 @@
|
||||
public function registerEvents(): array
|
||||
{
|
||||
return [
|
||||
AfterSheet::class => function(AfterSheet $event) {
|
||||
AfterSheet::class => function (AfterSheet $event) {
|
||||
// Get the sheet
|
||||
$sheet = $event->sheet->getDelegate();
|
||||
|
||||
@@ -285,4 +302,4 @@
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
namespace Modules\Lpj\Exports;
|
||||
|
||||
use Maatwebsite\Excel\Concerns\FromQuery;
|
||||
|
||||
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
|
||||
@@ -11,167 +12,299 @@ use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
|
||||
use Modules\Lpj\Models\Debiture;
|
||||
use Modules\Lpj\Models\Permohonan;
|
||||
use Modules\Lpj\Helpers\Lpj;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class LaporanPenilaiJaminanExport implements FromQuery, WithHeadings, WithMapping, ShouldAutoSize
|
||||
class LaporanPenilaiJaminanExport implements FromCollection, WithHeadings, WithMapping, ShouldAutoSize
|
||||
{
|
||||
protected $tanggalAwal;
|
||||
protected $tanggalAkhir;
|
||||
protected $status;
|
||||
protected $selectedIds;
|
||||
|
||||
public function __construct($tanggalAwal = null, $tanggalAkhir = null, $status = null, $selectedIds = null)
|
||||
protected $request;
|
||||
|
||||
public function __construct($request)
|
||||
{
|
||||
$this->tanggalAwal = $tanggalAwal;
|
||||
$this->tanggalAkhir = $tanggalAkhir;
|
||||
$this->status = $status;
|
||||
$this->selectedIds = $selectedIds;
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
|
||||
public function query()
|
||||
public function collection()
|
||||
{
|
||||
$query = Permohonan::query()
|
||||
->with(['user', 'debiture', 'branch', 'tujuanPenilaian', 'penilaian', 'dokumenjaminan.jenisJaminan','nilaiPlafond', 'penilai', 'inspeksi']);
|
||||
$query = Permohonan::query();
|
||||
$query = $query->where('status', 'done');
|
||||
|
||||
// Filter by date range if provided
|
||||
if ($this->tanggalAwal && $this->tanggalAkhir) {
|
||||
$query->whereBetween('tanggal_permohonan', [$this->tanggalAwal, $this->tanggalAkhir]);
|
||||
}
|
||||
// Apply date range filter if provided
|
||||
if ($this->request->has('start_date') || $this->request->has('end_date')) {
|
||||
$startDate = $this->request->start_date ?? '1900-01-01';
|
||||
$endDate = $this->request->end_date ?? now()->toDateString();
|
||||
|
||||
$query->where('status', 'done');
|
||||
// Filter by status if provided
|
||||
if ($this->status) {
|
||||
$types = is_array($this->status) ? $this->status : [$this->status];
|
||||
$types = array_map('strtolower', $types);
|
||||
$query->whereHas('penilai', function (Builder $query) use ($types) {
|
||||
$query->whereIn('type_penilai', $types);
|
||||
$query->where(function ($q) use ($startDate, $endDate) {
|
||||
|
||||
$q->whereHas('penilaian', function ($q2) use ($startDate, $endDate) {
|
||||
$q2->whereBetween('tanggal_kunjungan', [$startDate, $endDate]);
|
||||
});
|
||||
|
||||
// OR check if has penawaran with date in range
|
||||
$q->orWhereHas('penawaran', function ($q3) use ($startDate, $endDate) {
|
||||
$q3->whereBetween('tanggal_penilaian_sebelumnya', [$startDate, $endDate]);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Filter by laporan type if provided
|
||||
if ($this->request->has('laporan') && is_array($this->request->laporan) && !empty($this->request->laporan)) {
|
||||
foreach ($this->request->laporan as $type) {
|
||||
$query->whereHas('penilai', function ($q) use ($type) {
|
||||
$q->where('type_penilai', 'LIKE', '%' . $type . '%');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Apply branch filter if provided
|
||||
if ($this->request->has('branch_id') && !empty($this->request->branch_id)) {
|
||||
$query->where('branch_id', $this->request->branch_id);
|
||||
}
|
||||
|
||||
// Filter by selected IDs if provided
|
||||
if ($this->selectedIds) {
|
||||
$selectedIds = is_array($this->selectedIds) ? $this->selectedIds : explode(',', $this->selectedIds);
|
||||
if ($this->request->has('selected_ids') && !empty($this->request->selected_ids)) {
|
||||
$selectedIds = is_array($this->request->selected_ids) ? $this->request->selected_ids : explode(',', $this->request->selected_ids);
|
||||
$query->whereIn('id', $selectedIds);
|
||||
}
|
||||
|
||||
return $query;
|
||||
// Apply search filter if provided
|
||||
if ($this->request->has('search') && !empty($this->request->search)) {
|
||||
$search = $this->request->search;
|
||||
$query->where(function ($q) use ($search) {
|
||||
$q->where('nomor_registrasi', 'LIKE', '%' . $search . '%');
|
||||
$q->orWhere('tanggal_permohonan', 'LIKE', '%' . $search . '%');
|
||||
$q->orWhereRelation('user', 'name', 'LIKE', '%' . $search . '%');
|
||||
$q->orWhereRelation('tujuanPenilaian', 'name', 'LIKE', '%' . $search . '%');
|
||||
$q->orWhereRelation('branch', 'name', 'LIKE', '%' . $search . '%');
|
||||
$q->orWhereRelation('debiture', DB::raw('LOWER(name)'), 'LIKE', '%' . strtolower($search) . '%');
|
||||
$q->orWhereRelation('jenisFasilitasKredit', 'name', 'LIKE', '%' . $search . '%');
|
||||
$q->orWhereRelation('jenisPenilaian', 'name', 'LIKE', '%' . $search . '%');
|
||||
$q->orWhere('status', 'LIKE', '%' . $search . '%');
|
||||
});
|
||||
}
|
||||
|
||||
// Default ordering
|
||||
$query->orderBy('nomor_registrasi', 'asc');
|
||||
|
||||
public function map($row): array
|
||||
return $query->get();
|
||||
}
|
||||
|
||||
protected $rowNumber = 0;
|
||||
public function map($permohonan): array
|
||||
{
|
||||
$this->rowNumber++;
|
||||
$luas_tanah = 0;
|
||||
$luas_bangunan = 0;
|
||||
$nilai_tanah = 0;
|
||||
$nilai_bangunan = 0;
|
||||
$npw = 0;
|
||||
$nilai_liquidasi = 0;
|
||||
|
||||
// ambil data alamat dari inspeksi
|
||||
$alamat_inspeksi = null;
|
||||
if (isset($permohonan->penilai->lpj)) {
|
||||
$lpj = json_decode($permohonan->penilai->lpj, true);
|
||||
$npw = str_replace('.', '', $lpj['total_nilai_pasar_wajar'] ?? 0);
|
||||
|
||||
if ($row->inspeksi) {
|
||||
$alamat_inspeksi = json_decode($row->inspeksi->data_form, true) ?? null;
|
||||
$alamat_inspeksi = $alamat_inspeksi['asset']['alamat']['sesuai'] ?? $alamat_inspeksi['asset']['alamat']['tidak sesuai'] ?? [];
|
||||
$luas_tanah = $lpj['luas_tanah'] ?? 0;
|
||||
$luas_bangunan = $lpj['luas_bangunan'] ?? 0;
|
||||
$nilai_tanah = str_replace('.', '', $lpj['nilai_tanah_2'] ?? 0);
|
||||
$nilai_bangunan = str_replace('.', '', $lpj['nilai_bangunan_2'] ?? 0);
|
||||
$nilai_liquidasi = str_replace('.', '', $lpj['likuidasi_nilai_2'] ?? 0);
|
||||
}
|
||||
$alamat_inspeksi = $alamat_inspeksi['address'] ?? '-';
|
||||
|
||||
|
||||
// ambil data dari table penilai
|
||||
$fieldPenilai = ['lpj', 'resume', 'memo', 'rap', 'call-report'];
|
||||
$penilaiCek = null;
|
||||
|
||||
// Cari field yang tersedia
|
||||
foreach ($fieldPenilai as $value) {
|
||||
if (!empty($row->penilai->$value)) {
|
||||
$penilaiCek = $row->penilai->$value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$decodePenilai = json_decode($penilaiCek, true) ?? [];
|
||||
// Ambil nilai utama
|
||||
$luasTanah = $decodePenilai['luas_tanah'] ?? 0;
|
||||
$nilaiTanah1 = $decodePenilai['nilai_tanah_1'] ?? 0;
|
||||
$luasBangunan = $decodePenilai['luas_bangunan'] ?? 0;
|
||||
$nilaiBangunan1 = $decodePenilai['nilai_bangunan_1'] ?? 0;
|
||||
$totalNilaiPasar = $decodePenilai['total_nilai_pasar_wajar'] ?? 0;
|
||||
$likuidasi = $decodePenilai['likuidasi'] ?? 0;
|
||||
|
||||
// Ambil data npw_tambahan jika ada
|
||||
$npwTambahan = $decodePenilai['npw_tambahan'] ?? [];
|
||||
$tambahanDetails = [];
|
||||
foreach ($npwTambahan as $tambahan) {
|
||||
$tambahanDetails[] = sprintf(
|
||||
'%s: Luas: %s, Nilai 1: %s, Nilai 2: %s',
|
||||
$tambahan['name'] ?? '-',
|
||||
$tambahan['luas'] ?? 0,
|
||||
$tambahan['nilai_1'] ?? 0,
|
||||
$tambahan['nilai_2'] ?? 0
|
||||
);
|
||||
}
|
||||
$tambahanSummary = implode("; ", $tambahanDetails);
|
||||
|
||||
// Ambil data penilaian dari table penilaian
|
||||
$user_penilai = $row->penilaian->userPenilai ?? null;
|
||||
$user_penilai_name = null;
|
||||
foreach ($user_penilai as $value) {
|
||||
if ($value->role == 'penilai') {
|
||||
$user_penilai_name = $value->user->name;
|
||||
$nik_penilai = $value->user->nik ?? '-';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return [
|
||||
$row->id,
|
||||
$row->nomor_registrasi,
|
||||
$row->user->name,
|
||||
$row->branch->name,
|
||||
$row->tujuanPenilaian->name,
|
||||
$row->debiture->name,
|
||||
$row->penilai->type_penilai ?? '-',
|
||||
$alamat_inspeksi ?? '-',
|
||||
$luasTanah,
|
||||
$luasBangunan,
|
||||
$nilaiTanah1,
|
||||
$nilaiBangunan1,
|
||||
$totalNilaiPasar,
|
||||
$likuidasi,
|
||||
$row->laporan->created_at ?? '-',
|
||||
$user_penilai_name,
|
||||
$nik_penilai,
|
||||
$row->created_at,
|
||||
$this->rowNumber,
|
||||
$permohonan->nomor_registrasi,
|
||||
$permohonan->tanggal_permohonan ?? '',
|
||||
$permohonan->debiture->branch->name ?? '',
|
||||
$permohonan->user->name ?? $permohonan->mig_nama_ao ?? '',
|
||||
$permohonan->debiture->cif ?? '',
|
||||
$permohonan->debiture->name ?? '',
|
||||
$permohonan->tujuanPenilaian->name,
|
||||
$permohonan->jenisPenilaian->name ?? '',
|
||||
$permohonan->jenisFasilitasKredit->name,
|
||||
$permohonan->documents->pluck('jenisJaminan.name')->unique()->implode(', '),
|
||||
$permohonan->documents->map(function ($document) {
|
||||
return formatAlamat($document);
|
||||
})->unique()->implode(', '),
|
||||
$permohonan->documents->flatMap(function ($document) {
|
||||
return $document->detail->map(function ($detail) {
|
||||
return (!empty($detail->dokumen_nomor) && is_array($detail->dokumen_nomor))
|
||||
? ($detail->jenisLegalitasJaminan->name ?? '') . "\n" . implode(', ', $detail->dokumen_nomor)
|
||||
: null;
|
||||
});
|
||||
})->filter()->unique()->implode(', '),
|
||||
$permohonan->documents->pluck('pemilik.name')->unique()->implode(', '),
|
||||
$luas_tanah . ' m²',
|
||||
formatRupiah($nilai_tanah, 2),
|
||||
$luas_bangunan . ' m²',
|
||||
formatRupiah($nilai_bangunan, 2),
|
||||
formatRupiah($permohonan->nilai_njop ?? 0, 2),
|
||||
formatRupiah($npw, 2),
|
||||
formatRupiah($nilai_liquidasi, 2),
|
||||
$permohonan->documents->map(function ($document) {
|
||||
return formatTanggalIndonesia($document->created_at);
|
||||
})->first(),
|
||||
'', // tanggal_spk
|
||||
'', // nomor_spk
|
||||
'', // tanggal_rencana_kunjungan
|
||||
$permohonan->penilaian && $permohonan->penilaian->tanggal_kunjungan
|
||||
? formatTanggalIndonesia($permohonan->penilaian->tanggal_kunjungan)
|
||||
: '',
|
||||
'', // tanggal_delivered
|
||||
'', // jangka_waktu_sla
|
||||
($permohonan->approval_dd_at || $permohonan->approval_eo_at) ?
|
||||
formatTanggalIndonesia($permohonan->approval_dd_at ?? $permohonan->approval_eo_at) : '',
|
||||
$permohonan->penilaian && $permohonan->penilaian->tanggal_kunjungan
|
||||
? formatTanggalIndonesia($permohonan->penilaian->tanggal_kunjungan)
|
||||
: '',
|
||||
$permohonan->penilaian->_user_penilai->userPenilaiTeam->name ?? '',
|
||||
$permohonan->approveSo->name ?? '',
|
||||
$permohonan->penilai->type_penilai?? '',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function headings(): array
|
||||
{
|
||||
return [
|
||||
'ID',
|
||||
'No',
|
||||
'Nomor Registrasi',
|
||||
'User Pemohon',
|
||||
'Tanggal Permohonan',
|
||||
'Cabang',
|
||||
'Pemohon',
|
||||
'CIF',
|
||||
'Nama Debitur',
|
||||
'Jenis Penilaian',
|
||||
'Tujuan Penilaian',
|
||||
'Debitur',
|
||||
'Jenis Laporan',
|
||||
'Lokasi Jaminan',
|
||||
'Jenis Fasilitas Kredit',
|
||||
'Jenis Agunan',
|
||||
'Alamat Agunan',
|
||||
'Bukti Kepemilikan',
|
||||
'Nama Pemilik',
|
||||
'Luas Tanah',
|
||||
'Nilai Tanah',
|
||||
'Luas Bangunan',
|
||||
'Harga Tanah',
|
||||
'Harga Bangunan',
|
||||
'Nilai Bangunan',
|
||||
'Nilai NJOP',
|
||||
'Nilai Pasar Wajar',
|
||||
'Likuidasi',
|
||||
'Nilai Likuidasi',
|
||||
'Tanggal Dokumen Diterima',
|
||||
'Tanggal SPK',
|
||||
'Nomor SPK',
|
||||
'Tanggal Rencana Kunjungan',
|
||||
'Tanggal Kunjungan',
|
||||
'Tanggal Delivered',
|
||||
'Jangka Waktu SLA',
|
||||
'Tanggal Laporan',
|
||||
'Tanggal Review',
|
||||
'Nama Penilai',
|
||||
'Nik Penilai',
|
||||
'Created At',
|
||||
'Nama Team Leader',
|
||||
'Laporan',
|
||||
|
||||
];
|
||||
}
|
||||
public function columnFormats(): array
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function title(): string
|
||||
{
|
||||
return 'Laporan Hasil Penilaian Jaminan Internal & External';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function startCell(): string
|
||||
{
|
||||
return 'A7';
|
||||
}
|
||||
|
||||
public function registerEvents(): array
|
||||
{
|
||||
return [
|
||||
'A' => NumberFormat::FORMAT_NUMBER,
|
||||
'C' => NumberFormat::FORMAT_DATE_DATETIME,
|
||||
'K' => NumberFormat::FORMAT_DATE_DATETIME,
|
||||
'N' => NumberFormat::FORMAT_DATE_DATETIME
|
||||
AfterSheet::class => function (AfterSheet $event) {
|
||||
// Get the sheet
|
||||
$sheet = $event->sheet->getDelegate();
|
||||
|
||||
// Set the title
|
||||
$sheet->setCellValue('A1', 'LAPORAN PENILAIAN JAMINAN');
|
||||
$sheet->getStyle('A1')->getFont()->setBold(true)->setSize(16);
|
||||
|
||||
// Merge cells for title
|
||||
$sheet->mergeCells('A1:AH1');
|
||||
$sheet->getStyle('A1')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
|
||||
|
||||
// Set the branch information if filtered
|
||||
$branchInfo = '';
|
||||
if ($this->request->has('branch_id') && !empty($this->request->branch_id)) {
|
||||
$branch = Branch::find($this->request->branch_id);
|
||||
if ($branch) {
|
||||
$branchInfo = 'Cabang: ' . $branch->name;
|
||||
$sheet->setCellValue('A2', $branchInfo);
|
||||
$sheet->mergeCells('A2:AH2');
|
||||
$sheet->getStyle('A2')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
|
||||
$sheet->getStyle('A2')->getFont()->setBold(true);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the period
|
||||
$startDate = $this->request->start_date ?? '';
|
||||
$endDate = $this->request->end_date ?? '';
|
||||
|
||||
$rowIndex = $branchInfo ? 3 : 2;
|
||||
|
||||
if ($startDate && $endDate) {
|
||||
$startDateFormatted = Carbon::parse($startDate)->format('d F Y');
|
||||
$endDateFormatted = Carbon::parse($endDate)->format('d F Y');
|
||||
$sheet->setCellValue('A' . $rowIndex, 'Periode: ' . $startDateFormatted . ' - ' . $endDateFormatted);
|
||||
} else {
|
||||
$sheet->setCellValue('A' . $rowIndex, 'Periode: Semua Data');
|
||||
}
|
||||
$sheet->mergeCells('A' . $rowIndex . ':AH' . $rowIndex);
|
||||
$sheet->getStyle('A' . $rowIndex)->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
|
||||
|
||||
// Set the date of export
|
||||
$rowIndex++;
|
||||
$sheet->setCellValue('A' . $rowIndex, 'Tanggal Export: ' . Carbon::now()->format('d F Y H:i:s'));
|
||||
|
||||
// Set the user who exported
|
||||
$rowIndex++;
|
||||
$userName = Auth::user() ? Auth::user()->name : 'System';
|
||||
$sheet->setCellValue('A' . $rowIndex, 'Diexport oleh: ' . $userName);
|
||||
|
||||
// Add a blank line
|
||||
$rowIndex++;
|
||||
$sheet->setCellValue('A' . $rowIndex, '');
|
||||
|
||||
// Style the header row
|
||||
$headerRange = 'A7:' . $sheet->getHighestColumn() . '7';
|
||||
$sheet->getStyle($headerRange)->getFont()->setBold(true);
|
||||
$sheet->getStyle($headerRange)->getFill()
|
||||
->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
|
||||
->getStartColor()->setARGB('FFCCCCCC');
|
||||
|
||||
// Auto-size columns - fixed to handle columns beyond Z
|
||||
$highestColumn = $sheet->getHighestColumn();
|
||||
$highestColumnIndex = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString($highestColumn);
|
||||
|
||||
for ($i = 1; $i <= $highestColumnIndex; $i++) {
|
||||
$currentColumn = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($i);
|
||||
$sheet->getColumnDimension($currentColumn)->setAutoSize(true);
|
||||
}
|
||||
|
||||
// Add borders to all cells with data
|
||||
$dataRange = 'A7:' . $sheet->getHighestColumn() . $sheet->getHighestRow();
|
||||
$sheet->getStyle($dataRange)->getBorders()->getAllBorders()->setBorderStyle(\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN);
|
||||
|
||||
// Center align the header row
|
||||
$sheet->getStyle($headerRange)->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
|
||||
|
||||
// Set text wrap for header cells
|
||||
$sheet->getStyle($headerRange)->getAlignment()->setWrapText(true);
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Exports;
|
||||
namespace Modules\Lpj\Exports;
|
||||
|
||||
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||
use Maatwebsite\Excel\Concerns\WithTitle;
|
||||
use Maatwebsite\Excel\Concerns\WithCustomStartCell;
|
||||
use Maatwebsite\Excel\Concerns\WithEvents;
|
||||
use Maatwebsite\Excel\Events\AfterSheet;
|
||||
use Modules\Lpj\Models\Permohonan;
|
||||
use Modules\Lpj\Models\Branch;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class LaporanPenilaianJaminanExport implements FromCollection, WithHeadings, WithMapping, WithTitle, WithCustomStartCell, WithEvents
|
||||
{
|
||||
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||
use Maatwebsite\Excel\Concerns\WithTitle;
|
||||
use Maatwebsite\Excel\Concerns\WithCustomStartCell;
|
||||
use Maatwebsite\Excel\Concerns\WithEvents;
|
||||
use Maatwebsite\Excel\Events\AfterSheet;
|
||||
use Modules\Lpj\Models\Permohonan;
|
||||
use Modules\Lpj\Models\Branch;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
class LaporanPenilaianJaminanExport implements FromCollection, WithHeadings, WithMapping, WithTitle, WithCustomStartCell, WithEvents
|
||||
{
|
||||
protected $request;
|
||||
|
||||
public function __construct($request)
|
||||
@@ -30,10 +30,22 @@
|
||||
|
||||
// Apply date range filter if provided
|
||||
if ($this->request->has('start_date') || $this->request->has('end_date')) {
|
||||
$query->whereBetween('tanggal_permohonan', [
|
||||
$this->request->start_date ?? '1900-01-01',
|
||||
$this->request->end_date ?? now()->toDateString()
|
||||
]);
|
||||
|
||||
$startDate = $this->request->start_date ?? '1900-01-01';
|
||||
$endDate = $this->request->end_date ?? now()->toDateString();
|
||||
|
||||
$query->where(function ($q) use ($startDate, $endDate) {
|
||||
|
||||
$q->whereHas('penilaian', function ($q2) use ($startDate, $endDate) {
|
||||
$q2->whereBetween('tanggal_kunjungan', [$startDate, $endDate]);
|
||||
});
|
||||
|
||||
// OR check if has penawaran with date in range
|
||||
$q->orWhereHas('penawaran', function ($q3) use ($startDate, $endDate) {
|
||||
$q3->whereBetween('tanggal_penilaian_sebelumnya', [$startDate, $endDate]);
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// Apply branch filter if provided
|
||||
@@ -43,7 +55,7 @@
|
||||
|
||||
if ($this->request->has('penilai_id') && !empty($this->request->penilai_id)) {
|
||||
$request = $this->request; // Store in a local variable
|
||||
$query->whereHas('penilaian._user_penilai.userPenilaiTeam', function($q) use ($request) {
|
||||
$query->whereHas('penilaian._user_penilai.userPenilaiTeam', function ($q) use ($request) {
|
||||
$q->where('user_id', $request->penilai_id);
|
||||
});
|
||||
}
|
||||
@@ -55,6 +67,7 @@
|
||||
$q->where('nomor_registrasi', 'LIKE', '%' . $search . '%');
|
||||
$q->orWhere('tanggal_permohonan', 'LIKE', '%' . $search . '%');
|
||||
$q->orWhereRelation('user', 'name', 'LIKE', '%' . $search . '%');
|
||||
$q->orWhereRelation('debiture', DB::raw('LOWER(name)'), 'LIKE', '%' . strtolower($search) . '%');
|
||||
$q->orWhereRelation('tujuanPenilaian', 'name', 'LIKE', '%' . $search . '%');
|
||||
$q->orWhereRelation('branch', 'name', 'LIKE', '%' . $search . '%');
|
||||
$q->orWhereRelation('jenisFasilitasKredit', 'name', 'LIKE', '%' . $search . '%');
|
||||
@@ -66,6 +79,8 @@
|
||||
// Default ordering
|
||||
$query->orderBy('nomor_registrasi', 'asc');
|
||||
|
||||
dd($query->toSql(), $query->getBindings());
|
||||
|
||||
return $query->with(['debiture.branch'])->get();
|
||||
}
|
||||
|
||||
@@ -164,7 +179,7 @@
|
||||
public function registerEvents(): array
|
||||
{
|
||||
return [
|
||||
AfterSheet::class => function(AfterSheet $event) {
|
||||
AfterSheet::class => function (AfterSheet $event) {
|
||||
// Get the sheet
|
||||
$sheet = $event->sheet->getDelegate();
|
||||
|
||||
@@ -226,7 +241,7 @@
|
||||
->getStartColor()->setARGB('FFCCCCCC');
|
||||
|
||||
// Auto-size columns
|
||||
foreach(range('A', $sheet->getHighestColumn()) as $column) {
|
||||
foreach (range('A', $sheet->getHighestColumn()) as $column) {
|
||||
$sheet->getColumnDimension($column)->setAutoSize(true);
|
||||
}
|
||||
|
||||
@@ -242,4 +257,4 @@
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Exports;
|
||||
|
||||
use Maatwebsite\Excel\Concerns\FromQuery;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||
use Maatwebsite\Excel\Concerns\WithStyles;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
|
||||
class LaporanSlikExport implements FromQuery, WithHeadings, WithMapping, WithStyles
|
||||
{
|
||||
protected $query;
|
||||
|
||||
public function __construct($query)
|
||||
{
|
||||
$this->query = $query;
|
||||
}
|
||||
|
||||
public function query()
|
||||
{
|
||||
return $this->query;
|
||||
}
|
||||
|
||||
public function headings(): array
|
||||
{
|
||||
return [
|
||||
'Sandi Bank',
|
||||
'Kode Kantor',
|
||||
'Kode Cabang',
|
||||
'Tahun',
|
||||
'Bulan',
|
||||
'No Rekening',
|
||||
'CIF',
|
||||
'Nama Debitur',
|
||||
'NPWP',
|
||||
'No KTP',
|
||||
'No Telp',
|
||||
'Alamat',
|
||||
'Kode Pos',
|
||||
'Kode Kab/Kota',
|
||||
'Kode Negara Domisili',
|
||||
'Kode Jenis',
|
||||
'Kode Sifat',
|
||||
'Kode Valuta',
|
||||
'Baki Debet',
|
||||
'Kolektibilitas',
|
||||
'Tanggal Mulai',
|
||||
'Tanggal Jatuh Tempo',
|
||||
'Tanggal Selesai',
|
||||
'Tanggal Restrukturisasi',
|
||||
'Kode Sebab Macet',
|
||||
'Tanggal Macet',
|
||||
'Kode Kondisi',
|
||||
'Tanggal Kondisi',
|
||||
'Nilai Agunan',
|
||||
'Jenis Agunan',
|
||||
'Kode Agunan',
|
||||
'Peringkat Agunan',
|
||||
'Fasilitas',
|
||||
'Status Agunan',
|
||||
'Tanggal Lapor',
|
||||
'Status',
|
||||
'Tanggal Dibuat',
|
||||
];
|
||||
}
|
||||
|
||||
public function map($laporanSlik): array
|
||||
{
|
||||
return [
|
||||
$laporanSlik->sandi_bank,
|
||||
$laporanSlik->kode_kantor,
|
||||
$laporanSlik->kode_cabang,
|
||||
$laporanSlik->tahun,
|
||||
$laporanSlik->bulan,
|
||||
$laporanSlik->no_rekening,
|
||||
$laporanSlik->cif,
|
||||
$laporanSlik->nama_debitur,
|
||||
$laporanSlik->npwp,
|
||||
$laporanSlik->no_ktp,
|
||||
$laporanSlik->no_telp,
|
||||
$laporanSlik->alamat,
|
||||
$laporanSlik->kode_pos,
|
||||
$laporanSlik->kode_kab_kota,
|
||||
$laporanSlik->kode_negara_domisili,
|
||||
$laporanSlik->kode_jenis,
|
||||
$laporanSlik->kode_sifat,
|
||||
$laporanSlik->kode_valuta,
|
||||
$laporanSlik->baki_debet,
|
||||
$laporanSlik->kolektibilitas,
|
||||
$laporanSlik->tanggal_mulai,
|
||||
$laporanSlik->tanggal_jatuh_tempo,
|
||||
$laporanSlik->tanggal_selesai,
|
||||
$laporanSlik->tanggal_restrukturisasi,
|
||||
$laporanSlik->kode_sebab_macet,
|
||||
$laporanSlik->tanggal_macet,
|
||||
$laporanSlik->kode_kondisi,
|
||||
$laporanSlik->tanggal_kondisi,
|
||||
$laporanSlik->nilai_agunan,
|
||||
$laporanSlik->jenis_agunan,
|
||||
$laporanSlik->kode_agunan,
|
||||
$laporanSlik->peringkat_agunan,
|
||||
$laporanSlik->fasilitas,
|
||||
$laporanSlik->status_agunan,
|
||||
$laporanSlik->tanggal_lapor,
|
||||
$laporanSlik->status,
|
||||
$laporanSlik->created_at->format('d/m/Y H:i'),
|
||||
];
|
||||
}
|
||||
|
||||
public function styles(Worksheet $sheet)
|
||||
{
|
||||
return [
|
||||
1 => ['font' => ['bold' => true]],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,8 @@
|
||||
use Modules\Lpj\Models\Penilaian;
|
||||
use Modules\Lpj\Models\TeamsUsers;
|
||||
use Modules\Usermanagement\Models\User;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
function formatTanggalIndonesia($date, $time = false)
|
||||
{
|
||||
@@ -528,17 +530,162 @@
|
||||
} else {
|
||||
return "Nomor HP tidak valid";
|
||||
}
|
||||
}
|
||||
|
||||
function parsePembandingMigration($keterangan) {
|
||||
$keterangan = preg_replace('/[-]{5,}/', '',$keterangan); // Hapus ------
|
||||
$keterangan = preg_replace('/[.]{5,}/', '',$keterangan); // Hapus .....
|
||||
|
||||
$keterangan = preg_replace('/\s+/', ' ',$keterangan);
|
||||
$keterangan = preg_replace('/\s*\n\s*/', "\n",$keterangan);
|
||||
|
||||
// Pecah teks per baris untuk diproses
|
||||
$lines = explode("\n",$keterangan);
|
||||
$cleaned = [];
|
||||
|
||||
foreach ($lines as $line) {
|
||||
$line = trim($line);
|
||||
if (!empty($line)) {
|
||||
// Format angka dalam format Rp. 123.456.789
|
||||
$line = preg_replace_callback('/Rp\.\s*([\d.,]+)/', function($matches) {
|
||||
$angka = str_replace(['.', ','], '', $matches[1]);
|
||||
return 'Rp. ' . number_format((int)$angka, 0, ',', '.');
|
||||
}, $line);
|
||||
|
||||
// Jika ada tanda pagar (#), pisahkan menjadi baris baru
|
||||
$line = str_replace('#', "\n#", $line);
|
||||
|
||||
$cleaned[] = $line;
|
||||
}
|
||||
}
|
||||
|
||||
function formatNotifikasi($notifikasi)
|
||||
return implode("\n", $cleaned);
|
||||
}
|
||||
/**
|
||||
* get full path to internal storage file or external storage file
|
||||
*
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
|
||||
function getFilePath($path)
|
||||
{
|
||||
$data = json_decode(json_encode($notifikasi->data));
|
||||
$message = $data->message;
|
||||
$data = $data->data;
|
||||
$notifikasi = [
|
||||
'title' => 'Permohonan : ' . $data->nomor_registrasi,
|
||||
'message' => $message,
|
||||
];
|
||||
return $notifikasi;
|
||||
// define base path external storage (use .env) example: 'F:\path\to\storage' in windows
|
||||
$externalBase = env('EXTERNAL_STORAGE_BASE_PATH', 'F:LPJ/lpj/LPJ Gambar/001/');
|
||||
|
||||
$segments = explode('/', $path);
|
||||
|
||||
if(strtoupper($segments[0]) === 'SURVEYOR'){
|
||||
$year = $segments[1];
|
||||
$month = ucfirst(strtolower($segments[2]));
|
||||
$date = $segments[3];
|
||||
$code = $segments[4];
|
||||
$file = $segments[5] ?? '';
|
||||
|
||||
$extenalFullpath = $externalBase . $year . '/' . $month . '/' . $date . '/' . $code . '/' . $file;
|
||||
|
||||
if(File::exists($extenalFullpath)){
|
||||
return $extenalFullpath;
|
||||
}
|
||||
}
|
||||
|
||||
// if not found in external storage, try to find in internal storage
|
||||
if (Storage::exists($path)) {
|
||||
return Storage::url('app/' . $path);
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
|
||||
|
||||
function parseTimestamp(?string $timestamp): ?string
|
||||
{
|
||||
if (!$timestamp) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Trim whitespace dan normalize
|
||||
$timestamp = trim($timestamp);
|
||||
|
||||
// Log untuk debugging
|
||||
Log::info('Mencoba parsing timestamp: "' . $timestamp . '"');
|
||||
|
||||
// Parsing dengan DateTime native PHP untuk lebih robust
|
||||
try {
|
||||
// Pattern untuk format d/m/Y H:i:s
|
||||
if (preg_match('/^(\d{1,2})\/(\d{1,2})\/(\d{4})\s+(\d{1,2}):(\d{1,2}):(\d{1,2})$/', $timestamp, $matches)) {
|
||||
$day = (int) $matches[1];
|
||||
$month = (int) $matches[2];
|
||||
$year = (int) $matches[3];
|
||||
$hour = (int) $matches[4];
|
||||
$minute = (int) $matches[5];
|
||||
$second = (int) $matches[6];
|
||||
|
||||
// Validasi nilai
|
||||
if ($day >= 1 && $day <= 31 && $month >= 1 && $month <= 12 && $year >= 1900 && $year <= 2100 &&
|
||||
$hour >= 0 && $hour <= 23 && $minute >= 0 && $minute <= 59 && $second >= 0 && $second <= 59) {
|
||||
|
||||
// Buat DateTime object langsung
|
||||
$dateTime = new \DateTime();
|
||||
$dateTime->setDate($year, $month, $day);
|
||||
$dateTime->setTime($hour, $minute, $second);
|
||||
|
||||
$result = $dateTime->format('Y-m-d H:i:s');
|
||||
Log::info('Berhasil parsing dengan DateTime: ' . $timestamp . ' -> ' . $result);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
// Pattern untuk format d/m/Y tanpa waktu
|
||||
if (preg_match('/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/', $timestamp, $matches)) {
|
||||
$day = (int) $matches[1];
|
||||
$month = (int) $matches[2];
|
||||
$year = (int) $matches[3];
|
||||
|
||||
// Validasi nilai
|
||||
if ($day >= 1 && $day <= 31 && $month >= 1 && $month <= 12 && $year >= 1900 && $year <= 2100) {
|
||||
|
||||
// Buat DateTime object langsung
|
||||
$dateTime = new \DateTime();
|
||||
$dateTime->setDate($year, $month, $day);
|
||||
$dateTime->setTime(0, 0, 0);
|
||||
|
||||
$result = $dateTime->format('Y-m-d H:i:s');
|
||||
Log::info('Berhasil parsing tanpa waktu dengan DateTime: ' . $timestamp . ' -> ' . $result);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal parsing dengan DateTime: ' . $timestamp . '. Error: ' . $e->getMessage());
|
||||
}
|
||||
|
||||
// Fallback ke format Carbon standar untuk format lainnya
|
||||
$formats = [
|
||||
'Y-m-d H:i:s',
|
||||
'Y-m-d',
|
||||
'd-m-Y H:i:s',
|
||||
'd-m-Y',
|
||||
'j-n-Y H:i:s',
|
||||
'j-n-Y',
|
||||
];
|
||||
|
||||
foreach ($formats as $format) {
|
||||
try {
|
||||
$carbon = \Carbon\Carbon::createFromFormat($format, $timestamp);
|
||||
|
||||
if ($carbon && $carbon->format($format) === $timestamp) {
|
||||
// Jika format tidak mengandung waktu, set ke awal hari
|
||||
if (!str_contains($format, 'H:i:s')) {
|
||||
$carbon = $carbon->startOfDay();
|
||||
}
|
||||
Log::info('Berhasil parsing dengan format ' . $format . ': ' . $timestamp . ' -> ' . $carbon->toDateTimeString());
|
||||
return $carbon->toDateTimeString();
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
// Lanjut ke format berikutnya
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Log::error('Tidak dapat memparsing timestamp dengan format apapun: "' . $timestamp . '"');
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -306,6 +306,7 @@ class ActivityController extends Controller
|
||||
$query = Permohonan::query();
|
||||
|
||||
// Apply search filter if provided
|
||||
$query = $query->orderBy('nomor_registrasi', 'desc');
|
||||
if ($request->has('search') && !empty($request->get('search'))) {
|
||||
$search = $request->get('search');
|
||||
$query->where(function ($q) use ($search) {
|
||||
@@ -324,7 +325,9 @@ class ActivityController extends Controller
|
||||
});
|
||||
}
|
||||
|
||||
// Default sorting if no sort provided
|
||||
|
||||
|
||||
// Apply sorting if provided
|
||||
if ($request->has('sortOrder') && !empty($request->get('sortOrder'))) {
|
||||
$order = $request->get('sortOrder');
|
||||
$column = $request->get('sortField');
|
||||
@@ -333,20 +336,13 @@ class ActivityController extends Controller
|
||||
$query->orderBy('nomor_registrasi', 'asc');
|
||||
}
|
||||
|
||||
// Get total count of records before pagination
|
||||
// Get the total count of records
|
||||
$totalRecords = $query->count();
|
||||
|
||||
// Pagination
|
||||
if ($request->has('page') && $request->has('size')) {
|
||||
$page = (int) $request->get('page', 1);
|
||||
$size = (int) $request->get('size', 10);
|
||||
$offset = ($page - 1) * $size;
|
||||
$query->skip($offset)->take($size);
|
||||
$size = $request->get('size', 10);
|
||||
if ($size == 0) {
|
||||
$size = 10;
|
||||
}
|
||||
|
||||
// Get filtered count
|
||||
$filteredRecords = $query->count();
|
||||
|
||||
// Filter by region if user is senior-officer
|
||||
if ($regionId) {
|
||||
$query->whereHas('region', function ($q) use ($regionId) {
|
||||
@@ -361,37 +357,36 @@ class ActivityController extends Controller
|
||||
});
|
||||
}
|
||||
|
||||
$totalRecords = $query->count();
|
||||
|
||||
// Pagination
|
||||
|
||||
// Apply pagination if provided
|
||||
if ($request->has('page') && $request->has('size')) {
|
||||
$page = (int) $request->get('page', 1);
|
||||
$size = (int) $request->get('size', 10);
|
||||
$offset = ($page - 1) * $size;
|
||||
$page = $request->get('page');
|
||||
$size = $request->get('size');
|
||||
$offset = ($page - 1) * $size; // Calculate the offset
|
||||
|
||||
$query->skip($offset)->take($size);
|
||||
}
|
||||
|
||||
// Get filtered count
|
||||
// Get the filtered count of records
|
||||
$filteredRecords = $query->count();
|
||||
|
||||
// Get data with necessary relationships
|
||||
$data = $query->with(['user', 'debiture', 'branch', 'tujuanPenilaian', 'penilaian', 'dokumenjaminan','nilaiPlafond'])->get();
|
||||
|
||||
// Calculate total pages
|
||||
$pageCount = ceil($totalRecords / $request->get('size', 10));
|
||||
// Calculate the page count
|
||||
$pageCount = ceil($totalRecords / $size);
|
||||
|
||||
// Calculate the current page number
|
||||
$currentPage = max(1, $request->get('page', 1));
|
||||
|
||||
|
||||
|
||||
// Calculate total pages
|
||||
$pageCount = ceil($totalRecords / $request->get('size', 10));
|
||||
|
||||
// Return the response data as a JSON object
|
||||
return response()->json([
|
||||
'draw' => $request->get('draw'),
|
||||
'recordsTotal' => $totalRecords,
|
||||
'recordsFiltered' => $filteredRecords,
|
||||
'pageCount' => $pageCount,
|
||||
'page' => $request->get('page', 1),
|
||||
'page' => $currentPage,
|
||||
'totalCount' => $totalRecords,
|
||||
'data' => $data,
|
||||
]);
|
||||
|
||||
@@ -1,183 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Exception;
|
||||
use Modules\Lpj\Models\Debiture;
|
||||
|
||||
/**
|
||||
* Controller untuk API pencarian debitur
|
||||
* Digunakan untuk autocomplete search pada form pembayaran
|
||||
*/
|
||||
class DebiturController extends Controller
|
||||
{
|
||||
/**
|
||||
* Pencarian debitur untuk autocomplete
|
||||
*
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function search(Request $request): JsonResponse
|
||||
{
|
||||
try {
|
||||
// Log aktivitas pencarian
|
||||
Log::info('API Debitur Search - Request', [
|
||||
'query' => $request->get('q'),
|
||||
'user_id' => Auth::id()
|
||||
]);
|
||||
|
||||
$query = $request->get('q', '');
|
||||
|
||||
// Validasi minimal 2 karakter untuk pencarian
|
||||
if (strlen($query) < 2) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Minimal 2 karakter untuk pencarian',
|
||||
'data' => []
|
||||
], 400);
|
||||
}
|
||||
|
||||
// Mulai database transaction
|
||||
DB::beginTransaction();
|
||||
|
||||
try {
|
||||
// Query pencarian debitur
|
||||
// Asumsi tabel debitur dengan kolom: id, code, nama, alamat
|
||||
$debiturs = Debiture::query()
|
||||
->select('id', 'cif', 'name', 'address')
|
||||
->whereAny(['cif','name'], 'LIKE', "%{$query}%")
|
||||
->orderBy('name', 'asc')
|
||||
->limit(20) // Batasi hasil maksimal 20
|
||||
->get();
|
||||
|
||||
// Format data untuk TomSelect
|
||||
$formattedData = $debiturs->map(function($debitur) {
|
||||
return [
|
||||
'id' => $debitur->id,
|
||||
'kode_debitur' => $debitur->cif,
|
||||
'name' => $debitur->name,
|
||||
'address' => $debitur->address
|
||||
];
|
||||
});
|
||||
|
||||
DB::commit();
|
||||
|
||||
// Log hasil pencarian
|
||||
Log::info('API Debitur Search - Success', [
|
||||
'query' => $query,
|
||||
'results_count' => $formattedData->count(),
|
||||
'user_id' => Auth::id()
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Data debitur berhasil ditemukan',
|
||||
'data' => $formattedData
|
||||
]);
|
||||
|
||||
} catch (Exception $e) {
|
||||
DB::rollback();
|
||||
throw $e;
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
// Log error
|
||||
Log::error('API Debitur Search - Error', [
|
||||
'query' => $request->get('q'),
|
||||
'error' => $e->getMessage(),
|
||||
'trace' => $e->getTraceAsString(),
|
||||
'user_id' => Auth::id()
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Terjadi kesalahan saat mencari data debitur',
|
||||
'error' => config('app.debug') ? $e->getMessage() : 'Internal Server Error'
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get detail debitur berdasarkan code
|
||||
*
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function getByCode(Request $request): JsonResponse
|
||||
{
|
||||
try {
|
||||
$code = $request->get('code');
|
||||
|
||||
if (empty($code)) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Code debitur harus diisi',
|
||||
'data' => null
|
||||
], 400);
|
||||
}
|
||||
|
||||
// Log aktivitas get detail
|
||||
Log::info('API Debitur GetByCode - Request', [
|
||||
'code' => $code,
|
||||
'user_id' => Auth::id()
|
||||
]);
|
||||
|
||||
DB::beginTransaction();
|
||||
|
||||
try {
|
||||
$debitur = DB::table('debitur')
|
||||
->select('id', 'code', 'nama', 'alamat', 'telepon', 'email')
|
||||
->where('code', $code)
|
||||
->where('status', 'aktif')
|
||||
->first();
|
||||
|
||||
if (!$debitur) {
|
||||
DB::rollback();
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Debitur tidak ditemukan',
|
||||
'data' => null
|
||||
], 404);
|
||||
}
|
||||
|
||||
DB::commit();
|
||||
|
||||
Log::info('API Debitur GetByCode - Success', [
|
||||
'code' => $code,
|
||||
'debitur_id' => $debitur->id,
|
||||
'user_id' => Auth::id()
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Data debitur berhasil ditemukan',
|
||||
'data' => $debitur
|
||||
]);
|
||||
|
||||
} catch (Exception $e) {
|
||||
DB::rollback();
|
||||
throw $e;
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
Log::error('API Debitur GetByCode - Error', [
|
||||
'code' => $request->get('code'),
|
||||
'error' => $e->getMessage(),
|
||||
'trace' => $e->getTraceAsString(),
|
||||
'user_id' => Auth::id()
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Terjadi kesalahan saat mengambil data debitur',
|
||||
'error' => config('app.debug') ? $e->getMessage() : 'Internal Server Error'
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,209 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Exception;
|
||||
use Illuminate\Http\Request;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
use Modules\Lpj\Imports\BucokImport;
|
||||
use Modules\Lpj\Models\Bucok;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Controller untuk mengelola data Bucok
|
||||
*
|
||||
* @package Modules\Lpj\Http\Controllers
|
||||
*/
|
||||
class BucokController extends Controller
|
||||
{
|
||||
public $user;
|
||||
|
||||
/**
|
||||
* Menampilkan halaman index bucok
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return view('lpj::bucok.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Menampilkan detail bucok
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
$bucok = Bucok::findOrFail($id);
|
||||
return view('lpj::bucok.show', compact('bucok'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data untuk datatables dengan server-side processing
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function dataForDatatables(Request $request)
|
||||
{
|
||||
if (is_null($this->user) || !$this->user->can('bucok.view')) {
|
||||
// abort(403, 'Sorry! You are not allowed to view bucok.');
|
||||
}
|
||||
|
||||
// Retrieve data from the database
|
||||
$query = Bucok::query();
|
||||
|
||||
// Apply search filter if provided
|
||||
if ($request->has('search') && !empty($request->get('search'))) {
|
||||
$search = $request->get('search');
|
||||
$query->where(function ($q) use ($search) {
|
||||
$q->where('nomor_tiket', 'LIKE', "%$search%")
|
||||
->orWhere('deskripsi', 'LIKE', "%$search%")
|
||||
->orWhere('nomor_coa', 'LIKE', "%$search%")
|
||||
->orWhere('nama_coa', 'LIKE', "%$search%")
|
||||
->orWhere('cost_center', 'LIKE', "%$search%")
|
||||
->orWhere('nama_sub_direktorat', 'LIKE', "%$search%")
|
||||
->orWhere('nama_direktorat_cabang', 'LIKE', "%$search%")
|
||||
->orWhere('penyelesaian', 'LIKE', "%$search%")
|
||||
->orWhere('keterangan_gantung', 'LIKE', "%$search%");
|
||||
});
|
||||
}
|
||||
|
||||
// Apply date range filter
|
||||
if ($request->has('start_date') && !empty($request->get('start_date'))) {
|
||||
$query->whereDate('tanggal', '>=', $request->get('start_date'));
|
||||
}
|
||||
if ($request->has('end_date') && !empty($request->get('end_date'))) {
|
||||
$query->whereDate('tanggal', '<=', $request->get('end_date'));
|
||||
}
|
||||
|
||||
// Apply year filter
|
||||
if ($request->has('year') && !empty($request->get('year'))) {
|
||||
$query->byYear($request->get('year'));
|
||||
}
|
||||
|
||||
// Apply month filter
|
||||
if ($request->has('month') && !empty($request->get('month'))) {
|
||||
$query->byMonth($request->get('month'));
|
||||
}
|
||||
|
||||
// Apply cost center filter
|
||||
if ($request->has('cost_center') && !empty($request->get('cost_center'))) {
|
||||
$query->byCostCenter($request->get('cost_center'));
|
||||
}
|
||||
|
||||
// Apply completion status filter
|
||||
if ($request->has('completion_status') && $request->get('completion_status') !== '') {
|
||||
$isCompleted = $request->get('completion_status') == '1';
|
||||
$query->byCompletionStatus($isCompleted);
|
||||
}
|
||||
|
||||
// Apply sorting if provided
|
||||
if ($request->has('sortOrder') && !empty($request->get('sortOrder'))) {
|
||||
$order = $request->get('sortOrder');
|
||||
$column = $request->get('sortField', 'created_at');
|
||||
$query->orderBy($column, $order);
|
||||
} else {
|
||||
$query->orderBy('created_at', 'desc');
|
||||
}
|
||||
|
||||
// Get the total count of records
|
||||
$totalRecords = $query->count();
|
||||
|
||||
// Apply pagination if provided
|
||||
if ($request->has('page') && $request->has('size')) {
|
||||
$page = $request->get('page');
|
||||
$size = $request->get('size');
|
||||
$offset = ($page - 1) * $size; // Calculate the offset
|
||||
|
||||
$query->skip($offset)->take($size);
|
||||
}
|
||||
|
||||
// Get the filtered count of records
|
||||
$filteredRecords = $query->count();
|
||||
|
||||
// Get the data for the current page with relationships
|
||||
$data = $query->get();
|
||||
|
||||
// Transform data untuk datatables
|
||||
$transformedData = $data->map(function ($item) {
|
||||
return [
|
||||
'id' => $item->id,
|
||||
'no' => $item->no,
|
||||
'tanggal' => $item->tanggal ? dateFormat($item->tanggal,true) : '-',
|
||||
'bulan' => $item->bulan,
|
||||
'tahun' => $item->tahun,
|
||||
'nomor_tiket' => $item->nomor_tiket,
|
||||
'nomor_coa' => $item->nomor_coa,
|
||||
'nama_coa' => $item->nama_coa,
|
||||
'deskripsi' => $item->deskripsi,
|
||||
'nominal' => $item->nominal_formatted,
|
||||
'penyelesaian' => $item->penyelesaian,
|
||||
'umur_aging' => $item->umur_aging,
|
||||
'cost_center' => $item->cost_center,
|
||||
'nama_sub_direktorat' => $item->nama_sub_direktorat,
|
||||
'nama_direktorat_cabang' => $item->nama_direktorat_cabang,
|
||||
'tanggal_penyelesaian' => $item->tanggal_penyelesaian ? dateFormat($item->tanggal_penyelesaian,true) : '-',
|
||||
'nominal_penyelesaian' => $item->nominal_penyelesaian_formatted,
|
||||
'status_penyelesaian' => $item->status_penyelesaian,
|
||||
'status_badge' => $item->status_badge,
|
||||
'created_by' => $item->creator?->name ?? '-',
|
||||
'created_at' => dateFormat($item->created_at,true)
|
||||
];
|
||||
});
|
||||
|
||||
// Calculate the page count
|
||||
$pageCount = ceil($totalRecords / ($request->get('size', 10)));
|
||||
|
||||
// Calculate the current page number
|
||||
$currentPage = $request->get('page', 1);
|
||||
|
||||
// Return the response data as a JSON object
|
||||
return response()->json([
|
||||
'draw' => $request->get('draw'),
|
||||
'recordsTotal' => $totalRecords,
|
||||
'recordsFiltered' => $filteredRecords,
|
||||
'pageCount' => $pageCount,
|
||||
'page' => $currentPage,
|
||||
'totalCount' => $totalRecords,
|
||||
'data' => $transformedData,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Import data bucok dari Excel
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function import(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'file' => 'required|mimes:xlsx,xls,csv|max:10240' // Max 10MB
|
||||
]);
|
||||
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
Log::info('Importing Bucok data', ['user_id' => Auth::id(), 'filename' => $request->file('file')->getClientOriginalName()]);
|
||||
|
||||
$import = new BucokImport();
|
||||
Excel::import($import, $request->file('file'));
|
||||
$statistics = $import->getImportStatistics();
|
||||
|
||||
DB::commit();
|
||||
Log::info('Bucok data imported successfully', ['user_id' => Auth::id()]);
|
||||
|
||||
return redirect()->back()->with('success', 'Data Bucok berhasil diimport. Total: ' . $statistics['total_processed'] . ', Created: ' . $statistics['created'] . ', Updated: ' . $statistics['updated'] . ', Skipped: ' . $statistics['skipped'] . ', Errors: ' . $statistics['errors']);
|
||||
} catch (Exception $e) {
|
||||
DB::rollback();
|
||||
Log::error('Failed to import Bucok data', ['error' => $e->getMessage(), 'user_id' => Auth::id()]);
|
||||
|
||||
return redirect()->back()->with('error', 'Gagal import data: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -406,7 +406,9 @@
|
||||
|
||||
|
||||
// Remove values from $legalitasJaminan that are in $currentLegalitasJaminan
|
||||
$legalitasJaminan = array_diff($legalitasJaminan, $currentLegalitasJaminan->pluck('code')->toArray());
|
||||
$legalitasJaminan = is_array($legalitasJaminan)
|
||||
? array_diff($legalitasJaminan, $currentLegalitasJaminan->pluck('code')->toArray())
|
||||
: [];
|
||||
|
||||
$legalitas = JenisLegalitasJaminan::whereIn('code', $legalitasJaminan)->get();
|
||||
}
|
||||
|
||||
@@ -169,11 +169,11 @@
|
||||
}
|
||||
|
||||
return redirect()
|
||||
->route('admin-kredit.laporan.index')
|
||||
->route('laporan-admin-kredit.index')
|
||||
->with('success', 'Laporan Admin Kredit updated successfully');
|
||||
} catch (Exception $e) {
|
||||
return redirect()
|
||||
->route('admin-kredit.laporan.edit', $id)
|
||||
->route('laporan-admin-kredit.edit', $id)
|
||||
->with('error', 'Failed to update Laporan Admin Kredit');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,11 +75,9 @@ class LaporanController extends Controller
|
||||
}
|
||||
|
||||
// Retrieve data from the database
|
||||
$query = Permohonan::query()->whereIn('status',['proses-laporan','done', 'paparan', 'proses-paparan'])->whereNotNull('approval_so_at')->whereNotNull('approval_eo_at')->where(function ($q) {
|
||||
$q->whereIn('nilai_plafond_id', [1,4])
|
||||
->whereNotNull('approval_dd_at')
|
||||
->orWhereIn('nilai_plafond_id', [2,3]);
|
||||
});
|
||||
$query = Permohonan::query()
|
||||
->whereIn('status',['proses-laporan','done', 'paparan', 'proses-paparan']);
|
||||
|
||||
|
||||
$query = $query->orderBy('nomor_registrasi', 'desc');
|
||||
// Apply search filter if provided
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Http\Controllers;
|
||||
namespace Modules\Lpj\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
use Modules\Lpj\Exports\LaporanHasilPenilaianJaminanInternalExternalExport;
|
||||
use Modules\Lpj\Models\Permohonan;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
use Modules\Lpj\Exports\LaporanHasilPenilaianJaminanInternalExternalExport;
|
||||
use Modules\Lpj\Models\Permohonan;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class LaporanHasilPenilaianJaminanInternalExternalController extends Controller
|
||||
{
|
||||
class LaporanHasilPenilaianJaminanInternalExternalController extends Controller
|
||||
{
|
||||
public $user;
|
||||
|
||||
/**
|
||||
@@ -60,6 +61,7 @@
|
||||
$q->orWhereRelation('user', 'name', 'LIKE', '%' . $search->search . '%');
|
||||
$q->orWhereRelation('tujuanPenilaian', 'name', 'LIKE', '%' . $search->search . '%');
|
||||
$q->orWhereRelation('branch', 'name', 'LIKE', '%' . $search->search . '%');
|
||||
$q->orWhereRelation('debiture', DB::raw('LOWER(name)'), 'LIKE', '%' . strtolower($search->search) . '%');
|
||||
$q->orWhereRelation('jenisFasilitasKredit', 'name', 'LIKE', '%' . $search->search . '%');
|
||||
$q->orWhereRelation('jenisPenilaian', 'name', 'LIKE', '%' . $search->search . '%');
|
||||
$q->orWhere('status', 'LIKE', '%' . $search->search . '%');
|
||||
@@ -129,7 +131,7 @@
|
||||
'alamat_agunan' => $permohonan->documents?->map(function ($document) {
|
||||
return formatAlamat($document);
|
||||
})->unique()->implode(', '),
|
||||
'bukti_kepemilikan' => (function() use ($permohonan) {
|
||||
'bukti_kepemilikan' => (function () use ($permohonan) {
|
||||
$legalitasItems = $permohonan->documents?->flatMap(function ($document) {
|
||||
return $document->detail->map(function ($detail) {
|
||||
// Jika tidak ada jenis legalitas jaminan, lewati
|
||||
@@ -208,4 +210,4 @@
|
||||
{
|
||||
return Excel::download(new LaporanHasilPenilaianJaminanInternalExternalExport($request), 'laporan_hasil_penilaian_jaminan_internal_external.xlsx');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,10 @@ use Modules\Lpj\Models\Permohonan;
|
||||
use Modules\Lpj\Models\StatusPermohonan;
|
||||
use Modules\Lpj\Exports\LaporanPenilaiJaminanExport;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
use Modules\Lpj\Models\Branch;
|
||||
use Modules\Lpj\Services\PreviewLaporanService;
|
||||
use Modules\Lpj\Models\Inspeksi;
|
||||
use Modules\Lpj\Models\Penilai;
|
||||
|
||||
class LaporanPenilaiJaminanController extends Controller
|
||||
{
|
||||
@@ -16,59 +20,31 @@ class LaporanPenilaiJaminanController extends Controller
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
|
||||
protected $previewLaporanService;
|
||||
|
||||
public function __construct(PreviewLaporanService $previewLaporanService)
|
||||
{
|
||||
$this->previewLaporanService = $previewLaporanService;
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$status_permohonan = StatusPermohonan::all();
|
||||
return view('lpj::laporan-penilai-jaminan.index', compact('status_permohonan'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return view('lpj::create');
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the specified resource.
|
||||
*/
|
||||
public function show($id)
|
||||
public function show($permohonan_id, $dokumen_id, $jaminan_id)
|
||||
{
|
||||
return view('lpj::laporan-penilai-jaminan.show');
|
||||
$back = route('laporan-penilai-jaminan.index');
|
||||
return $this->previewLaporanService->previewLaporan($permohonan_id, $dokumen_id, $jaminan_id, $back);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
return view('lpj::edit');
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
public function destroy($id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
public function dataForDatatables(Request $request)
|
||||
{
|
||||
@@ -93,91 +69,104 @@ class LaporanPenilaiJaminanController extends Controller
|
||||
// dd($startDate);
|
||||
// Retrieve data from the database
|
||||
$query = Permohonan::query();
|
||||
|
||||
$query = $query->where('status', 'done')->orderBy('tanggal_permohonan', 'desc');
|
||||
// Apply search filter if provided
|
||||
if ($request->has('search') && !empty($request->get('search'))) {
|
||||
$search = $request->get('search');
|
||||
$paramsSearch = json_decode($search);
|
||||
$search = json_decode($request->get('search'));
|
||||
|
||||
if (!empty($search->start_date) || !empty($search->end_date)) {
|
||||
$startDate = $search->start_date ?? '1900-01-01';
|
||||
$endDate = $search->end_date ?? now()->toDateString();
|
||||
|
||||
$query->where(function ($q) use ($startDate, $endDate) {
|
||||
|
||||
$q->whereHas('penilaian', function ($q2) use ($startDate, $endDate) {
|
||||
$q2->whereBetween('tanggal_kunjungan', [$startDate, $endDate]);
|
||||
});
|
||||
|
||||
// OR check if has penawaran with date in range
|
||||
$q->orWhereHas('penawaran', function ($q3) use ($startDate, $endDate) {
|
||||
$q3->whereBetween('tanggal_penilaian_sebelumnya', [$startDate, $endDate]);
|
||||
});
|
||||
});
|
||||
|
||||
$query->where(function ($q) use ($search) {
|
||||
$q->where('nomor_registrasi', 'LIKE', '%' . $search . '%')
|
||||
->orWhere('tanggal_permohonan', 'LIKE', '%' . $search . '%')
|
||||
->orWhereRelation('user', 'name', 'LIKE', '%' . $search . '%')
|
||||
->orWhereRelation('debiture', 'name', 'LIKE', '%' . $search . '%')
|
||||
->orWhereRelation('tujuanPenilaian', 'name', 'LIKE', '%' . $search . '%')
|
||||
->orWhereRelation('branch', 'name', 'LIKE', '%' . $search . '%');
|
||||
|
||||
if (!empty($paramsSearch->tanggal_awal) && !empty($paramsSearch->tanggal_akhir)) {
|
||||
$q->whereBetween('tanggal_permohonan', [$paramsSearch->tanggal_awal, $paramsSearch->tanggal_akhir]);
|
||||
}
|
||||
|
||||
|
||||
$statusKeywords = explode(',', $search);
|
||||
foreach ($statusKeywords as $keyword) {
|
||||
$q->orWhereRelation('penilai', 'type_penilai', 'LIKE', '%' . trim($keyword) . '%');
|
||||
if (isset($search->branch_id) && !empty($search->branch_id)) {
|
||||
$query->where('branch_id', $search->branch_id);
|
||||
}
|
||||
|
||||
if (isset($search->laporan) && is_array($search->laporan) && !empty($search->laporan)) {
|
||||
foreach ($search->laporan as $type) {
|
||||
$query->whereHas('penilai', function ($q) use ($type) {
|
||||
$q->where('type_penilai', 'LIKE', '%' . $type . '%');
|
||||
});
|
||||
}
|
||||
$query->where('status', 'done');
|
||||
}
|
||||
|
||||
|
||||
// dd($search->search);
|
||||
|
||||
// Default sorting if no sort provided
|
||||
if (isset($search->search)) {
|
||||
|
||||
$query->where(function ($q) use ($search) {
|
||||
$q->where('nomor_registrasi', 'LIKE', '%' . $search->search . '%');
|
||||
$q->orWhere('tanggal_permohonan', 'LIKE', '%' . $search->search . '%');
|
||||
$q->orWhereRelation('user', 'name', 'LIKE', '%' . $search->search . '%');
|
||||
$q->orWhereRelation('tujuanPenilaian', 'name', 'LIKE', '%' . $search->search . '%');
|
||||
$q->orWhereRelation('branch', 'name', 'LIKE', '%' . $search->search . '%');
|
||||
$q->orWhereRelation('debiture', DB::raw('LOWER(name)'), 'LIKE', '%' . strtolower($search->search) . '%');
|
||||
|
||||
$q->orWhereRelation('jenisFasilitasKredit', 'name', 'LIKE', '%' . $search->search . '%');
|
||||
$q->orWhereRelation('jenisPenilaian', 'name', 'LIKE', '%' . $search->search . '%');
|
||||
$q->orWhere('status', 'LIKE', '%' . $search->search . '%');
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Apply sorting if provided
|
||||
if ($request->has('sortOrder') && !empty($request->get('sortOrder'))) {
|
||||
$order = $request->get('sortOrder');
|
||||
$column = $request->get('sortField');
|
||||
$query->orderBy($column, $order);
|
||||
} else {
|
||||
$query->orderBy('nomor_registrasi', 'asc');
|
||||
}
|
||||
|
||||
// Get total count of records before pagination
|
||||
|
||||
// Get the total count of records
|
||||
$totalRecords = $query->count();
|
||||
|
||||
// Pagination
|
||||
// Apply pagination if provided
|
||||
if ($request->has('page') && $request->has('size')) {
|
||||
$page = (int) $request->get('page', 1);
|
||||
$size = (int) $request->get('size', 10);
|
||||
$offset = ($page - 1) * $size;
|
||||
$page = $request->get('page');
|
||||
$size = $request->get('size');
|
||||
$offset = ($page - 1) * $size; // Calculate the offset
|
||||
|
||||
$query->skip($offset)->take($size);
|
||||
}
|
||||
|
||||
// Get filtered count
|
||||
// Get the filtered count of records
|
||||
$filteredRecords = $query->count();
|
||||
|
||||
|
||||
|
||||
$totalRecords = $query->count();
|
||||
|
||||
// Pagination
|
||||
if ($request->has('page') && $request->has('size')) {
|
||||
$page = (int) $request->get('page', 1);
|
||||
$size = (int) $request->get('size', 10);
|
||||
$offset = ($page - 1) * $size;
|
||||
$query->skip($offset)->take($size);
|
||||
}
|
||||
|
||||
// Get filtered count
|
||||
$filteredRecords = $query->count();
|
||||
|
||||
// Get data with necessary relationships
|
||||
$data = $query->with(['user', 'debiture', 'branch', 'tujuanPenilaian', 'penilaian', 'dokumenjaminan.jenisJaminan','nilaiPlafond', 'penilai'])->get();
|
||||
$data = $query->with(['user', 'debiture', 'branch', 'tujuanPenilaian', 'penilaian', 'dokumenjaminan.jenisJaminan','nilaiPlafond', 'penilai', 'dokumenjaminan.inspeksi'])->get();
|
||||
|
||||
// Calculate total pages
|
||||
$pageCount = ceil($totalRecords / $request->get('size', 10));
|
||||
// Calculate the page count
|
||||
$pageCount = ceil($totalRecords / $size);
|
||||
|
||||
// Calculate the current page number
|
||||
$currentPage = max(1, $request->get('page', 1));
|
||||
|
||||
|
||||
|
||||
// Calculate total pages
|
||||
$pageCount = ceil($totalRecords / $request->get('size', 10));
|
||||
|
||||
// Return the response data as a JSON object
|
||||
return response()->json([
|
||||
'draw' => $request->get('draw'),
|
||||
'recordsTotal' => $totalRecords,
|
||||
'recordsFiltered' => $filteredRecords,
|
||||
'pageCount' => $pageCount,
|
||||
'page' => $request->get('page', 1),
|
||||
'page' => $currentPage,
|
||||
'totalCount' => $totalRecords,
|
||||
'data' => $data,
|
||||
]);
|
||||
@@ -185,15 +174,53 @@ class LaporanPenilaiJaminanController extends Controller
|
||||
|
||||
public function export(Request $request)
|
||||
{
|
||||
$tanggalAwal = $request->input('tanggal_awal');
|
||||
$tanggalAkhir = $request->input('tanggal_akhir');
|
||||
$status = $request->input('status');
|
||||
$selectedIds = $request->input('selected_ids');
|
||||
$startDate = $request->input('start_date');
|
||||
$endDate = $request->input('end_date');
|
||||
|
||||
// Validate the date format
|
||||
if (isset($startDate) && isset($endDate)) {
|
||||
$startDate = date('Y-m-d', strtotime($startDate));
|
||||
$endDate = date('Y-m-d', strtotime($endDate));
|
||||
|
||||
if ($startDate > $endDate) {
|
||||
return redirect()->back()->with('error', 'Tanggal awal tidak boleh lebih kecil dari tanggal akhir');
|
||||
}
|
||||
}
|
||||
// name the file
|
||||
$filename = $this->createNameLaporan($request);
|
||||
|
||||
$filename = 'laporan_penilai_jaminan_' . date('YmdHis') . '.xlsx';
|
||||
return Excel::download(
|
||||
new LaporanPenilaiJaminanExport($tanggalAwal, $tanggalAkhir, $status, $selectedIds),
|
||||
new LaporanPenilaiJaminanExport($request),
|
||||
$filename
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function createNameLaporan($request)
|
||||
{
|
||||
$startDate = $request->start_date ?? null;
|
||||
$endDate = $request->end_date ?? null;
|
||||
$branchId = $request->branch_id ?? null;
|
||||
$laporan = $request->laporan ?? null;
|
||||
|
||||
// Initialize filename parts
|
||||
$parts = ['Laporan Penilai Jaminan'];
|
||||
if ($startDate && $endDate) {
|
||||
$parts[] = "{$startDate}_{$endDate}";
|
||||
}
|
||||
if ($laporan) {
|
||||
$parts[] = $laporan;
|
||||
}
|
||||
if ($branchId) {
|
||||
$parts[] = $this->getBranchId($branchId);
|
||||
}
|
||||
// Return concatenated filename with extension
|
||||
return implode('_', $parts) . '.xlsx';
|
||||
}
|
||||
|
||||
public function getBranchId($branchId)
|
||||
{
|
||||
$branchesName = Branch::find($branchId)->name ?? null;
|
||||
return $branchesName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Http\Controllers;
|
||||
namespace Modules\Lpj\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\Lpj\Exports\LaporanPenilaianJaminanExport;
|
||||
use Modules\Lpj\Models\Permohonan;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\Lpj\Exports\LaporanPenilaianJaminanExport;
|
||||
use Modules\Lpj\Models\Permohonan;
|
||||
use Modules\Lpj\Models\Penilaian;
|
||||
use Modules\Lpj\Models\PenawaranTender;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class LaporanPenilaianJaminanController extends Controller
|
||||
{
|
||||
class LaporanPenilaianJaminanController extends Controller
|
||||
{
|
||||
public $user;
|
||||
|
||||
/**
|
||||
@@ -34,11 +37,19 @@
|
||||
if ($request->has('search') && !empty($request->get('search'))) {
|
||||
$search = json_decode($request->get('search'));
|
||||
|
||||
if (isset($search->start_date) || isset($search->end_date)) {
|
||||
$query->whereBetween('tanggal_permohonan', [
|
||||
$search->start_date ?? '1900-01-01',
|
||||
$search->end_date ?? now()->toDateString()
|
||||
]);
|
||||
|
||||
if (!empty($search->start_date) || !empty($search->end_date)) {
|
||||
$startDate = $search->start_date ?? '1900-01-01';
|
||||
$endDate = $search->end_date ?? now()->toDateString();
|
||||
|
||||
$query->where(function ($q) use ($startDate, $endDate) {
|
||||
$q->whereHas('penilaian', function ($q2) use ($startDate, $endDate) {
|
||||
$q2->whereBetween('tanggal_kunjungan', [$startDate, $endDate]);
|
||||
})
|
||||
->orWhereHas('penawaran', function ($q3) use ($startDate, $endDate) {
|
||||
$q3->whereBetween('tanggal_penilaian_sebelumnya', [$startDate, $endDate]);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Filter by branch if provided
|
||||
@@ -47,7 +58,7 @@
|
||||
}
|
||||
|
||||
if (isset($search->penilai_id) && !empty($search->penilai_id)) {
|
||||
$query->whereHas('penilaian._user_penilai.userPenilaiTeam', function($q) use ($search) {
|
||||
$query->whereHas('penilaian._user_penilai.userPenilaiTeam', function ($q) use ($search) {
|
||||
$q->where('user_id', $search->penilai_id);
|
||||
});
|
||||
}
|
||||
@@ -60,6 +71,8 @@
|
||||
$q->orWhereRelation('user', 'name', 'LIKE', '%' . $search->search . '%');
|
||||
$q->orWhereRelation('tujuanPenilaian', 'name', 'LIKE', '%' . $search->search . '%');
|
||||
$q->orWhereRelation('branch', 'name', 'LIKE', '%' . $search->search . '%');
|
||||
$q->orWhereRelation('debiture', DB::raw('LOWER(name)'), 'LIKE', '%' . strtolower($search->search) . '%');
|
||||
|
||||
$q->orWhereRelation('jenisFasilitasKredit', 'name', 'LIKE', '%' . $search->search . '%');
|
||||
$q->orWhereRelation('jenisPenilaian', 'name', 'LIKE', '%' . $search->search . '%');
|
||||
$q->orWhere('status', 'LIKE', '%' . $search->search . '%');
|
||||
@@ -125,13 +138,13 @@
|
||||
return formatAlamat($document);
|
||||
})->unique()->implode(', '),
|
||||
'luas_tanah' => $luas_tanah . ' m²',
|
||||
'nilai_tanah' => formatRupiah($nilai_tanah,2),
|
||||
'nilai_tanah' => formatRupiah($nilai_tanah, 2),
|
||||
'luas_bangunan' => $luas_bangunan . ' m²',
|
||||
'nilai_bangunan' => formatRupiah($nilai_bangunan,2),
|
||||
'nilai_bangunan' => formatRupiah($nilai_bangunan, 2),
|
||||
'tanggal_laporan' => $permohonan->approval_dd_at ?? $permohonan->approval_eo_at ?? '',
|
||||
'tanggal_review' => $permohonan->penilaian?->tanggal_kunjungan ?? '',
|
||||
'nilai_pasar_wajar' => formatRupiah($npw,2),
|
||||
'nilai_likuidasi' => formatRupiah($nilai_liquidasi,2),
|
||||
'nilai_pasar_wajar' => formatRupiah($npw, 2),
|
||||
'nilai_likuidasi' => formatRupiah($nilai_liquidasi, 2),
|
||||
'nama_penilai' => $permohonan->penilaian?->_user_penilai?->userPenilaiTeam?->name,
|
||||
];
|
||||
});
|
||||
@@ -156,6 +169,12 @@
|
||||
|
||||
public function export(Request $request)
|
||||
{
|
||||
return Excel::download(new LaporanPenilaianJaminanExport($request), 'laporan_penilaian_jaminan.xlsx');
|
||||
}
|
||||
$startDate = $request->start_date;
|
||||
$endDate = $request->end_date;
|
||||
// name of the file
|
||||
$fileName = 'laporan_penilaian_jaminan_' . $startDate . '_' . $endDate . '.xlsx';
|
||||
return Excel::download(new LaporanPenilaianJaminanExport($request), $fileName);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,304 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
use Modules\Lpj\Models\LaporanSlik;
|
||||
use Modules\Lpj\Models\Slik;
|
||||
use Modules\Lpj\Exports\LaporanSlikExport;
|
||||
|
||||
class LaporanSlikController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return view('lpj::laporan-slik.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
public function store(Request $request): JsonResponse
|
||||
{
|
||||
try {
|
||||
$request->validate([
|
||||
'slik_id' => 'required|exists:sliks,id'
|
||||
]);
|
||||
|
||||
$slik = Slik::findOrFail($request->slik_id);
|
||||
|
||||
// Cek apakah data sudah ada di laporan_slik
|
||||
$existing = LaporanSlik::where('slik_id', $slik->id)->first();
|
||||
if ($existing) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Data sudah ada di laporan SLIK'
|
||||
], 422);
|
||||
}
|
||||
|
||||
// Copy data dari tabel slik ke laporan_slik
|
||||
$laporanSlik = LaporanSlik::create([
|
||||
'slik_id' => $slik->id,
|
||||
'sandi_bank' => $slik->sandi_bank,
|
||||
'kode_kantor' => $slik->kode_kantor,
|
||||
'kode_cabang' => $slik->kode_cabang,
|
||||
'tahun' => $slik->tahun,
|
||||
'bulan' => $slik->bulan,
|
||||
'no_rekening' => $slik->no_rekening,
|
||||
'cif' => $slik->cif,
|
||||
'kode_jenis' => $slik->kode_jenis,
|
||||
'kode_jenis_ket' => $slik->kode_jenis_ket,
|
||||
'kode_sifat' => $slik->kode_sifat,
|
||||
'kode_sifat_ket' => $slik->kode_sifat_ket,
|
||||
'kode_valuta' => $slik->kode_valuta,
|
||||
'kode_valuta_ket' => $slik->kode_valuta_ket,
|
||||
'baki_debet' => $slik->baki_debet,
|
||||
'kolektibilitas' => $slik->kolektibilitas,
|
||||
'kolektibilitas_ket' => $slik->kolektibilitas_ket,
|
||||
'tanggal_mulai' => $slik->tanggal_mulai,
|
||||
'tanggal_jatuh_tempo' => $slik->tanggal_jatuh_tempo,
|
||||
'tanggal_selesai' => $slik->tanggal_selesai,
|
||||
'tanggal_restrukturisasi' => $slik->tanggal_restrukturisasi,
|
||||
'kode_sebab_macet' => $slik->kode_sebab_macet,
|
||||
'kode_sebab_macet_ket' => $slik->kode_sebab_macet_ket,
|
||||
'tanggal_macet' => $slik->tanggal_macet,
|
||||
'kode_kondisi' => $slik->kode_kondisi,
|
||||
'kode_kondisi_ket' => $slik->kode_kondisi_ket,
|
||||
'tanggal_kondisi' => $slik->tanggal_kondisi,
|
||||
'nilai_agunan' => $slik->nilai_agunan,
|
||||
'nilai_agunan_ket' => $slik->nilai_agunan_ket,
|
||||
'jenis_agunan' => $slik->jenis_agunan,
|
||||
'kode_agunan' => $slik->kode_agunan,
|
||||
'kode_agunan_ket' => $slik->kode_agunan_ket,
|
||||
'peringkat_agunan' => $slik->peringkat_agunan,
|
||||
'peringkat_agunan_ket' => $slik->peringkat_agunan_ket,
|
||||
'nama_debitur' => $slik->nama_debitur,
|
||||
'npwp' => $slik->npwp,
|
||||
'no_ktp' => $slik->no_ktp,
|
||||
'no_telp' => $slik->no_telp,
|
||||
'kode_kab_kota' => $slik->kode_kab_kota,
|
||||
'kode_kab_kota_ket' => $slik->kode_kab_kota_ket,
|
||||
'kode_negara_domisili' => $slik->kode_negara_domisili,
|
||||
'kode_negara_domisili_ket' => $slik->kode_negara_domisili_ket,
|
||||
'kode_pos' => $slik->kode_pos,
|
||||
'alamat' => $slik->alamat,
|
||||
'fasilitas' => $slik->fasilitas,
|
||||
'status_agunan' => $slik->status_agunan,
|
||||
'tanggal_lapor' => $slik->tanggal_lapor,
|
||||
'status' => 'active',
|
||||
'created_by' => auth()->id(),
|
||||
'updated_by' => auth()->id(),
|
||||
]);
|
||||
|
||||
// Hapus data dari tabel slik setelah berhasil dipindahkan
|
||||
$slik->delete();
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Data berhasil dipindahkan ke laporan SLIK',
|
||||
'data' => $laporanSlik
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error moving SLIK to laporan: ' . $e->getMessage());
|
||||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Terjadi kesalahan saat memindahkan data'
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Data untuk datatables dengan server-side processing
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function dataForDatatables(Request $request)
|
||||
{
|
||||
try {
|
||||
// Retrieve data from the database
|
||||
$query = LaporanSlik::query();
|
||||
|
||||
// Apply search filter if provided
|
||||
if ($request->has('search') && !empty($request->get('search'))) {
|
||||
$search = $request->get('search');
|
||||
$query->where(function ($q) use ($search) {
|
||||
$q->where('sandi_bank', 'LIKE', "%$search%")
|
||||
->orWhere('no_rekening', 'LIKE', "%$search%")
|
||||
->orWhere('cif', 'LIKE', "%$search%")
|
||||
->orWhere('nama_debitur', 'LIKE', "%$search%")
|
||||
->orWhere('fasilitas', 'LIKE', "%$search%")
|
||||
->orWhere('status_agunan', 'LIKE', "%$search%");
|
||||
});
|
||||
}
|
||||
|
||||
// Apply year filter
|
||||
if ($request->has('year') && !empty($request->get('year'))) {
|
||||
$query->where('tahun', $request->get('year'));
|
||||
}
|
||||
|
||||
// Apply month filter
|
||||
if ($request->has('month') && !empty($request->get('month'))) {
|
||||
$query->where('bulan', $request->get('month'));
|
||||
}
|
||||
|
||||
// Apply sandi bank filter
|
||||
if ($request->has('sandi_bank') && !empty($request->get('sandi_bank'))) {
|
||||
$query->where('sandi_bank', $request->get('sandi_bank'));
|
||||
}
|
||||
|
||||
// Apply kolektibilitas filter
|
||||
if ($request->has('kolektibilitas') && !empty($request->get('kolektibilitas'))) {
|
||||
$query->where('kolektibilitas', $request->get('kolektibilitas'));
|
||||
}
|
||||
|
||||
// Apply status filter
|
||||
if ($request->has('status') && !empty($request->get('status'))) {
|
||||
$query->where('status', $request->get('status'));
|
||||
}
|
||||
|
||||
// Apply sorting if provided
|
||||
if ($request->has('sortOrder') && !empty($request->get('sortOrder'))) {
|
||||
$order = $request->get('sortOrder');
|
||||
$column = $request->get('sortField', 'created_at');
|
||||
$query->orderBy($column, $order);
|
||||
} else {
|
||||
$query->orderBy('created_at', 'desc');
|
||||
}
|
||||
|
||||
// Get the total count of records
|
||||
$totalRecords = $query->count();
|
||||
|
||||
// Apply pagination if provided
|
||||
if ($request->has('page') && $request->has('size')) {
|
||||
$page = $request->get('page');
|
||||
$size = $request->get('size');
|
||||
$offset = ($page - 1) * $size; // Calculate the offset
|
||||
|
||||
$query->skip($offset)->take($size);
|
||||
}
|
||||
|
||||
// Get the filtered count of records
|
||||
$filteredRecords = $query->count();
|
||||
|
||||
// Get the data for the current page
|
||||
$data = $query->get();
|
||||
|
||||
// Transform data untuk datatables
|
||||
$transformedData = $data->map(function ($item) {
|
||||
return [
|
||||
'id' => $item->id,
|
||||
'sandi_bank' => $item->sandi_bank,
|
||||
'tahun' => $item->tahun,
|
||||
'bulan' => $item->bulan,
|
||||
'no_rekening' => $item->no_rekening,
|
||||
'cif' => $item->cif,
|
||||
'nama_debitur' => $item->nama_debitur,
|
||||
'kolektibilitas' => $item->kolektibilitas,
|
||||
'kolektibilitas_badge' => $item->kolektibilitas_badge ?? '',
|
||||
'fasilitas' => $item->fasilitas,
|
||||
'nilai_agunan' => $item->nilai_agunan_formatted ?? '',
|
||||
'status_agunan' => $item->status_agunan,
|
||||
'status_badge' => $item->status_badge ?? '',
|
||||
'created_by' => $item->creator?->name ?? '-',
|
||||
'created_at' => dateFormat($item->created_at, true) ?? $item->created_at->format('d/m/Y H:i')
|
||||
];
|
||||
});
|
||||
|
||||
// Calculate the page count
|
||||
$pageCount = ceil($totalRecords / ($request->get('size', 10)));
|
||||
|
||||
// Calculate the current page number
|
||||
$currentPage = $request->get('page', 1);
|
||||
|
||||
// Return the response data as a JSON object
|
||||
return response()->json([
|
||||
'draw' => $request->get('draw'),
|
||||
'recordsTotal' => $totalRecords,
|
||||
'recordsFiltered' => $filteredRecords,
|
||||
'pageCount' => $pageCount,
|
||||
'page' => $currentPage,
|
||||
'totalCount' => $totalRecords,
|
||||
'data' => $transformedData,
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error in laporan slik datatables: ' . $e->getMessage());
|
||||
|
||||
return response()->json([
|
||||
'draw' => $request->get('draw'),
|
||||
'recordsTotal' => 0,
|
||||
'recordsFiltered' => 0,
|
||||
'pageCount' => 0,
|
||||
'page' => 1,
|
||||
'totalCount' => 0,
|
||||
'data' => [],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
try {
|
||||
$laporanSlik = LaporanSlik::findOrFail($id);
|
||||
return view('lpj::laporan-slik.show', compact('laporanSlik'));
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error showing laporan slik: ' . $e->getMessage());
|
||||
return back()->with('error', 'Data tidak ditemukan');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Export laporan SLIK to Excel
|
||||
*/
|
||||
public function export(Request $request)
|
||||
{
|
||||
try {
|
||||
$query = LaporanSlik::query();
|
||||
|
||||
// Apply filters
|
||||
if ($request->has('search') && $request->search) {
|
||||
$search = $request->search;
|
||||
$query->where(function($q) use ($search) {
|
||||
$q->where('nama_debitur', 'like', "%{$search}%")
|
||||
->orWhere('no_rekening', 'like', "%{$search}%")
|
||||
->orWhere('cif', 'like', "%{$search}%");
|
||||
});
|
||||
}
|
||||
|
||||
if ($request->has('year') && $request->year) {
|
||||
$query->where('tahun', $request->year);
|
||||
}
|
||||
|
||||
if ($request->has('month') && $request->month) {
|
||||
$query->where('bulan', $request->month);
|
||||
}
|
||||
|
||||
if ($request->has('status') && $request->status) {
|
||||
$query->where('status', $request->status);
|
||||
}
|
||||
|
||||
$filename = 'laporan-slik-' . now()->format('Y-m-d-His') . '.xlsx';
|
||||
|
||||
return Excel::download(new LaporanSlikExport($query), $filename);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error exporting laporan slik: ' . $e->getMessage());
|
||||
return back()->with('error', 'Gagal export data: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,558 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Http\Controllers;
|
||||
|
||||
use Exception;
|
||||
use Modules\Lpj\Models\Noc;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Modules\Lpj\Models\Permohonan;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Barryvdh\DomPDF\Facade\Pdf;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class MemoController extends Controller
|
||||
{
|
||||
public $user;
|
||||
|
||||
/**
|
||||
* Menampilkan halaman index memo penyelesaian
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
Log::info('MemoController: Mengakses halaman index memo penyelesaian');
|
||||
return view('lpj::memo.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Menampilkan form untuk membuat memo penyelesaian dengan data yang dipilih
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function create(Request $request)
|
||||
{
|
||||
Log::info('MemoController: Mengakses halaman create memo penyelesaian');
|
||||
|
||||
$selectedIds = $request->get('selected_ids', []);
|
||||
|
||||
// Pastikan $selectedIds selalu berupa array
|
||||
if (is_string($selectedIds)) {
|
||||
$selectedIds = explode(',', $selectedIds);
|
||||
}
|
||||
|
||||
// Filter array untuk menghilangkan nilai kosong
|
||||
$selectedIds = array_filter($selectedIds, function($id) {
|
||||
return !empty(trim($id));
|
||||
});
|
||||
|
||||
$permohonanList = [];
|
||||
$totalBiayaPJ = 0;
|
||||
|
||||
if (!empty($selectedIds) && count($selectedIds) > 0) {
|
||||
try {
|
||||
$permohonanList = Permohonan::with([
|
||||
'user',
|
||||
'debiture',
|
||||
'branch',
|
||||
'tujuanPenilaian',
|
||||
'penilaian',
|
||||
'jenisFasilitasKredit',
|
||||
'documents.inspeksi',
|
||||
'penilai',
|
||||
'documents.detail',
|
||||
'noc'
|
||||
])->whereIn('id', $selectedIds)->get();
|
||||
|
||||
// Hitung total biaya PJ dari nominal_bayar di tabel NOC
|
||||
$totalBiayaPJ = Noc::whereIn('permohonan_id', $selectedIds)
|
||||
->sum('nominal_bayar');
|
||||
|
||||
Log::info('MemoController: Total Biaya PJ dihitung: ' . $totalBiayaPJ);
|
||||
|
||||
} catch (Exception $e) {
|
||||
Log::error('MemoController: Error saat mengambil data permohonan - ' . $e->getMessage());
|
||||
return redirect()->back()->with('error', 'Terjadi kesalahan saat memuat data');
|
||||
}
|
||||
}
|
||||
|
||||
return view('lpj::memo.create', compact('permohonanList', 'totalBiayaPJ'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Menyimpan memo penyelesaian yang telah dibuat
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
Log::info('MemoController: Memulai proses penyimpanan memo penyelesaian');
|
||||
|
||||
DB::beginTransaction();
|
||||
|
||||
try {
|
||||
// Validasi input
|
||||
$request->validate([
|
||||
'permohonan_ids' => 'required|array',
|
||||
'permohonan_ids.*' => 'exists:permohonan,id',
|
||||
'memo_number' => 'required|string|max:255',
|
||||
'payment_date' => 'required|date',
|
||||
'memo_date' => 'required|date'
|
||||
]);
|
||||
|
||||
$permohonanIds = $request->permohonan_ids;
|
||||
$memoNumber = $request->memo_number;
|
||||
$paymentDate = $request->payment_date;
|
||||
$memoDate = $request->memo_date;
|
||||
|
||||
// Update status permohonan yang dipilih
|
||||
foreach ($permohonanIds as $permohonanId) {
|
||||
$permohonan = Permohonan::find($permohonanId);
|
||||
if ($permohonan) {
|
||||
$permohonan->status = 'memo-penyelesaian';
|
||||
$permohonan->memo_penyelesaian_number = $memoNumber;
|
||||
$permohonan->memo_penyelesaian_date = $memoDate;
|
||||
$permohonan->memo_penyelesaian_payment_date = $paymentDate;
|
||||
$permohonan->memo_penyelesaian_created_at = now();
|
||||
//$permohonan->save();
|
||||
|
||||
Log::info('MemoController: Berhasil update permohonan ID: ' . $permohonanId);
|
||||
}
|
||||
}
|
||||
|
||||
DB::commit();
|
||||
Log::info('MemoController: Berhasil menyimpan memo penyelesaian untuk ' . count($permohonanIds) . ' permohonan');
|
||||
|
||||
return redirect()->route('memo.index')
|
||||
->with('success', 'Memo penyelesaian berhasil dibuat untuk ' . count($permohonanIds) . ' permohonan');
|
||||
|
||||
} catch (Exception $e) {
|
||||
DB::rollback();
|
||||
Log::error('MemoController: Error saat menyimpan memo penyelesaian - ' . $e->getMessage());
|
||||
|
||||
return redirect()->back()
|
||||
->withInput()
|
||||
->with('error', 'Terjadi kesalahan saat menyimpan memo penyelesaian: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Menampilkan detail memo penyelesaian
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
Log::info('MemoController: Mengakses detail memo penyelesaian ID: ' . $id);
|
||||
|
||||
$permohonan = Permohonan::with([
|
||||
'user',
|
||||
'debiture',
|
||||
'branch',
|
||||
'tujuanPenilaian',
|
||||
'penilaian',
|
||||
'jenisFasilitasKredit',
|
||||
'documents.inspeksi',
|
||||
'penilai',
|
||||
'documents.detail',
|
||||
'noc'
|
||||
])->findOrFail($id);
|
||||
|
||||
return view('lpj::memo.show', compact('permohonan'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Mengambil data untuk datatables pada halaman memo penyelesaian
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function dataForDatatables(Request $request)
|
||||
{
|
||||
Log::info('MemoController: Mengambil data untuk datatables');
|
||||
|
||||
if (is_null($this->user) || !$this->user->can('debitur.view')) {
|
||||
Log::warning('MemoController: User tidak memiliki permission untuk melihat data');
|
||||
// abort(403, 'Sorry! You are not allowed to view users.');
|
||||
}
|
||||
|
||||
// Mengambil data dari database dengan kondisi yang sama seperti LaporanController
|
||||
$query = Permohonan::query()
|
||||
->whereIn('status', ['proses-laporan', 'done', 'paparan', 'proses-paparan', 'memo-penyelesaian'])
|
||||
/*->whereNotNull('approval_so_at')
|
||||
->whereNotNull('approval_eo_at')
|
||||
->where(function ($q) {
|
||||
$q->whereIn('nilai_plafond_id', [1, 4])
|
||||
->whereNotNull('approval_dd_at')
|
||||
->orWhereIn('nilai_plafond_id', [2, 3]);
|
||||
})*/
|
||||
->whereHas('noc'); // Hanya tampilkan permohonan yang memiliki NOC
|
||||
|
||||
|
||||
$query = $query->orderBy('nomor_registrasi', 'desc');
|
||||
|
||||
// Apply search filter jika ada
|
||||
if ($request->has('search') && !empty($request->get('search'))) {
|
||||
$searchParams = explode('|', $request->get('search'));
|
||||
|
||||
$filterJenisPenilaian = $searchParams[0] ?? '';
|
||||
$searchTerm = $searchParams[1] ?? '';
|
||||
|
||||
// Filter berdasarkan jenis penilaian
|
||||
if (!empty($filterJenisPenilaian)) {
|
||||
$query->where('jenis_penilaian_id', $filterJenisPenilaian);
|
||||
Log::info('Applied jenis penilaian filter', ['filter' => $filterJenisPenilaian]);
|
||||
}
|
||||
|
||||
$query->where(function ($q) use ($searchTerm) {
|
||||
$q->where('nomor_registrasi', 'LIKE', '%' . $searchTerm . '%');
|
||||
$q->orWhere('tanggal_permohonan', 'LIKE', '%' . $searchTerm . '%');
|
||||
$q->orWhereRelation('user', 'name', 'LIKE', '%' . $searchTerm . '%');
|
||||
$q->orWhereRelation('debiture', 'name', 'LIKE', '%' . $searchTerm . '%');
|
||||
$q->orWhereRelation('tujuanPenilaian', 'name', 'LIKE', '%' . $searchTerm . '%');
|
||||
$q->orWhereRelation('branch', 'name', 'LIKE', '%' . $searchTerm . '%');
|
||||
$q->orWhere('status', 'LIKE', '%' . $searchTerm . '%');
|
||||
});
|
||||
}
|
||||
|
||||
// Apply sorting jika ada
|
||||
if ($request->has('sortOrder') && !empty($request->get('sortOrder'))) {
|
||||
$order = $request->get('sortOrder');
|
||||
$column = $request->get('sortField');
|
||||
$query->orderBy($column, $order);
|
||||
}
|
||||
|
||||
// Mendapatkan total count records
|
||||
$totalRecords = $query->count();
|
||||
$size = $request->get('size', 10);
|
||||
if ($size == 0) {
|
||||
$size = 10;
|
||||
}
|
||||
|
||||
// Apply pagination jika ada
|
||||
if ($request->has('page') && $request->has('size')) {
|
||||
$page = $request->get('page');
|
||||
$size = $request->get('size');
|
||||
$offset = ($page - 1) * $size;
|
||||
|
||||
$query->skip($offset)->take($size);
|
||||
}
|
||||
|
||||
// Mendapatkan filtered count records
|
||||
$filteredRecords = $query->count();
|
||||
|
||||
// Mendapatkan data untuk halaman saat ini
|
||||
$data = $query->with([
|
||||
'user',
|
||||
'debiture',
|
||||
'branch',
|
||||
'tujuanPenilaian',
|
||||
'jenisPenilaian',
|
||||
'penilaian',
|
||||
'jenisFasilitasKredit',
|
||||
'documents.inspeksi',
|
||||
'penilai',
|
||||
'documents.detail',
|
||||
'noc'
|
||||
])->get();
|
||||
|
||||
// Menghitung page count
|
||||
$pageCount = ceil($totalRecords / $size);
|
||||
|
||||
// Menghitung current page number
|
||||
$currentPage = max(1, $request->get('page', 1));
|
||||
|
||||
Log::info('MemoController: Berhasil mengambil data datatables - Total: ' . $totalRecords . ', Filtered: ' . $filteredRecords);
|
||||
|
||||
// Return response data sebagai JSON object
|
||||
return response()->json([
|
||||
'draw' => $request->get('draw'),
|
||||
'recordsTotal' => $totalRecords,
|
||||
'recordsFiltered' => $filteredRecords,
|
||||
'pageCount' => $pageCount,
|
||||
'page' => $currentPage,
|
||||
'totalCount' => $totalRecords,
|
||||
'data' => $data,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mengambil total biaya PJ berdasarkan permohonan yang dipilih
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function getTotalBiayaPJ(Request $request)
|
||||
{
|
||||
Log::info('MemoController: Mengambil total biaya PJ');
|
||||
|
||||
try {
|
||||
$permohonanIds = $request->get('permohonan_ids', []);
|
||||
|
||||
// Pastikan $permohonanIds selalu berupa array
|
||||
if (is_string($permohonanIds)) {
|
||||
$permohonanIds = explode(',', $permohonanIds);
|
||||
}
|
||||
|
||||
// Filter array untuk menghilangkan nilai kosong
|
||||
$permohonanIds = array_filter($permohonanIds, function($id) {
|
||||
return !empty(trim($id));
|
||||
});
|
||||
|
||||
$totalBiayaPJ = 0;
|
||||
|
||||
if (!empty($permohonanIds) && count($permohonanIds) > 0) {
|
||||
// Hitung total biaya PJ dari nominal_bayar di tabel NOC
|
||||
$totalBiayaPJ = \Modules\Lpj\Models\Noc::whereIn('permohonan_id', $permohonanIds)
|
||||
->sum('nominal_bayar');
|
||||
}
|
||||
|
||||
Log::info('MemoController: Total Biaya PJ berhasil dihitung: ' . $totalBiayaPJ);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'total_biaya_pj' => $totalBiayaPJ,
|
||||
'total_biaya_pj_formatted' => 'Rp ' . number_format($totalBiayaPJ, 0, ',', '.')
|
||||
]);
|
||||
|
||||
} catch (Exception $e) {
|
||||
Log::error('MemoController: Error saat menghitung total biaya PJ - ' . $e->getMessage());
|
||||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Terjadi kesalahan saat menghitung total biaya PJ'
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Menampilkan preview memo penyelesaian sebelum menyimpan
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function preview(Request $request)
|
||||
{
|
||||
Log::info('MemoController: Mengakses halaman preview memo penyelesaian');
|
||||
|
||||
|
||||
$permohonanIds = $request->permohonan_ids;
|
||||
$memoNumber = $request->memo_number;
|
||||
$paymentDate = $request->payment_date;
|
||||
$memoDate = $request->memo_date;
|
||||
|
||||
try {
|
||||
// Ambil data permohonan yang dipilih
|
||||
$permohonanList = Permohonan::with([
|
||||
'user',
|
||||
'debiture',
|
||||
'branch',
|
||||
'penilaian',
|
||||
'jenisPenilaian',
|
||||
'jenisFasilitasKredit',
|
||||
'documents.inspeksi',
|
||||
'penilai',
|
||||
'documents.detail',
|
||||
'noc'
|
||||
])->whereIn('id', $permohonanIds);
|
||||
|
||||
// Hitung total biaya PJ dari nominal_bayar di tabel NOC
|
||||
$totalBiayaPJ = Noc::whereIn('permohonan_id', $permohonanIds)
|
||||
->sum('nominal_bayar');
|
||||
|
||||
// Data untuk template memo
|
||||
$memoData = [
|
||||
'memo_number' => $memoNumber,
|
||||
'memo_date' => $memoDate,
|
||||
'payment_date' => $paymentDate,
|
||||
'total_biaya_pj' => $totalBiayaPJ,
|
||||
'permohonan_list' => $permohonanList->get(),
|
||||
'debitur_count' => $permohonanList->get()->count(),
|
||||
'jaminan_info' => $this->getJaminanInfo($permohonanList->get()),
|
||||
'jenisPenilaian' => $permohonanList->pluck('jenis_penilaian_id')->first()
|
||||
];
|
||||
|
||||
$permohonanList= $permohonanList->get();
|
||||
|
||||
Log::info('MemoController: Data preview memo berhasil disiapkan');
|
||||
|
||||
return view('lpj::memo.preview', compact('memoData', 'permohonanList', 'totalBiayaPJ'));
|
||||
|
||||
} catch (Exception $e) {
|
||||
Log::error('MemoController: Error saat menyiapkan preview memo - ' . $e->getMessage());
|
||||
return redirect()->back()
|
||||
->withInput()
|
||||
->with('error', 'Terjadi kesalahan saat menyiapkan preview memo: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate PDF memo penyelesaian dan simpan ke database
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function generatePdf(Request $request)
|
||||
{
|
||||
Log::info('MemoController: Memulai generate PDF memo penyelesaian');
|
||||
|
||||
DB::beginTransaction();
|
||||
|
||||
try {
|
||||
// Validasi input
|
||||
|
||||
$permohonanIds = $request->permohonan_ids;
|
||||
$memoNumber = $request->memo_number;
|
||||
$paymentDate = $request->payment_date;
|
||||
$memoDate = $request->memo_date;
|
||||
|
||||
// Ambil data permohonan yang dipilih
|
||||
$permohonanList = Permohonan::with([
|
||||
'user',
|
||||
'debiture',
|
||||
'branch',
|
||||
'penilaian',
|
||||
'jenisPenilaian',
|
||||
'jenisFasilitasKredit',
|
||||
'documents.inspeksi',
|
||||
'penilai',
|
||||
'documents.detail',
|
||||
'noc'
|
||||
])->whereIn('id', $permohonanIds);
|
||||
|
||||
// Hitung total biaya PJ dari nominal_bayar di tabel NOC
|
||||
$totalBiayaPJ = Noc::whereIn('permohonan_id', $permohonanIds)
|
||||
->sum('nominal_bayar');
|
||||
|
||||
// Data untuk template memo
|
||||
$memoData = [
|
||||
'memo_number' => $memoNumber,
|
||||
'memo_date' => $memoDate,
|
||||
'payment_date' => $paymentDate,
|
||||
'total_biaya_pj' => $totalBiayaPJ,
|
||||
'permohonan_list' => $permohonanList->get(),
|
||||
'debitur_count' => $permohonanList->get()->count(),
|
||||
'jaminan_info' => $this->getJaminanInfo($permohonanList->get()),
|
||||
'jenisPenilaian' => $permohonanList->pluck('jenis_penilaian_id')->first()
|
||||
];
|
||||
|
||||
$permohonanList= $permohonanList->get();
|
||||
|
||||
// Generate PDF dari template
|
||||
$pdf = Pdf::loadView('lpj::memo.pdf-template', compact('memoData', 'permohonanList', 'totalBiayaPJ'))
|
||||
->setPaper('a4', 'portrait')
|
||||
->setOptions([
|
||||
'defaultFont' => 'Times-Roman',
|
||||
'isRemoteEnabled' => true,
|
||||
'isHtml5ParserEnabled' => true,
|
||||
'isPhpEnabled' => true,
|
||||
'dpi' => 150,
|
||||
'defaultPaperSize' => 'a4',
|
||||
'chroot' => public_path(),
|
||||
]);
|
||||
|
||||
// Nama file PDF
|
||||
$fileName = 'memo-penyelesaian-' . str_replace(['/', ' '], ['-', '-'], $memoNumber) . '-' . date('Y-m-d-H-i-s') . '.pdf';
|
||||
$filePath = 'memo-penyelesaian/' . $fileName;
|
||||
|
||||
// Simpan PDF ke storage
|
||||
Storage::disk('public')->put($filePath, $pdf->output());
|
||||
|
||||
// Update status permohonan yang dipilih
|
||||
// Update data di tabel NOC untuk setiap permohonan
|
||||
foreach ($permohonanIds as $permohonanId) {
|
||||
// Cari NOC berdasarkan permohonan_id
|
||||
$noc = Noc::where('permohonan_id', $permohonanId)->first();
|
||||
|
||||
if ($noc) {
|
||||
// Update field memo penyelesaian di tabel NOC
|
||||
$noc->memo_penyelesaian = $filePath;
|
||||
$noc->memo_penyelesaian_number = $memoNumber;
|
||||
$noc->memo_penyelesaian_date = $memoDate;
|
||||
$noc->memo_penyelesaian_payment_date = $paymentDate;
|
||||
$noc->memo_penyelesaian_created_at = now();
|
||||
$noc->save();
|
||||
|
||||
Log::info('MemoController: Berhasil update NOC untuk permohonan ID: ' . $permohonanId);
|
||||
} else {
|
||||
Log::warning('MemoController: NOC tidak ditemukan untuk permohonan ID: ' . $permohonanId);
|
||||
}
|
||||
}
|
||||
|
||||
DB::commit();
|
||||
Log::info('MemoController: Berhasil generate PDF dan menyimpan memo penyelesaian untuk ' . count($permohonanIds) . ' permohonan');
|
||||
|
||||
// Return PDF untuk download
|
||||
return $pdf->download('memo-penyelesaian-' . $memoNumber . '.pdf');
|
||||
|
||||
} catch (Exception $e) {
|
||||
DB::rollback();
|
||||
Log::error('MemoController: Error saat generate PDF memo penyelesaian - ' . $e->getMessage());
|
||||
|
||||
return redirect()->back()
|
||||
->with('error', 'Terjadi kesalahan saat generate PDF memo penyelesaian: ' . $e->getMessage())
|
||||
->withInput();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function untuk mendapatkan informasi jaminan
|
||||
*
|
||||
* @param $permohonanList
|
||||
* @return string
|
||||
*/
|
||||
private function getJaminanInfo($permohonanList)
|
||||
{
|
||||
$jaminanTypes = [];
|
||||
foreach ($permohonanList as $permohonan) {
|
||||
if ($permohonan->tujuanPenilaian) {
|
||||
$jaminanTypes[] = $permohonan->tujuanPenilaian->name;
|
||||
}
|
||||
}
|
||||
|
||||
$uniqueJaminan = array_unique($jaminanTypes);
|
||||
return implode(' & ', $uniqueJaminan);
|
||||
}
|
||||
/**
|
||||
* Download PDF memo penyelesaian
|
||||
*
|
||||
* @param int $id - ID permohonan
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function downloadPdf($id)
|
||||
{
|
||||
Log::info('MemoController: Download PDF memo penyelesaian untuk permohonan ID: ' . $id);
|
||||
|
||||
try {
|
||||
// Cari NOC berdasarkan permohonan_id
|
||||
$noc = Noc::where('permohonan_id', $id)->first();
|
||||
|
||||
if (!$noc || !$noc->memo_penyelesaian) {
|
||||
Log::warning('MemoController: PDF memo penyelesaian tidak ditemukan untuk permohonan ID: ' . $id);
|
||||
return redirect()->back()->with('error', 'File PDF memo penyelesaian tidak ditemukan.');
|
||||
}
|
||||
|
||||
// Cek apakah file ada di storage
|
||||
if (!Storage::disk('public')->exists($noc->memo_penyelesaian)) {
|
||||
Log::warning('MemoController: File PDF tidak ada di storage: ' . $noc->memo_penyelesaian);
|
||||
return redirect()->back()->with('error', 'File PDF tidak ditemukan di server.');
|
||||
}
|
||||
|
||||
// Download file
|
||||
$fileName = 'memo-penyelesaian-' . $noc->memo_penyelesaian_number . '.pdf';
|
||||
|
||||
Log::info('MemoController: Berhasil download PDF memo penyelesaian: ' . $fileName);
|
||||
|
||||
return Storage::disk('public')->download($noc->memo_penyelesaian, $fileName);
|
||||
|
||||
} catch (Exception $e) {
|
||||
Log::error('MemoController: Error saat download PDF memo penyelesaian - ' . $e->getMessage());
|
||||
return redirect()->back()->with('error', 'Terjadi kesalahan saat mengunduh file PDF.');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,10 +6,10 @@
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Modules\Lpj\Http\Requests\NocRequest;
|
||||
use Modules\Lpj\Models\Bucok;
|
||||
use Modules\Lpj\Models\Noc;
|
||||
use Modules\Lpj\Models\Noc;
|
||||
use Modules\Lpj\Models\PenawaranTender;
|
||||
use Modules\Lpj\Models\Permohonan;
|
||||
use Modules\Lpj\Models\PersetujuanPenawaran;
|
||||
use Modules\Lpj\Models\JenisPenilaian;
|
||||
|
||||
class NocController extends Controller
|
||||
{
|
||||
@@ -26,15 +26,13 @@ use Modules\Lpj\Models\Noc;
|
||||
public function pembayaran()
|
||||
{
|
||||
$persetujuanPenawarans = PersetujuanPenawaran::all();
|
||||
$jenisPenilaians = JenisPenilaian::get();
|
||||
return view('lpj::noc.pembayaran', compact('persetujuanPenawarans', 'jenisPenilaians'));
|
||||
return view('lpj::noc.pembayaran', compact('persetujuanPenawarans'));
|
||||
}
|
||||
|
||||
public function penyelesaian()
|
||||
{
|
||||
$persetujuanPenawarans = PersetujuanPenawaran::all();
|
||||
$jenisPenilaians = JenisPenilaian::get();
|
||||
return view('lpj::noc.penyelesaian', compact('persetujuanPenawarans', 'jenisPenilaians'));
|
||||
return view('lpj::noc.penyelesaian', compact('persetujuanPenawarans'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,27 +47,21 @@ use Modules\Lpj\Models\Noc;
|
||||
public function store(NocRequest $request)
|
||||
{
|
||||
$validated = $request->validated();
|
||||
|
||||
|
||||
$validated['updated_by'] = Auth::id();
|
||||
if (request()->get('status_bayar') == "sudah_bayar") {
|
||||
$validated['status'] = '1';
|
||||
$status = "spk";
|
||||
} else {
|
||||
$status = "persetujuan-penawaran";
|
||||
}
|
||||
|
||||
|
||||
$dataNoc = [
|
||||
'nominal_bayar' => $validated['nominal_bayar'],
|
||||
'total_pembukuan' => $validated['total_pembukuan'],
|
||||
'tanggal_pembayaran' => $validated['tanggal_pembayaran'] ?? date('Y-m-d'),
|
||||
'status_bayar' => $validated['nominal_bayar'] < $validated['total_harus_bayar'] ? false : true,
|
||||
'catatan_noc' => $validated['catatan_noc'] ?? '',
|
||||
'status_kurang_bayar' => $validated['status_kurang_bayar'] ?? '0',
|
||||
'status_lebih_bayar' => $validated['status_lebih_bayar'] ?? '0',
|
||||
'nominal_kurang_bayar' => $validated['nominal_kurang_bayar'] ?? '0',
|
||||
'nominal_lebih_bayar' => $validated['nominal_lebih_bayar'] ?? '0',
|
||||
'bukti_pengembalian' => $validated['bukti_pengembalian'] ?? '',
|
||||
'catatan_noc' => $validated['catatan_noc'],
|
||||
];
|
||||
|
||||
if($validated['permohonan_id']){
|
||||
$noc = Noc::updateOrCreate(
|
||||
[
|
||||
'permohonan_id' => $validated['permohonan_id'],
|
||||
@@ -77,14 +69,6 @@ use Modules\Lpj\Models\Noc;
|
||||
],
|
||||
$dataNoc,
|
||||
);
|
||||
} else {
|
||||
$noc = Noc::updateOrCreate(
|
||||
[
|
||||
'persetujuan_penawaran_id' => $validated['persetujuan_penawaran_id'],
|
||||
],
|
||||
$dataNoc,
|
||||
);
|
||||
}
|
||||
|
||||
$folderPath = 'noc/' . request()->get('persetujuan_penawaran_id') . '/bukti_ksl/';
|
||||
|
||||
@@ -96,11 +80,26 @@ use Modules\Lpj\Models\Noc;
|
||||
}
|
||||
$noc->save();
|
||||
|
||||
$bucok = Bucok::where('nomor_tiket', $noc->nomor_tiket)->first();
|
||||
$bucok->nominal_penyelesaian = $noc->total_pembukuan ?? '';
|
||||
$bucok->tanggal_penyelesaian = $noc->tanggal_pembayaran ?? date('Y-m-d');
|
||||
$bucok->penyelesaian = 'Selesai';
|
||||
$bucok->save();
|
||||
/* Update the status of the related permohonan to 'spk'
|
||||
$permohonan = Permohonan::find(request()->get('permohonan_id'));
|
||||
if ($permohonan) {
|
||||
$permohonan->status_bayar = request()->get('status_pembayar');
|
||||
if ($permohonan->jenis_penilaian_id == 2) {
|
||||
$permohonan->status = $status;
|
||||
}
|
||||
$permohonan->save();
|
||||
|
||||
// andy add, update status penawaran.status='spk'
|
||||
// $penawaran = PenawaranTender::where('nomor_registrasi',$permohonan->nomor_registrasi)->first();
|
||||
if ($permohonan->jenis_penilaian_id == 2) {
|
||||
PenawaranTender::where('nomor_registrasi', $permohonan->nomor_registrasi)->update([
|
||||
'status' => $status,
|
||||
'updated_by' => Auth::id(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
}
|
||||
// andy add, update status penawaran.status='spk'
|
||||
}*/
|
||||
|
||||
return redirect()
|
||||
->route('noc.index')->with('success', 'NOC berhasil disimpan.');
|
||||
@@ -113,7 +112,6 @@ use Modules\Lpj\Models\Noc;
|
||||
{
|
||||
$validated = $request->validated();
|
||||
|
||||
|
||||
if($request->get('is_memo')){
|
||||
|
||||
$memo = Noc::find($request->get('is_memo'));
|
||||
@@ -135,7 +133,6 @@ use Modules\Lpj\Models\Noc;
|
||||
->route('laporan.index')->with('success', 'Memo Penyelesaian updated successfully');
|
||||
}
|
||||
$dataNoc = [
|
||||
'total_pembukuan' => $validated['total_pembukuan'],
|
||||
'nominal_penyelesaian' => $validated['nominal_penyelesaian'],
|
||||
'tanggal_penyelesaian' => $validated['tanggal_penyelesaian'] ?? date('Y-m-d'),
|
||||
'status_pelunasan' => ((int)$validated['nominal_bayar'] + (int)$validated['nominal_penyelesaian']) === (int)$validated['total_harus_bayar'] ? true : false,
|
||||
@@ -218,16 +215,15 @@ use Modules\Lpj\Models\Noc;
|
||||
$query = PersetujuanPenawaran::query();
|
||||
|
||||
// Filter for pembayaran (where memo_penyelesaian is null)
|
||||
/*$query->whereDoesntHave('noc', function($q) {
|
||||
$query->whereDoesntHave('noc', function($q) {
|
||||
$q->whereNotNull('memo_penyelesaian');
|
||||
});*/
|
||||
});
|
||||
|
||||
// Apply search filter if provided
|
||||
if ($request->has('search') && !empty($request->get('search'))) {
|
||||
$search = $request->get('search');
|
||||
$query->where(function ($q) use ($search) {
|
||||
$q->orWhereRelation('penawaran', 'nomor_registrasi', 'LIKE', '%' . $search . '%')
|
||||
->orWhereRelation('permohonan.jenisPenilaian', 'name', 'LIKE', '%' . $search . '%');
|
||||
$q->orWhereRelation('penawaran', 'nomor_registrasi', 'LIKE', '%' . $search . '%');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -259,11 +255,9 @@ use Modules\Lpj\Models\Noc;
|
||||
$data = $data->map(function ($persetujuanPenawaran) {
|
||||
return [
|
||||
'id' => $persetujuanPenawaran->id,
|
||||
'nomor_registrasi' => $persetujuanPenawaran->permohonan?->nomor_registrasi ?? $persetujuanPenawaran->penawaran?->nomor_registrasi,
|
||||
'nomor_tiket' => $persetujuanPenawaran->nomor_tiket ?? '',
|
||||
'nama_debitur' => $persetujuanPenawaran?->permohonan?->debiture->name ?? $persetujuanPenawaran->penawaran?->permohonan?->debiture->name ?? $persetujuanPenawaran->noc?->debiture->name,
|
||||
'kode_cabang' => $persetujuanPenawaran?->permohonan?->branch->code ?? $persetujuanPenawaran->penawaran?->permohonan?->branch->code ?? $persetujuanPenawaran->noc?->branch->code,
|
||||
'cabang' => $persetujuanPenawaran?->permohonan?->branch->name ?? $persetujuanPenawaran->penawaran?->permohonan?->branch->name ?? $persetujuanPenawaran->noc?->branch->name,
|
||||
'nomor_registrasi' => $persetujuanPenawaran->permohonan->nomor_registrasi ?? $persetujuanPenawaran->penawaran->nomor_registrasi,
|
||||
'nama_debitur' => $persetujuanPenawaran->permohonan->debiture->name ?? $persetujuanPenawaran->penawaran->permohonan->debiture->name,
|
||||
'cabang' => $persetujuanPenawaran->permohonan->branch->name ?? $persetujuanPenawaran->penawaran->permohonan->branch->name,
|
||||
'tanggal_pembayaran' => dateFormat(
|
||||
$persetujuanPenawaran->noc->tanggal_pembayaran ?? $persetujuanPenawaran->noc?->created_at,
|
||||
true,
|
||||
@@ -273,19 +267,11 @@ use Modules\Lpj\Models\Noc;
|
||||
'nominal_diterima' => currencyFormat(
|
||||
$persetujuanPenawaran->noc->nominal_bayar ?? 0,
|
||||
),
|
||||
'jenis_penilaian' => $persetujuanPenawaran->permohonan?->jenisPenilaian?->name ?? "",
|
||||
'bukti_ksl' => $persetujuanPenawaran->noc->bukti_ksl ?? $persetujuanPenawaran->bukti_ksl ?? null,
|
||||
'bukti_bayar' => $persetujuanPenawaran->bukti_bayar ?? null,
|
||||
'updated_at' => dateFormat($persetujuanPenawaran->updated_at, true),
|
||||
];
|
||||
})->sortBy('updated_at', 1)->values();
|
||||
|
||||
// Calculate total nominal diterima from all filtered data (not just current page)
|
||||
$totalNominalDiterima = $data->sum(function ($item) {
|
||||
// Extract numeric value from formatted currency string
|
||||
$nominal = str_replace(['Rp', '.', ',00'], '', $item['nominal_diterima']);
|
||||
return (float) $nominal;
|
||||
});
|
||||
})->sortBy('updated_at', 1);
|
||||
|
||||
// Calculate the page count
|
||||
$pageCount = ceil($totalRecords / $request->get('size'));
|
||||
@@ -301,7 +287,6 @@ use Modules\Lpj\Models\Noc;
|
||||
'pageCount' => $pageCount,
|
||||
'page' => $currentPage,
|
||||
'totalCount' => $totalRecords,
|
||||
'totalNominalDiterima' => $totalNominalDiterima,
|
||||
'data' => $data,
|
||||
]);
|
||||
}
|
||||
@@ -316,14 +301,15 @@ use Modules\Lpj\Models\Noc;
|
||||
$query = PersetujuanPenawaran::query();
|
||||
|
||||
// Filter for penyelesaian (where memo_penyelesaian is not null)
|
||||
|
||||
$query->whereHas('noc', function($q) {
|
||||
$q->whereNotNull('memo_penyelesaian');
|
||||
});
|
||||
|
||||
// Apply search filter if provided
|
||||
if ($request->has('search') && !empty($request->get('search'))) {
|
||||
$search = $request->get('search');
|
||||
$query->where(function ($q) use ($search) {
|
||||
$q->orWhereRelation('penawaran', 'nomor_registrasi', 'LIKE', '%' . $search . '%')
|
||||
->orWhereRelation('permohonan.jenisPenilaian', 'name', 'LIKE', '%' . $search . '%');
|
||||
$q->orWhereRelation('penawaran', 'nomor_registrasi', 'LIKE', '%' . $search . '%');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -355,11 +341,9 @@ use Modules\Lpj\Models\Noc;
|
||||
$data = $data->map(function ($persetujuanPenawaran) {
|
||||
return [
|
||||
'id' => $persetujuanPenawaran->id,
|
||||
'nomor_registrasi' => $persetujuanPenawaran->permohonan?->nomor_registrasi ?? $persetujuanPenawaran->penawaran?->nomor_registrasi ?? '',
|
||||
'nomor_tiket' => $persetujuanPenawaran->nomor_tiket ?? '',
|
||||
'nama_debitur' => $persetujuanPenawaran->permohonan->debiture->name ?? $persetujuanPenawaran->penawaran->permohonan->debiture->name ?? $persetujuanPenawaran->noc->debiture->name,
|
||||
'kode_cabang' => $persetujuanPenawaran?->permohonan?->branch->code ?? $persetujuanPenawaran->penawaran?->permohonan?->branch->code ?? $persetujuanPenawaran->noc?->branch->code,
|
||||
'cabang' => $persetujuanPenawaran->permohonan->branch->name ?? $persetujuanPenawaran->penawaran->permohonan->branch->name ?? $persetujuanPenawaran->noc?->branch->name,
|
||||
'nomor_registrasi' => $persetujuanPenawaran->permohonan->nomor_registrasi ?? $persetujuanPenawaran->penawaran->nomor_registrasi,
|
||||
'nama_debitur' => $persetujuanPenawaran->permohonan->debiture->name ?? $persetujuanPenawaran->penawaran->permohonan->debiture->name,
|
||||
'cabang' => $persetujuanPenawaran->permohonan->branch->name ?? $persetujuanPenawaran->penawaran->permohonan->branch->name,
|
||||
'tanggal_pembayaran' => dateFormat(
|
||||
$persetujuanPenawaran->noc->tanggal_pembayaran ?? $persetujuanPenawaran->noc?->created_at,
|
||||
true,
|
||||
@@ -369,7 +353,6 @@ use Modules\Lpj\Models\Noc;
|
||||
'nominal_diterima' => currencyFormat(
|
||||
$persetujuanPenawaran->noc->nominal_bayar ?? 0,
|
||||
),
|
||||
'jenis_penilaian' => $persetujuanPenawaran->permohonan?->jenisPenilaian?->name ?? "",
|
||||
'bukti_ksl' => $persetujuanPenawaran->noc->bukti_ksl ?? $persetujuanPenawaran->bukti_ksl ?? null,
|
||||
'bukti_bayar' => $persetujuanPenawaran->bukti_bayar ?? null,
|
||||
'memo_penyelesaian' => $persetujuanPenawaran->noc->memo_penyelesaian ?? $persetujuanPenawaran->memo_penyelesaian ?? null,
|
||||
@@ -382,15 +365,7 @@ use Modules\Lpj\Models\Noc;
|
||||
true) : '-',
|
||||
'updated_at' => dateFormat($persetujuanPenawaran->updated_at, true),
|
||||
];
|
||||
})->sortBy('updated_at', 1)->values();
|
||||
|
||||
|
||||
// Calculate total nominal diterima from all filtered data (not just current page)
|
||||
$totalNominalDiterima = $data->sum(function ($item) {
|
||||
// Extract numeric value from formatted currency string
|
||||
$nominal = str_replace(['Rp', '.', ',00'], '', $item['nominal_diterima']);
|
||||
return (float) $nominal;
|
||||
});
|
||||
})->sortBy('updated_at', 1);
|
||||
|
||||
// Calculate the page count
|
||||
$pageCount = ceil($totalRecords / $request->get('size'));
|
||||
@@ -406,7 +381,6 @@ use Modules\Lpj\Models\Noc;
|
||||
'pageCount' => $pageCount,
|
||||
'page' => $currentPage,
|
||||
'totalCount' => $totalRecords,
|
||||
'totalNominalDiterima' => $totalNominalDiterima,
|
||||
'data' => $data,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -2,17 +2,21 @@
|
||||
|
||||
namespace Modules\Lpj\Http\Controllers;
|
||||
|
||||
use Exception;
|
||||
use Modules\Lpj\Models\Noc;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\Lpj\Models\Bucok;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Modules\Lpj\Models\Permohonan;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Exception;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Modules\Lpj\Models\PenawaranTender;
|
||||
use Modules\Lpj\Models\PersetujuanPenawaran;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
use Modules\Lpj\Http\Requests\PersetujuanPenawaranRequest;
|
||||
use Modules\Lpj\Models\PenawaranTender;
|
||||
use Modules\Lpj\Models\Permohonan;
|
||||
use Modules\Lpj\Models\PersetujuanPenawaran;
|
||||
|
||||
// use Modules\Lpj\Models\JenisPenilaian;
|
||||
|
||||
// use Modules\Lpj\Models\Regions;
|
||||
|
||||
class PembayaranController extends Controller
|
||||
{
|
||||
@@ -23,14 +27,6 @@ class PembayaranController extends Controller
|
||||
return view('lpj::pembayaran.index');
|
||||
}
|
||||
|
||||
public function kurang(){
|
||||
return view('lpj::pembayaran.kurang');
|
||||
}
|
||||
|
||||
public function lebih(){
|
||||
return view('lpj::pembayaran.lebih');
|
||||
}
|
||||
|
||||
public function approval()
|
||||
{
|
||||
return view('lpj::pembayaran.approval');
|
||||
@@ -111,115 +107,16 @@ class PembayaranController extends Controller
|
||||
]);
|
||||
}
|
||||
|
||||
public function create(){
|
||||
return view('lpj::pembayaran.create');
|
||||
}
|
||||
|
||||
public function edit($id)
|
||||
{
|
||||
|
||||
$req = request()->all();
|
||||
|
||||
if(isset($req['tiket'])){
|
||||
$persetujuanPenawaran = PersetujuanPenawaran::find($id);
|
||||
$permohonan = Permohonan::find($persetujuanPenawaran?->permohonan_id);
|
||||
} else {
|
||||
$permohonan = Permohonan::find($id);
|
||||
$persetujuanPenawaran = PersetujuanPenawaran::where('permohonan_id', $permohonan->id)->first();
|
||||
}
|
||||
|
||||
$persetujuanPenawaran = PersetujuanPenawaran::where('permohonan_id', $permohonan->id)->first();
|
||||
return view('lpj::pembayaran.form', compact('permohonan', 'persetujuanPenawaran'));
|
||||
}
|
||||
|
||||
public function editKurang($id){
|
||||
$noc = Noc::find($id);
|
||||
$permohonan = Permohonan::find($noc->permohonan_id);
|
||||
$persetujuanPenawaran = PersetujuanPenawaran::where('permohonan_id', $permohonan->id)->first();
|
||||
return view('lpj::pembayaran.form-kurang', compact('noc','permohonan','persetujuanPenawaran'));
|
||||
}
|
||||
|
||||
public function editLebih($id){
|
||||
$noc = Noc::find($id);
|
||||
$permohonan = Permohonan::find($noc->permohonan_id);
|
||||
$persetujuanPenawaran = PersetujuanPenawaran::where('permohonan_id', $permohonan->id)->first();
|
||||
return view('lpj::pembayaran.form-lebih', compact('noc','permohonan','persetujuanPenawaran'));
|
||||
}
|
||||
|
||||
public function store(PersetujuanPenawaranRequest $request)
|
||||
{
|
||||
$req = request()->all();
|
||||
|
||||
if($req['type'] == 'create'){
|
||||
$data = [
|
||||
'nomor_tiket' => $req['nomor_tiket'] ?? '',
|
||||
'nominal_bayar' => $req['nominal_bayar'] ?? '',
|
||||
'catatan' => $req['catatan'] ?? ''
|
||||
];
|
||||
|
||||
if(request()->hasFile('bukti_bayar')){
|
||||
$folderPath = 'persetujuan_penawaran/bukti_bayar/' . $req['nomor_tiket'];
|
||||
$data['bukti_bayar'] = $request->file('bukti_bayar')->store($folderPath, 'public');
|
||||
}
|
||||
|
||||
$persetujuanPenawaran = PersetujuanPenawaran::create($data);
|
||||
$noc = [
|
||||
'persetujuan_penawaran_id' => $persetujuanPenawaran->id,
|
||||
'nomor_tiket' => $req['nomor_tiket'] ?? '',
|
||||
'debiture_id' => $req['debitur_id'] ?? '',
|
||||
'branch_id' => Auth::user()->branch_id,
|
||||
];
|
||||
$noc = Noc::create($noc);
|
||||
|
||||
$bucok = [
|
||||
'tanggal_penuh' => $persetujuanPenawaran->created_at,
|
||||
'tanggal' => $persetujuanPenawaran->created_at->format('d'),
|
||||
'bulan' => $persetujuanPenawaran->created_at->format('m'),
|
||||
'tahun' => $persetujuanPenawaran->created_at->format('Y'),
|
||||
'nomor_tiket' => $req['nomor_tiket'] ?? '',
|
||||
'nominal' => $req['nominal_bayar'] ?? '',
|
||||
'nominal_berjalan' => $req['nominal_bayar'] ?? '',
|
||||
'penyelesaian' => 'Belum Selesai',
|
||||
'nama_sub_direktorat' => $noc->branch?->name ?? '',
|
||||
'nama_direktorat_cabang' => $noc->branch?->name ?? '',
|
||||
];
|
||||
|
||||
Bucok::updateOrCreate([
|
||||
'nomor_tiket' => $req['nomor_tiket'] ?? '',
|
||||
], $bucok);
|
||||
|
||||
return redirect()
|
||||
->route('pembayaran.index')->with('success', 'Pembayaran berhasil disimpan.');
|
||||
}
|
||||
|
||||
if($req['type'] == 'kurang_bayar'){
|
||||
$noc = Noc::find($req['noc_id']);
|
||||
$noc->nominal_pelunasan = $req['nominal_pelunasan'];
|
||||
if (request()->hasFile('bukti_ksl_kurang_bayar')) {
|
||||
$folderPath = 'persetujuan_penawaran/bukti_ksl_kurang_bayar/' . $req['noc_id'];
|
||||
$noc->bukti_ksl_kurang_bayar = $request->file('bukti_ksl_kurang_bayar')->store($folderPath, 'public');
|
||||
}
|
||||
$noc->save();
|
||||
|
||||
$persetujuanPenawaran = PersetujuanPenawaran::find($noc->persetujuan_penawaran_id);
|
||||
$persetujuanPenawaran->bukti_ksl_kurang_bayar = $noc->bukti_ksl_kurang_bayar;
|
||||
$persetujuanPenawaran->nominal_kurang_bayar = $req['nominal_pelunasan'];
|
||||
$persetujuanPenawaran->save();
|
||||
return redirect()
|
||||
->route('pembayaran.kurang.index')->with('success', 'Pelunasan Kurang Bayar berhasil disimpan.');
|
||||
}
|
||||
|
||||
if($req['type'] == 'lebih_bayar'){
|
||||
$noc = Noc::find($req['noc_id']);
|
||||
if (request()->hasFile('bukti_ksl_lebih_bayar')) {
|
||||
$folderPath = 'persetujuan_penawaran/bukti_ksl_lebih_bayar/' . $req['noc_id'];
|
||||
$noc->bukti_ksl_lebih_bayar = $request->file('bukti_ksl_lebih_bayar')->store($folderPath, 'public');
|
||||
}
|
||||
$noc->save();
|
||||
|
||||
return redirect()
|
||||
->route('pembayaran.lebih.index')->with('success', 'Pengembalian Lebih Bayar berhasil disimpan.');
|
||||
}
|
||||
|
||||
$validated = $request->validated();
|
||||
$validated['created_by'] = Auth::id();
|
||||
$validated['status'] = '0';
|
||||
@@ -252,15 +149,6 @@ class PembayaranController extends Controller
|
||||
$validated
|
||||
);
|
||||
|
||||
if(isset($validated['nomor_tiket'])){
|
||||
$noc = Noc::where('nomor_tiket',$validated['nomor_tiket'])->first();
|
||||
if($noc){
|
||||
$noc->persetujuan_penawaran_id = $persetujuanPenawaran->id;
|
||||
$noc->permohonan_id = $validated['permohonan_id'];
|
||||
$noc->save();
|
||||
}
|
||||
}
|
||||
|
||||
$folderPath = 'persetujuan_penawaran/' . $validated['penawaran_id'];
|
||||
|
||||
if ($request->hasFile('bukti_bayar')) {
|
||||
@@ -366,23 +254,31 @@ class PembayaranController extends Controller
|
||||
// abort(403, 'Sorry! You are not allowed to view users.');
|
||||
}
|
||||
|
||||
$query = PersetujuanPenawaran::query();
|
||||
$query = Permohonan::query()->where(function ($query) {
|
||||
$query->where(['status_bayar' => 'belum_bayar', 'jenis_penilaian_id' => 1])
|
||||
->orWhere('status', 'revisi-pembayaran');
|
||||
})
|
||||
->where(function ($query) {
|
||||
$query->whereNotIn('id', function ($subquery) {
|
||||
$subquery->select('permohonan_id')
|
||||
->from('persetujuan_penawaran')
|
||||
->whereNotNull('permohonan_id');
|
||||
});
|
||||
});
|
||||
|
||||
$query->where(function($q) {
|
||||
$q->whereRelation('permohonan', function($query) {
|
||||
$query->where('status_bayar', 'belum_bayar')
|
||||
->where('jenis_penilaian_id', 1);
|
||||
});
|
||||
});
|
||||
$query->orWhereRelation('permohonan','status_bayar','revisi-pembayaran');
|
||||
$query->orWhere(function($q) {
|
||||
$q->where('permohonan_id',null);
|
||||
$q->where('nomor_tiket','!=',null);
|
||||
});
|
||||
|
||||
// Pencarian berdasarkan parameter search
|
||||
if ($request->has('search') && !empty($request->get('search'))) {
|
||||
$search = $request->get('search');
|
||||
$query->where(function ($q) use ($search) {
|
||||
$q->where('nomor_registrasi', 'LIKE', '%' . $search . '%');
|
||||
$q->orWhere('tanggal_permohonan', 'LIKE', '%' . $search . '%');
|
||||
$q->orWhereRelation('user', 'name', 'LIKE', '%' . $search . '%');
|
||||
$q->orWhereRelation('debiture', 'name', 'LIKE', '%' . $search . '%');
|
||||
$q->orWhereRelation('jenisPenilaian', 'name', 'LIKE', '%' . $search . '%');
|
||||
$q->orWhereRelation('branch', 'name', 'LIKE', '%' . $search . '%');
|
||||
$q->orWhere('status', 'LIKE', '%' . $search . '%');
|
||||
});
|
||||
}
|
||||
|
||||
// Sorting berdasarkan sortField dan sortOrder
|
||||
@@ -412,160 +308,8 @@ class PembayaranController extends Controller
|
||||
$filteredRecords = $query->count();
|
||||
|
||||
// Ambil data dengan relasi
|
||||
$data = $query->get();
|
||||
$data = $query->with(['user', 'debiture', 'branch', 'jenisPenilaian'])->get();
|
||||
|
||||
$data = $data->map(function ($item) {
|
||||
return [
|
||||
'id' => $item->permohonan?->id ?? $item->id,
|
||||
'nomor_registrasi' => $item->permohonan?->nomor_registrasi,
|
||||
'nomor_tiket' => $item->nomor_tiket ?? '',
|
||||
'debiture' => $item->permohonan?->debiture ?? $item->noc?->debiture,
|
||||
'user' => $item->permohonan?->user ?? $item->creator,
|
||||
'status_bayar' => $item->permohonan?->status_bayar ?? ($item->nomor_tiket ? 'Sudah Bayar' : ''),
|
||||
'tanggal_permohonan' => $item->permohonan?->tanggal_permohonan ?? '',
|
||||
'branch' => $item->permohonan?->branch ?? $item->noc?->branch,
|
||||
'is_permohonan' => $item->permohonan ?? ''
|
||||
];
|
||||
});
|
||||
|
||||
|
||||
// Hitung jumlah halaman
|
||||
$pageCount = ceil($totalRecords / $size);
|
||||
|
||||
// Ambil current page
|
||||
$currentPage = max(1, $request->get('page', 1));
|
||||
|
||||
// Return JSON response
|
||||
return response()->json([
|
||||
'draw' => $request->get('draw'),
|
||||
'recordsTotal' => $totalRecords,
|
||||
'recordsFiltered' => $filteredRecords,
|
||||
'pageCount' => $pageCount,
|
||||
'page' => $currentPage,
|
||||
'totalCount' => $totalRecords,
|
||||
'data' => $data,
|
||||
]);
|
||||
}
|
||||
|
||||
public function dataForDatatablesKurang(Request $request)
|
||||
{
|
||||
if (is_null($this->user) || !$this->user->can('debitur.view')) {
|
||||
// abort(403, 'Sorry! You are not allowed to view users.');
|
||||
}
|
||||
|
||||
$query = Noc::query()->where(function ($query) {
|
||||
$query->where(['status_kurang_bayar' => '1'])
|
||||
->where('bukti_ksl_kurang_bayar',null);
|
||||
});
|
||||
|
||||
// Sorting berdasarkan sortField dan sortOrder
|
||||
if ($request->has('sortOrder') && !empty($request->get('sortOrder'))) {
|
||||
$order = $request->get('sortOrder');
|
||||
$column = $request->get('sortField');
|
||||
$query->orderBy($column, $order);
|
||||
}
|
||||
|
||||
// Hitung total records
|
||||
$totalRecords = $query->count();
|
||||
|
||||
// Pagination (default page size 10)
|
||||
$size = $request->get('size', 10);
|
||||
if ($size == 0) {
|
||||
$size = 10;
|
||||
}
|
||||
|
||||
if ($request->has('page') && $request->has('size')) {
|
||||
$page = $request->get('page', 1);
|
||||
$offset = ($page - 1) * $size;
|
||||
|
||||
$query->skip($offset)->take($size);
|
||||
}
|
||||
|
||||
// Filtered records
|
||||
$filteredRecords = $query->count();
|
||||
|
||||
// Ambil data dengan relasi
|
||||
$data = $query->get();
|
||||
|
||||
$data = $data->map(function ($item) {
|
||||
return [
|
||||
'id' => $item->id,
|
||||
'permohonan' => $item->permohonan,
|
||||
'pemohon' => $item->permohonan->user,
|
||||
'branch' => $item->permohonan->branch,
|
||||
'debiture' => $item->permohonan->debiture,
|
||||
'nominal_kurang_bayar' => formatRupiah($item->nominal_kurang_bayar,2)
|
||||
];
|
||||
});
|
||||
|
||||
// Hitung jumlah halaman
|
||||
$pageCount = ceil($totalRecords / $size);
|
||||
|
||||
// Ambil current page
|
||||
$currentPage = max(1, $request->get('page', 1));
|
||||
|
||||
// Return JSON response
|
||||
return response()->json([
|
||||
'draw' => $request->get('draw'),
|
||||
'recordsTotal' => $totalRecords,
|
||||
'recordsFiltered' => $filteredRecords,
|
||||
'pageCount' => $pageCount,
|
||||
'page' => $currentPage,
|
||||
'totalCount' => $totalRecords,
|
||||
'data' => $data,
|
||||
]);
|
||||
}
|
||||
|
||||
public function dataForDatatablesLebih(Request $request)
|
||||
{
|
||||
if (is_null($this->user) || !$this->user->can('debitur.view')) {
|
||||
// abort(403, 'Sorry! You are not allowed to view users.');
|
||||
}
|
||||
|
||||
$query = Noc::query()->where(function ($query) {
|
||||
$query->where(['status_lebih_bayar' => '1'])
|
||||
->where('bukti_ksl_lebih_bayar',null);
|
||||
});
|
||||
|
||||
// Sorting berdasarkan sortField dan sortOrder
|
||||
if ($request->has('sortOrder') && !empty($request->get('sortOrder'))) {
|
||||
$order = $request->get('sortOrder');
|
||||
$column = $request->get('sortField');
|
||||
$query->orderBy($column, $order);
|
||||
}
|
||||
|
||||
// Hitung total records
|
||||
$totalRecords = $query->count();
|
||||
|
||||
// Pagination (default page size 10)
|
||||
$size = $request->get('size', 10);
|
||||
if ($size == 0) {
|
||||
$size = 10;
|
||||
}
|
||||
|
||||
if ($request->has('page') && $request->has('size')) {
|
||||
$page = $request->get('page', 1);
|
||||
$offset = ($page - 1) * $size;
|
||||
|
||||
$query->skip($offset)->take($size);
|
||||
}
|
||||
|
||||
// Filtered records
|
||||
$filteredRecords = $query->count();
|
||||
|
||||
// Ambil data dengan relasi
|
||||
$data = $query->get();
|
||||
|
||||
$data = $data->map(function ($item) {
|
||||
return [
|
||||
'id' => $item->id,
|
||||
'permohonan' => $item->permohonan,
|
||||
'pemohon' => $item->permohonan->user,
|
||||
'branch' => $item->permohonan->branch,
|
||||
'debiture' => $item->permohonan->debiture,
|
||||
'nominal_lebih_bayar' => formatRupiah($item->nominal_lebih_bayar,2)
|
||||
];
|
||||
});
|
||||
|
||||
// Hitung jumlah halaman
|
||||
$pageCount = ceil($totalRecords / $size);
|
||||
|
||||
@@ -26,18 +26,21 @@ use Modules\Lpj\Http\Requests\FormSurveyorRequest;
|
||||
use Modules\Lpj\Models\Authorization;
|
||||
use Modules\Lpj\Models\Debiture;
|
||||
use Modules\Lpj\Services\SaveFormInspesksiService;
|
||||
use Modules\Lpj\Services\PreviewLaporanService;
|
||||
|
||||
class PenilaiController extends Controller
|
||||
{
|
||||
public $user;
|
||||
protected $surveyorController;
|
||||
protected $inspeksiService;
|
||||
protected $previewLaporanService;
|
||||
|
||||
|
||||
public function __construct(SurveyorController $surveyorController, SaveFormInspesksiService $inspeksiService)
|
||||
public function __construct(SurveyorController $surveyorController, SaveFormInspesksiService $inspeksiService, PreviewLaporanService $previewLaporanService)
|
||||
{
|
||||
$this->surveyorController = $surveyorController;
|
||||
$this->inspeksiService = $inspeksiService;
|
||||
$this->previewLaporanService = $previewLaporanService;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -548,13 +551,7 @@ class PenilaiController extends Controller
|
||||
return view('lpj::penilai.components.call-report', compact('permohonan', 'basicData', 'nomorLaporan', 'forminspeksi', 'cities', 'districts', 'villages', 'cekAlamat', 'callReport'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
public function destroy($id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
|
||||
public function dataForDatatables(Request $request)
|
||||
{
|
||||
@@ -700,6 +697,7 @@ class PenilaiController extends Controller
|
||||
'lokasi_lengkap' => $data->lokasi_lengkap ?? '',
|
||||
];
|
||||
|
||||
if(isset($dataPembanding)){
|
||||
// Extract data pembanding
|
||||
if (isset($dataPembanding['data_pembanding'])) {
|
||||
foreach ($dataPembanding['data_pembanding'] as $index => $pembanding) {
|
||||
@@ -712,6 +710,7 @@ class PenilaiController extends Controller
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now create the export
|
||||
// return response()->json([ 'data' => $fotoForm]);
|
||||
@@ -1277,132 +1276,13 @@ class PenilaiController extends Controller
|
||||
|
||||
|
||||
|
||||
public function print_out(Request $request)
|
||||
public function print_out_laporan($permohonan_id, $document_id, $jaminan_id)
|
||||
{
|
||||
$documentId = $request->query('documentId');
|
||||
$jaminanId = $request->query('jaminanId');
|
||||
$permohonanId = $request->query('permohonanId');
|
||||
$statusLpj = $request->query('statusLpj');
|
||||
$tipeLaporan = $request->query('type');
|
||||
|
||||
$permohonan = $this->surveyorController->getPermohonanJaminanId(
|
||||
$permohonanId,
|
||||
$documentId,
|
||||
$jaminanId
|
||||
);
|
||||
|
||||
$basicData = $this->surveyorController->getCommonData();
|
||||
|
||||
$inspeksi = Inspeksi::where('permohonan_id', $permohonanId)->where('dokument_id', $documentId)->first();
|
||||
$lpj = Penilai::where('permohonan_id', $permohonanId)->where('dokument_id', $documentId)->first();
|
||||
|
||||
$nomorLaporan = getNomorLaporan($permohonanId, $documentId);
|
||||
$tanggalLaporan = $lpj->created_at ?? null;
|
||||
$forminspeksi = null;
|
||||
$lpjData = null;
|
||||
$formFoto = null;
|
||||
|
||||
if ($inspeksi) {
|
||||
$forminspeksi = json_decode($inspeksi->data_form, true);
|
||||
$formFoto = json_decode($inspeksi->foto_form, true);
|
||||
// $denahForm = json_decode($data->denah_form, true);
|
||||
$dataPembanding = json_decode($inspeksi->data_pembanding, true);
|
||||
// jika tidak ada id kembalikan ke halaman sebelumnya
|
||||
if (!$permohonan_id || !$document_id || !$jaminan_id) {
|
||||
return redirect()->back()->with('error', 'Laporan tidak valid');
|
||||
}
|
||||
|
||||
if ($lpj) {
|
||||
$lpjData = json_decode($lpj->lpj, true);
|
||||
$memo = json_decode($lpj->memo, true);
|
||||
$resumeData = json_decode($lpj->resume, true);
|
||||
$rap = json_decode($lpj->rap, true);
|
||||
$report = json_decode($lpj->call_report, true);
|
||||
}
|
||||
|
||||
$inputAddress = $forminspeksi['asset']['alamat']['sesuai'] ?? $forminspeksi['asset']['alamat']['tidak sesuai'] ?? [];
|
||||
|
||||
$alamat = [
|
||||
'address' => $inputAddress['address'] ?? null,
|
||||
'village_code' => getWilayahName($inputAddress['village_code'] ?? null, 'village'),
|
||||
'district_code' => getWilayahName($inputAddress['district_code'] ?? null, 'district'),
|
||||
'city_code' => getWilayahName($inputAddress['city_code'] ?? null, 'city'),
|
||||
'province_code' => getWilayahName($inputAddress['province_code'] ?? null, 'province')
|
||||
];
|
||||
|
||||
$viewLaporan = $this->getViewLaporan($tipeLaporan);
|
||||
try {
|
||||
|
||||
if ($statusLpj) {
|
||||
// $pdf = view('lpj::' . $viewLaporan, compact(
|
||||
$pdf = PDF::loadView('lpj::' . $viewLaporan, compact(
|
||||
'permohonan',
|
||||
'forminspeksi',
|
||||
'lpjData',
|
||||
'formFoto',
|
||||
'basicData',
|
||||
'inspeksi',
|
||||
'lpj',
|
||||
'statusLpj',
|
||||
'alamat',
|
||||
'dataPembanding',
|
||||
'nomorLaporan',
|
||||
'memo',
|
||||
'resumeData',
|
||||
'tanggalLaporan',
|
||||
'rap',
|
||||
'report'
|
||||
));
|
||||
// return $pdf;
|
||||
$cleanNomorLaporan = str_replace(['/', '\\'], '-', $nomorLaporan);
|
||||
$pdf->setPaper('A4', 'portrait');
|
||||
$pdf->set_option('isHtml5ParserEnabled', true);
|
||||
$pdf->set_option('isPhpEnabled', true);
|
||||
return response($pdf->output(), 200)
|
||||
->header('Content-Type', 'application/pdf')
|
||||
->header('Content-Disposition', 'inline; filename="Laporan_' . $tipeLaporan . '_' . $permohonan->debiture->name . '_' . $cleanNomorLaporan . '.pdf"');
|
||||
// return $pdf->stream();
|
||||
} else {
|
||||
// $pdf = view('lpj::' . $viewLaporan, compact(
|
||||
$pdf = PDF::loadView('lpj::' . $viewLaporan, compact(
|
||||
'permohonan',
|
||||
'forminspeksi',
|
||||
'lpjData',
|
||||
'formFoto',
|
||||
'basicData',
|
||||
'inspeksi',
|
||||
'lpj',
|
||||
'statusLpj',
|
||||
'alamat',
|
||||
'dataPembanding',
|
||||
'nomorLaporan',
|
||||
'memo',
|
||||
'resumeData',
|
||||
'tanggalLaporan',
|
||||
'rap',
|
||||
'report'
|
||||
));
|
||||
// return $pdf;
|
||||
$cleanNomorLaporan = str_replace(['/', '\\'], '-', $nomorLaporan);
|
||||
$pdf->setPaper('A4', 'portrait');
|
||||
$pdf->set_option('isHtml5ParserEnabled', true);
|
||||
$pdf->set_option('isPhpEnabled', true);
|
||||
return $pdf->download('Laporan_' . $tipeLaporan . '_' . $permohonan->debiture->name . '_' . $cleanNomorLaporan . '_data.pdf');
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Log::error('PDF generation failed: ' . $e->getMessage());
|
||||
return response()->json(['error' => 'Failed to generate PDF. Please check the log for details.' . $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
|
||||
private function getViewLaporan($tipe)
|
||||
{
|
||||
$viewMap = [
|
||||
'sederhana' => 'penilai.components.print-out-sederhana',
|
||||
'standar' => 'penilai.components.print-out-standar',
|
||||
'resume' => 'penilai.components.print-resume',
|
||||
'memo' => 'penilai.components.print-memo',
|
||||
'rap' => 'penilai.components.print-out-rap',
|
||||
'call-report' => 'penilai.components.print-out-call-report'
|
||||
];
|
||||
return $viewMap[$tipe] ?? 'penilai.components.print-resume';
|
||||
return $this->previewLaporanService->printOutLaporan($permohonan_id, $document_id, $jaminan_id);
|
||||
}
|
||||
|
||||
|
||||
@@ -1429,46 +1309,7 @@ class PenilaiController extends Controller
|
||||
];
|
||||
}
|
||||
|
||||
public function checkPrintOutLaporan(Request $request)
|
||||
{
|
||||
$permohonanId = $request->query('permohonanId');
|
||||
$documentId = $request->query('documentId');
|
||||
|
||||
// Ambil data berdasarkan ID
|
||||
$statusLpj = Penilai::where('permohonan_id', $permohonanId)
|
||||
->where('dokument_id', $documentId)
|
||||
->first();
|
||||
|
||||
// Jika data tidak ditemukan, kembalikan status null
|
||||
if (!$statusLpj) {
|
||||
return response()->json(['status' => null]);
|
||||
}
|
||||
|
||||
// Tentukan tipe berdasarkan kondisi
|
||||
$type = $statusLpj->type_penilai ?? null;
|
||||
|
||||
if ($type === 'memo') {
|
||||
return $this->checkDataMemo($type, $statusLpj);
|
||||
}
|
||||
|
||||
if ($type === 'resume') {
|
||||
return $this->checkDataResume($type, $statusLpj);
|
||||
}
|
||||
|
||||
|
||||
if ($type === 'standar' || $type === 'sederhana') {
|
||||
return $this->checkDataLpj($type, $statusLpj);
|
||||
}
|
||||
|
||||
if ($type === 'rap') {
|
||||
return $this->checkDataRap($type, $statusLpj);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Kembalikan respons dengan tipe yang sesuai
|
||||
return response()->json(['status' => $type]);
|
||||
}
|
||||
|
||||
|
||||
public function generateNoLaporan($permohonan, $documentId, $type)
|
||||
@@ -1508,239 +1349,6 @@ class PenilaiController extends Controller
|
||||
}
|
||||
|
||||
|
||||
public function checkDataMemo($type, $statusLpj)
|
||||
{
|
||||
// Ambil data JSON dari statusLpj
|
||||
$data = json_decode($statusLpj->memo, true) ?? [];
|
||||
|
||||
$validationRules = [
|
||||
'memo' => [
|
||||
'kepada',
|
||||
'dari',
|
||||
'nomor_memo',
|
||||
'tanggal',
|
||||
'perihal',
|
||||
'jenis_asset_tidak_sesuai',
|
||||
'lokasi.lokasi',
|
||||
'lokasi.province_code',
|
||||
'lokasi.city_code',
|
||||
'lokasi.district_code',
|
||||
'lokasi.village_code',
|
||||
'lokasi.penilai',
|
||||
'terlampir',
|
||||
'hasil_survey',
|
||||
'kesimpulan_saran',
|
||||
],
|
||||
];
|
||||
|
||||
// Validasi data JSON
|
||||
if (isset($validationRules[$type])) {
|
||||
$missingFields = [];
|
||||
|
||||
foreach ($validationRules[$type] as $field) {
|
||||
$keys = explode('.', $field);
|
||||
$value = $data;
|
||||
|
||||
foreach ($keys as $key) {
|
||||
if (!isset($value[$key])) {
|
||||
$missingFields[] = $field;
|
||||
break;
|
||||
}
|
||||
$value = $value[$key];
|
||||
}
|
||||
}
|
||||
|
||||
// Jika ada field yang kosong, kembalikan error
|
||||
if (!empty($missingFields)) {
|
||||
return response()->json([
|
||||
'status' => null,
|
||||
'message' => "Silahkan lengkapi data memo terlebih dahulu.",
|
||||
'missing_fields' => $missingFields,
|
||||
], 400);
|
||||
}
|
||||
}
|
||||
|
||||
// Jika data valid
|
||||
return response()->json([
|
||||
'status' => $type,
|
||||
'message' => "Data memo valid.",
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public function checkDataResume($type, $statusLpj)
|
||||
{
|
||||
// Ambil data JSON dari statusLpj
|
||||
$data = json_decode($statusLpj->resume, true) ?? [];
|
||||
|
||||
$validationRules = [
|
||||
'resume' => [
|
||||
'fisik'
|
||||
],
|
||||
];
|
||||
|
||||
// Validasi data JSON
|
||||
if (isset($validationRules[$type])) {
|
||||
$missingFields = [];
|
||||
|
||||
foreach ($validationRules[$type] as $field) {
|
||||
$keys = explode('.', $field);
|
||||
$value = $data;
|
||||
|
||||
foreach ($keys as $key) {
|
||||
if (!isset($value[$key])) {
|
||||
$missingFields[] = $field;
|
||||
break;
|
||||
}
|
||||
$value = $value[$key];
|
||||
}
|
||||
|
||||
// Validasi khusus untuk array fisik dan sesuai_imb
|
||||
if ($field === 'fisik' || $field === 'sesuai_imb') {
|
||||
if (empty($value) || !is_array($value)) {
|
||||
$missingFields[] = $field;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Validasi struktur data di dalam array
|
||||
foreach ($value as $item) {
|
||||
$requiredKeys = ['sertifikat', 'luas_tanah', 'nilai'];
|
||||
foreach ($requiredKeys as $requiredKey) {
|
||||
if (!isset($item[$requiredKey])) {
|
||||
$missingFields[] = $field . '.' . $requiredKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Jika ada field yang kosong, kembalikan error
|
||||
if (!empty($missingFields)) {
|
||||
return response()->json([
|
||||
'status' => null,
|
||||
'message' => "Silahkan lengkapi data resume terlebih dahulu.",
|
||||
'missing_fields' => $missingFields,
|
||||
], 400);
|
||||
}
|
||||
}
|
||||
|
||||
// Jika data valid
|
||||
return response()->json([
|
||||
'status' => $type,
|
||||
'message' => "Data resume valid.",
|
||||
]);
|
||||
}
|
||||
|
||||
public function checkDataLpj($type, $statusLpj)
|
||||
{
|
||||
// Ambil data JSON dari statusLpj
|
||||
$data = json_decode($statusLpj->lpj, true) ?? [];
|
||||
|
||||
$validationRules = [
|
||||
'lpj' => [
|
||||
'luas_tanah',
|
||||
'nilai_tanah_1',
|
||||
'nilai_tanah_2',
|
||||
'luas_bangunan',
|
||||
'nilai_bangunan_1',
|
||||
'nilai_bangunan_2',
|
||||
'total_nilai_pasar_wajar',
|
||||
'likuidasi',
|
||||
'likuidasi_nilai_1',
|
||||
'likuidasi_nilai_2',
|
||||
'asuransi_luas_bangunan',
|
||||
'asuransi_nilai_1',
|
||||
'asuransi_nilai_2',
|
||||
'npw_tambahan'
|
||||
],
|
||||
];
|
||||
|
||||
// Validasi data JSON
|
||||
if (isset($validationRules[$type])) {
|
||||
$missingFields = [];
|
||||
|
||||
foreach ($validationRules[$type] as $field) {
|
||||
// Penanganan khusus untuk field yang boleh null
|
||||
if (in_array($field, ['sarana_pelengkap_penilai', 'nilai_sarana_pelengkap_1', 'nilai_sarana_pelengkap_2'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($data[$field])) {
|
||||
$missingFields[] = $field;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Validasi khusus untuk npw_tambahan
|
||||
if ($field === 'npw_tambahan' && is_array($data[$field])) {
|
||||
foreach ($data[$field] as $index => $item) {
|
||||
$requiredKeys = ['name', 'luas', 'nilai_1', 'nilai_2'];
|
||||
foreach ($requiredKeys as $key) {
|
||||
if (!isset($item[$key])) {
|
||||
$missingFields[] = "npw_tambahan[$index].$key";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Jika ada field yang kosong, kembalikan error
|
||||
if (!empty($missingFields)) {
|
||||
return response()->json([
|
||||
'status' => null,
|
||||
'message' => "Silahkan lengkapi data LPJ terlebih dahulu.",
|
||||
'missing_fields' => $missingFields,
|
||||
], 400);
|
||||
}
|
||||
}
|
||||
|
||||
// Jika data valid
|
||||
return response()->json([
|
||||
'status' => $type,
|
||||
'message' => "Data LPJ valid.",
|
||||
]);
|
||||
}
|
||||
|
||||
public function checkDataRap($type, $statusLpj)
|
||||
{
|
||||
// Ambil data JSON dari statusLpj
|
||||
$data = json_decode($statusLpj->rap, true) ?? [];
|
||||
|
||||
$requiredFields = [
|
||||
'dari',
|
||||
'kepada',
|
||||
'perihal',
|
||||
'tanggal',
|
||||
'nomor_rap'
|
||||
];
|
||||
|
||||
// Cek apakah ada field yang kosong
|
||||
$missingFields = [];
|
||||
foreach ($requiredFields as $field) {
|
||||
if (!isset($data[$field]) || empty($data[$field])) {
|
||||
$missingFields[] = $field;
|
||||
}
|
||||
}
|
||||
|
||||
// Jika ada field yang kosong, kembalikan error
|
||||
if (!empty($missingFields)) {
|
||||
return response()->json([
|
||||
'status' => null,
|
||||
'message' => "Silahkan lengkapi data RAP terlebih dahulu.",
|
||||
'missing_fields' => $missingFields
|
||||
], 400);
|
||||
}
|
||||
|
||||
// Jika semua data terisi
|
||||
return response()->json([
|
||||
'status' => $type,
|
||||
'message' => "Data RAP valid."
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
public function revisiSurveyor(Request $request, $id)
|
||||
{
|
||||
$permohonan = Permohonan::findOrFail($id);
|
||||
@@ -1771,4 +1379,24 @@ class PenilaiController extends Controller
|
||||
'message' => 'Berhasil Revisi Ke surveyor',
|
||||
], 200);
|
||||
}
|
||||
|
||||
public function showLaporanInspeksi(
|
||||
$permohonan_id,
|
||||
$dokumen_id,
|
||||
$jaminan_id,
|
||||
Request $request)
|
||||
{
|
||||
if ($request->type == 'penilai') {
|
||||
$back = route('penilai.show', $permohonan_id);
|
||||
}else{
|
||||
$back = route('surveyor.show', $permohonan_id);
|
||||
}
|
||||
|
||||
return $this->previewLaporanService->previewLaporan($permohonan_id, $dokumen_id, $jaminan_id, $back);
|
||||
}
|
||||
|
||||
public function showInspectionReportReview($permohonan_id, $dokumen_id, $jaminan_id)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,473 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Exception;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
use Modules\Lpj\Imports\SlikImport;
|
||||
use Modules\Lpj\Models\Slik;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Controller untuk mengelola data Slik
|
||||
*
|
||||
* Menangani operasi CRUD dan import data Slik dari file Excel
|
||||
* dengan fitur server-side processing untuk datatables
|
||||
*
|
||||
* @package Modules\Lpj\Http\Controllers
|
||||
*/
|
||||
class SlikController extends Controller
|
||||
{
|
||||
public $user;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->user = Auth::user();
|
||||
}
|
||||
|
||||
/**
|
||||
* Menampilkan halaman index slik
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return view('lpj::slik.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Menampilkan detail slik
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
$slik = Slik::findOrFail($id);
|
||||
return view('lpj::slik.show', compact('slik'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data untuk datatables dengan server-side processing
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function dataForDatatables(Request $request)
|
||||
{
|
||||
// Authorization check dapat ditambahkan sesuai kebutuhan
|
||||
// if (is_null($this->user)) {
|
||||
// abort(403, 'Unauthorized access.');
|
||||
// }
|
||||
|
||||
// Retrieve data from the database
|
||||
$query = Slik::query();
|
||||
|
||||
// Apply search filter if provided
|
||||
if ($request->has('search') && !empty($request->get('search'))) {
|
||||
$search = $request->get('search');
|
||||
$query->where(function ($q) use ($search) {
|
||||
$q->where('sandi_bank', 'LIKE', "%$search%")
|
||||
->orWhere('no_rekening', 'LIKE', "%$search%")
|
||||
->orWhere('cif', 'LIKE', "%$search%")
|
||||
->orWhere('nama_debitur', 'LIKE', "%$search%")
|
||||
->orWhere('nama_cabang', 'LIKE', "%$search%")
|
||||
->orWhere('jenis_agunan', 'LIKE', "%$search%")
|
||||
->orWhere('nama_pemilik_agunan', 'LIKE', "%$search%")
|
||||
->orWhere('alamat_agunan', 'LIKE', "%$search%")
|
||||
->orWhere('lokasi_agunan', 'LIKE', "%$search%");
|
||||
});
|
||||
}
|
||||
|
||||
// Apply year filter
|
||||
if ($request->has('year') && !empty($request->get('year'))) {
|
||||
$query->byYear($request->get('year'));
|
||||
}
|
||||
|
||||
// Apply month filter
|
||||
if ($request->has('month') && !empty($request->get('month'))) {
|
||||
$query->byMonth($request->get('month'));
|
||||
}
|
||||
|
||||
// Apply sandi bank filter
|
||||
if ($request->has('sandi_bank') && !empty($request->get('sandi_bank'))) {
|
||||
$query->where('sandi_bank', $request->get('sandi_bank'));
|
||||
}
|
||||
|
||||
// Apply kolektibilitas filter
|
||||
if ($request->has('kolektibilitas') && !empty($request->get('kolektibilitas'))) {
|
||||
$query->where('kolektibilitas', $request->get('kolektibilitas'));
|
||||
}
|
||||
|
||||
// Apply jenis agunan filter
|
||||
if ($request->has('jenis_agunan') && !empty($request->get('jenis_agunan'))) {
|
||||
$query->where('jenis_agunan', $request->get('jenis_agunan'));
|
||||
}
|
||||
|
||||
// Apply sorting if provided
|
||||
if ($request->has('sortOrder') && !empty($request->get('sortOrder'))) {
|
||||
$order = $request->get('sortOrder');
|
||||
$column = $request->get('sortField', 'created_at');
|
||||
$query->orderBy($column, $order);
|
||||
} else {
|
||||
$query->orderBy('created_at', 'desc');
|
||||
}
|
||||
|
||||
// Get the total count of records
|
||||
$totalRecords = $query->count();
|
||||
|
||||
// Apply pagination if provided
|
||||
if ($request->has('page') && $request->has('size')) {
|
||||
$page = $request->get('page');
|
||||
$size = $request->get('size');
|
||||
$offset = ($page - 1) * $size; // Calculate the offset
|
||||
|
||||
$query->skip($offset)->take($size);
|
||||
}
|
||||
|
||||
// Get the filtered count of records
|
||||
$filteredRecords = $query->count();
|
||||
|
||||
// Get the data for the current page with relationships
|
||||
$data = $query->get();
|
||||
|
||||
// Transform data untuk datatables
|
||||
$transformedData = $data->map(function ($item) {
|
||||
return [
|
||||
'id' => $item->id,
|
||||
'sandi_bank' => $item->sandi_bank,
|
||||
'tahun' => $item->tahun,
|
||||
'bulan' => $item->bulan,
|
||||
'no_rekening' => $item->no_rekening,
|
||||
'cif' => $item->cif,
|
||||
'nama_debitur' => $item->nama_debitur,
|
||||
'kolektibilitas' => $item->kolektibilitas,
|
||||
'kolektibilitas_badge' => $item->kolektibilitas_badge,
|
||||
'fasilitas' => $item->fasilitas,
|
||||
'jenis_agunan' => $item->jenis_agunan,
|
||||
'nama_pemilik_agunan' => $item->nama_pemilik_agunan,
|
||||
'nilai_agunan' => $item->nilai_agunan_formatted,
|
||||
'nilai_agunan_ljk' => $item->nilai_agunan_ljk_formatted,
|
||||
'alamat_agunan' => $item->alamat_agunan,
|
||||
'lokasi_agunan' => $item->lokasi_agunan,
|
||||
'nama_cabang' => $item->nama_cabang,
|
||||
'kode_cabang' => $item->kode_cabang,
|
||||
'created_by' => $item->creator?->name ?? '-',
|
||||
'created_at' => dateFormat($item->created_at, true)
|
||||
];
|
||||
});
|
||||
|
||||
// Calculate the page count
|
||||
$pageCount = ceil($totalRecords / ($request->get('size', 10)));
|
||||
|
||||
// Calculate the current page number
|
||||
$currentPage = $request->get('page', 1);
|
||||
|
||||
// Return the response data as a JSON object
|
||||
return response()->json([
|
||||
'draw' => $request->get('draw'),
|
||||
'recordsTotal' => $totalRecords,
|
||||
'recordsFiltered' => $filteredRecords,
|
||||
'pageCount' => $pageCount,
|
||||
'page' => $currentPage,
|
||||
'totalCount' => $totalRecords,
|
||||
'data' => $transformedData,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Import data slik dari Excel dengan optimasi memory dan progress tracking
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function import(Request $request)
|
||||
{
|
||||
Log::info('SlikController: Starting import process with optimizations', [
|
||||
'user_id' => Auth::id(),
|
||||
'request_size' => $request->header('Content-Length'),
|
||||
'has_file' => $request->hasFile('file'),
|
||||
'memory_limit' => ini_get('memory_limit'),
|
||||
'max_execution_time' => ini_get('max_execution_time')
|
||||
]);
|
||||
|
||||
// Validasi file upload dengan logging detail dan error handling komprehensif
|
||||
try {
|
||||
// Cek apakah ada file yang diupload
|
||||
if (!$request->hasFile('file')) {
|
||||
Log::error('SlikController: Tidak ada file yang diupload', [
|
||||
'user_id' => Auth::id(),
|
||||
'files_count' => count($request->allFiles()),
|
||||
'request_data' => $request->all()
|
||||
]);
|
||||
throw ValidationException::withMessages(['file' => 'Tidak ada file yang diupload.']);
|
||||
}
|
||||
|
||||
$file = $request->file('file');
|
||||
|
||||
// Cek apakah file valid
|
||||
if (!$file->isValid()) {
|
||||
$error = $file->getError();
|
||||
$errorMessage = match($error) {
|
||||
UPLOAD_ERR_INI_SIZE => 'File terlalu besar (melebihi upload_max_filesize).',
|
||||
UPLOAD_ERR_FORM_SIZE => 'File terlalu besar (melebihi MAX_FILE_SIZE).',
|
||||
UPLOAD_ERR_PARTIAL => 'File hanya terupload sebagian.',
|
||||
UPLOAD_ERR_NO_FILE => 'Tidak ada file yang diupload.',
|
||||
UPLOAD_ERR_NO_TMP_DIR => 'Direktori temp tidak tersedia.',
|
||||
UPLOAD_ERR_CANT_WRITE => 'Gagal menulis file ke disk.',
|
||||
UPLOAD_ERR_EXTENSION => 'Upload dibatalkan oleh ekstensi PHP.',
|
||||
default => 'Error upload tidak diketahui: ' . $error
|
||||
};
|
||||
|
||||
Log::error('SlikController: File upload tidak valid', [
|
||||
'error' => $error,
|
||||
'error_message' => $errorMessage,
|
||||
'user_id' => Auth::id(),
|
||||
'file_info' => [
|
||||
'name' => $file->getClientOriginalName(),
|
||||
'size' => $file->getSize(),
|
||||
'mime' => $file->getMimeType()
|
||||
]
|
||||
]);
|
||||
throw ValidationException::withMessages(['file' => $errorMessage]);
|
||||
}
|
||||
|
||||
$maxFileSize = config('import.slik.max_file_size', 50) * 1024; // dalam KB
|
||||
$request->validate([
|
||||
'file' => 'required|file|mimes:xlsx,xls|max:' . $maxFileSize
|
||||
]);
|
||||
Log::info('SlikController: Validasi file berhasil');
|
||||
} catch (\Illuminate\Validation\ValidationException $e) {
|
||||
Log::error('SlikController: Validasi file gagal', [
|
||||
'errors' => $e->errors(),
|
||||
'user_id' => Auth::id(),
|
||||
'request_size' => $request->header('Content-Length')
|
||||
]);
|
||||
throw $e;
|
||||
}
|
||||
|
||||
try {
|
||||
$uploadedFile = $request->file('file');
|
||||
$originalName = $uploadedFile->getClientOriginalName();
|
||||
$fileSize = $uploadedFile->getSize();
|
||||
|
||||
Log::info('SlikController: Memulai import data Slik', [
|
||||
'user_id' => Auth::id(),
|
||||
'filename' => $originalName,
|
||||
'filesize' => $fileSize,
|
||||
'filesize_mb' => round($fileSize / 1024 / 1024, 2),
|
||||
'mime_type' => $uploadedFile->getMimeType(),
|
||||
'extension' => $uploadedFile->getClientOriginalExtension()
|
||||
]);
|
||||
|
||||
// Generate unique import ID
|
||||
$importId = uniqid('slik_import_');
|
||||
$userId = Auth::id() ?? 1;
|
||||
|
||||
// Cek apakah menggunakan queue processing untuk file besar
|
||||
$useQueue = config('import.slik.queue.enabled', false) && $fileSize > (5 * 1024 * 1024); // > 5MB
|
||||
|
||||
// Pastikan direktori temp ada
|
||||
$tempDir = storage_path('app/temp');
|
||||
if (!file_exists($tempDir)) {
|
||||
mkdir($tempDir, 0755, true);
|
||||
Log::info('SlikController: Direktori temp dibuat', ['path' => $tempDir]);
|
||||
}
|
||||
|
||||
// Simpan file sementara dengan nama unik
|
||||
$tempFileName = 'slik_import_' . time() . '_' . uniqid() . '.' . $uploadedFile->getClientOriginalExtension();
|
||||
$tempFilePath = $tempDir . '/' . $tempFileName;
|
||||
|
||||
Log::info('SlikController: Memindahkan file ke temp', [
|
||||
'temp_path' => $tempFilePath,
|
||||
'use_queue' => $useQueue
|
||||
]);
|
||||
|
||||
// Pindahkan file ke direktori temp
|
||||
$uploadedFile->move($tempDir, $tempFilePath);
|
||||
|
||||
// Verifikasi file berhasil dipindahkan
|
||||
if (!file_exists($tempFilePath)) {
|
||||
throw new Exception('File gagal dipindahkan ke direktori temp');
|
||||
}
|
||||
|
||||
Log::info('SlikController: File berhasil dipindahkan', [
|
||||
'file_size' => filesize($tempFilePath)
|
||||
]);
|
||||
|
||||
if ($useQueue) {
|
||||
Log::info('SlikController: Menggunakan queue processing untuk file besar', [
|
||||
'import_id' => $importId,
|
||||
'file_size_mb' => round($fileSize / 1024 / 1024, 2)
|
||||
]);
|
||||
|
||||
// Dispatch job ke queue
|
||||
\Modules\Lpj\Jobs\ProcessSlikImport::dispatch($tempFilePath, $userId, $importId);
|
||||
|
||||
return redirect()->back()->with('success', 'Import sedang diproses di background. ID: ' . $importId);
|
||||
}
|
||||
|
||||
// Import langsung untuk file kecil
|
||||
Log::info('SlikController: Processing file directly', [
|
||||
'import_id' => $importId,
|
||||
'file_size_mb' => round($fileSize / 1024 / 1024, 2)
|
||||
]);
|
||||
|
||||
// Set optimasi memory untuk import langsung
|
||||
$memoryLimit = config('import.slik.memory_limit', 256);
|
||||
ini_set('memory_limit', $memoryLimit . 'M');
|
||||
ini_set('max_execution_time', config('import.slik.timeout', 30000));
|
||||
|
||||
// Enable garbage collection jika diizinkan
|
||||
if (config('import.slik.enable_gc', true)) {
|
||||
gc_enable();
|
||||
}
|
||||
|
||||
// Proses import menggunakan SlikImport class
|
||||
Log::info('SlikController: Memulai proses Excel import');
|
||||
$import = new SlikImport();
|
||||
Excel::import($import, $tempFilePath);
|
||||
Log::info('SlikController: Excel import selesai');
|
||||
|
||||
// Force garbage collection setelah selesai
|
||||
if (config('import.slik.enable_gc', true)) {
|
||||
gc_collect_cycles();
|
||||
}
|
||||
|
||||
// Hapus file temporary setelah import
|
||||
if (file_exists($tempFilePath)) {
|
||||
unlink($tempFilePath);
|
||||
Log::info('SlikController: File temp berhasil dihapus');
|
||||
}
|
||||
|
||||
Log::info('SlikController: Data Slik berhasil diimport', [
|
||||
'user_id' => Auth::id(),
|
||||
'import_id' => $importId
|
||||
]);
|
||||
|
||||
return redirect()->back()->with('success', 'Data Slik berhasil diimport dari file Excel.');
|
||||
|
||||
} catch (Exception $e) {
|
||||
// Hapus file temporary jika ada error
|
||||
if (isset($tempFilePath) && file_exists($tempFilePath)) {
|
||||
unlink($tempFilePath);
|
||||
Log::info('SlikController: File temp dihapus karena error');
|
||||
}
|
||||
|
||||
Log::error('SlikController: Gagal import data Slik', [
|
||||
'error' => $e->getMessage(),
|
||||
'trace' => $e->getTraceAsString(),
|
||||
'user_id' => Auth::id(),
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine(),
|
||||
'memory_usage' => memory_get_usage(true)
|
||||
]);
|
||||
|
||||
return redirect()->back()->with('error', 'Gagal import data Slik: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Menampilkan halaman form import
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function importForm()
|
||||
{
|
||||
return view('lpj::slik.import');
|
||||
}
|
||||
|
||||
/**
|
||||
* Download template Excel untuk import
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\BinaryFileResponse
|
||||
*/
|
||||
public function downloadTemplate()
|
||||
{
|
||||
$templatePath = resource_path('metronic/slik.xlsx');
|
||||
|
||||
if (!file_exists($templatePath)) {
|
||||
return redirect()->back()->with('error', 'Template file tidak ditemukan.');
|
||||
}
|
||||
|
||||
return response()->download($templatePath, 'template_slik.xlsx');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get import progress
|
||||
*
|
||||
* @param string $importId
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function progress(string $importId)
|
||||
{
|
||||
try {
|
||||
$progressService = new \Modules\Lpj\Services\ImportProgressService();
|
||||
$progress = $progressService->getProgress($importId);
|
||||
|
||||
if (!$progress) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Progress import tidak ditemukan'
|
||||
], 404);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'progress' => $progress
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::error('SlikController: Error getting progress', [
|
||||
'import_id' => $importId,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Gagal mendapatkan progress: ' . $e->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hapus semua data slik
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function truncate()
|
||||
{
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
Log::info('SlikController: Menghapus semua data Slik', [
|
||||
'user_id' => Auth::id()
|
||||
]);
|
||||
|
||||
Slik::truncate();
|
||||
|
||||
DB::commit();
|
||||
Log::info('SlikController: Semua data Slik berhasil dihapus', [
|
||||
'user_id' => Auth::id()
|
||||
]);
|
||||
|
||||
return redirect()->back()->with('success', 'Semua data Slik berhasil dihapus.');
|
||||
|
||||
} catch (Exception $e) {
|
||||
DB::rollback();
|
||||
Log::error('SlikController: Gagal menghapus data Slik', [
|
||||
'error' => $e->getMessage(),
|
||||
'user_id' => Auth::id()
|
||||
]);
|
||||
|
||||
return redirect()->back()->with('error', 'Gagal menghapus data Slik: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2718,7 +2718,7 @@ class SurveyorController extends Controller
|
||||
$fileName = 'inspeksi-' . $namaDebiture . '-data.pdf';
|
||||
$pdf->set_option('isHtml5ParserEnabled', true);
|
||||
$pdf->set_option('isPhpEnabled', true);
|
||||
return $pdf->stream($fileName);
|
||||
return $pdf->download($fileName);
|
||||
}
|
||||
|
||||
public function approveReschedule(Request $request, $id)
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
private function getBasicInfoRules()
|
||||
{
|
||||
return [
|
||||
'permohonan_id' => 'nullable|exists:permohonan,id',
|
||||
'permohonan_id' => 'required|exists:permohonan,id',
|
||||
'persetujuan_penawaran_id' => 'required|exists:persetujuan_penawaran,id',
|
||||
'status' => 'nullable|boolean',
|
||||
'created_by' => 'nullable|exists:users,id',
|
||||
@@ -72,16 +72,10 @@
|
||||
return [
|
||||
'total_harus_bayar' => 'nullable|numeric|min:0',
|
||||
'nominal_bayar' => 'nullable|numeric|min:0',
|
||||
'total_pembukuan' => 'nullable|numeric|min:0',
|
||||
'bukti_ksl' => $fileRule,
|
||||
'bukti_bayar' => $fileRule,
|
||||
'status_bayar' => 'nullable|boolean',
|
||||
'tanggal_pembayaran' => 'nullable|date',
|
||||
'status_kurang_bayar' => 'nullable|boolean',
|
||||
'status_lebih_bayar' => 'nullable|boolean',
|
||||
'nominal_kurang_bayar' => 'nullable|numeric|min:0',
|
||||
'nominal_lebih_bayar' => 'nullable|numeric|min:0',
|
||||
'bukti_pengembalian' => 'nullable|file|mimes:pdf,jpg,jpeg,png|max:2048',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -101,10 +95,6 @@
|
||||
'bukti_penyelesaian' => $fileRule,
|
||||
'memo_penyelesaian' => $fileRule,
|
||||
'catatan_noc' => 'nullable|string',
|
||||
'nomor_tiket' => 'nullable|string',
|
||||
'nomor_rekening_lebih_bayar' => 'nullable|string',
|
||||
'bukti_ksl_lebih_bayar' => 'nullable|string',
|
||||
'bukti_ksl_kurang_bayar' => 'nullable|string'
|
||||
];
|
||||
}
|
||||
|
||||
@@ -130,6 +120,7 @@
|
||||
public function messages()
|
||||
{
|
||||
return [
|
||||
'permohonan_id.required' => 'ID Permohonan harus diisi',
|
||||
'permohonan_id.exists' => 'ID Permohonan tidak valid',
|
||||
'persetujuan_penawaran_id.required' => 'ID Persetujuan Penawaran harus diisi',
|
||||
'persetujuan_penawaran_id.exists' => 'ID Persetujuan Penawaran tidak valid',
|
||||
@@ -157,11 +148,6 @@
|
||||
'authorized_status.boolean' => 'Status Otorisasi harus berupa boolean',
|
||||
'authorized_at.date' => 'Format Tanggal Otorisasi tidak valid',
|
||||
'authorized_by.exists' => 'User Otorisasi tidak valid',
|
||||
'status_kurang_bayar.boolean' => 'Status Kurang Bayar harus berupa boolean',
|
||||
'status_lebih_bayar.boolean' => 'Status Lebih Bayar harus berupa boolean',
|
||||
'nominal_kurang_bayar.numeric' => 'Nominal Kurang Bayar harus berupa angka',
|
||||
'nominal_kurang_bayar.min' => 'Nominal Kurang Bayar minimal 0',
|
||||
'nominal_lebih_bayar.numeric' => 'Nominal Lebih Bayar harus berupa angka',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,9 +17,6 @@
|
||||
'permohonan_id' => 'nullable|exists:permohonan,id',
|
||||
'penawaran_id' => 'nullable|exists:penawaran,id',
|
||||
'nomor_proposal_penawaran' => 'nullable|string|max:255',
|
||||
'nomor_tiket' => 'nullable|string|max:100',
|
||||
'nominal_kurang_bayar' => 'nullable|string|max:100',
|
||||
'bukti_ksl_kurang_bayar' => 'nullable|file|mimes:pdf,doc,docx|max:10240',
|
||||
'tanggal_proposal_penawaran' => 'nullable|date',
|
||||
'biaya_final' => 'nullable|numeric|min:0',
|
||||
'sla_resume' => 'nullable|numeric|min:0',
|
||||
@@ -40,8 +37,6 @@
|
||||
'penawaran_id.required' => 'Penawaran ID wajib diisi.',
|
||||
'penawaran_id.exists' => 'Penawaran ID tidak valid.',
|
||||
'nomor_proposal_penawaran.required' => 'Nomor proposal penawaran wajib diisi.',
|
||||
'nomor_tiket.string' => 'Nomor tiket harus berupa teks.',
|
||||
'nomor_tiket.max' => 'Nomor tiket tidak boleh lebih dari 100 karakter.',
|
||||
'tanggal_proposal_penawaran.required' => 'Tanggal proposal penawaran wajib diisi.',
|
||||
'tanggal_proposal_penawaran.date' => 'Tanggal proposal penawaran harus berupa tanggal yang valid.',
|
||||
'biaya_final.required' => 'Biaya final wajib diisi.',
|
||||
|
||||
@@ -1,341 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Imports;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Maatwebsite\Excel\Concerns\ToCollection;
|
||||
use Maatwebsite\Excel\Concerns\WithStartRow;
|
||||
use Maatwebsite\Excel\Concerns\WithValidation;
|
||||
use Maatwebsite\Excel\Concerns\WithBatchInserts;
|
||||
use Maatwebsite\Excel\Concerns\WithChunkReading;
|
||||
use Modules\Lpj\Models\Bucok;
|
||||
use Carbon\Carbon;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Kelas untuk mengimpor data Excel ke tabel bucoks
|
||||
* Menggunakan Laravel Excel dengan validasi dan batch processing
|
||||
* Data dimulai dari baris ke-5 tanpa header
|
||||
*/
|
||||
class BucokImport implements ToCollection, WithStartRow, WithValidation, WithBatchInserts, WithChunkReading
|
||||
{
|
||||
private $importedCount = 0;
|
||||
private $skippedCount = 0;
|
||||
private $createdCount = 0;
|
||||
private $updatedCount = 0;
|
||||
private $errors = [];
|
||||
|
||||
/**
|
||||
* Menentukan baris mulai membaca data (baris ke-5)
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function startRow(): int
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
/**
|
||||
* Memproses koleksi data dari Excel
|
||||
*
|
||||
* @param Collection $collection
|
||||
* @return void
|
||||
*/
|
||||
public function collection(Collection $collection)
|
||||
{
|
||||
DB::beginTransaction();
|
||||
|
||||
try {
|
||||
foreach ($collection as $rowIndex => $row) {
|
||||
// Log setiap baris yang diproses
|
||||
Log::info('Processing Bucok import row', [
|
||||
'row_number' => $rowIndex + 5, // +5 karena mulai dari baris 5
|
||||
'row_data' => $row->toArray()
|
||||
]);
|
||||
|
||||
// Konversi row ke array dengan indeks numerik
|
||||
$rowArray = $row->toArray();
|
||||
|
||||
// Skip baris kosong
|
||||
if (empty(array_filter($rowArray))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Validasi data baris
|
||||
$mappedData = $this->mapRowToBucok($rowArray, $rowIndex + 5);
|
||||
|
||||
// Update atau create berdasarkan nomor_tiket
|
||||
if (!empty($mappedData['nomor_tiket'])) {
|
||||
// Update atau create berdasarkan nomor_tiket
|
||||
$bucok = Bucok::updateOrCreate(
|
||||
['nomor_tiket' => $mappedData['nomor_tiket']], // Kondisi pencarian
|
||||
array_merge($mappedData, ['updated_by' => auth()->id()]) // Data yang akan diupdate/create
|
||||
);
|
||||
|
||||
// Log dan tracking apakah data di-update atau di-create
|
||||
if ($bucok->wasRecentlyCreated) {
|
||||
$this->createdCount++;
|
||||
Log::info('Bucok created successfully', [
|
||||
'row_number' => $rowIndex + 5,
|
||||
'nomor_tiket' => $mappedData['nomor_tiket'],
|
||||
'action' => 'created'
|
||||
]);
|
||||
} else {
|
||||
$this->updatedCount++;
|
||||
Log::info('Bucok updated successfully', [
|
||||
'row_number' => $rowIndex + 5,
|
||||
'nomor_tiket' => $mappedData['nomor_tiket'],
|
||||
'action' => 'updated'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->importedCount++;
|
||||
}
|
||||
|
||||
DB::commit();
|
||||
|
||||
// Log summary
|
||||
Log::info('Bucok import completed', [
|
||||
'imported' => $this->importedCount,
|
||||
'skipped' => $this->skippedCount,
|
||||
'total_errors' => count($this->errors)
|
||||
]);
|
||||
|
||||
} catch (Exception $e) {
|
||||
DB::rollback();
|
||||
Log::error('Bucok import failed', ['error' => $e->getMessage()]);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mapping data Excel berdasarkan indeks kolom ke struktur model Bucok
|
||||
* Kolom dimulai dari indeks 0 (A=0, B=1, C=2, dst.)
|
||||
*
|
||||
* @param array $row
|
||||
* @param int $rowNumber
|
||||
* @return array
|
||||
*/
|
||||
private function mapRowToBucok(array $row, int $rowNumber): array
|
||||
{
|
||||
return [
|
||||
'no' => $row[0] ?? null, // Kolom A
|
||||
'tanggal' => !empty($row[1]) ? $this->parseDate($row[1]) : null, // Kolom B
|
||||
'bulan' => $row[2] ?? null, // Kolom C
|
||||
'tahun' => $row[3] ?? null, // Kolom D
|
||||
'tanggal_penuh' => !empty($row[4]) ? $this->parseDate($row[4]) : null, // Kolom E
|
||||
'nomor_categ' => $row[5] ?? null, // Kolom F
|
||||
'coa_summary' => $row[6] ?? null, // Kolom G
|
||||
'nomor_coa' => $row[7] ?? null, // Kolom H
|
||||
'nama_coa' => $row[8] ?? null, // Kolom I
|
||||
'nomor_tiket' => $row[9] ?? null, // Kolom J - Auto-generate jika kosong
|
||||
'deskripsi' => $row[10] ?? null, // Kolom K
|
||||
'nominal' => $this->parseNumeric($row[11] ?? 0), // Kolom L
|
||||
'penyelesaian' => $row[12] ?? 'Belum Selesai', // Kolom M
|
||||
'umur_aging' => $this->parseNumeric($row[13] ?? 0), // Kolom N
|
||||
'cost_center' => $row[14] ?? null, // Kolom O
|
||||
'nama_sub_direktorat' => $row[15] ?? null, // Kolom P
|
||||
'nama_direktorat_cabang' => $row[16] ?? null, // Kolom Q
|
||||
'tanggal_penyelesaian' => !empty($row[17]) ? $this->parseDate($row[17]) : null, // Kolom R
|
||||
'nominal_penyelesaian' => $this->parseNumeric($row[18] ?? 0), // Kolom S
|
||||
'nominal_berjalan' => $this->parseNumeric($row[19] ?? 0), // Kolom T
|
||||
'amortisasi_berjalan' => $this->parseNumeric($row[20] ?? 0), // Kolom U
|
||||
'sistem_berjalan' => $this->parseNumeric($row[21] ?? 0), // Kolom V
|
||||
'lainnya_berjalan' => $this->parseNumeric($row[22] ?? 0), // Kolom W
|
||||
'nominal_gantung' => $this->parseNumeric($row[23] ?? 0), // Kolom X
|
||||
'aset_gantung' => $this->parseNumeric($row[24] ?? 0), // Kolom Y
|
||||
'keterangan_gantung' => $row[25] ?? null, // Kolom Z
|
||||
'lainnya_satu' => $row[26] ?? null, // Kolom AA
|
||||
'lainnya_dua' => $row[27] ?? null, // Kolom AB
|
||||
'created_by' => auth()->id(),
|
||||
'updated_by' => auth()->id()
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse tanggal dari berbagai format
|
||||
*
|
||||
* @param mixed $dateValue
|
||||
* @return Carbon|null
|
||||
*/
|
||||
private function parseDate($dateValue)
|
||||
{
|
||||
if (empty($dateValue)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
// Jika berupa angka Excel date serial
|
||||
if (is_numeric($dateValue)) {
|
||||
return Carbon::createFromFormat('Y-m-d', \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($dateValue)->format('Y-m-d'));
|
||||
}
|
||||
|
||||
// Jika berupa string tanggal
|
||||
return Carbon::parse($dateValue);
|
||||
} catch (Exception $e) {
|
||||
Log::warning('Failed to parse date', ['value' => $dateValue, 'error' => $e->getMessage()]);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse nilai numerik dari berbagai format
|
||||
*
|
||||
* @param mixed $numericValue
|
||||
* @return float
|
||||
*/
|
||||
private function parseNumeric($numericValue): float
|
||||
{
|
||||
if (empty($numericValue)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Hapus karakter non-numerik kecuali titik dan koma
|
||||
$cleaned = preg_replace('/[^0-9.,\-]/', '', $numericValue);
|
||||
|
||||
// Ganti koma dengan titik untuk decimal
|
||||
$cleaned = str_replace(',', '.', $cleaned);
|
||||
|
||||
return (float) $cleaned;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validasi data yang sudah dimapping
|
||||
*
|
||||
* @param array $data
|
||||
* @return \Illuminate\Validation\Validator
|
||||
*/
|
||||
private function validateMappedData(array $data)
|
||||
{
|
||||
return Validator::make($data, [
|
||||
'no' => 'nullable|integer',
|
||||
'tanggal' => 'nullable|date',
|
||||
'bulan' => 'nullable|integer|between:1,12',
|
||||
'tahun' => 'nullable|integer|min:2000|max:2099',
|
||||
'tanggal_penuh' => 'nullable|date',
|
||||
'nomor_categ' => 'nullable|string|max:50',
|
||||
'coa_summary' => 'nullable|string|max:255',
|
||||
'nomor_coa' => 'nullable|string|max:50',
|
||||
'nama_coa' => 'nullable|string|max:255',
|
||||
'nomor_tiket' => 'nullable|string|max:50',
|
||||
'deskripsi' => 'nullable|string',
|
||||
'nominal' => 'nullable|numeric|min:0',
|
||||
'penyelesaian' => 'nullable|in:Selesai,Belum Selesai,Dalam Proses',
|
||||
'umur_aging' => 'nullable|integer|min:0',
|
||||
'cost_center' => 'nullable|string|max:100',
|
||||
'nama_sub_direktorat' => 'nullable|string|max:255',
|
||||
'nama_direktorat_cabang' => 'nullable|string|max:255',
|
||||
'tanggal_penyelesaian' => 'nullable|date',
|
||||
'nominal_penyelesaian' => 'nullable|numeric|min:0',
|
||||
'nominal_berjalan' => 'nullable|numeric|min:0',
|
||||
'amortisasi_berjalan' => 'nullable|numeric|min:0',
|
||||
'sistem_berjalan' => 'nullable|numeric|min:0',
|
||||
'lainnya_berjalan' => 'nullable|numeric|min:0',
|
||||
'nominal_gantung' => 'nullable|numeric|min:0',
|
||||
'aset_gantung' => 'nullable|numeric|min:0',
|
||||
'keterangan_gantung' => 'nullable|string',
|
||||
'lainnya_satu' => 'nullable|string',
|
||||
'lainnya_dua' => 'nullable|string'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Aturan validasi untuk seluruh file Excel (tidak digunakan karena tanpa header)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Ukuran batch untuk insert
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function batchSize(): int
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ukuran chunk untuk membaca file
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function chunkSize(): int
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mendapatkan jumlah data yang berhasil diimpor
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getImportedCount(): int
|
||||
{
|
||||
return $this->importedCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mendapatkan jumlah data yang berhasil dibuat
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getCreatedCount(): int
|
||||
{
|
||||
return $this->createdCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mendapatkan jumlah data yang berhasil diupdate
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getUpdatedCount(): int
|
||||
{
|
||||
return $this->updatedCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mendapatkan statistik lengkap import
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getImportStatistics(): array
|
||||
{
|
||||
return [
|
||||
'total_processed' => $this->importedCount,
|
||||
'created' => $this->createdCount,
|
||||
'updated' => $this->updatedCount,
|
||||
'skipped' => $this->skippedCount,
|
||||
'errors' => count($this->errors)
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Mendapatkan jumlah data yang dilewati
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getSkippedCount(): int
|
||||
{
|
||||
return $this->skippedCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mendapatkan daftar error yang terjadi
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getErrors(): array
|
||||
{
|
||||
return $this->errors;
|
||||
}
|
||||
}
|
||||
@@ -1,415 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Imports;
|
||||
|
||||
use Modules\Lpj\Models\Slik;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Maatwebsite\Excel\Concerns\ToCollection;
|
||||
use Maatwebsite\Excel\Concerns\WithStartRow;
|
||||
use Maatwebsite\Excel\Concerns\WithChunkReading;
|
||||
use Maatwebsite\Excel\Concerns\WithBatchInserts;
|
||||
use Maatwebsite\Excel\Concerns\WithCustomCsvSettings;
|
||||
|
||||
|
||||
/**
|
||||
* Class SlikImport
|
||||
*
|
||||
* Handle import data Excel untuk modul Slik
|
||||
* Menggunakan Laravel Excel package untuk membaca file Excel
|
||||
* dengan optimasi memory dan chunk processing
|
||||
*
|
||||
* @package Modules\Lpj\app\Imports
|
||||
*/
|
||||
class SlikImport implements ToCollection, WithStartRow, WithBatchInserts, WithChunkReading, WithCustomCsvSettings
|
||||
{
|
||||
/**
|
||||
* Mulai membaca dari baris ke-5 (skip header)
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function startRow(): int
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch size untuk insert data dari konfigurasi
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function batchSize(): int
|
||||
{
|
||||
return config('import.slik.batch_size', 50);
|
||||
}
|
||||
|
||||
/**
|
||||
* Chunk size untuk membaca file dari konfigurasi
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function chunkSize(): int
|
||||
{
|
||||
return config('import.slik.chunk_size', 50);
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom CSV settings untuk optimasi pembacaan file
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCsvSettings(): array
|
||||
{
|
||||
return [
|
||||
'input_encoding' => 'UTF-8',
|
||||
'delimiter' => ',',
|
||||
'enclosure' => '"',
|
||||
'escape_character' => '\\',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Process collection data dari Excel dengan optimasi memory
|
||||
*
|
||||
* @param Collection $collection
|
||||
* @return void
|
||||
*/
|
||||
public function collection(Collection $collection)
|
||||
{
|
||||
// Set memory limit dari konfigurasi
|
||||
$memoryLimit = config('import.slik.memory_limit', 1024);
|
||||
$currentMemoryLimit = ini_get('memory_limit');
|
||||
|
||||
if ($currentMemoryLimit !== '-1' && $this->convertToBytes($currentMemoryLimit) < $memoryLimit * 1024 * 1024) {
|
||||
ini_set('memory_limit', $memoryLimit . 'M');
|
||||
}
|
||||
|
||||
// Set timeout handler
|
||||
$timeout = config('import.slik.timeout', 1800);
|
||||
set_time_limit($timeout);
|
||||
|
||||
// Force garbage collection sebelum memulai
|
||||
if (config('import.slik.enable_gc', true)) {
|
||||
gc_collect_cycles();
|
||||
}
|
||||
|
||||
Log::info('SlikImport: Memulai import data', [
|
||||
'total_rows' => $collection->count(),
|
||||
'memory_usage' => memory_get_usage(true),
|
||||
'memory_peak' => memory_get_peak_usage(true),
|
||||
'memory_limit' => ini_get('memory_limit'),
|
||||
'php_version' => PHP_VERSION,
|
||||
'memory_limit_before' => $currentMemoryLimit,
|
||||
'config' => [
|
||||
'memory_limit' => $memoryLimit,
|
||||
'chunk_size' => $this->chunkSize(),
|
||||
'batch_size' => $this->batchSize()
|
||||
]
|
||||
]);
|
||||
|
||||
DB::beginTransaction();
|
||||
|
||||
try {
|
||||
$processedRows = 0;
|
||||
$skippedRows = 0;
|
||||
$errorRows = 0;
|
||||
$totalRows = $collection->count();
|
||||
|
||||
foreach ($collection as $index => $row) {
|
||||
// Log progress setiap 25 baris untuk chunk lebih kecil
|
||||
if ($index % 25 === 0) {
|
||||
Log::info('SlikImport: Processing chunk', [
|
||||
'current_row' => $index + 5,
|
||||
'progress' => round(($index / max($totalRows, 1)) * 100, 2) . '%',
|
||||
'processed' => $processedRows,
|
||||
'skipped' => $skippedRows,
|
||||
'errors' => $errorRows,
|
||||
'memory_usage' => memory_get_usage(true),
|
||||
'memory_peak' => memory_get_peak_usage(true),
|
||||
'memory_diff' => memory_get_peak_usage(true) - memory_get_usage(true)
|
||||
]);
|
||||
}
|
||||
|
||||
// Skip baris kosong
|
||||
if ($this->isEmptyRow($row)) {
|
||||
$skippedRows++;
|
||||
Log::debug('SlikImport: Skipping empty row', ['row_number' => $index + 5]);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Validasi data
|
||||
if (!$this->validateRow($row)) {
|
||||
$errorRows++;
|
||||
Log::warning('SlikImport: Invalid row data', [
|
||||
'row_number' => $index + 5,
|
||||
'data' => $row->toArray()
|
||||
]);
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
// Map data dari Excel ke model
|
||||
$slikData = $this->mapRowToSlik($row);
|
||||
|
||||
// Update atau create berdasarkan no_rekening dan cif
|
||||
$slik = Slik::updateOrCreate(
|
||||
[
|
||||
'no_rekening' => $slikData['no_rekening'],
|
||||
'cif' => $slikData['cif']
|
||||
],
|
||||
$slikData
|
||||
);
|
||||
|
||||
$processedRows++;
|
||||
|
||||
// Log detail untuk baris pertama sebagai sample
|
||||
if ($index === 0) {
|
||||
Log::info('SlikImport: Sample data processed', [
|
||||
'slik_id' => $slik->id,
|
||||
'no_rekening' => $slik->no_rekening,
|
||||
'cif' => $slik->cif,
|
||||
'was_recently_created' => $slik->wasRecentlyCreated
|
||||
]);
|
||||
}
|
||||
|
||||
// Force garbage collection setiap 25 baris untuk mengurangi memory
|
||||
if (config('import.slik.enable_gc', true) && $index > 0 && $index % 25 === 0) {
|
||||
gc_collect_cycles();
|
||||
}
|
||||
|
||||
// Unset data yang sudah tidak digunakan untuk mengurangi memory
|
||||
if ($index > 0 && $index % 25 === 0) {
|
||||
unset($slikData, $slik);
|
||||
}
|
||||
|
||||
// Reset collection internal untuk mengurangi memory
|
||||
if ($index > 0 && $index % 100 === 0) {
|
||||
$collection = collect($collection->slice($index + 1)->values());
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
$errorRows++;
|
||||
Log::error('SlikImport: Error processing row', [
|
||||
'row_number' => $index + 5,
|
||||
'error' => $e->getMessage(),
|
||||
'data' => $row->toArray(),
|
||||
'memory_usage' => memory_get_usage(true)
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
DB::commit();
|
||||
|
||||
// Force garbage collection setelah selesai
|
||||
if (config('import.slik.enable_gc', true)) {
|
||||
gc_collect_cycles();
|
||||
}
|
||||
|
||||
// Cleanup variables
|
||||
unset($collection);
|
||||
|
||||
Log::info('SlikImport: Import berhasil diselesaikan', [
|
||||
'total_rows' => $totalRows,
|
||||
'processed_rows' => $processedRows,
|
||||
'skipped_rows' => $skippedRows,
|
||||
'error_rows' => $errorRows,
|
||||
'final_memory_usage' => memory_get_usage(true),
|
||||
'peak_memory_usage' => memory_get_peak_usage(true),
|
||||
'memory_saved' => memory_get_peak_usage(true) - memory_get_usage(true),
|
||||
'memory_efficiency' => ($processedRows > 0) ? round(memory_get_peak_usage(true) / $processedRows, 2) : 0
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
|
||||
// Force garbage collection jika error
|
||||
if (config('import.slik.enable_gc', true)) {
|
||||
gc_collect_cycles();
|
||||
}
|
||||
|
||||
$errorType = 'general';
|
||||
if (str_contains(strtolower($e->getMessage()), 'memory')) {
|
||||
$errorType = 'memory';
|
||||
} elseif (str_contains(strtolower($e->getMessage()), 'timeout') || str_contains(strtolower($e->getMessage()), 'maximum execution time')) {
|
||||
$errorType = 'timeout';
|
||||
}
|
||||
|
||||
Log::error('SlikImport: Error during import', [
|
||||
'error' => $e->getMessage(),
|
||||
'error_type' => $errorType,
|
||||
'exception_type' => get_class($e),
|
||||
'trace' => $e->getTraceAsString(),
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine(),
|
||||
'memory_usage' => memory_get_usage(true),
|
||||
'memory_peak' => memory_get_peak_usage(true),
|
||||
'memory_limit' => ini_get('memory_limit'),
|
||||
'timeout_limit' => ini_get('max_execution_time'),
|
||||
'is_memory_error' => str_contains(strtolower($e->getMessage()), 'memory'),
|
||||
'is_timeout_error' => str_contains(strtolower($e->getMessage()), 'timeout') || str_contains(strtolower($e->getMessage()), 'maximum execution time')
|
||||
]);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert memory limit string ke bytes
|
||||
*
|
||||
* @param string $memoryLimit
|
||||
* @return int
|
||||
*/
|
||||
private function convertToBytes(string $memoryLimit): int
|
||||
{
|
||||
$memoryLimit = trim($memoryLimit);
|
||||
$lastChar = strtolower(substr($memoryLimit, -1));
|
||||
$number = (int) substr($memoryLimit, 0, -1);
|
||||
|
||||
switch ($lastChar) {
|
||||
case 'g':
|
||||
return $number * 1024 * 1024 * 1024;
|
||||
case 'm':
|
||||
return $number * 1024 * 1024;
|
||||
case 'k':
|
||||
return $number * 1024;
|
||||
default:
|
||||
return (int) $memoryLimit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cek apakah baris kosong
|
||||
*
|
||||
* @param Collection $row
|
||||
* @return bool
|
||||
*/
|
||||
private function isEmptyRow(Collection $row): bool
|
||||
{
|
||||
return $row->filter(function ($value) {
|
||||
return !empty(trim($value));
|
||||
})->isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Validasi data baris
|
||||
*
|
||||
* @param Collection $row
|
||||
* @return bool
|
||||
*/
|
||||
private function validateRow(Collection $row): bool
|
||||
{
|
||||
// Validasi minimal: sandi_bank, no_rekening, dan cif harus ada
|
||||
return !empty(trim($row[0])) && // sandi_bank
|
||||
!empty(trim($row[5])) && // no_rekening
|
||||
!empty(trim($row[6])); // cif
|
||||
}
|
||||
|
||||
/**
|
||||
* Map data dari baris Excel ke array untuk model Slik
|
||||
*
|
||||
* @param Collection $row
|
||||
* @return array
|
||||
*/
|
||||
private function mapRowToSlik(Collection $row): array
|
||||
{
|
||||
return [
|
||||
'sandi_bank' => trim($row[0]) ?: null,
|
||||
'tahun' => $this->parseInteger($row[1]),
|
||||
'bulan' => $this->parseInteger($row[2]),
|
||||
'flag_detail' => trim($row[3]) ?: null,
|
||||
'kode_register_agunan' => trim($row[4]) ?: null,
|
||||
'no_rekening' => trim($row[5]) ?: null,
|
||||
'cif' => trim($row[6]) ?: null,
|
||||
'kolektibilitas' => trim($row[7]) ?: null,
|
||||
'fasilitas' => trim($row[8]) ?: null,
|
||||
'jenis_segmen_fasilitas' => trim($row[9]) ?: null,
|
||||
'status_agunan' => trim($row[10]) ?: null,
|
||||
'jenis_agunan' => trim($row[11]) ?: null,
|
||||
'peringkat_agunan' => trim($row[12]) ?: null,
|
||||
'lembaga_pemeringkat' => trim($row[13]) ?: null,
|
||||
'jenis_pengikatan' => trim($row[14]) ?: null,
|
||||
'tanggal_pengikatan' => $this->parseDate($row[15]),
|
||||
'nama_pemilik_agunan' => trim($row[16]) ?: null,
|
||||
'bukti_kepemilikan' => trim($row[17]) ?: null,
|
||||
'alamat_agunan' => trim($row[18]) ?: null,
|
||||
'lokasi_agunan' => trim($row[19]) ?: null,
|
||||
'nilai_agunan' => $this->parseDecimal($row[20]),
|
||||
'nilai_agunan_menurut_ljk' => $this->parseDecimal($row[21]),
|
||||
'tanggal_penilaian_ljk' => $this->parseDate($row[22]),
|
||||
'nilai_agunan_penilai_independen' => $this->parseDecimal($row[23]),
|
||||
'nama_penilai_independen' => trim($row[24]) ?: null,
|
||||
'tanggal_penilaian_penilai_independen' => $this->parseDate($row[25]),
|
||||
'jumlah_hari_tunggakan' => $this->parseInteger($row[26]),
|
||||
'status_paripasu' => trim($row[27]) ?: null,
|
||||
'prosentase_paripasu' => $this->parseDecimal($row[28]),
|
||||
'status_kredit_join' => trim($row[29]) ?: null,
|
||||
'diasuransikan' => trim($row[30]) ?: null,
|
||||
'keterangan' => trim($row[31]) ?: null,
|
||||
'kantor_cabang' => trim($row[32]) ?: null,
|
||||
'operasi_data' => trim($row[33]) ?: null,
|
||||
'kode_cabang' => trim($row[34]) ?: null,
|
||||
'nama_debitur' => trim($row[35]) ?: null,
|
||||
'nama_cabang' => trim($row[36]) ?: null,
|
||||
'flag' => trim($row[37]) ?: null,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse integer value
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return int|null
|
||||
*/
|
||||
private function parseInteger($value): ?int
|
||||
{
|
||||
if (empty(trim($value))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (int) $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse decimal value
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return float|null
|
||||
*/
|
||||
private function parseDecimal($value): ?float
|
||||
{
|
||||
if (empty(trim($value))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Remove currency formatting
|
||||
$cleaned = str_replace([',', '.'], ['', '.'], $value);
|
||||
$cleaned = preg_replace('/[^0-9.]/', '', $cleaned);
|
||||
|
||||
return (float) $cleaned;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse date value
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return string|null
|
||||
*/
|
||||
private function parseDate($value): ?string
|
||||
{
|
||||
if (empty(trim($value))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
// Try to parse various date formats
|
||||
$date = \Carbon\Carbon::parse($value);
|
||||
return $date->format('Y-m-d');
|
||||
} catch (\Exception $e) {
|
||||
Log::warning('SlikImport: Invalid date format', [
|
||||
'value' => $value,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,179 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Jobs;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Modules\Lpj\Imports\SlikImport;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
|
||||
class ProcessSlikImport implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
public $timeout = 1800; // 30 menit untuk file besar
|
||||
public $tries = 5; // Tambah retry untuk file sangat besar
|
||||
public $maxExceptions = 5;
|
||||
public $backoff = [60, 300, 900, 1800, 3600]; // Exponential backoff dalam detik
|
||||
|
||||
protected string $filePath;
|
||||
protected int $userId;
|
||||
protected string $importId;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @param string $filePath
|
||||
* @param int $userId
|
||||
* @param string $importId
|
||||
*/
|
||||
public function __construct(string $filePath, int $userId, string $importId)
|
||||
{
|
||||
$this->filePath = $filePath;
|
||||
$this->userId = $userId;
|
||||
$this->importId = $importId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
Log::info('ProcessSlikImport: Memulai proses import via queue', [
|
||||
'file_path' => $this->filePath,
|
||||
'user_id' => $this->userId,
|
||||
'import_id' => $this->importId,
|
||||
'memory_limit' => ini_get('memory_limit'),
|
||||
'max_execution_time' => ini_get('max_execution_time')
|
||||
]);
|
||||
|
||||
try {
|
||||
// Cek file size terlebih dahulu
|
||||
$fileSize = filesize($this->filePath);
|
||||
$maxFileSize = config('import.slik.max_file_size', 50) * 1024 * 1024; // Convert MB to bytes
|
||||
|
||||
if ($fileSize > $maxFileSize) {
|
||||
throw new \Exception('File terlalu besar: ' . number_format($fileSize / 1024 / 1024, 2) . ' MB. Maksimum: ' . config('import.slik.max_file_size', 50) . ' MB');
|
||||
}
|
||||
|
||||
// Set optimasi memory untuk queue processing
|
||||
$memoryLimit = config('import.slik.memory_limit', 1024);
|
||||
ini_set('memory_limit', $memoryLimit . 'M');
|
||||
ini_set('max_execution_time', config('import.slik.timeout', 1800));
|
||||
|
||||
// Set timeout untuk XML Scanner
|
||||
$xmlScannerTimeout = config('import.slik.xml_scanner.timeout', 1800);
|
||||
$xmlScannerMemory = config('import.slik.xml_scanner.memory_limit', 1024);
|
||||
|
||||
// Enable garbage collection jika diizinkan
|
||||
if (config('import.slik.enable_gc', true)) {
|
||||
gc_enable();
|
||||
}
|
||||
|
||||
// Update progress status
|
||||
$this->updateProgress('processing', 0, 'Memproses file Excel...');
|
||||
|
||||
Log::info('SlikImport: Processing file', [
|
||||
'file' => basename($this->filePath),
|
||||
'file_size' => number_format(filesize($this->filePath) / 1024 / 1024, 2) . ' MB',
|
||||
'memory_limit' => $memoryLimit . 'M',
|
||||
'timeout' => config('import.slik.timeout', 1800),
|
||||
'enable_gc' => config('import.slik.enable_gc', true),
|
||||
'xml_scanner_timeout' => config('import.slik.xml_scanner.timeout', 1800),
|
||||
'chunk_size' => config('import.slik.chunk_size', 50),
|
||||
'batch_size' => config('import.slik.batch_size', 50),
|
||||
]);
|
||||
|
||||
// Import file menggunakan SlikImport
|
||||
$import = new SlikImport();
|
||||
Excel::import($import, $this->filePath);
|
||||
|
||||
// Update progress selesai
|
||||
$this->updateProgress('completed', 100, 'Import berhasil diselesaikan');
|
||||
|
||||
Log::info('ProcessSlikImport: Import berhasil diselesaikan', [
|
||||
'import_id' => $this->importId,
|
||||
'file_path' => $this->filePath,
|
||||
'memory_usage' => memory_get_usage(true),
|
||||
'memory_peak' => memory_get_peak_usage(true)
|
||||
]);
|
||||
|
||||
// Hapus file temporary setelah selesai
|
||||
if (config('import.general.cleanup_temp_files', true)) {
|
||||
Storage::delete($this->filePath);
|
||||
Log::info('ProcessSlikImport: File temporary dihapus', ['file_path' => $this->filePath]);
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
// Update progress error
|
||||
$this->updateProgress('failed', 0, 'Error: ' . $e->getMessage());
|
||||
|
||||
Log::error('ProcessSlikImport: Error saat proses import', [
|
||||
'import_id' => $this->importId,
|
||||
'error' => $e->getMessage(),
|
||||
'trace' => $e->getTraceAsString(),
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine(),
|
||||
'memory_usage' => memory_get_usage(true)
|
||||
]);
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update progress import
|
||||
*
|
||||
* @param string $status
|
||||
* @param int $percentage
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
private function updateProgress(string $status, int $percentage, string $message): void
|
||||
{
|
||||
if (config('import.slik.progress.enabled', true)) {
|
||||
$cacheKey = config('import.slik.progress.cache_key', 'slik_import_progress') . '_' . $this->importId;
|
||||
$cacheTtl = config('import.slik.progress.cache_ttl', 3600);
|
||||
|
||||
$progressData = [
|
||||
'status' => $status,
|
||||
'percentage' => $percentage,
|
||||
'message' => $message,
|
||||
'timestamp' => now(),
|
||||
'user_id' => $this->userId
|
||||
];
|
||||
|
||||
cache()->put($cacheKey, $progressData, $cacheTtl);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle job failure
|
||||
*
|
||||
* @param \Throwable $exception
|
||||
* @return void
|
||||
*/
|
||||
public function failed(\Throwable $exception): void
|
||||
{
|
||||
Log::error('ProcessSlikImport: Job failed', [
|
||||
'import_id' => $this->importId,
|
||||
'error' => $exception->getMessage(),
|
||||
'trace' => $exception->getTraceAsString()
|
||||
]);
|
||||
|
||||
// Update progress ke failed
|
||||
$this->updateProgress('failed', 0, 'Import gagal: ' . $exception->getMessage());
|
||||
|
||||
// Cleanup file temporary
|
||||
if (Storage::exists($this->filePath)) {
|
||||
Storage::delete($this->filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Spatie\Activitylog\LogOptions;
|
||||
use Spatie\Activitylog\Traits\LogsActivity;
|
||||
use Mattiverse\Userstamps\Traits\Userstamps;
|
||||
use Wildside\Userstamps\Userstamps;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
|
||||
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Models;
|
||||
|
||||
use Illuminate\Foundation\Auth\User;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* Model Bucok untuk mengelola data bucok
|
||||
*
|
||||
* @property int $id
|
||||
* @property int|null $no
|
||||
* @property string|null $tanggal
|
||||
* @property string|null $bulan
|
||||
* @property int|null $tahun
|
||||
* @property string|null $tanggal_penuh
|
||||
* @property string|null $nomor_categ
|
||||
* @property string|null $coa_summary
|
||||
* @property string|null $nomor_coa
|
||||
* @property string|null $nama_coa
|
||||
* @property string $nomor_tiket
|
||||
* @property string|null $deskripsi
|
||||
* @property float|null $nominal
|
||||
* @property string|null $penyelesaian
|
||||
* @property int|null $umur_aging
|
||||
* @property string|null $cost_center
|
||||
* @property string|null $nama_sub_direktorat
|
||||
* @property string|null $nama_direktorat_cabang
|
||||
* @property string|null $tanggal_penyelesaian
|
||||
* @property float|null $nominal_penyelesaian
|
||||
* @property float|null $nominal_berjalan
|
||||
* @property float|null $amortisasi_berjalan
|
||||
* @property float|null $sistem_berjalan
|
||||
* @property float|null $lainnya_berjalan
|
||||
* @property float|null $nominal_gantung
|
||||
* @property float|null $aset_gantung
|
||||
* @property string|null $keterangan_gantung
|
||||
* @property string|null $lainnya_satu
|
||||
* @property string|null $lainnya_dua
|
||||
*/
|
||||
class Bucok extends Base
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
/**
|
||||
* Nama tabel yang digunakan oleh model
|
||||
*/
|
||||
protected $table = 'bucoks';
|
||||
|
||||
/**
|
||||
* Field yang dapat diisi secara mass assignment
|
||||
*/
|
||||
protected $fillable = [
|
||||
'no',
|
||||
'tanggal',
|
||||
'bulan',
|
||||
'tahun',
|
||||
'tanggal_penuh',
|
||||
'nomor_categ',
|
||||
'coa_summary',
|
||||
'nomor_coa',
|
||||
'nama_coa',
|
||||
'nomor_tiket',
|
||||
'deskripsi',
|
||||
'nominal',
|
||||
'penyelesaian',
|
||||
'umur_aging',
|
||||
'cost_center',
|
||||
'nama_sub_direktorat',
|
||||
'nama_direktorat_cabang',
|
||||
'tanggal_penyelesaian',
|
||||
'nominal_penyelesaian',
|
||||
'nominal_berjalan',
|
||||
'amortisasi_berjalan',
|
||||
'sistem_berjalan',
|
||||
'lainnya_berjalan',
|
||||
'nominal_gantung',
|
||||
'aset_gantung',
|
||||
'keterangan_gantung',
|
||||
'lainnya_satu',
|
||||
'lainnya_dua',
|
||||
];
|
||||
|
||||
/**
|
||||
* Casting tipe data untuk field tertentu
|
||||
*/
|
||||
protected $casts = [
|
||||
'no' => 'integer',
|
||||
'tanggal' => 'date',
|
||||
'tahun' => 'integer',
|
||||
'tanggal_penuh' => 'date',
|
||||
'nominal' => 'decimal:2',
|
||||
'umur_aging' => 'integer',
|
||||
'tanggal_penyelesaian' => 'date',
|
||||
'nominal_penyelesaian' => 'decimal:2',
|
||||
'nominal_berjalan' => 'decimal:2',
|
||||
'amortisasi_berjalan' => 'decimal:2',
|
||||
'sistem_berjalan' => 'decimal:2',
|
||||
'lainnya_berjalan' => 'decimal:2',
|
||||
'nominal_gantung' => 'decimal:2',
|
||||
'aset_gantung' => 'decimal:2',
|
||||
];
|
||||
|
||||
/**
|
||||
* Field yang akan di-hidden saat serialization
|
||||
*/
|
||||
protected $hidden = [
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'deleted_by',
|
||||
];
|
||||
}
|
||||
@@ -14,7 +14,7 @@ class Inspeksi extends Base
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*/
|
||||
protected $fillable = ['data_form', 'foto_form', 'denah_form','permohonan_id', 'name', 'status', 'authorized_status', 'authorized_at', 'authorized_by', 'created_by', 'updated_by', 'deleted_by','dokument_id','data_pembanding'];
|
||||
protected $fillable = ['data_form', 'foto_form', 'denah_form','permohonan_id', 'name', 'status', 'authorized_status', 'authorized_at', 'authorized_by', 'created_by', 'updated_by', 'deleted_by','dokument_id','data_pembanding','mig_detail_data_jaminan'];
|
||||
|
||||
public function permohonan()
|
||||
{
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Modules\Usermanagement\Models\User;
|
||||
|
||||
class LaporanSlik extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'laporan_slik';
|
||||
|
||||
protected $fillable = [
|
||||
'slik_id',
|
||||
'sandi_bank',
|
||||
'kode_kantor',
|
||||
'kode_cabang',
|
||||
'tahun',
|
||||
'bulan',
|
||||
'no_rekening',
|
||||
'cif',
|
||||
'kode_jenis',
|
||||
'kode_jenis_ket',
|
||||
'kode_sifat',
|
||||
'kode_sifat_ket',
|
||||
'kode_valuta',
|
||||
'kode_valuta_ket',
|
||||
'baki_debet',
|
||||
'kolektibilitas',
|
||||
'kolektibilitas_ket',
|
||||
'tanggal_mulai',
|
||||
'tanggal_jatuh_tempo',
|
||||
'tanggal_selesai',
|
||||
'tanggal_restrukturisasi',
|
||||
'kode_sebab_macet',
|
||||
'kode_sebab_macet_ket',
|
||||
'tanggal_macet',
|
||||
'kode_kondisi',
|
||||
'kode_kondisi_ket',
|
||||
'tanggal_kondisi',
|
||||
'nilai_agunan',
|
||||
'nilai_agunan_ket',
|
||||
'jenis_agunan',
|
||||
'kode_agunan',
|
||||
'kode_agunan_ket',
|
||||
'peringkat_agunan',
|
||||
'peringkat_agunan_ket',
|
||||
'nama_debitur',
|
||||
'npwp',
|
||||
'no_ktp',
|
||||
'no_telp',
|
||||
'kode_kab_kota',
|
||||
'kode_kab_kota_ket',
|
||||
'kode_negara_domisili',
|
||||
'kode_negara_domisili_ket',
|
||||
'kode_pos',
|
||||
'alamat',
|
||||
'fasilitas',
|
||||
'status_agunan',
|
||||
'tanggal_lapor',
|
||||
'status',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
];
|
||||
|
||||
public function slik()
|
||||
{
|
||||
return $this->belongsTo(Slik::class, 'slik_id');
|
||||
}
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function updater()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope untuk filter berdasarkan status
|
||||
*/
|
||||
public function scopeActive($query)
|
||||
{
|
||||
return $query->where('status', 'aktif');
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor untuk nilai agunan yang diformat
|
||||
*/
|
||||
public function getNilaiAgunanFormattedAttribute()
|
||||
{
|
||||
return number_format($this->nilai_agunan ?? 0, 0, ',', '.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor untuk status badge
|
||||
*/
|
||||
public function getStatusBadgeAttribute()
|
||||
{
|
||||
$status = $this->status ?? 'aktif';
|
||||
$class = $status == 'aktif' ? 'success' : 'danger';
|
||||
|
||||
return '<span class="badge badge-light-' . $class . '">' . ucfirst($status) . '</span>';
|
||||
}
|
||||
}
|
||||
@@ -2,28 +2,41 @@
|
||||
|
||||
namespace Modules\Lpj\Models;
|
||||
|
||||
use Illuminate\Foundation\Auth\User;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
// use Modules\Lpj\Database\Factories\NocFactory;
|
||||
|
||||
class Noc extends Base
|
||||
{
|
||||
protected $table = 'noc';
|
||||
|
||||
protected $guarded = ['id'];
|
||||
protected $fillable = [
|
||||
'permohonan_id',
|
||||
'persetujuan_penawaran_id',
|
||||
'bukti_bayar',
|
||||
'nominal_bayar',
|
||||
'status_bayar',
|
||||
'tanggal_pembayaran',
|
||||
'nominal_penyelesaian',
|
||||
'status_penyelesaiaan',
|
||||
'tanggal_penyelesaian',
|
||||
'bukti_penyelesaian',
|
||||
'bukti_ksl',
|
||||
'memo_penyelesaian',
|
||||
'catatan_noc',
|
||||
'status',
|
||||
'authorized_status',
|
||||
'authorized_at',
|
||||
'authorized_by',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'nominal_bayar' => 'decimal:2',
|
||||
'status_bayar' => 'boolean',
|
||||
'status_kurang_bayar' => 'boolean',
|
||||
'nominal_kurang_bayar' => 'decimal:2',
|
||||
'status_lebih_bayar' => 'boolean',
|
||||
'nominal_lebih_bayar' => 'decimal:2',
|
||||
'tanggal_pembayaran' => 'date',
|
||||
'nominal_penyelesaian' => 'decimal:2',
|
||||
'status_penyelesaiaan' => 'boolean',
|
||||
'tanggal_penyelesaian' => 'date',
|
||||
'memo_penyelesaian_date' => 'date',
|
||||
'memo_penyelesaian_payment_date' => 'date',
|
||||
'memo_penyelesaian_created_at' => 'datetime',
|
||||
'status' => 'boolean',
|
||||
'authorized_status' => 'boolean',
|
||||
'authorized_at' => 'datetime',
|
||||
@@ -46,12 +59,4 @@ class Noc extends Base
|
||||
{
|
||||
return $this->belongsTo(User::class, 'authorized_by');
|
||||
}
|
||||
|
||||
public function debiture(){
|
||||
return $this->belongsTo(Debiture::class,'debiture_id');
|
||||
}
|
||||
|
||||
public function branch(){
|
||||
return $this->belongsTo(Branch::class,'branch_id');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Modules\Lpj\Models;
|
||||
|
||||
use Modules\Usermanagement\Models\User;
|
||||
use Modules\Usermanagemenet\Models\User;
|
||||
|
||||
class PersetujuanPenawaran extends Base
|
||||
{
|
||||
@@ -13,9 +13,6 @@
|
||||
'permohonan_id',
|
||||
'penawaran_id',
|
||||
'nomor_proposal_penawaran',
|
||||
'nomor_tiket',
|
||||
'nominal_kurang_bayar',
|
||||
'bukti_ksl_kurang_bayar',
|
||||
'tanggal_proposal_penawaran',
|
||||
'biaya_final',
|
||||
'sla_resume',
|
||||
@@ -49,6 +46,12 @@
|
||||
return $this->belongsTo(Permohonan::class, 'permohonan_id');
|
||||
}
|
||||
|
||||
// Relationship with Region
|
||||
public function region()
|
||||
{
|
||||
return $this->belongsTo(Region::class);
|
||||
}
|
||||
|
||||
// Relationship with User (for authorized_by)
|
||||
public function authorizedBy()
|
||||
{
|
||||
|
||||
@@ -1,190 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* Model Slik untuk mengelola data SLIK (Sistem Layanan Informasi Keuangan)
|
||||
*
|
||||
* @property int $id
|
||||
* @property string|null $sandi_bank
|
||||
* @property string|null $tahun
|
||||
* @property string|null $bulan
|
||||
* @property string|null $flag_detail
|
||||
* @property string|null $kode_register_agunan
|
||||
* @property string|null $no_rekening
|
||||
* @property string|null $cif
|
||||
* @property string|null $kolektibilitas
|
||||
* @property string|null $fasilitas
|
||||
* @property string|null $jenis_segmen_fasilitas
|
||||
* @property string|null $status_agunan
|
||||
* @property string|null $jenis_agunan
|
||||
* @property string|null $peringkat_agunan
|
||||
* @property string|null $lembaga_pemeringkat
|
||||
* @property string|null $jenis_pengikatan
|
||||
* @property string|null $tanggal_pengikatan
|
||||
* @property string|null $nama_pemilik_agunan
|
||||
* @property string|null $bukti_kepemilikan
|
||||
* @property string|null $alamat_agunan
|
||||
* @property string|null $lokasi_agunan
|
||||
* @property string|null $nilai_agunan
|
||||
* @property string|null $nilai_agunan_menurut_ljk
|
||||
* @property string|null $tanggal_penilaian_ljk
|
||||
* @property string|null $nilai_agunan_penilai_independen
|
||||
* @property string|null $nama_penilai_independen
|
||||
* @property string|null $tanggal_penilaian_penilai_independen
|
||||
* @property string|null $jumlah_hari_tunggakan
|
||||
* @property string|null $status_paripasu
|
||||
* @property string|null $prosentase_paripasu
|
||||
* @property string|null $status_kredit_join
|
||||
* @property string|null $diasuransikan
|
||||
* @property string|null $keterangan
|
||||
* @property string|null $kantor_cabang
|
||||
* @property string|null $operasi_data
|
||||
* @property string|null $kode_cabang
|
||||
* @property string|null $nama_debitur
|
||||
* @property string|null $nama_cabang
|
||||
* @property string|null $flag
|
||||
*/
|
||||
class Slik extends Base
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
/**
|
||||
* Nama tabel yang digunakan oleh model
|
||||
*/
|
||||
protected $table = 'sliks';
|
||||
|
||||
/**
|
||||
* Field yang dapat diisi secara mass assignment
|
||||
*/
|
||||
protected $fillable = [
|
||||
'sandi_bank',
|
||||
'tahun',
|
||||
'bulan',
|
||||
'flag_detail',
|
||||
'kode_register_agunan',
|
||||
'no_rekening',
|
||||
'cif',
|
||||
'kolektibilitas',
|
||||
'fasilitas',
|
||||
'jenis_segmen_fasilitas',
|
||||
'status_agunan',
|
||||
'jenis_agunan',
|
||||
'peringkat_agunan',
|
||||
'lembaga_pemeringkat',
|
||||
'jenis_pengikatan',
|
||||
'tanggal_pengikatan',
|
||||
'nama_pemilik_agunan',
|
||||
'bukti_kepemilikan',
|
||||
'alamat_agunan',
|
||||
'lokasi_agunan',
|
||||
'nilai_agunan',
|
||||
'nilai_agunan_menurut_ljk',
|
||||
'tanggal_penilaian_ljk',
|
||||
'nilai_agunan_penilai_independen',
|
||||
'nama_penilai_independen',
|
||||
'tanggal_penilaian_penilai_independen',
|
||||
'jumlah_hari_tunggakan',
|
||||
'status_paripasu',
|
||||
'prosentase_paripasu',
|
||||
'status_kredit_join',
|
||||
'diasuransikan',
|
||||
'keterangan',
|
||||
'kantor_cabang',
|
||||
'operasi_data',
|
||||
'kode_cabang',
|
||||
'nama_debitur',
|
||||
'nama_cabang',
|
||||
'flag',
|
||||
];
|
||||
|
||||
/**
|
||||
* Casting tipe data untuk field tertentu
|
||||
*/
|
||||
protected $casts = [
|
||||
'tanggal_pengikatan' => 'date',
|
||||
'tanggal_penilaian_ljk' => 'date',
|
||||
'tanggal_penilaian_penilai_independen' => 'date',
|
||||
'nilai_agunan' => 'decimal:2',
|
||||
'nilai_agunan_menurut_ljk' => 'decimal:2',
|
||||
'nilai_agunan_penilai_independen' => 'decimal:2',
|
||||
'prosentase_paripasu' => 'decimal:2',
|
||||
'jumlah_hari_tunggakan' => 'integer',
|
||||
];
|
||||
|
||||
/**
|
||||
* Accessor untuk format nilai agunan dengan currency Indonesia
|
||||
*/
|
||||
public function getNilaiAgunanFormattedAttribute(): string
|
||||
{
|
||||
return $this->nilai_agunan ? 'Rp ' . number_format($this->nilai_agunan, 0, ',', '.') : 'Rp 0';
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor untuk format nilai agunan menurut LJK dengan currency Indonesia
|
||||
*/
|
||||
public function getNilaiAgunanMenurutLjkFormattedAttribute(): string
|
||||
{
|
||||
return $this->nilai_agunan_menurut_ljk ? 'Rp ' . number_format($this->nilai_agunan_menurut_ljk, 0, ',', '.') : 'Rp 0';
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor untuk format nilai agunan penilai independen dengan currency Indonesia
|
||||
*/
|
||||
public function getNilaiAgunanPenilaiIndependenFormattedAttribute(): string
|
||||
{
|
||||
return $this->nilai_agunan_penilai_independen ? 'Rp ' . number_format($this->nilai_agunan_penilai_independen, 0, ',', '.') : 'Rp 0';
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor untuk status badge berdasarkan status agunan
|
||||
*/
|
||||
public function getStatusBadgeAttribute(): string
|
||||
{
|
||||
$statusClass = match($this->status_agunan) {
|
||||
'Aktif' => 'badge-success',
|
||||
'Tidak Aktif' => 'badge-danger',
|
||||
'Pending' => 'badge-warning',
|
||||
default => 'badge-secondary'
|
||||
};
|
||||
|
||||
return '<span class="badge ' . $statusClass . '">' . ($this->status_agunan ?? 'Unknown') . '</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope untuk filter berdasarkan tahun
|
||||
*/
|
||||
public function scopeByYear($query, $year)
|
||||
{
|
||||
return $query->where('tahun', $year);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope untuk filter berdasarkan bulan
|
||||
*/
|
||||
public function scopeByMonth($query, $month)
|
||||
{
|
||||
return $query->where('bulan', $month);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope untuk filter berdasarkan sandi bank
|
||||
*/
|
||||
public function scopeBySandiBank($query, $sandiBank)
|
||||
{
|
||||
return $query->where('sandi_bank', $sandiBank);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope untuk filter berdasarkan kode cabang
|
||||
*/
|
||||
public function scopeByKodeCabang($query, $kodeCabang)
|
||||
{
|
||||
return $query->where('kode_cabang', $kodeCabang);
|
||||
}
|
||||
|
||||
// Method creator() dan editor() sudah disediakan oleh trait Userstamps
|
||||
}
|
||||
@@ -50,7 +50,7 @@ class DaftarPustakaService
|
||||
|
||||
// get all with pagination
|
||||
public function getAllDaftarPustaka($request)
|
||||
{
|
||||
{
|
||||
$query = DaftarPustaka::query();
|
||||
|
||||
// Filter pencarian
|
||||
@@ -72,7 +72,7 @@ class DaftarPustakaService
|
||||
$size = (int) $request->get('size', 10);
|
||||
|
||||
return $query->paginate($size, ['*'], 'page', $page);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private function handleUpload($file)
|
||||
@@ -80,14 +80,10 @@ class DaftarPustakaService
|
||||
$today = now();
|
||||
$folderPath = 'daftar_pustaka/' . $today->format('Y/m/d');
|
||||
|
||||
if (!file_exists(public_path($folderPath))) {
|
||||
mkdir(public_path($folderPath), 0755, true);
|
||||
}
|
||||
|
||||
$fileName = $file->getClientOriginalName();
|
||||
$file->move(public_path($folderPath), $fileName);
|
||||
$filePath = $file->storeAs($folderPath, $fileName, 'public');
|
||||
|
||||
return $folderPath . '/' . $fileName;
|
||||
return $filePath;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,236 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Services;
|
||||
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class ImportProgressService
|
||||
{
|
||||
protected string $cacheKeyPrefix;
|
||||
protected int $cacheTtl;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->cacheKeyPrefix = config('import.slik.progress.cache_key', 'slik_import_progress');
|
||||
$this->cacheTtl = config('import.slik.progress.cache_ttl', 3600);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start new import progress
|
||||
*
|
||||
* @param string $importId
|
||||
* @param int $userId
|
||||
* @param string $filename
|
||||
* @param int $totalRows
|
||||
* @return array
|
||||
*/
|
||||
public function start(string $importId, int $userId, string $filename, int $totalRows): array
|
||||
{
|
||||
$progressData = [
|
||||
'import_id' => $importId,
|
||||
'user_id' => $userId,
|
||||
'filename' => $filename,
|
||||
'total_rows' => $totalRows,
|
||||
'processed_rows' => 0,
|
||||
'skipped_rows' => 0,
|
||||
'error_rows' => 0,
|
||||
'status' => 'started',
|
||||
'percentage' => 0,
|
||||
'message' => 'Memulai import...',
|
||||
'started_at' => now(),
|
||||
'updated_at' => now()
|
||||
];
|
||||
|
||||
$cacheKey = $this->getCacheKey($importId);
|
||||
Cache::put($cacheKey, $progressData, $this->cacheTtl);
|
||||
|
||||
Log::info('ImportProgressService: Import started', $progressData);
|
||||
|
||||
return $progressData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update progress import
|
||||
*
|
||||
* @param string $importId
|
||||
* @param int $processedRows
|
||||
* @param int $skippedRows
|
||||
* @param int $errorRows
|
||||
* @param string|null $message
|
||||
* @return array
|
||||
*/
|
||||
public function update(string $importId, int $processedRows, int $skippedRows, int $errorRows, ?string $message = null): array
|
||||
{
|
||||
$cacheKey = $this->getCacheKey($importId);
|
||||
$progressData = Cache::get($cacheKey);
|
||||
|
||||
if (!$progressData) {
|
||||
Log::warning('ImportProgressService: Progress data not found', ['import_id' => $importId]);
|
||||
return [];
|
||||
}
|
||||
|
||||
$totalRows = $progressData['total_rows'];
|
||||
$percentage = $totalRows > 0 ? round(($processedRows / $totalRows) * 100, 2) : 0;
|
||||
|
||||
$progressData = array_merge($progressData, [
|
||||
'processed_rows' => $processedRows,
|
||||
'skipped_rows' => $skippedRows,
|
||||
'error_rows' => $errorRows,
|
||||
'percentage' => $percentage,
|
||||
'message' => $message ?? "Memproses baris {$processedRows} dari {$totalRows}...",
|
||||
'updated_at' => now()
|
||||
]);
|
||||
|
||||
Cache::put($cacheKey, $progressData, $this->cacheTtl);
|
||||
|
||||
// Log progress setiap 10%
|
||||
if ($percentage % 10 === 0) {
|
||||
Log::info('ImportProgressService: Progress update', [
|
||||
'import_id' => $importId,
|
||||
'percentage' => $percentage,
|
||||
'processed' => $processedRows,
|
||||
'total' => $totalRows
|
||||
]);
|
||||
}
|
||||
|
||||
return $progressData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark import as completed
|
||||
*
|
||||
* @param string $importId
|
||||
* @param string|null $message
|
||||
* @return array
|
||||
*/
|
||||
public function complete(string $importId, ?string $message = null): array
|
||||
{
|
||||
$cacheKey = $this->getCacheKey($importId);
|
||||
$progressData = Cache::get($cacheKey);
|
||||
|
||||
if (!$progressData) {
|
||||
Log::warning('ImportProgressService: Progress data not found for completion', ['import_id' => $importId]);
|
||||
return [];
|
||||
}
|
||||
|
||||
$progressData = array_merge($progressData, [
|
||||
'status' => 'completed',
|
||||
'percentage' => 100,
|
||||
'message' => $message ?? 'Import berhasil diselesaikan',
|
||||
'completed_at' => now(),
|
||||
'updated_at' => now()
|
||||
]);
|
||||
|
||||
Cache::put($cacheKey, $progressData, $this->cacheTtl);
|
||||
|
||||
Log::info('ImportProgressService: Import completed', [
|
||||
'import_id' => $importId,
|
||||
'total_rows' => $progressData['total_rows'],
|
||||
'processed_rows' => $progressData['processed_rows'],
|
||||
'skipped_rows' => $progressData['skipped_rows'],
|
||||
'error_rows' => $progressData['error_rows']
|
||||
]);
|
||||
|
||||
return $progressData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark import as failed
|
||||
*
|
||||
* @param string $importId
|
||||
* @param string $errorMessage
|
||||
* @return array
|
||||
*/
|
||||
public function fail(string $importId, string $errorMessage): array
|
||||
{
|
||||
$cacheKey = $this->getCacheKey($importId);
|
||||
$progressData = Cache::get($cacheKey);
|
||||
|
||||
if (!$progressData) {
|
||||
Log::warning('ImportProgressService: Progress data not found for failure', ['import_id' => $importId]);
|
||||
return [];
|
||||
}
|
||||
|
||||
$progressData = array_merge($progressData, [
|
||||
'status' => 'failed',
|
||||
'message' => 'Import gagal: ' . $errorMessage,
|
||||
'failed_at' => now(),
|
||||
'updated_at' => now()
|
||||
]);
|
||||
|
||||
Cache::put($cacheKey, $progressData, $this->cacheTtl);
|
||||
|
||||
Log::error('ImportProgressService: Import failed', [
|
||||
'import_id' => $importId,
|
||||
'error' => $errorMessage,
|
||||
'progress_data' => $progressData
|
||||
]);
|
||||
|
||||
return $progressData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get progress data
|
||||
*
|
||||
* @param string $importId
|
||||
* @return array|null
|
||||
*/
|
||||
public function getProgress(string $importId): ?array
|
||||
{
|
||||
$cacheKey = $this->getCacheKey($importId);
|
||||
return Cache::get($cacheKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all active imports for user
|
||||
*
|
||||
* @param int $userId
|
||||
* @return array
|
||||
*/
|
||||
public function getUserImports(int $userId): array
|
||||
{
|
||||
$pattern = $this->cacheKeyPrefix . '_*';
|
||||
$keys = Cache::get($pattern);
|
||||
|
||||
$imports = [];
|
||||
foreach ($keys as $key) {
|
||||
$data = Cache::get($key);
|
||||
if ($data && $data['user_id'] === $userId) {
|
||||
$imports[] = $data;
|
||||
}
|
||||
}
|
||||
|
||||
return $imports;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear progress data
|
||||
*
|
||||
* @param string $importId
|
||||
* @return bool
|
||||
*/
|
||||
public function clear(string $importId): bool
|
||||
{
|
||||
$cacheKey = $this->getCacheKey($importId);
|
||||
$result = Cache::forget($cacheKey);
|
||||
|
||||
Log::info('ImportProgressService: Progress data cleared', ['import_id' => $importId]);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate cache key
|
||||
*
|
||||
* @param string $importId
|
||||
* @return string
|
||||
*/
|
||||
private function getCacheKey(string $importId): string
|
||||
{
|
||||
return $this->cacheKeyPrefix . '_' . $importId;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Services;
|
||||
|
||||
use Modules\Lpj\Models\Permohonan;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\Usermanagement\Models\User;
|
||||
|
||||
class LaporanUserService
|
||||
{
|
||||
@@ -25,36 +27,15 @@ class LaporanUserService
|
||||
{
|
||||
|
||||
// Retrieve data from the database
|
||||
$query = Permohonan::query();
|
||||
$query = $query->where('status', 'done');
|
||||
|
||||
$query = User::query();
|
||||
// Apply search filter if provided
|
||||
if ($request->has('search') && !empty($request->get('search'))) {
|
||||
$search = json_decode($request->get('search'));
|
||||
|
||||
if (isset($search->start_date) || isset($search->end_date)) {
|
||||
$query->whereBetween('tanggal_permohonan', [
|
||||
$search->start_date ?? '1900-01-01',
|
||||
$search->end_date ?? now()->toDateString()
|
||||
]);
|
||||
}
|
||||
|
||||
// Filter by branch if provided
|
||||
if (isset($search->user_id) && !empty($search->user_id)) {
|
||||
$query->where('user_id', $search->user_id);
|
||||
}
|
||||
|
||||
if (isset($search->search)) {
|
||||
|
||||
$query->where(function ($q) use ($search) {
|
||||
$q->where('nomor_registrasi', 'LIKE', '%' . $search->search . '%');
|
||||
$q->orWhere('tanggal_permohonan', 'LIKE', '%' . $search->search . '%');
|
||||
$q->orWhereRelation('user', 'name', 'LIKE', '%' . $search->search . '%');
|
||||
$q->orWhereRelation('tujuanPenilaian', 'name', 'LIKE', '%' . $search->search . '%');
|
||||
$q->orWhereRelation('branch', 'name', 'LIKE', '%' . $search->search . '%');
|
||||
$q->orWhereRelation('jenisFasilitasKredit', 'name', 'LIKE', '%' . $search->search . '%');
|
||||
$q->orWhereRelation('jenisPenilaian', 'name', 'LIKE', '%' . $search->search . '%');
|
||||
$q->orWhere('status', 'LIKE', '%' . $search->search . '%');
|
||||
$q->whereRaw('LOWER(name) LIKE ?', ['%' . strtolower($search) . '%']);
|
||||
$q->where('nik', 'LIKE', '%' . $search->search . '%');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -82,28 +63,16 @@ class LaporanUserService
|
||||
$filteredRecords = $query->count();
|
||||
|
||||
// Get the data for the current page
|
||||
$data = $query->with(['debiture.branch'])->get();
|
||||
$data = $query->with(['branch', 'roles'])->get();
|
||||
|
||||
$data = $data->map(function ($permohonan) {
|
||||
|
||||
$npw = 0;
|
||||
|
||||
|
||||
if (isset($permohonan->penilai->lpj)) {
|
||||
$lpj = json_decode($permohonan->penilai->lpj, true);
|
||||
$npw = str_replace('.', '', $lpj['total_nilai_pasar_wajar'] ?? 0);
|
||||
}
|
||||
$data = $data->map(function ($user) {
|
||||
|
||||
return [
|
||||
'id' => $permohonan->id,
|
||||
'nomor_registrasi' => $permohonan->nomor_registrasi,
|
||||
'branch' => $permohonan->debiture->branch?->name,
|
||||
'name' => $permohonan->debiture?->name,
|
||||
'pemohon' => $permohonan->creator?->name,
|
||||
'tanggal_permohonan' => $permohonan->tanggal_permohonan,
|
||||
'nama_penilai' => $permohonan->penilaian?->_user_penilai?->userPenilaiTeam?->name,
|
||||
'tanggal_laporan' => $permohonan->approval_dd_at ?? $permohonan->approval_eo_at ?? '',
|
||||
'nilai_pasar_wajar' => formatRupiah($npw, 2)
|
||||
'id' => $user->id,
|
||||
'nik' => $user->nik,
|
||||
'name' => $user->name,
|
||||
'level' => $user->roles->pluck('name')->implode(', '),
|
||||
'approval_limit' => 0,
|
||||
];
|
||||
});
|
||||
|
||||
|
||||
733
app/Services/PreviewLaporanService.php
Normal file
733
app/Services/PreviewLaporanService.php
Normal file
@@ -0,0 +1,733 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Services;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use App\Helpers\Lpj;
|
||||
use Modules\Lpj\Models\Denah;
|
||||
use Modules\Lpj\Models\Teams;
|
||||
use Modules\Lpj\Models\Branch;
|
||||
use Modules\Lpj\Models\Lantai;
|
||||
use Barryvdh\DomPDF\Facade\Pdf;
|
||||
use Modules\Lpj\Models\Analisa;
|
||||
use Modules\Lpj\Models\Penilai;
|
||||
use Modules\Lpj\Models\Debiture;
|
||||
use Modules\Lpj\Models\Inspeksi;
|
||||
use Modules\Lpj\Models\Surveyor;
|
||||
use Modules\Lpj\Models\ViewUnit;
|
||||
use Modules\Location\Models\City;
|
||||
use Modules\Lpj\Models\JenisUnit;
|
||||
use Modules\Lpj\Models\Penilaian;
|
||||
use Modules\Lpj\Models\Perizinan;
|
||||
use Modules\Lpj\Models\BentukUnit;
|
||||
use Modules\Lpj\Models\JenisKapal;
|
||||
use Modules\Lpj\Models\LantaiUnit;
|
||||
use Modules\Lpj\Models\Lingkungan;
|
||||
use Modules\Lpj\Models\Permohonan;
|
||||
use Modules\Lpj\Models\PosisiUnit;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Modules\Lpj\Models\AnalisaUnit;
|
||||
use Modules\Lpj\Models\BentukTanah;
|
||||
use Modules\Lpj\Models\FotoJaminan;
|
||||
use Modules\Lpj\Models\KonturTanah;
|
||||
use Modules\Lpj\Models\RuteJaminan;
|
||||
use Modules\Location\Models\Village;
|
||||
use Modules\Lpj\Models\AnalisaFakta;
|
||||
use Modules\Lpj\Models\JenisJaminan;
|
||||
use Modules\Lpj\Models\JenisPesawat;
|
||||
use Modules\Lpj\Models\ObjekJaminan;
|
||||
use Modules\Lpj\Models\SpekBangunan;
|
||||
use Modules\Lpj\Models\TerletakArea;
|
||||
use Modules\Location\Models\District;
|
||||
use Modules\Location\Models\Province;
|
||||
use Modules\Lpj\Models\ArahMataAngin;
|
||||
use Modules\Lpj\Models\JenisBangunan;
|
||||
use Modules\Lpj\Models\PosisiKavling;
|
||||
use Modules\Lpj\Models\SifatBangunan;
|
||||
use Modules\Lpj\Models\DokumenJaminan;
|
||||
use Modules\Lpj\Models\FasilitasObjek;
|
||||
use Modules\Lpj\Models\JenisKendaraan;
|
||||
use Modules\Lpj\Models\ModelAlatBerat;
|
||||
use Modules\Lpj\Models\KetinggianTanah;
|
||||
use Modules\Lpj\Models\KondisiBangunan;
|
||||
use Modules\Lpj\Models\LaporanExternal;
|
||||
use Modules\Lpj\Models\MerupakanDaerah;
|
||||
use Modules\Lpj\Models\PerkerasanJalan;
|
||||
use Modules\Lpj\Models\SaranaPelengkap;
|
||||
use Modules\Lpj\Models\TujuanPenilaian;
|
||||
use Modules\Lpj\Models\FotoObjekJaminan;
|
||||
use Modules\Lpj\Models\LaluLintasLokasi;
|
||||
use Modules\Lpj\Models\TingkatKeramaian;
|
||||
use Modules\Lpj\Models\AnalisaLingkungan;
|
||||
use Modules\Lpj\Models\KondisiFisikTanah;
|
||||
use Modules\Lpj\Models\AnalisaTanahBagunan;
|
||||
use Modules\Lpj\Models\GolonganMasySekitar;
|
||||
use Modules\Lpj\Models\SpekBangunanAnalisa;
|
||||
use Modules\Lpj\Models\DetailDokumenJaminan;
|
||||
use Modules\Lpj\Models\SpekKategoritBangunan;
|
||||
use Modules\Lpj\Http\Requests\SurveyorRequest;
|
||||
use Modules\Lpj\Models\HubunganPemilikJaminan;
|
||||
use Modules\Lpj\Models\HubunganPenghuniJaminan;
|
||||
use Modules\Lpj\Models\SpekBagunanAnalisaDetail;
|
||||
use Modules\Lpj\Jobs\SendJadwalKunjunganEmailJob;
|
||||
use Modules\Lpj\Http\Requests\FormSurveyorRequest;
|
||||
|
||||
class PreviewLaporanService
|
||||
{
|
||||
/**
|
||||
* Preview Laporan dan unduh foto terkait dengan logika fallback path.
|
||||
*
|
||||
* Menghasilkan PDF atau paket unduhan foto berdasarkan status laporan.
|
||||
* Jika file foto asli tidak ditemukan dan status LPJ adalah 1, maka
|
||||
* sistem akan mencoba menggunakan fallback path dengan pola
|
||||
* `surveyor/001/{lastTwoParts}` untuk meminimalisir gambar hilang.
|
||||
*
|
||||
* @param int $permohonan_id ID Permohonan
|
||||
* @param int $dokumen_id ID Dokumen
|
||||
* @param int $jaminan_id ID Jaminan
|
||||
* @param string $back URL atau rute kembali
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function previewLaporan($permohonan_id, $dokumen_id, $jaminan_id, $back)
|
||||
{
|
||||
$permohonan = $this->getPermohonanJaminanId(
|
||||
$permohonan_id,
|
||||
$dokumen_id,
|
||||
$jaminan_id
|
||||
);
|
||||
// $tipeLaporanResponse = $this->checkPrintOutLaporan($permohonan_id, $document_id);
|
||||
// $tipeLaporan = $tipeLaporanResponse->getData();
|
||||
|
||||
// if (!$tipeLaporan->status) {
|
||||
// return redirect()->back()->with('error', 'Laporan tidak valid');
|
||||
// }
|
||||
$basicData = $this->getCommonData();
|
||||
|
||||
$inspeksi = Inspeksi::where('permohonan_id', $permohonan_id)->where('dokument_id', $dokumen_id)->first();
|
||||
$lpj = Penilai::where('permohonan_id', $permohonan_id)->where('dokument_id', $dokumen_id)->first();
|
||||
|
||||
$mig_permohonan = json_decode($permohonan->mig_permohonan);
|
||||
|
||||
$nomorLaporan = getNomorLaporan($permohonan_id, $dokumen_id);
|
||||
$tanggalLaporan = $permohonan->is_mig
|
||||
? ($mig_permohonan->mig_mst_jaminan_tgl_laporan ?? $mig_permohonan->mig_mst_jaminan_tgl_create ?? null)
|
||||
: ($lpj->created_at ?? null);
|
||||
$forminspeksi = null;
|
||||
$lpjData = null;
|
||||
$formFoto = null;
|
||||
|
||||
// if ($inspeksi) {
|
||||
$forminspeksi = json_decode($inspeksi?->data_form, true) ?? null;
|
||||
|
||||
$formFoto = json_decode($inspeksi?->foto_form, true) ?? null;
|
||||
// $denahForm = json_decode($data->denah_form, true);
|
||||
$dataPembanding = json_decode($inspeksi?->data_pembanding, true) ?? null;
|
||||
// }
|
||||
|
||||
// if ($lpj) {
|
||||
$lpjData = json_decode($lpj?->lpj, true) ?? null;
|
||||
$memo = json_decode($lpj?->memo, true) ?? null;
|
||||
$resumeData = json_decode($lpj?->resume, true) ?? null;
|
||||
$rap = json_decode($lpj?->rap, true);
|
||||
$report = json_decode($lpj?->call_report, true) ?? null;
|
||||
// }
|
||||
|
||||
$inputAddress = $forminspeksi['asset']['alamat']['sesuai'] ?? $forminspeksi['asset']['alamat']['tidak sesuai'] ?? [];
|
||||
|
||||
$alamat = [
|
||||
'address' => $inputAddress['address'] ?? null,
|
||||
'village_code' => getWilayahName($inputAddress['village_code'] ?? null, 'village'),
|
||||
'district_code' => getWilayahName($inputAddress['district_code'] ?? null, 'district'),
|
||||
'city_code' => getWilayahName($inputAddress['city_code'] ?? null, 'city'),
|
||||
'province_code' => getWilayahName($inputAddress['province_code'] ?? null, 'province')
|
||||
];
|
||||
|
||||
$statusLpj = 0;
|
||||
|
||||
// $viewLaporan = $this->getViewLaporan($tipeLaporan);
|
||||
return view('lpj::component.show-laporan-inspeksi', compact('permohonan', 'basicData', 'forminspeksi', 'alamat', 'lpjData', 'memo', 'resumeData', 'rap', 'report', 'lpj', 'formFoto', 'nomorLaporan', 'tanggalLaporan', 'dataPembanding', 'inspeksi', 'statusLpj', 'permohonan_id', 'back', ));
|
||||
}
|
||||
|
||||
public function printOutLaporan($permohonan_id, $document_id, $jaminan_id)
|
||||
{
|
||||
$tipeLaporanResponse = $this->checkPrintOutLaporan($permohonan_id, $document_id);
|
||||
$tipeLaporan = $tipeLaporanResponse->getData();
|
||||
|
||||
//dd($permohonan_id, $document_id, $tipeLaporan);
|
||||
|
||||
if (!$tipeLaporan->status) {
|
||||
//return redirect()->back()->with('error', 'Laporan tidak valid');
|
||||
}
|
||||
$permohonan = $this->getPermohonanJaminanId(
|
||||
$permohonan_id,
|
||||
$document_id,
|
||||
$jaminan_id
|
||||
);
|
||||
|
||||
$basicData = $this->getCommonData();
|
||||
|
||||
$inspeksi = Inspeksi::where('permohonan_id', $permohonan_id)->where('dokument_id', $document_id)->first();
|
||||
$lpj = Penilai::where('permohonan_id', $permohonan_id)->first(); //->where('dokument_id', $document_id)->first();
|
||||
|
||||
$mig_permohonan = json_decode($permohonan->mig_permohonan);
|
||||
$nomorLaporan = getNomorLaporan($permohonan_id, $document_id);
|
||||
|
||||
//Carbon::createFromFormat('d/m/Y H:i:s', $mig_permohonan->mig_mst_jaminan_tgl_laporan)->format('Y-m-d H:i:s');
|
||||
|
||||
$tanggalLaporan = $permohonan->is_mig
|
||||
? ($mig_permohonan->mig_mst_jaminan_tgl_laporan
|
||||
? Carbon::createFromFormat('d/m/Y H:i:s', $mig_permohonan->mig_mst_jaminan_tgl_laporan)->format('Y-m-d H:i:s')
|
||||
: ($mig_permohonan->mig_mst_jaminan_tgl_oto
|
||||
? Carbon::createFromFormat('d/m/Y H:i:s', $mig_permohonan->mig_mst_jaminan_tgl_oto)->format('Y-m-d H:i:s')
|
||||
: null))
|
||||
: ($lpj->created_at ?? null);
|
||||
|
||||
|
||||
$forminspeksi = null;
|
||||
$lpjData = null;
|
||||
$formFoto = null;
|
||||
|
||||
$dataPembanding ='';
|
||||
if ($inspeksi) {
|
||||
$forminspeksi = json_decode($inspeksi->data_form, true);
|
||||
$formFoto = json_decode($inspeksi->foto_form, true);
|
||||
// $denahForm = json_decode($data->denah_form, true);
|
||||
$dataPembanding = json_decode($inspeksi->data_pembanding, true);
|
||||
}
|
||||
|
||||
|
||||
if ($lpj) {
|
||||
$lpjData = json_decode($lpj->lpj, true);
|
||||
$memo = json_decode($lpj->memo, true);
|
||||
$resumeData = json_decode($lpj->resume, true);
|
||||
$rap = json_decode($lpj->rap, true);
|
||||
$report = json_decode($lpj->call_report, true);
|
||||
}
|
||||
|
||||
$inputAddress = $forminspeksi['asset']['alamat']['sesuai'] ?? $forminspeksi['asset']['alamat']['tidak sesuai'] ?? [];
|
||||
|
||||
$inputAddress = $forminspeksi['asset']['alamat']['sesuai'] ?? $forminspeksi['asset']['alamat']['tidak sesuai'] ?? [];
|
||||
$alamat = [
|
||||
'address' => $inputAddress['address'] ?? null,
|
||||
'village_code' => getWilayahName($inputAddress['village_code'] ?? null, 'village'),
|
||||
'district_code' => getWilayahName($inputAddress['district_code'] ?? null, 'district'),
|
||||
'city_code' => getWilayahName($inputAddress['city_code'] ?? null, 'city'),
|
||||
'province_code' => getWilayahName($inputAddress['province_code'] ?? null, 'province')
|
||||
];
|
||||
|
||||
$viewLaporan = $this->getViewLaporan($tipeLaporan->status);
|
||||
|
||||
$statusLpj = 1;
|
||||
|
||||
$mig_permohonan = json_decode($permohonan->mig_permohonan);
|
||||
if(($tipeLaporan->status === 'memo' && $permohonan->mig_permohonan) || $mig_permohonan->mig_mst_lpj_tot_nilai_pasar < 1){
|
||||
$paths = $formFoto['upload_foto'] ?? null;
|
||||
|
||||
if (!is_array($paths) || empty($paths)) {
|
||||
return response()->json(['error' => 'No files to download'], 404);
|
||||
}
|
||||
|
||||
$files = [];
|
||||
foreach ($paths as $path) {
|
||||
if (!$path['path']) {
|
||||
Log::warning('PreviewLaporanService: Path kosong terdeteksi dalam daftar paths.');
|
||||
continue;
|
||||
}
|
||||
|
||||
// Logika fallback untuk path file
|
||||
$originalPath = $path['path'];
|
||||
$fallbackPath = null;
|
||||
|
||||
// Jika file asli tidak ditemukan, buat fallback path
|
||||
if ($statusLpj == 1) {
|
||||
$fullOriginalPath = storage_path('app/public/' . $originalPath);
|
||||
|
||||
if (!file_exists($fullOriginalPath)) {
|
||||
// Ekstrak bagian akhir path (contoh: 251051/251051_2_2.png)
|
||||
$pathParts = explode('/', $originalPath);
|
||||
if (count($pathParts) >= 2) {
|
||||
$lastTwoParts = array_slice($pathParts, -2);
|
||||
$fallbackPath = 'surveyor/001/' . implode('/', $lastTwoParts);
|
||||
Log::info('PreviewLaporanService: Menggunakan fallback path kandidat.', [
|
||||
'original' => $originalPath,
|
||||
'fallback' => $fallbackPath,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tentukan path yang akan digunakan
|
||||
$pathToUse = ($fallbackPath && $statusLpj == 1 && file_exists(storage_path('app/public/' . $fallbackPath)))
|
||||
? $fallbackPath
|
||||
: $originalPath;
|
||||
|
||||
$fullPath = storage_path('app/public/' . $pathToUse);
|
||||
if (!file_exists($fullPath)) {
|
||||
Log::warning('PreviewLaporanService: File tidak ditemukan untuk original maupun fallback.', [
|
||||
'original' => $originalPath,
|
||||
'fallback' => $fallbackPath,
|
||||
'resolved' => $pathToUse,
|
||||
]);
|
||||
continue;
|
||||
}
|
||||
|
||||
Log::info('PreviewLaporanService: Menambahkan file untuk diunduh.', [
|
||||
'resolved' => $pathToUse,
|
||||
'fullPath' => $fullPath,
|
||||
]);
|
||||
$files[] = $fullPath;
|
||||
}
|
||||
|
||||
if (empty($files)) {
|
||||
Log::warning('PreviewLaporanService: Tidak ada file valid ditemukan setelah resolusi path.');
|
||||
return response()->json(['error' => 'No valid files found'], 404);
|
||||
}
|
||||
|
||||
// For single file, download directly
|
||||
if (count($files) === 1) {
|
||||
Log::info('PreviewLaporanService: Mengunduh single file.', ['file' => $files[0]]);
|
||||
return response()->download($files[0]);
|
||||
}
|
||||
|
||||
// For multiple files, create zip and download
|
||||
$zipName = 'photos_' . time() . '.zip';
|
||||
$zipPath = storage_path('app/public/' . $zipName);
|
||||
|
||||
$zip = new \ZipArchive();
|
||||
if ($zip->open($zipPath, \ZipArchive::CREATE) === true) {
|
||||
foreach ($files as $file) {
|
||||
$zip->addFile($file, basename($file));
|
||||
}
|
||||
$zip->close();
|
||||
Log::info('PreviewLaporanService: Zip file berhasil dibuat.', ['zip' => $zipPath, 'count' => count($files)]);
|
||||
return response()->download($zipPath)->deleteFileAfterSend(true);
|
||||
}
|
||||
|
||||
Log::error('PreviewLaporanService: Gagal membuat zip file.');
|
||||
return response()->json(['error' => 'Failed to create zip file'], 500);
|
||||
}
|
||||
try {
|
||||
$pdf = $this->generatePDF($viewLaporan, compact(
|
||||
'permohonan',
|
||||
'forminspeksi',
|
||||
'lpjData',
|
||||
'formFoto',
|
||||
'basicData',
|
||||
'inspeksi',
|
||||
'lpj',
|
||||
'statusLpj',
|
||||
'alamat',
|
||||
'dataPembanding',
|
||||
'nomorLaporan',
|
||||
'memo',
|
||||
'resumeData',
|
||||
'tanggalLaporan',
|
||||
'rap',
|
||||
'report'
|
||||
));
|
||||
|
||||
$cleanNomorLaporan = str_replace(['/', '\\'], '-', $nomorLaporan);
|
||||
$filename = 'Laporan_' . $tipeLaporan->status . '_' . $permohonan->debiture->name . '_' . $cleanNomorLaporan;
|
||||
|
||||
return $pdf->download($filename . '_data.pdf');
|
||||
} catch (\Exception $e) {
|
||||
Log::error('PDF generation failed: ' . $e->getMessage());
|
||||
return response()->json(['error' => 'Failed to generate PDF. Please check the log for details.'], 500);
|
||||
}
|
||||
}
|
||||
|
||||
private function generatePDF(string $viewLaporan, array $data)
|
||||
{
|
||||
//return view('lpj::' . $viewLaporan, $data);
|
||||
|
||||
$pdf = PDF::loadView('lpj::' . $viewLaporan, $data);
|
||||
$pdf->setPaper('A4', 'portrait');
|
||||
$pdf->set_option('isHtml5ParserEnabled', true);
|
||||
$pdf->set_option('isPhpEnabled', true);
|
||||
|
||||
return $pdf;
|
||||
}
|
||||
|
||||
|
||||
private function getViewLaporan($tipe)
|
||||
{
|
||||
$viewMap = [
|
||||
'sederhana' => 'penilai.components.print-out-sederhana',
|
||||
'standar' => 'penilai.components.print-out-standar',
|
||||
'resume' => 'penilai.components.print-resume',
|
||||
'memo' => 'penilai.components.print-memo',
|
||||
'rap' => 'penilai.components.print-out-rap',
|
||||
'call-report' => 'penilai.components.print-out-call-report'
|
||||
];
|
||||
return $viewMap[$tipe] ?? 'penilai.components.print-resume';
|
||||
}
|
||||
|
||||
public function checkPrintOutLaporan($permohonan_id, $dokumen_id)
|
||||
{
|
||||
|
||||
// Ambil data berdasarkan ID
|
||||
$statusLpj = Penilai::where('permohonan_id', $permohonan_id)
|
||||
//->where('dokument_id', $dokumen_id)
|
||||
->first();
|
||||
|
||||
|
||||
$permohonan = Permohonan::where('id', $permohonan_id)->first();
|
||||
|
||||
// Jika data tidak ditemukan, kembalikan status null
|
||||
if (!$statusLpj) {
|
||||
return response()->json(['status' => null]);
|
||||
}
|
||||
|
||||
// Tentukan tipe berdasarkan kondisi
|
||||
$type = $statusLpj->type_penilai ?? null;
|
||||
|
||||
if ($type === 'memo' && $permohonan->is_mig!=1) {
|
||||
return $this->checkDataMemo($type, $statusLpj);
|
||||
}
|
||||
|
||||
if ($type === 'resume') {
|
||||
return $this->checkDataResume($type, $statusLpj);
|
||||
}
|
||||
|
||||
|
||||
if ($type === 'standar' || $type === 'sederhana') {
|
||||
return $this->checkDataLpj($type, $statusLpj);
|
||||
}
|
||||
|
||||
if ($type === 'rap') {
|
||||
return $this->checkDataRap($type, $statusLpj);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Kembalikan respons dengan tipe yang sesuai
|
||||
return response()->json(['status' => $type]);
|
||||
}
|
||||
|
||||
public function checkDataMemo($type, $statusLpj)
|
||||
{
|
||||
// Ambil data JSON dari statusLpj
|
||||
$data = json_decode($statusLpj->memo, true) ?? [];
|
||||
|
||||
|
||||
$validationRules = [
|
||||
'memo' => [
|
||||
'kepada',
|
||||
'dari',
|
||||
'nomor_memo',
|
||||
'tanggal',
|
||||
'perihal',
|
||||
'jenis_asset_tidak_sesuai',
|
||||
'lokasi.lokasi',
|
||||
'lokasi.province_code',
|
||||
'lokasi.city_code',
|
||||
'lokasi.district_code',
|
||||
'lokasi.village_code',
|
||||
'lokasi.penilai',
|
||||
'terlampir',
|
||||
'hasil_survey',
|
||||
'kesimpulan_saran',
|
||||
],
|
||||
];
|
||||
|
||||
// Validasi data JSON
|
||||
if (isset($validationRules[$type])) {
|
||||
$missingFields = [];
|
||||
|
||||
foreach ($validationRules[$type] as $field) {
|
||||
$keys = explode('.', $field);
|
||||
$value = $data;
|
||||
|
||||
foreach ($keys as $key) {
|
||||
if (!isset($value[$key])) {
|
||||
$missingFields[] = $field;
|
||||
break;
|
||||
}
|
||||
$value = $value[$key];
|
||||
}
|
||||
}
|
||||
|
||||
// Jika ada field yang kosong, kembalikan error
|
||||
if (!empty($missingFields)) {
|
||||
return response()->json([
|
||||
'status' => null,
|
||||
'message' => "Silahkan lengkapi data memo terlebih dahulu.",
|
||||
'missing_fields' => $missingFields,
|
||||
], 400);
|
||||
}
|
||||
}
|
||||
|
||||
// Jika data valid
|
||||
return response()->json([
|
||||
'status' => $type,
|
||||
'message' => "Data memo valid.",
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public function checkDataResume($type, $statusLpj)
|
||||
{
|
||||
// Ambil data JSON dari statusLpj
|
||||
$data = json_decode($statusLpj->resume, true) ?? [];
|
||||
|
||||
$validationRules = [
|
||||
'resume' => [
|
||||
'fisik'
|
||||
],
|
||||
];
|
||||
|
||||
// Validasi data JSON
|
||||
if (isset($validationRules[$type])) {
|
||||
$missingFields = [];
|
||||
|
||||
foreach ($validationRules[$type] as $field) {
|
||||
$keys = explode('.', $field);
|
||||
$value = $data;
|
||||
|
||||
foreach ($keys as $key) {
|
||||
if (!isset($value[$key])) {
|
||||
$missingFields[] = $field;
|
||||
break;
|
||||
}
|
||||
$value = $value[$key];
|
||||
}
|
||||
|
||||
// Validasi khusus untuk array fisik dan sesuai_imb
|
||||
if ($field === 'fisik' || $field === 'sesuai_imb') {
|
||||
if (empty($value) || !is_array($value)) {
|
||||
$missingFields[] = $field;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Validasi struktur data di dalam array
|
||||
foreach ($value as $item) {
|
||||
$requiredKeys = ['sertifikat', 'luas_tanah', 'nilai'];
|
||||
foreach ($requiredKeys as $requiredKey) {
|
||||
if (!isset($item[$requiredKey])) {
|
||||
$missingFields[] = $field . '.' . $requiredKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Jika ada field yang kosong, kembalikan error
|
||||
if (!empty($missingFields)) {
|
||||
return response()->json([
|
||||
'status' => null,
|
||||
'message' => "Silahkan lengkapi data resume terlebih dahulu.",
|
||||
'missing_fields' => $missingFields,
|
||||
], 400);
|
||||
}
|
||||
}
|
||||
|
||||
// Jika data valid
|
||||
return response()->json([
|
||||
'status' => $type,
|
||||
'message' => "Data resume valid.",
|
||||
]);
|
||||
}
|
||||
|
||||
public function checkDataLpj($type, $statusLpj)
|
||||
{
|
||||
// Ambil data JSON dari statusLpj
|
||||
$data = json_decode($statusLpj->lpj, true) ?? [];
|
||||
|
||||
$validationRules = [
|
||||
'lpj' => [
|
||||
'luas_tanah',
|
||||
'nilai_tanah_1',
|
||||
'nilai_tanah_2',
|
||||
'luas_bangunan',
|
||||
'nilai_bangunan_1',
|
||||
'nilai_bangunan_2',
|
||||
'total_nilai_pasar_wajar',
|
||||
'likuidasi',
|
||||
'likuidasi_nilai_1',
|
||||
'likuidasi_nilai_2',
|
||||
'asuransi_luas_bangunan',
|
||||
'asuransi_nilai_1',
|
||||
'asuransi_nilai_2',
|
||||
'npw_tambahan'
|
||||
],
|
||||
];
|
||||
|
||||
// Validasi data JSON
|
||||
if (isset($validationRules[$type])) {
|
||||
$missingFields = [];
|
||||
|
||||
foreach ($validationRules[$type] as $field) {
|
||||
// Penanganan khusus untuk field yang boleh null
|
||||
if (in_array($field, ['sarana_pelengkap_penilai', 'nilai_sarana_pelengkap_1', 'nilai_sarana_pelengkap_2'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($data[$field])) {
|
||||
$missingFields[] = $field;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Validasi khusus untuk npw_tambahan
|
||||
if ($field === 'npw_tambahan' && is_array($data[$field])) {
|
||||
foreach ($data[$field] as $index => $item) {
|
||||
$requiredKeys = ['name', 'luas', 'nilai_1', 'nilai_2'];
|
||||
foreach ($requiredKeys as $key) {
|
||||
if (!isset($item[$key])) {
|
||||
$missingFields[] = "npw_tambahan[$index].$key";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Jika ada field yang kosong, kembalikan error
|
||||
if (!empty($missingFields)) {
|
||||
return response()->json([
|
||||
'status' => null,
|
||||
'message' => "Silahkan lengkapi data LPJ terlebih dahulu.",
|
||||
'missing_fields' => $missingFields,
|
||||
], 400);
|
||||
}
|
||||
}
|
||||
|
||||
// Jika data valid
|
||||
return response()->json([
|
||||
'status' => $type,
|
||||
'message' => "Data LPJ valid.",
|
||||
]);
|
||||
}
|
||||
|
||||
public function checkDataRap($type, $statusLpj)
|
||||
{
|
||||
// Ambil data JSON dari statusLpj
|
||||
$data = json_decode($statusLpj->rap, true) ?? [];
|
||||
|
||||
$requiredFields = [
|
||||
'dari',
|
||||
'kepada',
|
||||
'perihal',
|
||||
'tanggal',
|
||||
'nomor_rap'
|
||||
];
|
||||
|
||||
// Cek apakah ada field yang kosong
|
||||
$missingFields = [];
|
||||
foreach ($requiredFields as $field) {
|
||||
if (!isset($data[$field]) || empty($data[$field])) {
|
||||
$missingFields[] = $field;
|
||||
}
|
||||
}
|
||||
|
||||
// Jika ada field yang kosong, kembalikan error
|
||||
if (!empty($missingFields)) {
|
||||
return response()->json([
|
||||
'status' => null,
|
||||
'message' => "Silahkan lengkapi data RAP terlebih dahulu.",
|
||||
'missing_fields' => $missingFields
|
||||
], 400);
|
||||
}
|
||||
|
||||
// Jika semua data terisi
|
||||
return response()->json([
|
||||
'status' => $type,
|
||||
'message' => "Data RAP valid."
|
||||
]);
|
||||
}
|
||||
private function getPermohonanJaminanId($id, $dokumentId, $jaminanId)
|
||||
{
|
||||
return Permohonan::with([
|
||||
'user',
|
||||
'debiture.province',
|
||||
'debiture.city',
|
||||
'debiture.district',
|
||||
'debiture.village',
|
||||
'branch',
|
||||
'tujuanPenilaian',
|
||||
'penilaian',
|
||||
'penawaran',
|
||||
'debiture.documents' => function ($query) use ($dokumentId, $jaminanId) {
|
||||
$query->where('id', $dokumentId)
|
||||
->where('jenis_jaminan_id', $jaminanId);
|
||||
}
|
||||
])->findOrFail($id);
|
||||
}
|
||||
|
||||
public function getCommonData()
|
||||
{
|
||||
return [
|
||||
'branches' => Branch::all(),
|
||||
'bentukTanah' => BentukTanah::all(),
|
||||
'konturTanah' => KonturTanah::all(),
|
||||
'posisiKavling' => PosisiKavling::all(),
|
||||
'ketinggianTanah' => KetinggianTanah::all(),
|
||||
'kondisiFisikTanah' => KondisiFisikTanah::all(),
|
||||
'jenisBangunan' => JenisBangunan::all(),
|
||||
'kondisiBangunan' => KondisiBangunan::all(),
|
||||
'sifatBangunan' => SifatBangunan::all(),
|
||||
'spekKategoriBangunan' => SpekKategoritBangunan::all(),
|
||||
'spekBangunan' => SpekBangunan::all(),
|
||||
'saranaPelengkap' => SaranaPelengkap::all(),
|
||||
'arahMataAngin' => ArahMataAngin::all(),
|
||||
'lantai' => Lantai::all(),
|
||||
'viewUnit' => ViewUnit::all(),
|
||||
'golMasySekitar' => GolonganMasySekitar::all(),
|
||||
'tingkatKeramaian' => TingkatKeramaian::all(),
|
||||
'laluLintasLokasi' => LaluLintasLokasi::all(),
|
||||
'jenisPesawat' => JenisPesawat::all(),
|
||||
'modelAlatBerat' => ModelAlatBerat::all(),
|
||||
'jenisKapal' => JenisKapal::all(),
|
||||
'jenisKendaraan' => JenisKendaraan::all(),
|
||||
'terletakArea' => TerletakArea::all(),
|
||||
'posisiUnit' => PosisiUnit::all(),
|
||||
'bentukUnit' => BentukUnit::all(),
|
||||
'fasilitasObjek' => FasilitasObjek::all(),
|
||||
'merupakanDaerah' => MerupakanDaerah::all(),
|
||||
'jenisUnit' => JenisUnit::all(),
|
||||
'jenisJaminan' => JenisJaminan::all(),
|
||||
'hubCadeb' => HubunganPemilikJaminan::all(),
|
||||
'hubPenghuni' => HubunganPenghuniJaminan::all(),
|
||||
'perkerasanJalan' => PerkerasanJalan::all(),
|
||||
'terletakDiArea' => TerletakArea::all(),
|
||||
'tujuanPenilaian' => TujuanPenilaian::all(),
|
||||
'perizinan' => Perizinan::all(),
|
||||
'foto' => FotoObjekJaminan::all()
|
||||
];
|
||||
}
|
||||
|
||||
private const HEADERS = [
|
||||
'bentuk-tanah' => ['Bentuk Tanah', 'bentuk-tanah'],
|
||||
'kontur-tanah' => ['Kontur Tanah', 'kontur-tanah'],
|
||||
'posisi-kavling' => ['Posisi Kavling', 'posisi-kavling'],
|
||||
'ketinggian-tanah' => ['Ketinggian Tanah', 'ketinggian-tanah'],
|
||||
'kondisi-fisik-tanah' => ['Kondisi Fisik Tanah', 'kondisi-fisik-tanah'],
|
||||
'jenis-bangunan' => ['Jenis Bangunan', 'jenis-bangunan'],
|
||||
'kondisi-bangunan' => ['Kondisi Bangunan', 'kondisi-bangunan'],
|
||||
'sifat-bangunan' => ['Sifat Bangunan', 'sifat-bangunan'],
|
||||
'sarana-pelengkap' => ['Sarana Pelengkap', 'sarana-pelengkap'],
|
||||
'lalu-lintas-lokasi' => ['Lalu Lintas Depan Lokasi', 'lalu-lintas-lokasi'],
|
||||
'tingkat-keramaian' => ['Tingkat Keramaian', 'tingkat-keramaian'],
|
||||
'gol-mas-sekitar' => ['Golongan Masyarakat Sekitar', 'gol-mas-sekitar'],
|
||||
'spek-kategori-bangunan' => ['Spek Kategori Bangunan', 'spek-kategori-bangunan'],
|
||||
'spek-bangunan' => ['Spek Bangunan', 'spek-bangunan'],
|
||||
'lantai-unit' => ['Lantai Unit', 'lantai-unit'],
|
||||
'view-unit' => ['View Unit', 'view-unit'],
|
||||
'perkerasan-jalan' => ['Perkerasan jalan', 'perkerasan-jalan'],
|
||||
'jenis-pesawat' => ['Jenis pesawat', 'jenis-pesawat'],
|
||||
'model-alat-berat' => ['Model alat berat', 'model-alat-berat'],
|
||||
'jenis-kapal' => ['Jenis kapal', 'jenis-kapal'],
|
||||
'jenis-kendaraan' => ['Jenis kendaraan', 'jenis-kendaraan'],
|
||||
'jenis-unit' => ['Jenis unit', 'jenis-unit'],
|
||||
'terletak-area' => ['Terletak di Area', 'terletak-area'],
|
||||
'merupakan-daerah' => ['Merupakan Daerah', 'merupakan-daerah'],
|
||||
'posisi-unit' => ['Posisi unit', 'posisi-unit'],
|
||||
'bentuk-unit' => ['Bentuk unit', 'bentuk-unit'],
|
||||
'fasilitas-objek' => ['Fasilitas Umum Dekat Objek', 'fasilitas-objek'],
|
||||
'foto-objek-jaminan' => ['Foto Objek Jaminan', 'foto-objek-jaminan'],
|
||||
'perizinan' => ['Perizinan', 'perizinan'],
|
||||
];
|
||||
|
||||
}
|
||||
107
app/Services/TypeLaporanService.php
Normal file
107
app/Services/TypeLaporanService.php
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Services;
|
||||
|
||||
class TypeLaporanService
|
||||
{
|
||||
public function handleRequest($type, $permohonanId, $documentId, $jaminanId, $surveyorController)
|
||||
{
|
||||
$permohonan = $this->getPermohonanData($surveyorController, $permohonanId, $documentId, $jaminanId);
|
||||
|
||||
if ($permohonan->status == 'proses-laporan') {
|
||||
throw new \Exception('Masih dalam proses laporan');
|
||||
}
|
||||
|
||||
$nomorLaporan = $this->generateNomorLaporan($surveyorController, $permohonan, $documentId, $type);
|
||||
$inspeksi = $this->getInspeksi($permohonanId, $documentId);
|
||||
$this->updatePenilai($permohonanId, $documentId, $type);
|
||||
|
||||
$debitur = Debiture::find($permohonan->debiture_id);
|
||||
$forminspeksi = $inspeksi ? json_decode($inspeksi->data_form, true) : null;
|
||||
|
||||
$locationCodes = $this->getAlamatData($debitur, $forminspeksi);
|
||||
$locationData = $this->getLocationData(
|
||||
$locationCodes['provinceCode'],
|
||||
$locationCodes['cityCode'],
|
||||
$locationCodes['districtCode'],
|
||||
$forminspeksi
|
||||
);
|
||||
|
||||
return [
|
||||
'permohonan' => $permohonan,
|
||||
'nomorLaporan' => $nomorLaporan,
|
||||
'basicData' => $surveyorController->getCommonData(),
|
||||
'cities' => $locationData['cities'],
|
||||
'districts' => $locationData['districts'],
|
||||
'villages' => $locationData['villages'],
|
||||
'forminspeksi' => $forminspeksi,
|
||||
];
|
||||
}
|
||||
|
||||
private function getPermohonanData($surveyorController, $permohonanId, $documentId, $jaminanId)
|
||||
{
|
||||
return $surveyorController->getPermohonanData($permohonanId, $documentId, $jaminanId);
|
||||
}
|
||||
|
||||
private function generateNomorLaporan($surveyorController, $permohonan, $documentId, $type)
|
||||
{
|
||||
return $surveyorController->generateNomorLaporan($permohonan, $documentId, $type);
|
||||
}
|
||||
|
||||
private function getInspeksi($permohonanId, $documentId)
|
||||
{
|
||||
return Inspeksi::where('permohonan_id', $permohonanId)
|
||||
->where('document_id', $documentId)
|
||||
->first();
|
||||
}
|
||||
|
||||
private function updatePenilai($permohonanId, $documentId, $type)
|
||||
{
|
||||
// Logika untuk memperbarui data berdasarkan tipe laporan
|
||||
}
|
||||
|
||||
private function getAlamatData($debitur, $forminspeksi)
|
||||
{
|
||||
return [
|
||||
'provinceCode' => $debitur->province_id ?? $forminspeksi['province'],
|
||||
'cityCode' => $debitur->city_id ?? $forminspeksi['city'],
|
||||
'districtCode' => $debitur->district_id ?? $forminspeksi['district'],
|
||||
];
|
||||
}
|
||||
|
||||
private function getLocationData($provinceCode, $cityCode, $districtCode, $forminspeksi)
|
||||
{
|
||||
return [
|
||||
'cities' => $this->fetchCityData($provinceCode),
|
||||
'districts' => $this->fetchDistrictData($cityCode),
|
||||
'villages' => $this->fetchVillageData($districtCode),
|
||||
];
|
||||
}
|
||||
|
||||
private function fetchCityData($provinceCode)
|
||||
{
|
||||
return City::where('province_code', $provinceCode)->get();
|
||||
}
|
||||
private function fetchDistrictData($cityCode)
|
||||
{
|
||||
return District::where('city_code', $cityCode)->get();
|
||||
}
|
||||
private function fetchVillageData($districtCode)
|
||||
{
|
||||
return Village::where('district_code', $districtCode)->get();
|
||||
}
|
||||
|
||||
private function updateOrCreatePenilai($permohonan_id, $document_id, $type, $data)
|
||||
{
|
||||
return Penilai::updateOrCreate(
|
||||
[
|
||||
'permohonan_id' => $permohonan_id,
|
||||
'dokument_id' => $document_id,
|
||||
|
||||
],
|
||||
[
|
||||
$type => json_encode($data),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -2,62 +2,4 @@
|
||||
|
||||
return [
|
||||
'name' => 'Lpj',
|
||||
'import' => [
|
||||
'slik' => [
|
||||
// Memory limit untuk import (dalam MB)
|
||||
'memory_limit' => env('SLIK_IMPORT_MEMORY_LIMIT', 1024),
|
||||
|
||||
// Ukuran chunk untuk processing (jumlah baris per chunk)
|
||||
'chunk_size' => env('SLIK_IMPORT_CHUNK_SIZE', 50),
|
||||
|
||||
// Ukuran batch untuk database insert
|
||||
'batch_size' => env('SLIK_IMPORT_BATCH_SIZE', 50),
|
||||
|
||||
// Timeout untuk import (dalam detik)
|
||||
'timeout' => env('SLIK_IMPORT_TIMEOUT', 1800), // 30 menit untuk file besar
|
||||
|
||||
// Maksimum file size yang diizinkan (dalam MB)
|
||||
'max_file_size' => env('SLIK_IMPORT_MAX_FILE_SIZE', 50),
|
||||
|
||||
// Enable garbage collection untuk optimasi memory
|
||||
'enable_gc' => env('SLIK_IMPORT_ENABLE_GC', true),
|
||||
|
||||
// Enable progress logging
|
||||
'enable_progress_logging' => env('SLIK_IMPORT_ENABLE_PROGRESS_LOGGING', true),
|
||||
|
||||
// Enable detailed error logging
|
||||
'enable_error_logging' => env('SLIK_IMPORT_ENABLE_ERROR_LOGGING', true),
|
||||
|
||||
// XML Scanner settings untuk optimasi memory
|
||||
'xml_scanner' => [
|
||||
'timeout' => env('SLIK_XML_SCANNER_TIMEOUT', 1800), // 30 menit
|
||||
'memory_limit' => env('SLIK_XML_SCANNER_MEMORY_LIMIT', 1024), // 1GB
|
||||
'chunk_size' => env('SLIK_XML_SCANNER_CHUNK_SIZE', 50), // Lebih kecil untuk XML
|
||||
],
|
||||
|
||||
// Queue processing untuk file besar
|
||||
'queue' => [
|
||||
'enabled' => env('SLIK_IMPORT_QUEUE_ENABLED', false),
|
||||
'connection' => env('SLIK_IMPORT_QUEUE_CONNECTION', 'database'),
|
||||
'queue_name' => env('SLIK_IMPORT_QUEUE_NAME', 'imports'),
|
||||
'chunk_size' => env('SLIK_IMPORT_QUEUE_CHUNK_SIZE', 500),
|
||||
],
|
||||
|
||||
// Progress tracking
|
||||
'progress' => [
|
||||
'enabled' => env('SLIK_IMPORT_PROGRESS_ENABLED', true),
|
||||
'update_interval' => env('SLIK_IMPORT_PROGRESS_INTERVAL', 50), // update setiap 50 baris
|
||||
'cache_key' => 'slik_import_progress',
|
||||
'cache_ttl' => 3600, // 1 jam
|
||||
],
|
||||
],
|
||||
|
||||
// General import settings
|
||||
'general' => [
|
||||
'default_memory_limit' => env('IMPORT_DEFAULT_MEMORY_LIMIT', 128),
|
||||
'max_execution_time' => env('IMPORT_MAX_EXECUTION_TIME', 300000),
|
||||
'temp_directory' => env('IMPORT_TEMP_DIRECTORY', storage_path('app/temp')),
|
||||
'cleanup_temp_files' => env('IMPORT_CLEANUP_TEMP_FILES', true),
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class () extends Migration {
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('debitures', function (Blueprint $table) {
|
||||
// nullable
|
||||
$table->string('cif', 16)
|
||||
->nullable()
|
||||
->default('0000000000')
|
||||
->comment('asal data LPJ.PRM_DEBITUR.KODE_CIF. Pada KODE_CIF ada yang digitnya 16 => 3372040405810002')
|
||||
->change();
|
||||
$table->unsignedBigInteger('branch_id')->nullable()->change();
|
||||
$table->string('nomor_id', 50)->nullable()->change();
|
||||
|
||||
$table->unsignedBigInteger('mig_kd_debitur_seq')->nullable()->comment('asal data LPJ.PRM_DEBITUR.KD_DEBITUR_SEQ. Berguna untuk update debitur_id menggunakan KD_DEBITUR_SEQ nya');
|
||||
$table->timestamp('processed_at')->nullable();
|
||||
$table->char('is_mig', 1)->nullable()->comment('untuk menandakan row ini dari LPJ OLD');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('debitures', function (Blueprint $table) {
|
||||
// Kembalikan kolom branch_id agar tidak nullable (asumsi awal NOT NULL)
|
||||
$table->unsignedBigInteger('branch_id')->nullable(false)->change();
|
||||
|
||||
// Kembalikan kolom yang diubah nullable menjadi NOT NULL
|
||||
$table->string('cif', 10)->nullable(false)->change();
|
||||
$table->string('nomor_id', 50)->nullable(false)->change();
|
||||
|
||||
// Hapus kolom tambahan yang dibuat di up()
|
||||
$table->dropColumn([
|
||||
'mig_kd_debitur_seq',
|
||||
'mig_urut_seq_addr',
|
||||
'mig_urut_seq_comm',
|
||||
'processed_at',
|
||||
'is_mig'
|
||||
]);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class () extends Migration {
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('permohonan', function (Blueprint $table) {
|
||||
// nullable
|
||||
$table->unsignedBigInteger('branch_id')->nullable()->change();
|
||||
$table->unsignedBigInteger('user_id')->nullable()->change();
|
||||
|
||||
|
||||
$table->unsignedBigInteger('mig_kd_debitur_seq')->nullable()->comment('asal data LPJ.PRM_DEBITUR.KD_DEBITUR_SEQ. Berguna untuk update debitur_id menggunakan KD_DEBITUR_SEQ nya');
|
||||
$table->unsignedBigInteger('nomor_lpj')->nullable();
|
||||
$table->string('mig_nama_ao')->nullable();
|
||||
$table->char('is_mig', 1)->nullable()->comment('untuk menandakan row ini dari LPJ OLD');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('permohonan', function (Blueprint $table) {
|
||||
// Kembalikan kolom branch_id agar tidak nullable (asumsi awal NOT NULL)
|
||||
$table->unsignedBigInteger('branch_id')->nullable(false)->change();
|
||||
$table->unsignedBigInteger('user_id')->nullable(false)->change();
|
||||
|
||||
|
||||
|
||||
// Hapus kolom tambahan yang dibuat di up()
|
||||
$table->dropColumn([
|
||||
'mig_kd_debitur_seq',
|
||||
'nomor_lpj',
|
||||
'mig_nama_ao',
|
||||
'is_mig'
|
||||
]);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class () extends Migration {
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('dokumen_jaminan', function (Blueprint $table) {
|
||||
// nullable
|
||||
|
||||
$table->unsignedBigInteger('mig_kd_debitur_seq')->nullable()->comment('asal data LPJ.PRM_DEBITUR.KD_DEBITUR_SEQ. Berguna untuk update debitur_id menggunakan KD_DEBITUR_SEQ nya');
|
||||
$table->unsignedBigInteger('nomor_lpj')->nullable();
|
||||
$table->timestamp('processed_at')->nullable();
|
||||
$table->char('is_mig', 1)->nullable()->comment('untuk menandakan row ini dari LPJ OLD');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('dokumen_jaminan', function (Blueprint $table) {
|
||||
|
||||
|
||||
// Hapus kolom tambahan yang dibuat di up()
|
||||
$table->dropColumn([
|
||||
'nomor_lpj',
|
||||
'mig_kd_debitur_seq',
|
||||
'processed_at',
|
||||
'is_mig'
|
||||
]);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class () extends Migration {
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('pemilik_jaminan', function (Blueprint $table) {
|
||||
// nullable
|
||||
|
||||
$table->unsignedBigInteger('mig_kd_debitur_seq')->nullable()->comment('asal data LPJ.PRM_DEBITUR.KD_DEBITUR_SEQ. Berguna untuk update debitur_id menggunakan KD_DEBITUR_SEQ nya');
|
||||
$table->timestamp('processed_at')->nullable();
|
||||
$table->char('is_mig', 1)->nullable()->comment('untuk menandakan row ini dari LPJ OLD');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('pemilik_jaminan', function (Blueprint $table) {
|
||||
|
||||
|
||||
// Hapus kolom tambahan yang dibuat di up()
|
||||
$table->dropColumn([
|
||||
'mig_kd_debitur_seq',
|
||||
'processed_at',
|
||||
'is_mig'
|
||||
]);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('inspeksi', function (Blueprint $table) {
|
||||
$table->unsignedBigInteger('nomor_lpj')->nullable();
|
||||
$table->timestamp('processed_at')->nullable();
|
||||
$table->char('is_mig', 1)->nullable()->comment('untuk menandakan row ini dari LPJ OLD');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('inspeksi', function (Blueprint $table) {
|
||||
$table->dropColumn('nomor_lpj');
|
||||
$table->dropColumn('processed_at');
|
||||
$table->dropColumn('is_mig');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('penilai', function (Blueprint $table) {
|
||||
$table->unsignedBigInteger('nomor_lpj')->nullable();
|
||||
$table->timestamp('processed_at')->nullable();
|
||||
$table->char('is_mig', 1)->nullable()->comment('untuk menandakan row ini dari LPJ OLD');
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('penilai', function (Blueprint $table) {
|
||||
$table->dropColumn('nomor_lpj');
|
||||
$table->dropColumn('processed_at');
|
||||
$table->dropColumn('is_mig');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -1,36 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration {
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('noc', function (Blueprint $table) {
|
||||
// Field untuk informasi memo penyelesaian
|
||||
$table->string('memo_penyelesaian_number')->nullable()->after('memo_penyelesaian');
|
||||
$table->date('memo_penyelesaian_date')->nullable()->after('memo_penyelesaian_number');
|
||||
$table->date('memo_penyelesaian_payment_date')->nullable()->after('memo_penyelesaian_date');
|
||||
$table->timestamp('memo_penyelesaian_created_at')->nullable()->after('memo_penyelesaian_date');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('noc', function (Blueprint $table) {
|
||||
$table->dropColumn([
|
||||
'memo_penyelesaian_number',
|
||||
'memo_penyelesaian_date',
|
||||
'memo_penyelesaian_payment_date',
|
||||
'memo_penyelesaian_created_at'
|
||||
]);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('noc', function (Blueprint $table) {
|
||||
$table->decimal('total_pembukuan', 10, 2)->after('nominal_bayar');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('noc', function (Blueprint $table) {
|
||||
$table->dropColumn('total_pembukuan');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -1,44 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration {
|
||||
/**
|
||||
* Menjalankan migration untuk menambahkan field status pembayaran
|
||||
* Field yang ditambahkan: status_kurang_bayar, nominal_kurang_bayar,
|
||||
* status_lebih_bayar, nominal_lebih_bayar, bukti_pengembalian
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('noc', function (Blueprint $table) {
|
||||
// Field untuk status kurang bayar
|
||||
$table->boolean('status_kurang_bayar')->default(false)->after('status_bayar');
|
||||
$table->decimal('nominal_kurang_bayar', 15, 2)->nullable()->after('status_kurang_bayar');
|
||||
|
||||
// Field untuk status lebih bayar
|
||||
$table->boolean('status_lebih_bayar')->default(false)->after('nominal_kurang_bayar');
|
||||
$table->decimal('nominal_lebih_bayar', 15, 2)->nullable()->after('status_lebih_bayar');
|
||||
|
||||
// Field untuk bukti pengembalian jika lebih bayar
|
||||
$table->string('bukti_pengembalian')->nullable()->after('nominal_lebih_bayar');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Rollback migration
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('noc', function (Blueprint $table) {
|
||||
$table->dropColumn([
|
||||
'status_kurang_bayar',
|
||||
'nominal_kurang_bayar',
|
||||
'status_lebih_bayar',
|
||||
'nominal_lebih_bayar',
|
||||
'bukti_pengembalian'
|
||||
]);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -1,67 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration {
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('bucoks', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('no')->nullable(); // Nomor urut
|
||||
$table->string('tanggal')->nullable(); // Tanggal
|
||||
$table->string('bulan')->nullable(); // Bulan
|
||||
$table->string('tahun')->nullable(); // Tahun
|
||||
$table->string('tanggal_penuh')->nullable(); // Tanggal lengkap
|
||||
$table->string('nomor_categ')->nullable(); // Nomor kategori
|
||||
$table->string('coa_summary')->nullable(); // COA Summary
|
||||
$table->string('nomor_coa')->nullable(); // Nomor COA
|
||||
$table->string('nama_coa')->nullable(); // Nama COA
|
||||
$table->string('nomor_tiket')->unique(); // Nomor tiket (unique)
|
||||
$table->string('deskripsi')->nullable(); // Deskripsi
|
||||
$table->string('nominal')->nullable(); // Nominal
|
||||
$table->string('penyelesaian')->nullable(); // Penyelesaian
|
||||
$table->string('umur_aging')->nullable(); // Umur aging
|
||||
$table->string('cost_center')->nullable(); // Cost center
|
||||
$table->string('nama_sub_direktorat')->nullable(); // Nama sub direktorat
|
||||
$table->string('nama_direktorat_cabang')->nullable(); // Nama direktorat cabang
|
||||
$table->string('tanggal_penyelesaian')->nullable(); // Tanggal penyelesaian
|
||||
$table->string('nominal_penyelesaian')->nullable(); // Nominal penyelesaian
|
||||
$table->string('nominal_berjalan')->nullable(); // Nominal berjalan
|
||||
$table->string('amortisasi_berjalan')->nullable(); // Amortisasi berjalan
|
||||
$table->string('sistem_berjalan')->nullable(); // Sistem berjalan
|
||||
$table->string('lainnya_berjalan')->nullable(); // Lainnya berjalan
|
||||
$table->string('nominal_gantung')->nullable(); // Nominal gantung
|
||||
$table->string('aset_gantung')->nullable(); // Aset gantung
|
||||
$table->string('keterangan_gantung')->nullable(); // Keterangan gantung
|
||||
$table->string('lainnya_satu')->nullable(); // Lainnya satu
|
||||
$table->string('lainnya_dua')->nullable(); // Lainnya dua
|
||||
|
||||
// Standard Laravel fields
|
||||
$table->timestamps();
|
||||
$table->string('created_by')->nullable();
|
||||
$table->string('updated_by')->nullable();
|
||||
$table->string('deleted_by')->nullable();
|
||||
$table->softDeletes();
|
||||
|
||||
// Indexes untuk performa
|
||||
$table->index(['nomor_tiket']);
|
||||
$table->index(['tanggal']);
|
||||
$table->index(['tahun']);
|
||||
$table->index(['nomor_coa']);
|
||||
$table->index(['cost_center']);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('bucoks');
|
||||
}
|
||||
};
|
||||
@@ -1,59 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
* Menambahkan kolom nomor_tiket ke tabel persetujuan_penawaran
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('persetujuan_penawaran', function (Blueprint $table) {
|
||||
// Menambahkan kolom nomor_tiket setelah nomor_proposal_penawaran
|
||||
$table->string('nomor_tiket', 100)->nullable()->after('nomor_proposal_penawaran')
|
||||
->comment('Nomor tiket untuk tracking persetujuan penawaran');
|
||||
$table->string('nominal_kurang_bayar')->nullable()->after('nomor_proposal_penawaran');
|
||||
$table->string('bukti_ksl_kurang_bayar')->nullable()->after('nominal_kurang_bayar');
|
||||
|
||||
});
|
||||
|
||||
Schema::table('noc', function (Blueprint $table) {
|
||||
// Menambahkan kolom nomor_tiket setelah nomor_proposal_penawaran
|
||||
$table->string('nomor_tiket', 100)->nullable()->after('persetujuan_penawaran_id')
|
||||
->comment('Nomor tiket untuk tracking persetujuan penawaran');
|
||||
$table->string('nomor_rekening_lebih_bayar',20)->nullable()->after('nominal_lebih_bayar');
|
||||
$table->string('bukti_ksl_lebih_bayar')->nullable()->after('nomor_rekening_lebih_bayar');
|
||||
$table->string('bukti_ksl_kurang_bayar')->nullable()->after('bukti_ksl_lebih_bayar');
|
||||
$table->string('nominal_pelunasan')->nullable()->after('bukti_ksl_kurang_bayar');
|
||||
$table->string('debiture_id')->nullable()->after('persetujuan_penawaran_id');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
* Menghapus kolom nomor_tiket dari tabel persetujuan_penawaran
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('persetujuan_penawaran', function (Blueprint $table) {
|
||||
// Menghapus kolom nomor_tiket
|
||||
$table->dropColumn('nomor_tiket');
|
||||
$table->dropColumn('nominal_kurang_bayar');
|
||||
$table->dropColumn('bukti_ksl_kurang_bayar');
|
||||
});
|
||||
|
||||
Schema::table('noc', function (Blueprint $table) {
|
||||
// Menghapus kolom nomor_tiket
|
||||
$table->dropColumn('nomor_tiket');
|
||||
$table->dropColumn('nomor_rekening_lebih_bayar');
|
||||
$table->dropColumn('bukti_ksl_lebih_bayar');
|
||||
$table->dropColumn('bukti_ksl_kurang_bayar');
|
||||
$table->dropColumn('nominal_pelunasan');
|
||||
$table->dropColumn('debiture_id');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('noc', function (Blueprint $table) {
|
||||
$table->bigInteger('branch_id')->nullable()->after('debiture_id');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('noc', function (Blueprint $table) {
|
||||
$table->dropColumn('branch_id');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -1,88 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration {
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* Migration untuk membuat tabel sliks dengan semua field yang diperlukan
|
||||
* berdasarkan header Excel yang diberikan untuk import data SLIK
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('sliks', function (Blueprint $table) {
|
||||
$table->id();
|
||||
|
||||
// Field utama berdasarkan header Excel
|
||||
$table->string('sandi_bank')->nullable(); // Sandi Bank
|
||||
$table->string('tahun')->nullable(); // Tahun
|
||||
$table->string('bulan')->nullable(); // Bulan
|
||||
$table->string('flag_detail')->nullable(); // Flag Detail
|
||||
$table->string('kode_register_agunan')->nullable(); // Kode Register Agunan
|
||||
$table->string('no_rekening')->nullable(); // No Rekening
|
||||
$table->string('cif')->nullable(); // CIF
|
||||
$table->string('kolektibilitas')->nullable(); // Kolektibilitas
|
||||
$table->string('fasilitas')->nullable(); // Fasilitas
|
||||
$table->string('jenis_segmen_fasilitas')->nullable(); // Jenis Segmen Fasilitas
|
||||
$table->string('status_agunan')->nullable(); // Status Agunan
|
||||
$table->string('jenis_agunan')->nullable(); // Jenis Agunan
|
||||
$table->string('peringkat_agunan')->nullable(); // Peringkat Agunan
|
||||
$table->string('lembaga_pemeringkat')->nullable(); // Lembaga Pemeringkat
|
||||
$table->string('jenis_pengikatan')->nullable(); // Jenis Pengikatan
|
||||
$table->string('tanggal_pengikatan')->nullable(); // Tanggal Pengikatan
|
||||
$table->string('nama_pemilik_agunan')->nullable(); // Nama Pemilik Agunan
|
||||
$table->string('bukti_kepemilikan')->nullable(); // Bukti Kepemilikan
|
||||
$table->text('alamat_agunan')->nullable(); // Alamat Agunan
|
||||
$table->string('lokasi_agunan')->nullable(); // Lokasi Agunan
|
||||
$table->string('nilai_agunan')->nullable(); // Nilai Agunan
|
||||
$table->string('nilai_agunan_menurut_ljk')->nullable(); // Nilai Agunan Menurut LJK
|
||||
$table->string('tanggal_penilaian_ljk')->nullable(); // Tanggal Penilaian LJK
|
||||
$table->string('nilai_agunan_penilai_independen')->nullable(); // Nilai Agunan Penilai Independen
|
||||
$table->string('nama_penilai_independen')->nullable(); // Nama Penilai Independen
|
||||
$table->string('tanggal_penilaian_penilai_independen')->nullable(); // Tanggal Penilaian Penilai Independen
|
||||
$table->string('jumlah_hari_tunggakan')->nullable(); // Jumlah Hari Tunggakan
|
||||
$table->string('status_paripasu')->nullable(); // Status Paripasu
|
||||
$table->string('prosentase_paripasu')->nullable(); // Prosentase Paripasu
|
||||
$table->string('status_kredit_join')->nullable(); // Status Kredit Join
|
||||
$table->string('diasuransikan')->nullable(); // Diasuransikan
|
||||
$table->text('keterangan')->nullable(); // Keterangan
|
||||
$table->string('kantor_cabang')->nullable(); // Kantor Cabang
|
||||
$table->string('operasi_data')->nullable(); // Operasi Data
|
||||
$table->string('kode_cabang')->nullable(); // Kode Cabang
|
||||
$table->string('nama_debitur')->nullable(); // Nama Debitur
|
||||
$table->string('nama_cabang')->nullable(); // Nama Cabang
|
||||
$table->string('flag')->nullable(); // Flag
|
||||
|
||||
// Standard Laravel fields
|
||||
$table->timestamps();
|
||||
$table->string('created_by')->nullable();
|
||||
$table->string('updated_by')->nullable();
|
||||
$table->string('deleted_by')->nullable();
|
||||
$table->softDeletes();
|
||||
|
||||
// Indexes untuk performa query
|
||||
$table->index(['sandi_bank']);
|
||||
$table->index(['tahun']);
|
||||
$table->index(['bulan']);
|
||||
$table->index(['no_rekening']);
|
||||
$table->index(['cif']);
|
||||
$table->index(['kode_register_agunan']);
|
||||
$table->index(['nama_debitur']);
|
||||
$table->index(['kode_cabang']);
|
||||
$table->index(['created_at']);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* Menghapus tabel sliks jika migration di-rollback
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('sliks');
|
||||
}
|
||||
};
|
||||
@@ -1,84 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('laporan_slik', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('slik_id')->nullable();
|
||||
$table->string('sandi_bank', 10)->nullable();
|
||||
$table->string('kode_kantor', 10)->nullable();
|
||||
$table->string('kode_cabang', 10)->nullable();
|
||||
$table->string('tahun', 4)->nullable();
|
||||
$table->string('bulan', 2)->nullable();
|
||||
$table->string('no_rekening', 50)->nullable();
|
||||
$table->string('cif', 50)->nullable();
|
||||
$table->string('kode_jenis', 10)->nullable();
|
||||
$table->string('kode_jenis_ket', 100)->nullable();
|
||||
$table->string('kode_sifat', 10)->nullable();
|
||||
$table->string('kode_sifat_ket', 100)->nullable();
|
||||
$table->string('kode_valuta', 5)->nullable();
|
||||
$table->string('kode_valuta_ket', 50)->nullable();
|
||||
$table->string('baki_debet', 20)->nullable();
|
||||
$table->string('kolektibilitas', 5)->nullable();
|
||||
$table->string('kolektibilitas_ket', 50)->nullable();
|
||||
$table->string('tanggal_mulai', 10)->nullable();
|
||||
$table->string('tanggal_jatuh_tempo', 10)->nullable();
|
||||
$table->string('tanggal_selesai', 10)->nullable();
|
||||
$table->string('tanggal_restrukturisasi', 10)->nullable();
|
||||
$table->string('kode_sebab_macet', 10)->nullable();
|
||||
$table->string('kode_sebab_macet_ket', 100)->nullable();
|
||||
$table->string('tanggal_macet', 10)->nullable();
|
||||
$table->string('kode_kondisi', 10)->nullable();
|
||||
$table->string('kode_kondisi_ket', 100)->nullable();
|
||||
$table->string('tanggal_kondisi', 10)->nullable();
|
||||
$table->string('nilai_agunan', 20)->nullable();
|
||||
$table->string('nilai_agunan_ket', 100)->nullable();
|
||||
$table->string('jenis_agunan', 50)->nullable();
|
||||
$table->string('kode_agunan', 10)->nullable();
|
||||
$table->string('kode_agunan_ket', 100)->nullable();
|
||||
$table->string('peringkat_agunan', 10)->nullable();
|
||||
$table->string('peringkat_agunan_ket', 100)->nullable();
|
||||
$table->string('nama_debitur', 100)->nullable();
|
||||
$table->string('npwp', 50)->nullable();
|
||||
$table->string('no_ktp', 50)->nullable();
|
||||
$table->string('no_telp', 50)->nullable();
|
||||
$table->string('kode_kab_kota', 10)->nullable();
|
||||
$table->string('kode_kab_kota_ket', 100)->nullable();
|
||||
$table->string('kode_negara_domisili', 10)->nullable();
|
||||
$table->string('kode_negara_domisili_ket', 100)->nullable();
|
||||
$table->string('kode_pos', 10)->nullable();
|
||||
$table->string('alamat', 200)->nullable();
|
||||
$table->string('fasilitas', 100)->nullable();
|
||||
$table->string('status_agunan', 20)->nullable();
|
||||
$table->string('tanggal_lapor', 10)->nullable();
|
||||
$table->string('status', 20)->default('aktif');
|
||||
$table->unsignedBigInteger('created_by')->nullable();
|
||||
$table->unsignedBigInteger('updated_by')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->index('slik_id');
|
||||
$table->index('no_rekening');
|
||||
$table->index('cif');
|
||||
$table->index('nama_debitur');
|
||||
$table->index(['tahun', 'bulan']);
|
||||
$table->index('created_at');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('laporan_slik');
|
||||
}
|
||||
};
|
||||
@@ -13,24 +13,25 @@ class HubunganPemilikJaminanSeeder extends Seeder
|
||||
public function run(): void
|
||||
{
|
||||
$hubungan_pemilik_jaminan = [
|
||||
[
|
||||
'name' => 'Milik Pribadi'
|
||||
],
|
||||
[
|
||||
'name' => 'Suami/Istri'
|
||||
],
|
||||
[
|
||||
'name' => 'Anak'
|
||||
],
|
||||
[
|
||||
'name' => 'Saudara Kandung'
|
||||
],
|
||||
[
|
||||
'name' => 'Ayah'
|
||||
],
|
||||
[
|
||||
'name' => 'Ibu'
|
||||
]
|
||||
['name' => 'Milik Pribadi'],
|
||||
['name' => 'Suami'],
|
||||
['name' => 'Anak'],
|
||||
['name' => 'Saudara'],
|
||||
['name' => 'Ayah'],
|
||||
['name' => 'Ibu'],
|
||||
['name' => 'Nenek'],
|
||||
['name' => 'Penjual/Developer'],
|
||||
[ 'name' => 'Kakak/adik kandung'],
|
||||
[ 'name' => 'Orang tua'],
|
||||
[ 'name' => 'Mitra Usaha'],
|
||||
[ 'name' => 'Pihak lain'],
|
||||
[ 'name' => 'Negara'],
|
||||
[ 'name' => 'Nenek/kakek'],
|
||||
[ 'name' => 'Milik Keluarga'],
|
||||
[ 'name' => 'Kakak/adik Orangtua'],
|
||||
[ 'name' => 'Istri'],
|
||||
[ 'name' => 'Pengurus'],
|
||||
[ 'name' => 'Lain - lain'],
|
||||
];
|
||||
|
||||
foreach ($hubungan_pemilik_jaminan as $hpj) {
|
||||
|
||||
@@ -69,6 +69,49 @@ class JenisFasilitasKreditSeeder extends Seeder
|
||||
'created_at' => now(),
|
||||
'updated_at' => now()
|
||||
],
|
||||
[
|
||||
'code' => 'JFK009',
|
||||
'name' => 'UMKM',
|
||||
'status' => 1,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now()
|
||||
],
|
||||
[
|
||||
'code' => 'JFK010',
|
||||
'name' => 'KORPORASI',
|
||||
'status' => 1,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now()
|
||||
],
|
||||
[
|
||||
'code' => 'JFK011',
|
||||
'name' => 'KPR 2',
|
||||
'status' => 1,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now()
|
||||
],
|
||||
[
|
||||
'code' => 'JFK012',
|
||||
'name' => 'KONSUMER',
|
||||
'status' => 1,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now()
|
||||
],
|
||||
[
|
||||
'code' => 'JFK013',
|
||||
'name' => 'KOMERSIL',
|
||||
'status' => 1,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now()
|
||||
],
|
||||
[
|
||||
'code' => 'JFK014',
|
||||
'name' => 'KPR REGULER',
|
||||
'status' => 1,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now()
|
||||
],
|
||||
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,36 +12,50 @@ class LpjDatabaseSeeder extends Seeder
|
||||
public function run(): void
|
||||
{
|
||||
$this->call([
|
||||
BranchSeeder::class,
|
||||
CurrencySeeder::class,
|
||||
HolidayCalendarSeeder::class,
|
||||
JenisFasilitasKreditSeeder::class,
|
||||
JenisLegalitasJaminanSeeder::class,
|
||||
JenisJaminanSeeder::class,
|
||||
JenisDokumenSeeder::class,
|
||||
TujuanPenilaianSeeder::class,
|
||||
NilaiPlatformSeeder::class,
|
||||
HubunganPemilikJaminanSeeder::class,
|
||||
HubunganPenghuniJaminanSeeder::class,
|
||||
ArahMataAnginSeeder::class,
|
||||
StatusPermohonanSeeder::class,
|
||||
RegionSeeder::class,
|
||||
TeamsSeeder::class,
|
||||
TeamUsersSeeder::class,
|
||||
JenisPenilaianSeeder::class,
|
||||
IjinUsahaSeeder::class,
|
||||
TujuanPenilaianKJPPSeeder::class,
|
||||
KJPPSeeder::class,
|
||||
JenisLaporanSeeder::class,
|
||||
DebitureSeeder::class,
|
||||
PemilikJaminanSeeder::class,
|
||||
DokumenJaminanSeeder::class,
|
||||
DetailDokumenJaminanSeeder::class,
|
||||
PermohonanSeeder::class,
|
||||
FotoObjekJaminanSeeder::class,
|
||||
|
||||
// BranchSeeder::class,
|
||||
// CurrencySeeder::class,
|
||||
// HolidayCalendarSeeder::class,
|
||||
// JenisFasilitasKreditSeeder::class,
|
||||
// JenisLegalitasJaminanSeeder::class,
|
||||
// JenisJaminanSeeder::class,
|
||||
// JenisDokumenSeeder::class,
|
||||
// TujuanPenilaianSeeder::class,
|
||||
// NilaiPlatformSeeder::class,
|
||||
// HubunganPemilikJaminanSeeder::class,
|
||||
// HubunganPenghuniJaminanSeeder::class,
|
||||
// ArahMataAnginSeeder::class,
|
||||
// StatusPermohonanSeeder::class,
|
||||
// RegionSeeder::class,
|
||||
// TeamsSeeder::class,
|
||||
// TeamUsersSeeder::class,
|
||||
// MasterDataSurveyorSeeder::class
|
||||
// JenisPenilaianSeeder::class,
|
||||
// IjinUsahaSeeder::class,
|
||||
// TujuanPenilaianKJPPSeeder::class,
|
||||
// KJPPSeeder::class,
|
||||
// JenisLaporanSeeder::class,
|
||||
// DebitureSeeder::class,
|
||||
// PemilikJaminanSeeder::class,
|
||||
// DokumenJaminanSeeder::class,
|
||||
// DetailDokumenJaminanSeeder::class,
|
||||
// PermohonanSeeder::class,
|
||||
// FotoObjekJaminanSeeder::class,
|
||||
// PenawaranSeeder::class,
|
||||
// DetailPenawaranSeeder::class,
|
||||
// PenilaianSeeder::class,
|
||||
// MigrationDebitureSeeder::class,
|
||||
// MigrationPermohonanSeeder::class,
|
||||
// MigrationDokumentJaminanSeeder::class,
|
||||
// MigrationDetailDokumenJaminanSeeder::class,
|
||||
// MigPenilaianAndPenilainTeamSeeder::class,
|
||||
// MigrationInpseksiSeeder::class,
|
||||
MigrationGambarInspeksiSeeder::class,
|
||||
// MigrationPembandingSeeder::class,
|
||||
// MigrationPenilaiSeeder::class
|
||||
|
||||
// ini untuk penilaian external
|
||||
// MigExternalPenawaranSeeder::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
45
database/seeders/MasterDataSurveyorSeeder.php
Normal file
45
database/seeders/MasterDataSurveyorSeeder.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class MasterDataSurveyorSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
|
||||
$nameTable = [
|
||||
'fasilitas_objek',
|
||||
'gol_mas_sekitar',
|
||||
'jenis_bangunan',
|
||||
'jenis_kapal',
|
||||
'jenis_kendaraan',
|
||||
'jenis_pesawat',
|
||||
'kondisi_bangunan',
|
||||
'kondisi_fisik_tanah',
|
||||
'kontur_tanah',
|
||||
'lalu_lintas_lokasi',
|
||||
'lantai',
|
||||
'merupakan_daerah',
|
||||
'perkerasan_jalan',
|
||||
'sifat_bangunan',
|
||||
'model_alat_berat',
|
||||
'posisi_kavling',
|
||||
'posisi_unit',
|
||||
'tingkat_keramaian',
|
||||
'sarana_pelengkap',
|
||||
'spek_kategori_bangunan',
|
||||
'spek_bangunan',
|
||||
'terletak_diarea',
|
||||
'view_unit'
|
||||
];
|
||||
|
||||
foreach ($nameTable as $table) {
|
||||
DB::unprepared(file_get_contents(__DIR__ . '/sql/' . $table . '.sql'));
|
||||
}
|
||||
}
|
||||
}
|
||||
306
database/seeders/MigExternalPenawaranSeeder.php
Normal file
306
database/seeders/MigExternalPenawaranSeeder.php
Normal file
@@ -0,0 +1,306 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Modules\Lpj\Models\Permohonan;
|
||||
use Modules\Lpj\Models\PenawaranTender;
|
||||
use Modules\Usermanagement\Models\User;
|
||||
use Modules\Lpj\Models\Penilaian;
|
||||
use Modules\Lpj\Models\PenilaianTeam;
|
||||
|
||||
class MigExternalPenawaranSeeder extends Seeder
|
||||
{
|
||||
protected $errorLogFile = __DIR__ . '/csv/penawaran/mig_penawaran_external_error.csv';
|
||||
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
// Bersihkan/Inisialisasi file error log
|
||||
$this->initializeErrorLog();
|
||||
// Path ke file csv
|
||||
$filePath = realpath(__DIR__ . '/csv/penawaran/mig_penawaran_external.csv');
|
||||
|
||||
if (!$filePath) {
|
||||
Log::error('File csv tidak ditemukan: ' . __DIR__ . '/csv/permohonan/mig_penawaran_external.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; // Ukuran batch
|
||||
$userDataChace = [];
|
||||
$nomorRegisCahce = [];
|
||||
$errorCount = 0; // Inisialisasi variabel errorCount
|
||||
$errorDebitureIds = []; // Inisialisasi array errorDebitureIds
|
||||
$totalData = 0;
|
||||
|
||||
// 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;
|
||||
|
||||
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++;
|
||||
|
||||
// Jika sudah mencapai batch size, proses batch
|
||||
if (count($rows) >= $batchSize) {
|
||||
$batchCount++;
|
||||
$this->command->info("Memproses batch ke-{$batchCount} ({$currentRow}/{$totalData})");
|
||||
$this->processBatch($rows, $nomorRegisCahce, $userDataChace, $errorCount, $errorDebitureIds, $totalData, $batchCount, $currentRow);
|
||||
$rows = [];
|
||||
}
|
||||
}
|
||||
|
||||
// Proses sisa data jika ada
|
||||
// print_r($rows[0]);
|
||||
if (!empty($rows)) {
|
||||
$batchCount++;
|
||||
$this->command->info("Memproses batch ke-{$batchCount} ({$currentRow}/{$totalData})");
|
||||
$this->processBatch($rows, $nomorRegisCahce, $userDataChace, $errorCount, $errorDebitureIds, $totalData, $batchCount, $currentRow);
|
||||
}
|
||||
|
||||
fclose($handle);
|
||||
|
||||
$this->command->info("Data debiture berhasil dimigrasikan. Total data: {$totalData}, Total batch: {$batchCount}, Total error: {$errorCount}");
|
||||
}
|
||||
|
||||
|
||||
private function processBatch(
|
||||
array $rows,
|
||||
array &$userDataChace,
|
||||
array &$nomorRegisCahce,
|
||||
int &$errorCount,
|
||||
array &$errorDebitureIds,
|
||||
int $totalData,
|
||||
int $batchCount,
|
||||
int $currentRow
|
||||
) {
|
||||
$userData = [];
|
||||
foreach ($rows as $index => $row) {
|
||||
try {
|
||||
// Jalankan setiap baris dengan transaksi sendiri
|
||||
DB::beginTransaction();
|
||||
|
||||
// Cek apakah sudah diproses
|
||||
$existingRecord = PenawaranTender::where('nomor_registrasi', $row['mig_nomor_jaminan'])->first();
|
||||
if ($existingRecord && $existingRecord->created_at) {
|
||||
$this->command->info('Data sudah diproses sebelumnya: ' . $row['mig_nomor_jaminan']);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ambil nomor registrasi
|
||||
$nomor_registrasi = $this->getNomorRegistrasiPermohonan($row['mig_nomor_jaminan'], $nomorRegisCahce);
|
||||
if (!$nomor_registrasi) {
|
||||
throw new \Exception("Nomor registrasi tidak valid");
|
||||
}
|
||||
|
||||
|
||||
$userIdUpdate = $this->getUserIdData($row['mig_created_by'] ?? null, $userData)['id'];
|
||||
$userIdOtorisasi = $this->getUserIdData($row['mig_authorized_by'] ?? null, $userData)['id'];
|
||||
|
||||
if (!$userIdUpdate || !$userIdOtorisasi) {
|
||||
// $this->logError($userIdUpdate, 'Salah satu user tidak ditemukan');
|
||||
continue;
|
||||
}
|
||||
|
||||
// Mapping field user
|
||||
$mapUser = [
|
||||
'created_by' => $userIdUpdate,
|
||||
'updated_by' => $userIdUpdate,
|
||||
'authorized_by' => $userIdOtorisasi,
|
||||
];
|
||||
|
||||
// create random code
|
||||
|
||||
$tgl = $this->parseTimestamp($row['mig_tgl_penyerahan']);
|
||||
|
||||
// ambil nilai tahun terakhir contoh 2023 maka ambil 23
|
||||
$year = date('y', strtotime($tgl));
|
||||
|
||||
// random code berdasarkan tgl contoh NP2300001
|
||||
|
||||
$code = 'NP' . $year . str_pad(rand(1, 99999), 5, '0', STR_PAD_LEFT); // outputnya NP2300001:
|
||||
// Cek apakah kode sudah ada
|
||||
$existingCode = PenawaranTender::where('code', $code)->first();
|
||||
if ($existingCode) {
|
||||
$code = 'NP' . $year . str_pad(rand(1, 99999), 5, '0', STR_PAD_LEFT);
|
||||
}
|
||||
|
||||
|
||||
// Buat penilaian
|
||||
$penilaian = PenawaranTender::create([
|
||||
'code' => $code,
|
||||
'nama_kjpp_sebelumnya' => $row['mig_nama_kjpp'],
|
||||
'biaya_kjpp_sebelumnya' => $row['mig_tot_jasa'],
|
||||
'tanggal_penilaian_sebelumnya' => $this->parseTimestamp($row['mig_tgl_penyerahan']),
|
||||
'nomor_registrasi' => $nomor_registrasi,
|
||||
'tujuan_penilaian_kjpp_id' => $this->checkTujuanPenilaian($row['mig_mst_jaminan_kd_tujuan_seq']),
|
||||
'jenis_laporan_id' => 1,
|
||||
'start_date' => $this->parseTimestamp($row['mig_tgl_penyerahan']),
|
||||
'end_date' => $this->parseTimestamp($row['mig_terima_laporan']),
|
||||
'catatan' => $row['mig_catatan'],
|
||||
'status' => 'spk',
|
||||
'created_at' => $this->parseTimestamp($row['mig_created_at']),
|
||||
'updated_at' => $this->parseTimestamp($row['mig_updated_at']),
|
||||
'authorized_by' => $mapUser['authorized_by'],
|
||||
'created_by' => $mapUser['created_by'],
|
||||
'updated_by' => $mapUser['updated_by'],
|
||||
]);
|
||||
|
||||
|
||||
|
||||
// Commit transaksi
|
||||
DB::commit();
|
||||
$this->command->info('Proses data penilaian ' . $row['mig_nomor_jaminan'] . ' (' . ($index + 1) . '/' . count($rows) . ')');
|
||||
|
||||
} catch (\Exception $e) {
|
||||
// Rollback jika ada error
|
||||
DB::rollBack();
|
||||
|
||||
Log::error('Error pada baris: ' . json_encode($row) . '. Pesan: ' . $e->getMessage());
|
||||
$errorCount++;
|
||||
$errorDebitureIds[] = $row['mig_team_id'] ?? '-';
|
||||
$this->logError($row['mig_team_id'] ?? '-', $e->getMessage());
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$this->command->info("Batch {$batchCount} selesai. Total error: " . count($errorDebitureIds));
|
||||
}
|
||||
|
||||
|
||||
private function getNomorRegistrasiPermohonan($nomor_registrasi_id, $nomorRegisCahce)
|
||||
{
|
||||
if (isset($nomorRegisCahce[$nomor_registrasi_id])) {
|
||||
return $nomorRegisCahce[$nomor_registrasi_id];
|
||||
}
|
||||
|
||||
$nomorRegis = Permohonan::where('nomor_registrasi', $nomor_registrasi_id)->first();
|
||||
|
||||
if (!$nomorRegis) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$nomorRegisCahce[$nomor_registrasi_id] = $nomorRegis->nomor_registrasi;
|
||||
return $nomorRegis->nomor_registrasi;
|
||||
}
|
||||
|
||||
private function getUserIdData(?string $code, array &$cache): array
|
||||
{
|
||||
if (!$code) {
|
||||
return ['id' => null, 'branch_id' => null];
|
||||
}
|
||||
|
||||
if (isset($cache[$code])) {
|
||||
return $cache[$code];
|
||||
}
|
||||
|
||||
$user = User::where('nik', $code)->first();
|
||||
|
||||
if ($user) {
|
||||
$cache[$code] = ['id' => $user->id, 'branch_id' => $user->branch_id];
|
||||
return $cache[$code];
|
||||
}
|
||||
|
||||
return ['id' => null, 'branch_id' => null];
|
||||
}
|
||||
|
||||
private function getUserId($mig_user_id, $userDataChace)
|
||||
{
|
||||
if (isset($userDataChace[$mig_user_id])) {
|
||||
return $userDataChace[$mig_user_id];
|
||||
}
|
||||
|
||||
$userId = User::where('nik', $mig_user_id)->first();
|
||||
|
||||
if (!$userId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$userDataChace[$mig_user_id] = $userId->id;
|
||||
return $userId->id;
|
||||
}
|
||||
|
||||
private function parseTimestamp(?string $timestamp): ?string
|
||||
{
|
||||
try {
|
||||
if ($timestamp) {
|
||||
// Cek jika format hanya tanggal (Y-m-d)
|
||||
if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $timestamp)) {
|
||||
return \Carbon\Carbon::createFromFormat('Y-m-d', $timestamp)
|
||||
->startOfDay()
|
||||
->toDateTimeString();
|
||||
}
|
||||
// Format lengkap (Y-m-d H:i:s)
|
||||
return \Carbon\Carbon::createFromFormat('Y-m-d H:i:s', $timestamp)->toDateTimeString();
|
||||
}
|
||||
return null;
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memparsing timestamp: ' . $timestamp . '. Pesan: ' . $e->getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private function initializeErrorLog()
|
||||
{
|
||||
// Jika file lama ada, hapus
|
||||
if (file_exists($this->errorLogFile)) {
|
||||
unlink($this->errorLogFile);
|
||||
}
|
||||
|
||||
// Buat file baru dengan header
|
||||
$handle = fopen($this->errorLogFile, 'w');
|
||||
fputcsv($handle, ['mig_kd_debitur_seq', 'Error']);
|
||||
fclose($handle);
|
||||
}
|
||||
|
||||
private function logError(string $kode, string $message)
|
||||
{
|
||||
// Catat ke log
|
||||
Log::error("Error migrasi debiture [$kode]: $message");
|
||||
|
||||
// Tulis ke file error
|
||||
$handle = fopen($this->errorLogFile, 'a');
|
||||
fputcsv($handle, [$kode, $message]);
|
||||
fclose($handle);
|
||||
}
|
||||
|
||||
private function checkTujuanPenilaian($code): int
|
||||
{
|
||||
$mapping = [
|
||||
1 => 7,
|
||||
2 => 5,
|
||||
3 => 8,
|
||||
6 => 6,
|
||||
];
|
||||
|
||||
return $mapping[$code] ?? 7;
|
||||
}
|
||||
}
|
||||
1036
database/seeders/MigInspeksiHelper.php
Normal file
1036
database/seeders/MigInspeksiHelper.php
Normal file
File diff suppressed because it is too large
Load Diff
313
database/seeders/MigPenilaianAndPenilainTeamSeeder.php
Normal file
313
database/seeders/MigPenilaianAndPenilainTeamSeeder.php
Normal file
@@ -0,0 +1,313 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Modules\Basicdata\Models\Branch;
|
||||
use Modules\Lpj\Models\Penilaian;
|
||||
use Modules\Usermanagement\Models\User;
|
||||
use Modules\Lpj\Models\PenilaianTeam;
|
||||
use Modules\Lpj\Models\Permohonan;
|
||||
|
||||
class MigPenilaianAndPenilainTeamSeeder extends Seeder
|
||||
{
|
||||
protected $errorLogFile = __DIR__ . '/csv/penilaian/mig_penilaian_and_team_error.csv';
|
||||
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
// Bersihkan/Inisialisasi file error log
|
||||
$this->initializeErrorLog();
|
||||
// Path ke file csv
|
||||
$filePath = realpath(__DIR__ . '/csv/penilaian/mig_penilaian_and_team.csv');
|
||||
|
||||
if (!$filePath) {
|
||||
Log::error('File csv tidak ditemukan: ' . __DIR__ . '/csv/penilaian/mig_penilaian_and_team.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; // Ukuran batch
|
||||
$userDataChace = [];
|
||||
$nomorRegisCahce = [];
|
||||
$errorCount = 0; // Inisialisasi variabel errorCount
|
||||
$errorDebitureIds = []; // Inisialisasi array errorDebitureIds
|
||||
$totalData = 0;
|
||||
|
||||
// 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;
|
||||
|
||||
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++;
|
||||
|
||||
// Jika sudah mencapai batch size, proses batch
|
||||
if (count($rows) >= $batchSize) {
|
||||
$batchCount++;
|
||||
$this->command->info("Memproses batch ke-{$batchCount} ({$currentRow}/{$totalData})");
|
||||
$this->processBatch($rows, $nomorRegisCahce, $userDataChace, $errorCount, $errorDebitureIds, $totalData, $batchCount, $currentRow);
|
||||
$rows = [];
|
||||
}
|
||||
}
|
||||
|
||||
// Proses sisa data jika ada
|
||||
// print_r($rows[0]);
|
||||
if (!empty($rows)) {
|
||||
$batchCount++;
|
||||
$this->command->info("Memproses batch ke-{$batchCount} ({$currentRow}/{$totalData})");
|
||||
$this->processBatch($rows, $nomorRegisCahce, $userDataChace, $errorCount, $errorDebitureIds, $totalData, $batchCount, $currentRow);
|
||||
}
|
||||
|
||||
fclose($handle);
|
||||
|
||||
$this->command->info("Data debiture berhasil dimigrasikan. Total data: {$totalData}, Total batch: {$batchCount}, Total error: {$errorCount}");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private function processBatch(
|
||||
array $rows,
|
||||
array &$userDataChace,
|
||||
array &$nomorRegisCahce,
|
||||
int &$errorCount,
|
||||
array &$errorDebitureIds,
|
||||
int $totalData,
|
||||
int $batchCount,
|
||||
int $currentRow
|
||||
) {
|
||||
$userData = [];
|
||||
foreach ($rows as $index => $row) {
|
||||
try {
|
||||
// Jalankan setiap baris dengan transaksi sendiri
|
||||
DB::beginTransaction();
|
||||
|
||||
// Cek apakah sudah diproses
|
||||
$existingRecord = Penilaian::where('nomor_registrasi', $row['mig_nomor_registrasi'])->first();
|
||||
if ($existingRecord && $existingRecord->created_at) {
|
||||
$this->command->info('Data sudah diproses sebelumnya: ' . $row['mig_nomor_registrasi']);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ambil nomor registrasi
|
||||
$nomor_registrasi = $this->getNomorRegistrasiPermohonan($row['mig_nomor_registrasi'], $nomorRegisCahce);
|
||||
if (!$nomor_registrasi) {
|
||||
throw new \Exception("Nomor registrasi tidak valid");
|
||||
}
|
||||
|
||||
// Ambil user ID
|
||||
$userId = $this->getUserId($row['mig_user_id'], $userDataChace);
|
||||
if (!$userId) {
|
||||
// $this->logError($row['mig_user_id'], 'Salah satu user tidak ditemukan');
|
||||
throw new \Exception($row['mig_user_id'] . " User tidak ditemukan");
|
||||
continue;
|
||||
}
|
||||
|
||||
$userIdUpdate = $this->getUserIdData($row['mig_created_by'] ?? null, $userData)['id'];
|
||||
$userIdOtorisasi = $this->getUserIdData($row['mig_authorized_by'] ?? null, $userData)['id'];
|
||||
|
||||
if (!$userIdUpdate || !$userIdOtorisasi) {
|
||||
// $this->logError($userIdUpdate, 'Salah satu user tidak ditemukan');
|
||||
continue;
|
||||
}
|
||||
|
||||
// Mapping field user
|
||||
$mapUser = [
|
||||
'created_by' => $userIdUpdate,
|
||||
'updated_by' => $userIdUpdate,
|
||||
'authorized_by' => $userIdOtorisasi,
|
||||
];
|
||||
|
||||
// Ambil team ID
|
||||
$teamId = $this->checkTeams($row['mig_team_id']);
|
||||
if (!$teamId) {
|
||||
throw new \Exception("Team tidak ditemukan");
|
||||
}
|
||||
|
||||
// Buat penilaian
|
||||
$penilaian = Penilaian::create([
|
||||
'nomor_registrasi' => $nomor_registrasi,
|
||||
'jenis_penilaian_id' => 1,
|
||||
'tanggal_kunjungan' => $this->parseTimestamp($row['mig_tanggal_kunjungan']) ?? now(),
|
||||
'waktu_penilaian' => $this->parseTimestamp($row['mig_waktu_penilaian']),
|
||||
'status' => 'done',
|
||||
'keterangan' => null,
|
||||
'created_at' => $this->parseTimestamp($row['mig_created_at']),
|
||||
'updated_at' => $this->parseTimestamp($row['mig_updated_at']),
|
||||
'authorized_by' => $mapUser['authorized_by'],
|
||||
'created_by' => $mapUser['created_by'],
|
||||
'updated_by' => $mapUser['updated_by'],
|
||||
]);
|
||||
|
||||
// Buat tim penilaian
|
||||
$roles = ['surveyor', 'penilai'];
|
||||
foreach ($roles as $role) {
|
||||
PenilaianTeam::create([
|
||||
'penilaian_id' => $penilaian->id,
|
||||
'user_id' => $userId,
|
||||
'role' => $role,
|
||||
'team_id' => $teamId,
|
||||
'created_at' => $this->parseTimestamp($row['mig_created_at']),
|
||||
'updated_at' => $this->parseTimestamp($row['mig_updated_at']),
|
||||
]);
|
||||
}
|
||||
|
||||
// Commit transaksi
|
||||
DB::commit();
|
||||
$this->command->info('Proses data penilaian ' . $row['mig_nomor_lpj'] . ' (' . ($index + 1) . '/' . count($rows) . ')');
|
||||
|
||||
} catch (\Exception $e) {
|
||||
// Rollback jika ada error
|
||||
DB::rollBack();
|
||||
|
||||
Log::error('Error pada baris: ' . json_encode($row) . '. Pesan: ' . $e->getMessage());
|
||||
$errorCount++;
|
||||
$errorDebitureIds[] = $row['mig_team_id'] ?? '-';
|
||||
$this->logError($row['mig_team_id'] ?? '-', $e->getMessage());
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$this->command->info("Batch {$batchCount} selesai. Total error: " . count($errorDebitureIds));
|
||||
}
|
||||
|
||||
|
||||
private function getNomorRegistrasiPermohonan($nomor_registrasi_id, $nomorRegisCahce)
|
||||
{
|
||||
if (isset($nomorRegisCahce[$nomor_registrasi_id])) {
|
||||
return $nomorRegisCahce[$nomor_registrasi_id];
|
||||
}
|
||||
|
||||
$nomorRegis = Permohonan::where('nomor_registrasi', $nomor_registrasi_id)->first();
|
||||
|
||||
if (!$nomorRegis) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$nomorRegisCahce[$nomor_registrasi_id] = $nomorRegis->nomor_registrasi;
|
||||
return $nomorRegis->nomor_registrasi;
|
||||
}
|
||||
private function getUserIdData(?string $code, array &$cache): array
|
||||
{
|
||||
if (!$code) {
|
||||
return ['id' => null, 'branch_id' => null];
|
||||
}
|
||||
|
||||
if (isset($cache[$code])) {
|
||||
return $cache[$code];
|
||||
}
|
||||
|
||||
$user = User::where('nik', $code)->first();
|
||||
|
||||
if ($user) {
|
||||
$cache[$code] = ['id' => $user->id, 'branch_id' => $user->branch_id];
|
||||
return $cache[$code];
|
||||
}
|
||||
|
||||
return ['id' => null, 'branch_id' => null];
|
||||
}
|
||||
|
||||
private function getUserId($mig_user_id, $userDataChace)
|
||||
{
|
||||
if (isset($userDataChace[$mig_user_id])) {
|
||||
return $userDataChace[$mig_user_id];
|
||||
}
|
||||
|
||||
$userId = User::where('nik', $mig_user_id)->first();
|
||||
|
||||
if (!$userId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$userDataChace[$mig_user_id] = $userId->id;
|
||||
return $userId->id;
|
||||
}
|
||||
|
||||
private function checkTeams($code): int
|
||||
{
|
||||
$mapping = [
|
||||
'01' => 1,
|
||||
'02' => 2,
|
||||
'04' => 4,
|
||||
'07' => 5,
|
||||
'06' => 3,
|
||||
];
|
||||
return $mapping[(string)$code] ?? 1;
|
||||
}
|
||||
|
||||
|
||||
private function parseTimestamp(?string $timestamp): ?string
|
||||
{
|
||||
try {
|
||||
if ($timestamp) {
|
||||
// Cek jika format hanya tanggal (Y-m-d)
|
||||
if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $timestamp)) {
|
||||
return \Carbon\Carbon::createFromFormat('Y-m-d', $timestamp)
|
||||
->startOfDay()
|
||||
->toDateTimeString();
|
||||
}
|
||||
// Format lengkap (Y-m-d H:i:s)
|
||||
return \Carbon\Carbon::createFromFormat('Y-m-d H:i:s', $timestamp)->toDateTimeString();
|
||||
}
|
||||
return null;
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memparsing timestamp: ' . $timestamp . '. Pesan: ' . $e->getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private function initializeErrorLog()
|
||||
{
|
||||
// Jika file lama ada, hapus
|
||||
if (file_exists($this->errorLogFile)) {
|
||||
unlink($this->errorLogFile);
|
||||
}
|
||||
|
||||
// Buat file baru dengan header
|
||||
$handle = fopen($this->errorLogFile, 'w');
|
||||
fputcsv($handle, ['mig_kd_debitur_seq', 'Error']);
|
||||
fclose($handle);
|
||||
}
|
||||
|
||||
private function logError(string $kode, string $message)
|
||||
{
|
||||
// Catat ke log
|
||||
Log::error("Error migrasi debiture [$kode]: $message");
|
||||
|
||||
// Tulis ke file error
|
||||
$handle = fopen($this->errorLogFile, 'a');
|
||||
fputcsv($handle, [$kode, $message]);
|
||||
fclose($handle);
|
||||
}
|
||||
|
||||
}
|
||||
246
database/seeders/MigrationDebitureSeeder.php
Normal file
246
database/seeders/MigrationDebitureSeeder.php
Normal file
@@ -0,0 +1,246 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Modules\Basicdata\Models\Branch;
|
||||
use Modules\Lpj\Models\Debiture;
|
||||
use Modules\Usermanagement\Models\User;
|
||||
|
||||
|
||||
class MigrationDebitureSeeder extends Seeder
|
||||
{
|
||||
protected $errorLogFile = __DIR__ . '/csv/debitures/error_migration.csv';
|
||||
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
// Bersihkan/Inisialisasi file error log
|
||||
$this->initializeErrorLog();
|
||||
|
||||
// Path ke file csv
|
||||
$filePath = realpath(__DIR__ . '/csv/debitures/mig_debiture.csv');
|
||||
|
||||
if (!$filePath) {
|
||||
Log::error('File csv tidak ditemukan: ' . __DIR__ . '/csv/debitures/mig_debiture.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 = [];
|
||||
$totalData = 0;
|
||||
|
||||
// Hitung total baris
|
||||
while (($data = fgetcsv($handle, 0, '~')) !== false) {
|
||||
$totalData++;
|
||||
}
|
||||
|
||||
rewind($handle);
|
||||
fgetcsv($handle, 0, '~'); // Lewati header
|
||||
|
||||
$currentRow = 0;
|
||||
$batchCount = 0;
|
||||
|
||||
while (($data = fgetcsv($handle, 0, '~')) !== false) {
|
||||
if (count($data) != count($header)) {
|
||||
$this->logError($data[0] ?? '-', 'Jumlah kolom tidak sesuai');
|
||||
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);
|
||||
$rows = [];
|
||||
}
|
||||
}
|
||||
|
||||
// print_r($rows);
|
||||
if (!empty($rows)) {
|
||||
$batchCount++;
|
||||
$this->command->info("Memproses batch ke-{$batchCount} ({$currentRow}/{$totalData})");
|
||||
$this->processBatch($rows, $branchCache, $userData);
|
||||
}
|
||||
|
||||
fclose($handle);
|
||||
|
||||
$this->command->info("Data debiture berhasil dimigrasikan. Total data: {$totalData}, Total batch: {$batchCount}");
|
||||
}
|
||||
|
||||
private function processBatch(array $rows, array &$branchCache, array &$userData)
|
||||
{
|
||||
foreach ($rows as $index => $row) {
|
||||
try {
|
||||
$kode = $row['mig_kd_debitur_seq'] ?? '-';
|
||||
|
||||
// Cek apakah sudah diproses sebelumnya
|
||||
$existingRecord = Debiture::where('mig_kd_debitur_seq', $kode)->first();
|
||||
if ($existingRecord && $existingRecord->processed_at) {
|
||||
$this->command->info("Data sudah diproses sebelumnya: $kode");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ambil branch_id
|
||||
$branchId = $this->getBranchId($row['mig_kd_cabang'] ?? null, $branchCache);
|
||||
if (!$branchId) {
|
||||
$this->logError($kode, 'Cabang tidak ditemukan');
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ambil user IDs berdasarkan NIK
|
||||
$userIdUpdate = $this->getUserId($row['mig_user_update'] ?? null, $userData)['id'];
|
||||
$userIdOtorisasi = $this->getUserId($row['mig_user_oto'] ?? null, $userData)['id'];
|
||||
|
||||
// if (!$userIdUpdate || !$userIdOtorisasi) {
|
||||
// $this->logError($kode, 'Salah satu user tidak ditemukan');
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// Mapping field user
|
||||
$mapUser = [
|
||||
'created_by' => $userIdUpdate,
|
||||
'updated_by' => $userIdUpdate,
|
||||
'authorized_by' => $userIdOtorisasi,
|
||||
];
|
||||
|
||||
// Parsing nomor HP
|
||||
$nomorHp = !empty($row['mig_phone']) ? preg_replace('/[^0-9]/', '', $row['mig_phone']) : null;
|
||||
$email = !empty($row['email']) ? $row['email'] : null;
|
||||
$nomorId = !empty($row['nomor_id']) ? $row['nomor_id'] : null;
|
||||
|
||||
// Parsing waktu
|
||||
$authorizedAt = $this->parseTimestamp($row['mig_tgl_oto'] ?? null);
|
||||
$createdAt = $this->parseTimestamp($row['created_at'] ?? null);
|
||||
$updatedAt = $this->parseTimestamp($row['updated_at'] ?? null);
|
||||
|
||||
if (!$createdAt || !$updatedAt) {
|
||||
$this->logError($kode, 'Gagal parsing created_at / updated_at');
|
||||
continue;
|
||||
}
|
||||
|
||||
// Simpan data
|
||||
Debiture::create([
|
||||
'branch_id' => $branchId,
|
||||
'name' => $row['name'] ?? '',
|
||||
'cif' => $row['cif'] ?: '0000000000',
|
||||
'phone' => $nomorHp,
|
||||
'nomor_id' => $nomorId,
|
||||
'email' => $email,
|
||||
'npwp' => null,
|
||||
'address' => $row['address'] ?? null,
|
||||
'authorized_at' => $authorizedAt,
|
||||
'authorized_by' => $mapUser['authorized_by'],
|
||||
'created_by' => $mapUser['created_by'] ?? null,
|
||||
'updated_by' => $mapUser['updated_by'] ?? null,
|
||||
'created_at' => $createdAt,
|
||||
'updated_at' => $updatedAt,
|
||||
'mig_kd_debitur_seq' => $row['mig_kd_debitur_seq'],
|
||||
'processed_at' => now(),
|
||||
'is_mig' => 1
|
||||
]);
|
||||
|
||||
$this->command->info("Proses data debiture $kode (" . ($index + 1) . '/' . count($rows) . ')');
|
||||
|
||||
} catch (\Exception $e) {
|
||||
$this->logError($row['mig_kd_debitur_seq'] ?? '-', "Error eksepsi: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function getBranchId(?string $code, array &$cache): ?int
|
||||
{
|
||||
if (!$code) return null;
|
||||
|
||||
if (isset($cache[$code])) {
|
||||
return $cache[$code];
|
||||
}
|
||||
|
||||
$branch = Branch::where('code', $code)->first();
|
||||
|
||||
if ($branch) {
|
||||
$cache[$code] = $branch->id;
|
||||
return $branch->id;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function getUserId(?string $code, array &$cache): array
|
||||
{
|
||||
if (!$code) return ['id' => null, 'branch_id' => null];
|
||||
|
||||
if (isset($cache[$code])) {
|
||||
return $cache[$code];
|
||||
}
|
||||
|
||||
$user = User::where('nik', $code)->first();
|
||||
|
||||
if ($user) {
|
||||
$cache[$code] = ['id' => $user->id, 'branch_id' => $user->branch_id];
|
||||
return $cache[$code];
|
||||
}
|
||||
|
||||
return ['id' => null, 'branch_id' => null];
|
||||
}
|
||||
|
||||
private function parseTimestamp(?string $timestamp): ?string
|
||||
{
|
||||
try {
|
||||
if ($timestamp) {
|
||||
// Cek jika format hanya tanggal (Y-m-d)
|
||||
if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $timestamp)) {
|
||||
return \Carbon\Carbon::createFromFormat('Y-m-d', $timestamp)
|
||||
->startOfDay()
|
||||
->toDateTimeString();
|
||||
}
|
||||
// Format lengkap (Y-m-d H:i:s)
|
||||
return \Carbon\Carbon::createFromFormat('Y-m-d H:i:s', $timestamp)->toDateTimeString();
|
||||
}
|
||||
return null;
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memparsing timestamp: ' . $timestamp . '. Pesan: ' . $e->getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private function initializeErrorLog()
|
||||
{
|
||||
// Jika file lama ada, hapus
|
||||
if (file_exists($this->errorLogFile)) {
|
||||
unlink($this->errorLogFile);
|
||||
}
|
||||
|
||||
// Buat file baru dengan header
|
||||
$handle = fopen($this->errorLogFile, 'w');
|
||||
fputcsv($handle, ['mig_kd_debitur_seq', 'Error']);
|
||||
fclose($handle);
|
||||
}
|
||||
|
||||
private function logError(string $kode, string $message)
|
||||
{
|
||||
// Catat ke log
|
||||
Log::error("Error migrasi debiture [$kode]: $message");
|
||||
|
||||
// Tulis ke file error
|
||||
$handle = fopen($this->errorLogFile, 'a');
|
||||
fputcsv($handle, [$kode, $message]);
|
||||
fclose($handle);
|
||||
}
|
||||
}
|
||||
345
database/seeders/MigrationDetailDokumenJaminanSeeder.php
Normal file
345
database/seeders/MigrationDetailDokumenJaminanSeeder.php
Normal file
@@ -0,0 +1,345 @@
|
||||
<?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/mig_detail_dokument_external_error.csv';
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
|
||||
public function run()
|
||||
{
|
||||
$this->initializeErrorLog();
|
||||
// Path ke file csv
|
||||
$filePath = realpath(__DIR__ . '/csv/detail-dokumen/mig_detail_dokument_external.csv');
|
||||
|
||||
if (!$filePath) {
|
||||
Log::error('File csv tidak ditemukan: ' . __DIR__ . '/csv/detail-dokumen/mig_detail_dokument_external.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;
|
||||
|
||||
// Cari debitur ID dari salah satu field
|
||||
foreach ($rows as $row) {
|
||||
if ($row['mig_nomor_laporan'] == $nomorLaporan) {
|
||||
$debiturId = $row['mig_kd_debitur_seq'] ?? null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$debiturId) {
|
||||
throw new \Exception('Debitur ID tidak ditemukan');
|
||||
}
|
||||
|
||||
// Ambil ID dokumen jaminan
|
||||
$dokumenJaminanId = $this->getDokumenJaminanId($debiturId, $dokumenJaminanCache);
|
||||
if (!$dokumenJaminanId) {
|
||||
throw new \Exception('Dokumen jaminan tidak ditemukan');
|
||||
}
|
||||
|
||||
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
|
||||
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,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
// 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, 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);
|
||||
}
|
||||
|
||||
}
|
||||
441
database/seeders/MigrationDokumentJaminanSeeder.php
Normal file
441
database/seeders/MigrationDokumentJaminanSeeder.php
Normal file
@@ -0,0 +1,441 @@
|
||||
<?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\PemilikJaminan;
|
||||
use Modules\Lpj\Models\HubunganPemilikJaminan;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
|
||||
class MigrationDokumentJaminanSeeder extends Seeder
|
||||
{
|
||||
protected $errorLogFile = __DIR__ . '/csv/dokumen-pemilik/mig_pemilik_dan_dokument_external_error_log.csv';
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->initializeErrorLog();
|
||||
// Path ke file csv
|
||||
$filePath = realpath(__DIR__ . '/csv/dokumen-pemilik/mig_pemilik_dan_dokument_external.csv');
|
||||
|
||||
if (!$filePath) {
|
||||
Log::error('File csv tidak ditemukan: ' . __DIR__ . '/csv/dokumen-pemilik/mig_pemilik_dan_dokument_external.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 = [];
|
||||
$pemilikJaminanCache = [];
|
||||
$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, $pemilikJaminanCache, $provinceCache, $cityCache, $districtCache, $subdistrictCache, $batchCount, $currentRow, $totalData, $errorCount, $errorDebitureIds, $hubunganPemilikCache);
|
||||
$rows = [];
|
||||
}
|
||||
}
|
||||
|
||||
// print_r($rows[0]);
|
||||
if (!empty($rows)) {
|
||||
$this->processBatch($rows, $permohonanCache, $jenisJaminanCache, $pemilikJaminanCache, $provinceCache, $cityCache, $districtCache, $subdistrictCache, $batchCount, $currentRow, $totalData, $errorCount, $errorDebitureIds, $hubunganPemilikCache);
|
||||
}
|
||||
|
||||
fclose($handle);
|
||||
|
||||
$this->command->info('Data debiture berhasil dimigrasikan.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Proses batch data.
|
||||
*/
|
||||
|
||||
private function processBatch(
|
||||
array $rows,
|
||||
array &$permohonanCache,
|
||||
array &$jenisJaminanCache,
|
||||
array &$pemilikJaminanCache,
|
||||
array &$provinceCache,
|
||||
array &$cityCache,
|
||||
array &$districtCache,
|
||||
array &$subdistrictCache,
|
||||
int $batchCount,
|
||||
int $currentRow,
|
||||
int $totalData,
|
||||
int &$errorCount,
|
||||
array &$errorDebitureIds,
|
||||
array &$hubunganPemilikCache
|
||||
) {
|
||||
foreach ($rows as $index => $row) {
|
||||
try {
|
||||
// Jalankan transaksi per-baris
|
||||
DB::beginTransaction();
|
||||
|
||||
// Cari permohonan
|
||||
|
||||
$permohonan = Permohonan::where('nomor_registrasi', $row['mig_nomor_jaminan'])->first();
|
||||
|
||||
if (empty($permohonan)) {
|
||||
throw new \Exception('Missing debiture_id' . $row['mig_nomor_jaminan']);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Pastikan permohonan_id belum digunakan di dokumen_jaminan
|
||||
$existingDokumen = DokumenJaminan::where('permohonan_id', $permohonan->id)->first();
|
||||
if ($existingDokumen) {
|
||||
throw new \Exception("permohonan_id {$permohonan->id} sudah digunakan di dokumen_jaminan");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ambil lokasi
|
||||
|
||||
// jika external silahkan matikan ini
|
||||
|
||||
$proviceCode = $this->getProvinceCode($row['mig_province_name'], $provinceCache);
|
||||
$cityCode = $this->getCityCode($row['mig_city_name'], $cityCache);
|
||||
$districtCode = $this->getDistrictCode($row['mig_district_name'], $districtCache);
|
||||
$subdistrict = $this->getSubdistrictCode($row['mig_village_name'], $subdistrictCache, $districtCache);
|
||||
// $hubunganPemilik = $this->getHubunganPemilikJaminanId($row['mig_hubungan_pemilik_jaminan'], $hubunganPemilikCache);
|
||||
|
||||
|
||||
$pemilik_jaminan_name = $this->getDebitureId($row['mig_kd_debitur_seq'], $pemilikJaminanCache);
|
||||
// Buat Pemilik Jaminan
|
||||
$pemilik_jaminan = PemilikJaminan::updateOrCreate([
|
||||
'debiture_id' => $permohonan->debiture_id,
|
||||
'hubungan_pemilik_jaminan_id' => 1,
|
||||
// 'name' => $row['name'],
|
||||
'name' => $pemilik_jaminan_name,
|
||||
'detail_sertifikat' => null,
|
||||
'npwp' => null,
|
||||
'nomor_id' => null,
|
||||
'email' => null,
|
||||
'phone' => null,
|
||||
// jika external silahkan matikan ini
|
||||
'province_code' => $proviceCode,
|
||||
'city_code' => $cityCode,
|
||||
'district_code' => $districtCode,
|
||||
'village_code' => $subdistrict['code'],
|
||||
'postal_code' => $subdistrict['postal_code'],
|
||||
'address' => $row['address'],
|
||||
'created_at' => $this->parseTimestamp($row['created_at']),
|
||||
'updated_at' => $this->parseTimestamp($row['updated_at']),
|
||||
'mig_kd_debitur_seq' => $row['mig_kd_debitur_seq'],
|
||||
'processed_at' => now(),
|
||||
'is_mig' => 1
|
||||
]);
|
||||
|
||||
// Buat Dokumen Jaminan
|
||||
DokumenJaminan::updateOrCreate([
|
||||
'debiture_id' => $permohonan->debiture_id,
|
||||
'permohonan_id' => $permohonan->id,
|
||||
'jenis_jaminan_id' => $this->getJaminanId($row['mig_jenis_seq']),
|
||||
'pemilik_jaminan_id' => $pemilik_jaminan->id,
|
||||
// jika external silahkan matikan ini
|
||||
// 'province_code' => $proviceCode,
|
||||
// 'city_code' => $cityCode,
|
||||
// 'district_code' => $districtCode,
|
||||
// 'village_code' => $subdistrict['code'],
|
||||
// 'postal_code' => $subdistrict['postal_code'],
|
||||
'address' => $row['address'],
|
||||
'created_at' => $this->parseTimestamp($row['created_at']),
|
||||
'updated_at' => $this->parseTimestamp($row['updated_at']),
|
||||
'mig_kd_debitur_seq' => $row['mig_kd_debitur_seq'],
|
||||
'processed_at' => now(),
|
||||
'is_mig' => 1
|
||||
]);
|
||||
|
||||
// Commit jika semua sukses
|
||||
DB::commit();
|
||||
$this->command->info("Proses dokumen jaminan: " . $row['mig_kd_debitur_seq'] . "Batch: {$batchCount} Baris: {$currentRow} Total: {$totalData} Error: {$errorCount}");
|
||||
|
||||
} catch (\Exception $e) {
|
||||
// Rollback hanya untuk baris ini
|
||||
DB::rollBack();
|
||||
|
||||
Log::error("Error pada baris: " . json_encode($row) . ". Pesan: " . $e->getMessage());
|
||||
$this->logError($row['mig_kd_debitur_seq'] ?? '-', $e->getMessage());
|
||||
$errorDebitureIds[] = $row['mig_kd_debitur_seq'] ?? '-';
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$this->command->info("Batch {$batchCount} selesai. Total error: " . count($errorDebitureIds));
|
||||
}
|
||||
// private function getPermohonanId($code,$cache)
|
||||
// {
|
||||
// if (isset($cache[$code])) {
|
||||
// return $cache[$code];
|
||||
// }
|
||||
|
||||
// $permohonan = Permohonan::where('mig_kd_debitur_seq', $code)->where('nomor_registrasi', $mig_nomor_jaminan)->first();
|
||||
|
||||
// if ($permohonan) {
|
||||
// $cache[$code] = $permohonan;
|
||||
// return $permohonan;
|
||||
// }
|
||||
|
||||
// return null;
|
||||
// }
|
||||
|
||||
|
||||
private function getJaminanId($code): ?int
|
||||
{
|
||||
$mapping = [
|
||||
7 => 17,
|
||||
8 => 13,
|
||||
6 => 32,
|
||||
1 => 17,
|
||||
2 => 26,
|
||||
3 => 27,
|
||||
4 => 50,
|
||||
5 => 21,
|
||||
138051314724 => 23,
|
||||
138027243057 => 34,
|
||||
138027664224 => 35,
|
||||
138027738489 => 10,
|
||||
138051485796 => 48,
|
||||
138051492883 => 47,
|
||||
138051515419 => 40,
|
||||
138051753311 => 41,
|
||||
138051754843 => 46,
|
||||
138051759078 => 42,
|
||||
138051480538 => 45,
|
||||
123382184742 => 18,
|
||||
138051483711 => 44,
|
||||
991 => 52
|
||||
];
|
||||
|
||||
return $mapping[$code] ?? 17;
|
||||
}
|
||||
|
||||
private function getPemilikJaminanId(string $code, array &$cache): ?int
|
||||
{
|
||||
if (isset($cache[$code])) {
|
||||
return $cache[$code];
|
||||
}
|
||||
|
||||
$jaminan = PemilikJaminan::where('mig_kd_debitur_seq', $code)->first();
|
||||
|
||||
if ($jaminan) {
|
||||
$cache[$code] = $jaminan->id;
|
||||
return $jaminan->id;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
private function getDebitureId(string $code, array &$cache): ?string
|
||||
{
|
||||
if (isset($cache[$code])) {
|
||||
return $cache[$code];
|
||||
}
|
||||
|
||||
$debiture = Debiture::where('mig_kd_debitur_seq', $code)->first();
|
||||
|
||||
if ($debiture) {
|
||||
$cache[$code] = $debiture->name;
|
||||
return $debiture->name;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private function getProvinceCode(string $name, array &$cache): ?string
|
||||
{
|
||||
|
||||
$normalizedName = strtolower($name);
|
||||
if (isset($cache[$normalizedName])) {
|
||||
return $cache[$normalizedName];
|
||||
}
|
||||
|
||||
$province = Province::whereRaw('LOWER(name) = ?', [strtolower($name)])->first();
|
||||
|
||||
if ($province) {
|
||||
$cache[$normalizedName] = $province->code;
|
||||
return $province->code;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function getCityCode(string $name, array &$cache): ?string
|
||||
{
|
||||
$normalizedName = strtolower($name);
|
||||
if (isset($cache[$normalizedName])) {
|
||||
return $cache[$normalizedName];
|
||||
}
|
||||
|
||||
$city = City::whereRaw('LOWER(name) = ?', [strtolower($name)])->first();
|
||||
|
||||
if ($city) {
|
||||
$cache[$normalizedName] = $city->code;
|
||||
return $city->code;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function getDistrictCode(string $name, array &$cache): ?string
|
||||
{
|
||||
$normalizedName = strtolower($name);
|
||||
if (isset($cache[$normalizedName])) {
|
||||
return $cache[$normalizedName];
|
||||
}
|
||||
|
||||
$district = District::whereRaw('LOWER(name) = ?', [strtolower($name)])->first();
|
||||
|
||||
if ($district) {
|
||||
$cache[$normalizedName] = $district->code;
|
||||
return $district->code;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function getSubdistrictCode(string $name, array &$cache, array &$districtCache): ?array
|
||||
{
|
||||
$normalizedName = strtolower($name);
|
||||
|
||||
// Pastikan cache menyimpan array, bukan hanya kode
|
||||
if (isset($cache[$normalizedName])) {
|
||||
return $cache[$normalizedName];
|
||||
}
|
||||
|
||||
// Ambil subdistrict dari database
|
||||
$subdistrict = Village::whereRaw('LOWER(name) = ?', [$normalizedName])->first();
|
||||
|
||||
// Jika ditemukan, simpan ke dalam cache sebagai array lengkap
|
||||
if ($subdistrict) {
|
||||
$cache[$normalizedName] = [
|
||||
'code' => $subdistrict->code,
|
||||
'postal_code' => $subdistrict->postal_code
|
||||
];
|
||||
return $cache[$normalizedName];
|
||||
}
|
||||
|
||||
// Jika tidak ditemukan, kembalikan null
|
||||
return [
|
||||
'code' => null,
|
||||
'postal_code' => null
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
private function getHubunganPemilikJaminanId(string $code, array &$cache): ?int
|
||||
{
|
||||
if (isset($cache[$code])) {
|
||||
return $cache[$code];
|
||||
}
|
||||
|
||||
$jaminan = HubunganPemilikJaminan::whereRaw('LOWER(name) = ?', [strtolower($code)])->first();
|
||||
|
||||
if ($jaminan) {
|
||||
$cache[$code] = $jaminan->id;
|
||||
return $jaminan->id;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Mengonversi nilai TIMESTAMP menjadi format datetime yang valid.
|
||||
*/
|
||||
private function parseTimestamp(?string $timestamp): ?string
|
||||
{
|
||||
try {
|
||||
if ($timestamp) {
|
||||
// Cek jika format hanya tanggal (Y-m-d)
|
||||
if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $timestamp)) {
|
||||
return \Carbon\Carbon::createFromFormat('Y-m-d', $timestamp)
|
||||
->startOfDay()
|
||||
->toDateTimeString();
|
||||
}
|
||||
// Format lengkap (Y-m-d H:i:s)
|
||||
return \Carbon\Carbon::createFromFormat('Y-m-d H:i:s', $timestamp)->toDateTimeString();
|
||||
}
|
||||
return null;
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memparsing timestamp: ' . $timestamp . '. Pesan: ' . $e->getMessage());
|
||||
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);
|
||||
}
|
||||
}
|
||||
292
database/seeders/MigrationGambarInspeksiSeeder.php
Normal file
292
database/seeders/MigrationGambarInspeksiSeeder.php
Normal file
@@ -0,0 +1,292 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Modules\Lpj\Models\Inspeksi;
|
||||
use Modules\Basicdata\Models\Branch;
|
||||
use Modules\Lpj\Models\DokumenJaminan;
|
||||
use Modules\Lpj\Models\Permohonan;
|
||||
use DateTime;
|
||||
|
||||
class MigrationGambarInspeksiSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
protected $errorLogFile = __DIR__ . '/csv/inspeksi/mig_inspeksi_foto_20253_error.csv';
|
||||
/**
|
||||
* Migrasi data gambar inspeksi dari file csv ke tabel inspeksi_gambar
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->initializeErrorLog();
|
||||
// Path ke file csv
|
||||
$filePath = realpath(__DIR__ . '/csv/inspeksi/mig_inspeksi_foto_20253.csv');
|
||||
|
||||
if (!$filePath) {
|
||||
Log::error('File csv tidak ditemukan: ' . __DIR__ . '/csv/inspeksi/mig_inspeksi_foto_20253.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::where('permohonan_id', $nomorRegis['id'])
|
||||
->where('dokument_id', $nomorRegis['dokument_id'])
|
||||
->whereNotNull('data_form')
|
||||
->update([
|
||||
'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' => [],
|
||||
'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('Y-m-d', $tgl);
|
||||
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);
|
||||
}
|
||||
}
|
||||
858
database/seeders/MigrationInpseksiSeeder.php
Normal file
858
database/seeders/MigrationInpseksiSeeder.php
Normal file
@@ -0,0 +1,858 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Modules\Lpj\Models\Inspeksi;
|
||||
use Modules\Basicdata\Models\Branch;
|
||||
use Modules\Lpj\Models\DokumenJaminan;
|
||||
use Modules\Lpj\Models\Permohonan;
|
||||
use Modules\Location\Models\City;
|
||||
use Modules\Location\Models\District;
|
||||
use Modules\Location\Models\Province;
|
||||
use Modules\Location\Models\Village;
|
||||
|
||||
// Load file helper
|
||||
require_once __DIR__ . '/MigInspeksiHelper.php';
|
||||
class MigrationInpseksiSeeder extends Seeder
|
||||
{
|
||||
protected $errorLogFile = __DIR__ . '/csv/inspeksi/mig_inspeksi_2025_error.csv';
|
||||
// protected $fielKesimpulan = ;
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->initializeErrorLog();
|
||||
// Path ke file csv
|
||||
$filePath = realpath(__DIR__ . '/csv/inspeksi/mig_inspeksi_2025.csv');
|
||||
|
||||
if (!$filePath) {
|
||||
Log::error('File csv tidak ditemukan: ' . __DIR__ . '/csv/inspeksi/mig_inspeksi_2025.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 = [];
|
||||
}
|
||||
}
|
||||
|
||||
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 &$debitureCache,
|
||||
int &$errorCount,
|
||||
array &$errorDebitureIds,
|
||||
int $totalData,
|
||||
int $batchCount,
|
||||
int $currentRow
|
||||
) {
|
||||
// Kelompokkan baris berdasarkan mig_nomor_jaminan
|
||||
$groupedData = $this->groupRowsByJaminan($rows);
|
||||
|
||||
foreach ($groupedData as $nomorJaminan => $groupRows) {
|
||||
try {
|
||||
// Ambil informasi permohonan
|
||||
$nomorRegis = $this->getNomorRegistrasiPermohonan($nomorJaminan, $branchCache);
|
||||
if (!$nomorRegis) {
|
||||
Log::warning("Nomor registrasi tidak ditemukan untuk nomor jaminan: {$nomorJaminan}");
|
||||
$errorCount++;
|
||||
$errorDebitureIds[] = $nomorJaminan;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Cek apakah sudah ada data
|
||||
$existingRecord = Inspeksi::where('permohonan_id', $nomorRegis['id'])
|
||||
->where('dokument_id', $nomorRegis['dokument_id'])
|
||||
->whereNotNull('data_form')
|
||||
->first();
|
||||
|
||||
if ($existingRecord) {
|
||||
$this->command->info("Data untuk nomor jaminan {$nomorJaminan} sudah ada. Lewati...");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ambil baris pertama untuk created_at/updated_at
|
||||
$firstRow = reset($groupRows);
|
||||
|
||||
// Bangun JSON lengkap
|
||||
$dataFormJson = $this->buildFullDataForm($groupRows);
|
||||
$jenisJaminan = $this->checkJenisJaminan($groupRows[0]['mig_name'] ?? '');
|
||||
|
||||
if (!$dataFormJson) {
|
||||
Log::warning("Data form kosong untuk nomor jaminan: {$nomorJaminan}");
|
||||
$errorCount++;
|
||||
$errorDebitureIds[] = $nomorJaminan;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Simpan ke database hanya sekali per grup
|
||||
Inspeksi::create([
|
||||
'name' => $jenisJaminan,
|
||||
'data_form' => $dataFormJson,
|
||||
'foto_form' => null,
|
||||
'data_pembanding' => null,
|
||||
'permohonan_id' => $nomorRegis['id'] ?? null,
|
||||
'dokument_id' => $nomorRegis['dokument_id'] ?? null,
|
||||
'created_at' => $this->parseTimestamp($firstRow['created_at'] ?? null),
|
||||
'updated_at' => $this->parseTimestamp($firstRow['updated_at'] ?? null),
|
||||
'nomor_lpj' => $nomorJaminan,
|
||||
'processed_at' => now(),
|
||||
'is_mig' => 1
|
||||
]);
|
||||
|
||||
$this->command->info("Berhasil simpan data inspeksi 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 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 buildFullDataForm(array $rows)
|
||||
{
|
||||
if (empty($rows)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$jenisJaminan = $rows[0]['mig_name'] ?? null;
|
||||
|
||||
if (!$jenisJaminan) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
$jsonResult = $this->checkBuildJson($jenisJaminan, $rows);
|
||||
// Validasi apakah hasil JSON valid
|
||||
json_decode($jsonResult);
|
||||
return $jsonResult;
|
||||
} catch (\Exception $e) {
|
||||
Log::error("Gagal build JSON untuk jenis jaminan {$jenisJaminan}: " . $e->getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private function loadKesimpulanByNomorLpj($nomorLpj)
|
||||
{
|
||||
$filePath = realpath(__DIR__ . '/csv/inspeksi/mig_inspeksi_kesimpulan_2025.csv');
|
||||
|
||||
if (!$filePath || !$nomorLpj) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (($handle = fopen($filePath, 'r')) === false) {
|
||||
Log::error("Gagal membuka file CSV kesimpulan: " . $filePath);
|
||||
return [];
|
||||
}
|
||||
|
||||
$header = fgetcsv($handle, 0, '~');
|
||||
$result = [];
|
||||
|
||||
while (($data = fgetcsv($handle, 0, '~')) !== false) {
|
||||
if (count($data) != count($header)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$row = array_combine($header, $data);
|
||||
|
||||
if ($row['mig_nomor_lpj'] === $nomorLpj) {
|
||||
$result[] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
// print_r($result);
|
||||
|
||||
fclose($handle);
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private function checkLingkungan($rows)
|
||||
{
|
||||
$dataToInsertJson = [];
|
||||
|
||||
// Inisialisasi struktur lingkungan
|
||||
$lingkungan = [
|
||||
'jarak_jalan_utama' => null,
|
||||
'jalan_linkungan' => null,
|
||||
'jarak_cbd_point' => null,
|
||||
'nama_cbd_point' => null,
|
||||
'lebar_perkerasan_jalan' => null,
|
||||
'perkerasan_jalan' => ['perkerasan_jalan' => [], 'lainnya' => null],
|
||||
'lalu_lintas' => null,
|
||||
'gol_mas_sekitar' => [],
|
||||
'tingkat_keramaian' => [],
|
||||
'terletak_diarea' => ['terletak_diarea' => [], 'lainnya' => null],
|
||||
'disekitar_lokasi' => null,
|
||||
'kondisi_bagunan_disekitar_lokasi' => null,
|
||||
'sifat_bagunan_disekitar_lokasi' => null,
|
||||
'dekat_makam' => 'tidak',
|
||||
'jarak_makam' => null,
|
||||
'nama_makam' => null,
|
||||
'dekat_tps' => 'tidak',
|
||||
'jarak_tps' => null,
|
||||
'nama_tps' => null,
|
||||
'dekat_lainnya' => null,
|
||||
'merupakan_daerah' => [],
|
||||
'fasilitas_dekat_object' => [],
|
||||
'fasilitas_dekat_object_input' => [
|
||||
'Tempat Ibadah' => null,
|
||||
'Rumah Sakit' => null,
|
||||
'Sekolah' => null,
|
||||
'Kantor Pemerintahan' => null,
|
||||
'Stasiun Kereta' => null,
|
||||
'Terminal Bus' => null,
|
||||
'Bandara' => null,
|
||||
'Pos Polisi' => null,
|
||||
'Lainnya' => null
|
||||
]
|
||||
];
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$name = trim($row['name']);
|
||||
$value = !empty($row['mig_name_keterangan_lain']) ? $row['mig_name_keterangan_lain'] : $row['mig_name_keterangan'];
|
||||
|
||||
switch ($name) {
|
||||
case 'Lebar jalan dimuka lokasi':
|
||||
$lingkungan['lebar_perkerasan_jalan'] = $row['mig_name_keterangan_lain'];
|
||||
break;
|
||||
|
||||
case 'Lapisan perkerasan jalan dari':
|
||||
if ($value === 'Lainnya') {
|
||||
$lingkungan['perkerasan_jalan']['perkerasan_jalan'][] = $value;
|
||||
$lingkungan['perkerasan_jalan']['lainnya'] = $row['mig_name_keterangan_lain'];
|
||||
} else {
|
||||
$lingkungan['perkerasan_jalan']['perkerasan_jalan'][] = $value;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Lalulintas didepan lokasi':
|
||||
$lingkungan['lalu_lintas'] = $value;
|
||||
break;
|
||||
|
||||
case 'Golongan Masyarakat sekitar':
|
||||
$lingkungan['gol_mas_sekitar'][] = $value;
|
||||
break;
|
||||
|
||||
case 'Dengan kondisi':
|
||||
$lingkungan['tingkat_keramaian'][] = $value;
|
||||
break;
|
||||
|
||||
case 'Terletak didaerah':
|
||||
if ($value === 'Lainnya') {
|
||||
$lingkungan['terletak_diarea']['terletak_diarea'][] = $value;
|
||||
$lingkungan['terletak_diarea']['lainnya'] = $row['mig_name_keterangan_lain'];
|
||||
} else {
|
||||
$lingkungan['terletak_diarea']['terletak_diarea'][] = $value;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Disekitar lokasi':
|
||||
$lingkungan['disekitar_lokasi'] = $value === 'Telah ada bangunan' ? 'sesuai' : 'tidak sesuai';
|
||||
break;
|
||||
|
||||
case 'Merupakan daerah':
|
||||
$lingkungan['merupakan_daerah'][] = $value;
|
||||
break;
|
||||
|
||||
case 'Fasilitas umum dekat lokasi':
|
||||
$lingkungan['fasilitas_dekat_object'][] = $value;
|
||||
if (isset($lingkungan['fasilitas_dekat_object_input'][$value])) {
|
||||
$lingkungan['fasilitas_dekat_object_input'][$value] = $value;
|
||||
} elseif ($value === 'Pasar / Swalayan') {
|
||||
$lingkungan['fasilitas_dekat_object_input']['Lainnya'] = 'pasar';
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Isi default jika kosong
|
||||
if (empty($lingkungan['fasilitas_dekat_object'])) {
|
||||
$lingkungan['fasilitas_dekat_object'] = [];
|
||||
}
|
||||
|
||||
// Masukkan ke array JSON
|
||||
$dataToInsertJson[] = json_encode([
|
||||
'lingkungan' => $lingkungan
|
||||
], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
||||
|
||||
return $dataToInsertJson;
|
||||
}
|
||||
|
||||
private function checkAsset(array $rows)
|
||||
{
|
||||
$dataToInsertJson = [];
|
||||
|
||||
// Ambil baris pertama saja
|
||||
$firstRow = reset($rows);
|
||||
|
||||
if (!$firstRow) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Inisialisasi variabel dari baris pertama
|
||||
$hubCadeb = null;
|
||||
$hubPenghuni = null;
|
||||
$jenisAsset = null;
|
||||
|
||||
// Ambil data utama dari baris pertama
|
||||
$pihakBank = $firstRow['mig_pihak_bank'] ?? null;
|
||||
$debiturPerwakilan = $firstRow['mig_debiture_perwakilan'] ?? null;
|
||||
$address = $firstRow['address'] ?? null;
|
||||
|
||||
// Kode wilayah
|
||||
$provinceCache = []; // cache untuk helper
|
||||
$cityCache = [];
|
||||
$districtCache = [];
|
||||
$subdistrictCache = [];
|
||||
|
||||
$proviceCode = $this->getProvinceCode($firstRow['mig_village_name'] ?? '', $provinceCache);
|
||||
$cityCode = $this->getCityCode($firstRow['mig_city_name'] ?? '', $cityCache);
|
||||
$districtCode = $this->getDistrictCode($firstRow['mig_district_name'] ?? '', $districtCache);
|
||||
$subdistrict = $this->getSubdistrictCode($firstRow['mig_province_name'] ?? '', $subdistrictCache, $districtCache);
|
||||
|
||||
// Proses hubungan pemilik/penghuni & jenis asset dari seluruh rows
|
||||
foreach ($rows as $row) {
|
||||
$name = trim($row['name'] ?? '');
|
||||
$keySesuaiORTidak = !empty($row['mig_name_keterangan_lain']) ? 'sesuai' : 'tidak sesuai';
|
||||
$value = !empty($row['mig_name_keterangan_lain'])
|
||||
? $row['mig_name_keterangan_lain']
|
||||
: $row['mig_name_keterangan'] ?? null;
|
||||
|
||||
switch ($name) {
|
||||
case 'Hubungan Pemilik Jaminan dengan Debitur':
|
||||
$hubCadeb = [
|
||||
$keySesuaiORTidak => $value
|
||||
];
|
||||
break;
|
||||
|
||||
case 'Hubungan Penghuni Jaminan dengan Debitur':
|
||||
$hubPenghuni = [
|
||||
$keySesuaiORTidak => $value
|
||||
];
|
||||
break;
|
||||
|
||||
case 'Jenis Bangunan':
|
||||
$jenisAsset = [
|
||||
$keySesuaiORTidak => $value
|
||||
];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Isi default jika kosong
|
||||
if (empty($hubCadeb)) {
|
||||
$hubCadeb = ["tidak sesuai" => null];
|
||||
}
|
||||
if (empty($hubPenghuni)) {
|
||||
$hubPenghuni = ["tidak sesuai" => null];
|
||||
}
|
||||
if (empty($jenisAsset)) {
|
||||
$jenisAsset = ["sesuai" => null];
|
||||
}
|
||||
|
||||
// Bangun struktur JSON
|
||||
$asset = [
|
||||
"debitur_perwakilan" => $debiturPerwakilan,
|
||||
"jenis_asset" => $jenisAsset,
|
||||
"alamat" => [
|
||||
"sesuai" => [
|
||||
"address" => $address,
|
||||
"village_code" => $subdistrict['code'],
|
||||
"district_code" => $districtCode,
|
||||
"city_code" => $cityCode,
|
||||
"province_code" => $proviceCode
|
||||
]
|
||||
],
|
||||
"hub_cadeb" => $hubCadeb,
|
||||
"hub_cadeb_penghuni" => $hubPenghuni,
|
||||
"pihak_bank" => $pihakBank,
|
||||
"kordinat_lng" => null,
|
||||
"kordinat_lat" => null
|
||||
];
|
||||
|
||||
// Masukkan ke array JSON
|
||||
$dataToInsertJson[] = json_encode([
|
||||
"asset" => $asset
|
||||
], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
||||
|
||||
return $dataToInsertJson;
|
||||
}
|
||||
|
||||
|
||||
private function checkKesimpulan($rows)
|
||||
{
|
||||
$dataToInsertJson = [];
|
||||
|
||||
$fakta = [
|
||||
'fakta_positif' => [],
|
||||
'fakta_negatif' => [],
|
||||
'rute_menuju' => null,
|
||||
'batas_batas' => ["Utara", "Timur", "Selatan", "Barat"],
|
||||
'batas_batas_input' => [
|
||||
"Utara" => null,
|
||||
"Timur Laut" => null,
|
||||
"Timur" => null,
|
||||
"Tenggara" => null,
|
||||
"Selatan" => null,
|
||||
"Barat Daya" => null,
|
||||
"Barat" => null,
|
||||
"Barat Laut" => null,
|
||||
"Utara Timur Laut" => null,
|
||||
"Timur Timur Laut" => null,
|
||||
"Timur Tenggara" => null,
|
||||
"Selatan Tenggara" => null,
|
||||
"Selatan Barat Daya" => null,
|
||||
"Barat Barat Daya" => null,
|
||||
"Barat Barat Laut" => null,
|
||||
"Utara Barat Laut" => null
|
||||
],
|
||||
'kondisi_lingkungan' => [],
|
||||
'kondisi_lain_bangunan' => [],
|
||||
'informasi_dokument' => [],
|
||||
'peruntukan' => null,
|
||||
'kdb' => null,
|
||||
'kdh' => null,
|
||||
'gsb' => null,
|
||||
'max_lantai' => null,
|
||||
'klb' => null,
|
||||
'gss' => null,
|
||||
'pelebaran_jalan' => null,
|
||||
'nama_petugas' => null,
|
||||
'keterangan' => [],
|
||||
'saran' => []
|
||||
];
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$jenis = trim($row['mig_keterangan']); // misal: Fakta Positif, Fakta Negatif, dll
|
||||
$keterangan = trim($row['mig_kesimpulan']);
|
||||
|
||||
switch ($jenis) {
|
||||
case 'Faktor Positif':
|
||||
$fakta['fakta_positif'][] = $keterangan;
|
||||
break;
|
||||
|
||||
case 'Faktor Negatif':
|
||||
$fakta['fakta_negatif'][] = $keterangan;
|
||||
break;
|
||||
|
||||
case 'Rute Menuju':
|
||||
$fakta['rute_menuju'] = $keterangan;
|
||||
break;
|
||||
|
||||
case 'Kondisi Lingkungan':
|
||||
$fakta['kondisi_lingkungan'][] = $keterangan;
|
||||
break;
|
||||
|
||||
case 'Kondisi Bangunan':
|
||||
$fakta['kondisi_lain_bangunan'][] = $keterangan;
|
||||
break;
|
||||
|
||||
case 'Lain - lain':
|
||||
$fakta['informasi_dokument'][] = $keterangan;
|
||||
break;
|
||||
|
||||
case 'CATATAN YANG PERLU DIPERHATIKAN':
|
||||
$fakta['keterangan'][] = $keterangan;
|
||||
break;
|
||||
case 'Catatan':
|
||||
$fakta['keterangan'][] = $keterangan;
|
||||
break;
|
||||
case 'Saran':
|
||||
$fakta['saran'][] = $keterangan;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$dataToInsertJson[] = json_encode([
|
||||
'fakta' => $fakta
|
||||
], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
||||
|
||||
return $dataToInsertJson;
|
||||
}
|
||||
|
||||
private function parseTimestamp(?string $timestamp): ?string
|
||||
{
|
||||
try {
|
||||
if ($timestamp) {
|
||||
// Cek jika format hanya tanggal (Y-m-d)
|
||||
if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $timestamp)) {
|
||||
return \Carbon\Carbon::createFromFormat('Y-m-d', $timestamp)
|
||||
->startOfDay()
|
||||
->toDateTimeString();
|
||||
}
|
||||
// Format lengkap (Y-m-d H:i:s)
|
||||
return \Carbon\Carbon::createFromFormat('Y-m-d H:i:s', $timestamp)->toDateTimeString();
|
||||
}
|
||||
return null;
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memparsing timestamp: ' . $timestamp . '. Pesan: ' . $e->getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private function getProvinceCode(string $name, array &$cache): ?string
|
||||
{
|
||||
|
||||
$normalizedName = strtolower($name);
|
||||
if (isset($cache[$normalizedName])) {
|
||||
return $cache[$normalizedName];
|
||||
}
|
||||
|
||||
$province = Province::whereRaw('LOWER(name) = ?', [strtolower($name)])->first();
|
||||
|
||||
if ($province) {
|
||||
$cache[$normalizedName] = $province->code;
|
||||
return $province->code;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function getCityCode(string $name, array &$cache): ?string
|
||||
{
|
||||
$normalizedName = strtolower($name);
|
||||
if (isset($cache[$normalizedName])) {
|
||||
return $cache[$normalizedName];
|
||||
}
|
||||
|
||||
$city = City::whereRaw('LOWER(name) = ?', [strtolower($name)])->first();
|
||||
|
||||
if ($city) {
|
||||
$cache[$normalizedName] = $city->code;
|
||||
return $city->code;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function getDistrictCode(string $name, array &$cache): ?string
|
||||
{
|
||||
$normalizedName = strtolower($name);
|
||||
if (isset($cache[$normalizedName])) {
|
||||
return $cache[$normalizedName];
|
||||
}
|
||||
|
||||
$district = District::whereRaw('LOWER(name) = ?', [strtolower($name)])->first();
|
||||
|
||||
if ($district) {
|
||||
$cache[$normalizedName] = $district->code;
|
||||
return $district->code;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function getSubdistrictCode(string $name, array &$cache, array &$districtCache): ?array
|
||||
{
|
||||
$normalizedName = strtolower($name);
|
||||
|
||||
// Pastikan cache menyimpan array, bukan hanya kode
|
||||
if (isset($cache[$normalizedName])) {
|
||||
return $cache[$normalizedName];
|
||||
}
|
||||
|
||||
// Ambil subdistrict dari database
|
||||
$subdistrict = Village::whereRaw('LOWER(name) = ?', [$normalizedName])->first();
|
||||
|
||||
// Jika ditemukan, simpan ke dalam cache sebagai array lengkap
|
||||
if ($subdistrict) {
|
||||
$cache[$normalizedName] = [
|
||||
'code' => $subdistrict->code,
|
||||
'postal_code' => $subdistrict->postal_code
|
||||
];
|
||||
return $cache[$normalizedName];
|
||||
}
|
||||
|
||||
// Jika tidak ditemukan, kembalikan null
|
||||
return [
|
||||
'code' => null,
|
||||
'postal_code' => null
|
||||
];
|
||||
}
|
||||
|
||||
private function initializeErrorLog()
|
||||
{
|
||||
$file = $this->errorLogFile;
|
||||
|
||||
// Hapus file lama jika ada
|
||||
if (file_exists($file)) {
|
||||
unlink($file);
|
||||
}
|
||||
|
||||
// Buat file baru dengan header
|
||||
$handle = fopen($file, 'w');
|
||||
fputcsv($handle, ['mig_mst_jaminan_nomor_jaminan', 'Error']);
|
||||
fclose($handle);
|
||||
}
|
||||
|
||||
private function logError($nomorJaminan, string $message)
|
||||
{
|
||||
Log::error("Error migrasi permohonan [$nomorJaminan]: $message");
|
||||
|
||||
// Tulis ke file error
|
||||
$handle = fopen($this->errorLogFile, 'a');
|
||||
fputcsv($handle, [$nomorJaminan, $message]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function checkJenisJaminan($input)
|
||||
{
|
||||
$input = trim($input);
|
||||
switch ($input) {
|
||||
case 'Tanah dan Bangunan eks KPR-BPPN':
|
||||
return 'tanah, bangunan, lingkungan, fakta, informasi';
|
||||
case 'Pabrik':
|
||||
return 'tanah, bangunan, lingkungan, fakta, informasi';
|
||||
case 'Kapal Laut':
|
||||
return 'kapal-laut';
|
||||
|
||||
case 'Tanah dan/atau Bangunan':
|
||||
return 'tanah, bangunan';
|
||||
|
||||
case 'Kendaraan Bermotor':
|
||||
return 'kendaraan-';
|
||||
|
||||
case 'Mesin-mesin dan Peralatan':
|
||||
return 'mesin';
|
||||
|
||||
case 'Barang Dagangan/FEO':
|
||||
return 'barang-dagangan';
|
||||
|
||||
case 'Pesawat Udara':
|
||||
return 'pesawat-udara';
|
||||
|
||||
case 'Alat Berat':
|
||||
return 'alat-berat';
|
||||
|
||||
case 'Deposito':
|
||||
return 'deposito';
|
||||
|
||||
case 'Rekening Giro / Tabungan':
|
||||
return 'rekening-giro-tabungan';
|
||||
|
||||
case 'Emas':
|
||||
return 'emas';
|
||||
|
||||
case 'Jaminan Pribadi / Personal Guarantee':
|
||||
return 'jaminan-pribadi';
|
||||
|
||||
case 'Jaminan Perusahaan / Corporate Guarantee':
|
||||
return 'jaminan-perusahaan';
|
||||
|
||||
case 'Resi Gudang':
|
||||
return 'resi-gudang';
|
||||
|
||||
case 'Surat Berharga dan Saham':
|
||||
return 'surat-berharga-saham';
|
||||
|
||||
case 'Tanah dan Bangunan (KerjaSama)':
|
||||
return 'tanah-bangunan-kerja-sama';
|
||||
|
||||
case 'Tanah Kavling (Kerjasama)':
|
||||
return 'tanah-kavling';
|
||||
|
||||
case 'Persediaan Barang / Barang Dagangan':
|
||||
return 'persediaan-barang';
|
||||
|
||||
case 'Apartemen':
|
||||
return 'apartemen';
|
||||
|
||||
case 'Tagihan / Piutang Dagang':
|
||||
return 'tagihan-piutang';
|
||||
|
||||
case 'Tanah dan/atau Bangunan KPR - SEDERHANA':
|
||||
return 'tanah-bangunan-kpr-sederhana';
|
||||
|
||||
default:
|
||||
return 'lainnya';
|
||||
}
|
||||
}
|
||||
|
||||
public function checkBuildJson($input, $rows = [])
|
||||
{
|
||||
$input = trim($input);
|
||||
|
||||
// Pastikan rows selalu array
|
||||
if (!is_array($rows)) {
|
||||
$rows = [$rows];
|
||||
}
|
||||
|
||||
switch ($input) {
|
||||
case 'Tanah dan Bangunan eks KPR-BPPN':
|
||||
case 'Pabrik':
|
||||
case 'Tanah dan/atau Bangunan':
|
||||
case 'Apartemen':
|
||||
case 'Tanah dan/atau Bangunan KPR - SEDERHANA':
|
||||
$assetJson = json_decode($this->checkAsset($rows)[0] ?? '', true);
|
||||
$tanahJson = json_decode(buildInspeksiTanah($rows)[0] ?? '', true);
|
||||
$bangunanJson = json_decode(buildInspeksiBangunan($rows)[0] ?? '', true);
|
||||
$lingkunganJson = json_decode($this->checkLingkungan($rows)[0] ?? '', true);
|
||||
|
||||
$nomorLpj = $rows[0]['mig_nomor_lpj'] ?? null;
|
||||
$kesimpulanRows = $this->loadKesimpulanByNomorLpj($nomorLpj);
|
||||
|
||||
$faktaJson = [];
|
||||
if (!empty($kesimpulanRows)) {
|
||||
$faktaResult = $this->checkKesimpulan($kesimpulanRows);
|
||||
$faktaJson = json_decode($faktaResult[0] ?? '', true)['fakta'] ?? [];
|
||||
}
|
||||
|
||||
return json_encode([
|
||||
'asset' => $assetJson['asset'] ?? [],
|
||||
'tanah' => $tanahJson['tanah'] ?? [],
|
||||
'bangunan' => $bangunanJson['bangunan'] ?? [],
|
||||
'lingkungan' => $lingkunganJson['lingkungan'] ?? [],
|
||||
'fakta' => $faktaJson
|
||||
], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
||||
|
||||
case 'Kapal Laut':
|
||||
$kapal = createInspeksiKapal($rows);
|
||||
return json_encode($kapal, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
||||
|
||||
case 'Kendaraan Bermotor':
|
||||
$kendaraan = createInspeksiKendaraan($rows);
|
||||
return json_encode($kendaraan, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
||||
|
||||
case 'Mesin-mesin dan Peralatan':
|
||||
$mesin = createInspeksiMesin($rows);
|
||||
return json_encode($mesin, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
||||
|
||||
case 'Pesawat Udara':
|
||||
$pesawat = createInspeksiPesawat($rows);
|
||||
return json_encode($pesawat, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
||||
|
||||
case 'Alat Berat':
|
||||
$alatBerat = createInspeksiAlatBerat($rows);
|
||||
return json_encode($alatBerat, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
||||
|
||||
case 'Barang Dagangan/FEO':
|
||||
case 'Deposito':
|
||||
case 'Rekening Giro / Tabungan':
|
||||
case 'Emas':
|
||||
case 'Jaminan Pribadi / Personal Guarantee':
|
||||
case 'Jaminan Perusahaan / Corporate Guarantee':
|
||||
case 'Resi Gudang':
|
||||
case 'Surat Berharga dan Saham':
|
||||
case 'Persediaan Barang / Barang Dagangan':
|
||||
case 'Tagihan / Piutang Dagang':
|
||||
return json_encode([
|
||||
'status' => 'pending',
|
||||
'message' => 'Fungsi untuk "' . $input . '" belum diimplementasikan.',
|
||||
'data' => $rows
|
||||
]);
|
||||
case 'Tanah dan Bangunan (KerjaSama)':
|
||||
case 'Tanah Kavling (Kerjasama)':
|
||||
$pesawat = buildRapJsonData($rows);
|
||||
return json_encode($pesawat, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
||||
default:
|
||||
return json_encode([
|
||||
'status' => 'unknown',
|
||||
'message' => 'Jenis aset tidak dikenali: ' . $input,
|
||||
'data' => $rows
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
16
database/seeders/MigrationLaporanSeeder.php
Normal file
16
database/seeders/MigrationLaporanSeeder.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class MigrationLaporanSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
// $this->call([]);
|
||||
}
|
||||
}
|
||||
225
database/seeders/MigrationPembandingSeeder.php
Normal file
225
database/seeders/MigrationPembandingSeeder.php
Normal file
@@ -0,0 +1,225 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Modules\Lpj\Models\Inspeksi;
|
||||
use Modules\Basicdata\Models\Branch;
|
||||
use Modules\Lpj\Models\DokumenJaminan;
|
||||
use Modules\Lpj\Models\Permohonan;
|
||||
|
||||
class MigrationPembandingSeeder extends Seeder
|
||||
{
|
||||
protected $errorLogFile = __DIR__ . '/csv/inspeksi/mig_pembanding_2025_error.csv';
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
// Path ke file csv
|
||||
$filePath = realpath(__DIR__ . '/csv/inspeksi/mig_pembanding_2025.csv');
|
||||
|
||||
if (!$filePath) {
|
||||
Log::error('File csv tidak ditemukan: ' . __DIR__ . '/csv/inspeksi/mig_pembanding_2025.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_lpj
|
||||
$groupedRows = $this->groupRowsByJaminan($rows);
|
||||
|
||||
print_r($groupedRows);
|
||||
|
||||
foreach ($groupedRows as $nomorLpj => $groupRows) {
|
||||
try {
|
||||
// Dapatkan info permohonan untuk update inspeksi
|
||||
$nomorRegis = $this->getNomorRegistrasiPermohonan($nomorLpj, $branchCache);
|
||||
if (!$nomorRegis) {
|
||||
Log::warning("Nomor registrasi tidak ditemukan untuk nomor LPJ: {$nomorLpj}");
|
||||
$errorCount++;
|
||||
$errorDebitureIds[] = $nomorLpj;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Bangun JSON data pembanding
|
||||
$pembandingJson = $this->checkPembanding($groupRows);
|
||||
|
||||
print_r($pembandingJson);
|
||||
|
||||
// Update ke tabel inspeksi
|
||||
|
||||
// print_r($pembandingJson);
|
||||
Inspeksi::where('permohonan_id', $nomorRegis['id'])
|
||||
->where('dokument_id', $nomorRegis['dokument_id'])
|
||||
->update([
|
||||
'data_pembanding' => $pembandingJson,
|
||||
'updated_at' => now()
|
||||
]);
|
||||
|
||||
$this->command->info("Berhasil update data_pembanding untuk nomor LPJ: {$nomorLpj}");
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::error("Error pada nomor LPJ {$nomorLpj}: " . $e->getMessage());
|
||||
$errorCount++;
|
||||
$errorDebitureIds[] = $nomorLpj;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
private function groupRowsByJaminan(array $rows): array
|
||||
{
|
||||
$grouped = [];
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$nomorJaminan = $row['mig_nomor_lpj'] ?? null;
|
||||
|
||||
if (!empty($nomorJaminan)) {
|
||||
$grouped[$nomorJaminan][] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
return $grouped;
|
||||
}
|
||||
|
||||
private function checkPembanding(array $rows)
|
||||
{
|
||||
$pembandingList = [];
|
||||
|
||||
foreach ($rows as $row) {
|
||||
// Pastikan kolom penting tersedia
|
||||
$urutan = (int)($row['mig_urutan'] ?? 999);
|
||||
$pembanding = trim($row['mig_pembanding'] ?? '');
|
||||
|
||||
// CUKUP VALIDASI PEMBANDING SAJA
|
||||
if (empty($pembanding)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$pembandingList[] = [
|
||||
'urutan' => $urutan,
|
||||
'keterangan' => $pembanding,
|
||||
];
|
||||
}
|
||||
|
||||
// Urutkan berdasarkan urutan
|
||||
usort($pembandingList, function ($a, $b) {
|
||||
return $a['urutan'] <=> $b['urutan'];
|
||||
});
|
||||
|
||||
// Hapus indeks 'urutan'
|
||||
$finalPembanding = array_map(function ($item) {
|
||||
unset($item['urutan']);
|
||||
return $item;
|
||||
}, $pembandingList);
|
||||
|
||||
return json_encode([
|
||||
'data_pembanding' => $finalPembanding
|
||||
], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
||||
}
|
||||
private function getNomorRegistrasiPermohonan($nomor_jaminan_id, array &$cache)
|
||||
{
|
||||
if (isset($cache[$nomor_jaminan_id])) {
|
||||
return $cache[$nomor_jaminan_id];
|
||||
}
|
||||
|
||||
$permohonan = Permohonan::where('nomor_lpj', $nomor_jaminan_id)->first();
|
||||
|
||||
if (!$permohonan) {
|
||||
$cache[$nomor_jaminan_id] = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
$dokumenJaminan = DokumenJaminan::where('permohonan_id', $permohonan->id)->first();
|
||||
|
||||
$result = [
|
||||
'id' => $permohonan->id,
|
||||
'dokument_id' => $dokumenJaminan ? $dokumenJaminan->id : null
|
||||
];
|
||||
|
||||
$cache[$nomor_jaminan_id] = $result;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function initializeErrorLog()
|
||||
{
|
||||
$file = $this->errorLogFile;
|
||||
|
||||
// Hapus file lama jika ada
|
||||
if (file_exists($file)) {
|
||||
unlink($file);
|
||||
}
|
||||
|
||||
// Buat file baru dengan header
|
||||
$handle = fopen($file, 'w');
|
||||
fputcsv($handle, ['mig_mst_jaminan_nomor_jaminan', 'Error']);
|
||||
fclose($handle);
|
||||
}
|
||||
|
||||
private function logError($nomorJaminan, string $message)
|
||||
{
|
||||
Log::error("Error migrasi permohonan [$nomorJaminan]: $message");
|
||||
|
||||
// Tulis ke file error
|
||||
$handle = fopen($this->errorLogFile, 'a');
|
||||
fputcsv($handle, [$nomorJaminan, $message]);
|
||||
|
||||
}
|
||||
}
|
||||
264
database/seeders/MigrationPemilikJaminanSeeder.php
Normal file
264
database/seeders/MigrationPemilikJaminanSeeder.php
Normal file
@@ -0,0 +1,264 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Modules\Lpj\Models\HubunganPemilikJaminan;
|
||||
use Modules\Lpj\Models\Debiture;
|
||||
use Modules\Lpj\Models\PemilikJaminan;
|
||||
use Modules\Basicdata\Models\Branch;
|
||||
use Modules\Usermanagement\Models\User;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Modules\Location\Models\Province;
|
||||
use Modules\Location\Models\City;
|
||||
use Modules\Location\Models\District;
|
||||
use Modules\Location\Models\Village;
|
||||
|
||||
class MigrationPemilikJaminanSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$filePath = realpath(__DIR__ . '/csv/mig_dokument_dan_pemilik.csv');
|
||||
|
||||
if (!$filePath) {
|
||||
Log::error('File CSV tidak ditemukan: ' . __DIR__ . '/csv/pemilik.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 = 100; // Ukuran batch
|
||||
$branchCache = [];
|
||||
$debitureCache = [];
|
||||
$hubunganPemilikCache = [];
|
||||
$provinceCache = [];
|
||||
$cityCache = [];
|
||||
$districtCache = [];
|
||||
$subdistrictCache = [];
|
||||
|
||||
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);
|
||||
|
||||
if (count($rows) >= $batchSize) {
|
||||
$this->processBatch($rows, $branchCache, $debitureCache, $hubunganPemilikCache, $provinceCache, $cityCache, $districtCache, $subdistrictCache);
|
||||
$rows = [];
|
||||
}
|
||||
}
|
||||
|
||||
// print_r($rows);
|
||||
if (!empty($rows)) {
|
||||
$this->processBatch($rows, $branchCache, $debitureCache, $hubunganPemilikCache, $provinceCache, $cityCache, $districtCache, $subdistrictCache);
|
||||
}
|
||||
|
||||
fclose($handle);
|
||||
|
||||
$this->command->info('Data permohonan berhasil dimigrasikan.');
|
||||
}
|
||||
|
||||
private function processBatch(array $rows, array &$branchCache, array &$debitureCache, array &$hubunganPemilikCache, array &$provinceCache, array &$cityCache, array &$districtCache, array &$subdistrictCache)
|
||||
{
|
||||
foreach ($rows as $index => $row) {
|
||||
$debitureId = $this->getDebiturId($row['mig_kd_debitur_seq'], $debitureCache);
|
||||
|
||||
if (!$debitureId) {
|
||||
Log::warning('Debitur tidak ditemukan untuk kode: ' . $row['mig_kd_debitur_seq']);
|
||||
continue;
|
||||
}
|
||||
|
||||
$hubunganPemilik = $this->getHubunganPemilikId($row['mig_hubungan_pemilik_jaminan'], $hubunganPemilikCache);
|
||||
|
||||
|
||||
$proviceCode = $this->getProvinceCode($row['mig_province_name'], $provinceCache);
|
||||
$cityCode = $this->getCityCode($row['mig_city_name'], $cityCache);
|
||||
$districtCode = $this->getDistrictCode($row['mig_district_name'], $districtCache);
|
||||
|
||||
$subdistrictCode = $this->getSubdistrictCode($row['mig_village_name'], $subdistrictCache, $districtCache);
|
||||
|
||||
|
||||
PemilikJaminan::create([
|
||||
'debiture_id' => $debitureId,
|
||||
'hubungan_pemilik_jaminan_id' => $hubunganPemilik,
|
||||
'name' => $row['name'],
|
||||
'detail_sertifikat' => null,
|
||||
'npwp' => null,
|
||||
'nomor_id' => null,
|
||||
'email' => null,
|
||||
'phone' => null,
|
||||
'province_code' => $proviceCode,
|
||||
'city_code' => $cityCode,
|
||||
'district_code' => $districtCode,
|
||||
'village_code' => $subdistrictCode['code'],
|
||||
'postal_code' => $subdistrictCode['postal_code'],
|
||||
'address' => $row['address'],
|
||||
'created_at' => $this->parseTimestamp($row['created_at']),
|
||||
'updated_at' => $this->parseTimestamp($row['updated_at']),
|
||||
'mig_kd_debitur_seq' => $row['mig_kd_debitur_seq'],
|
||||
'processed_at' => now(),
|
||||
'is_mig' => 1
|
||||
]);
|
||||
|
||||
$this->command->info('Proses data Pemilik Jaminan ' . $row['name'] . ' (' . ($index + 1) . '/' . count($rows) . ')');
|
||||
}
|
||||
}
|
||||
|
||||
private function getDebiturId(string $code, array &$cache): ?int
|
||||
{
|
||||
if (isset($cache[$code])) {
|
||||
return $cache[$code];
|
||||
}
|
||||
|
||||
$debitur = Debiture::where('mig_kd_debitur_seq', $code)->first();
|
||||
|
||||
if ($debitur) {
|
||||
$cache[$code] = $debitur->id;
|
||||
return $debitur->id;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function getHubunganPemilikId(string $name, array &$cache): ?int
|
||||
{
|
||||
// Normalisasi nama
|
||||
$normalizedName = strtolower(trim($name));
|
||||
|
||||
// Cek cache untuk menghindari query berulang
|
||||
if (isset($cache[$normalizedName])) {
|
||||
return $cache[$normalizedName];
|
||||
}
|
||||
|
||||
// Query database dengan pengamanan tambahan
|
||||
$hubunganPemilik = HubunganPemilikJaminan::whereRaw('LOWER(name) = ?', [$normalizedName])
|
||||
->whereNull('deleted_at') // Tambahkan ini jika Anda menggunakan soft deletes
|
||||
->first();
|
||||
|
||||
// Jika data ditemukan, simpan dalam cache
|
||||
if ($hubunganPemilik) {
|
||||
$cache[$normalizedName] = $hubunganPemilik->id;
|
||||
return $hubunganPemilik->id;
|
||||
}
|
||||
|
||||
// Default jika data tidak ditemukan
|
||||
$cache[$normalizedName] = 1; // Cache nilai default untuk menghindari query berulang
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
private function getProvinceCode(string $name, array &$cache): ?string
|
||||
{
|
||||
|
||||
$normalizedName = strtolower($name);
|
||||
if (isset($cache[$normalizedName])) {
|
||||
return $cache[$normalizedName];
|
||||
}
|
||||
|
||||
$province = Province::whereRaw('LOWER(name) = ?', [strtolower($name)])->first();
|
||||
|
||||
if ($province) {
|
||||
$cache[$normalizedName] = $province->code;
|
||||
return $province->code;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function getCityCode(string $name, array &$cache): ?string
|
||||
{
|
||||
$normalizedName = strtolower($name);
|
||||
if (isset($cache[$normalizedName])) {
|
||||
return $cache[$normalizedName];
|
||||
}
|
||||
|
||||
$city = City::whereRaw('LOWER(name) = ?', [strtolower($name)])->first();
|
||||
|
||||
if ($city) {
|
||||
$cache[$normalizedName] = $city->code;
|
||||
return $city->code;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function getDistrictCode(string $name, array &$cache): ?string
|
||||
{
|
||||
$normalizedName = strtolower($name);
|
||||
if (isset($cache[$normalizedName])) {
|
||||
return $cache[$normalizedName];
|
||||
}
|
||||
|
||||
$district = District::whereRaw('LOWER(name) = ?', [strtolower($name)])->first();
|
||||
|
||||
if ($district) {
|
||||
$cache[$normalizedName] = $district->code;
|
||||
return $district->code;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function getSubdistrictCode(string $name, array &$cache, array &$districtCache): ?array
|
||||
{
|
||||
$normalizedName = strtolower($name);
|
||||
|
||||
// Pastikan cache menyimpan array, bukan hanya kode
|
||||
if (isset($cache[$normalizedName])) {
|
||||
return $cache[$normalizedName];
|
||||
}
|
||||
|
||||
// Ambil subdistrict dari database
|
||||
$subdistrict = Village::whereRaw('LOWER(name) = ?', [$normalizedName])->first();
|
||||
|
||||
// Jika ditemukan, simpan ke dalam cache sebagai array lengkap
|
||||
if ($subdistrict) {
|
||||
$cache[$normalizedName] = [
|
||||
'code' => $subdistrict->code,
|
||||
'postal_code' => $subdistrict->postal_code
|
||||
];
|
||||
return $cache[$normalizedName];
|
||||
}
|
||||
|
||||
// Jika tidak ditemukan, kembalikan null
|
||||
return [
|
||||
'code' => null,
|
||||
'postal_code' => null
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
private function parseDate(?string $date): ?string
|
||||
{
|
||||
try {
|
||||
return $date ? \Carbon\Carbon::createFromFormat('Y-m-d', $date)->toDateString() : null;
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memparsing tanggal: ' . $date);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private function parseTimestamp(?string $timestamp): ?string
|
||||
{
|
||||
try {
|
||||
return $timestamp ? \Carbon\Carbon::createFromFormat('Y-m-d H:i:s', $timestamp)->toDateTimeString() : null;
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memparsing timestamp: ' . $timestamp);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
435
database/seeders/MigrationPenilaiSeeder.php
Normal file
435
database/seeders/MigrationPenilaiSeeder.php
Normal file
@@ -0,0 +1,435 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use Modules\Lpj\Models\DokumenJaminan;
|
||||
use Modules\Lpj\Models\Permohonan;
|
||||
use Modules\Lpj\Models\Penilai;
|
||||
use Modules\Lpj\Models\Laporan;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class MigrationPenilaiSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
protected $errorLogFile = __DIR__ . '/csv/penilai-laporan/mig_penilai_error.csv';
|
||||
public function run()
|
||||
{
|
||||
$this->initializeErrorLog();
|
||||
// Path ke file csv
|
||||
$filePath = realpath(__DIR__ . '/csv/penilai-laporan/mig_penilai.csv');
|
||||
|
||||
if (!$filePath) {
|
||||
Log::error('File csv tidak ditemukan: ' . __DIR__ . '/csv/penilai-laporan/mig_penilai.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);
|
||||
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_lpj
|
||||
$groupedRows = $this->groupRowsByLpj($rows);
|
||||
|
||||
foreach ($groupedRows as $nomorLpj => $groupRows) {
|
||||
try {
|
||||
// Ambil informasi permohonan dan dokument_id
|
||||
$nomorRegis = $this->getNomorRegistrasiPermohonan($nomorLpj, $branchCache);
|
||||
if (!$nomorRegis) {
|
||||
Log::warning("Nomor registrasi tidak ditemukan untuk nomor LPJ: {$nomorLpj}");
|
||||
$errorCount++;
|
||||
$errorDebitureIds[] = $nomorLpj;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Dapatkan type_penilai (misal: standar, sederhana)
|
||||
$firstRow = reset($groupRows);
|
||||
$typePenilai = $this->checkTypePenilai($firstRow['mig_kode_jenis_laporan'] ?? '');
|
||||
|
||||
if (!$typePenilai) {
|
||||
Log::warning("Tidak ada jenis laporan valid untuk nomor LPJ: {$nomorLpj}");
|
||||
$errorCount++;
|
||||
$errorDebitureIds[] = $nomorLpj;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Bangun JSON type_penilai
|
||||
$penilaiJson = $this->cekJenisPenilai($groupRows);
|
||||
|
||||
// Simpan ke tabel Penilai
|
||||
|
||||
// print_r(json_decode($penilaiJson, true));
|
||||
|
||||
// Mapping field JSON berdasarkan tipe penilaian
|
||||
$fillableFieldMap = [
|
||||
'memo' => 'memo',
|
||||
'standar' => 'lpj',
|
||||
'sederhana' => 'lpj',
|
||||
'call_report' => 'call_report',
|
||||
'rap' => 'rap',
|
||||
'resume' => 'resume'
|
||||
];
|
||||
|
||||
$fieldToUpdate = $fillableFieldMap[$typePenilai] ?? null;
|
||||
|
||||
if (!$fieldToUpdate) {
|
||||
Log::warning("Field tidak dikenali untuk tipe: {$typePenilai}");
|
||||
$errorCount++;
|
||||
$errorDebitureIds[] = $nomorLpj;
|
||||
continue;
|
||||
}
|
||||
|
||||
// NO: 001/241917/LPJ/PJ-2251/VII/24
|
||||
// 001 => kode cabang
|
||||
// 241917 => nomor lpj
|
||||
// LPJ => jenis laporan
|
||||
// PJ-2251 => nomor registrasi ambil nilai akhirnnya 242251
|
||||
// VII => bulan
|
||||
// 24 => tahun
|
||||
|
||||
// Generate nomor_laporan
|
||||
$tanggal = $firstRow['mig_crated_at'];
|
||||
$nomorD = $nomorRegis['nomor_registrasi'];
|
||||
$nomorRegistrasi = "PJ-{$nomorD}";
|
||||
$nomorLaporan = $this->generateNomorLaporan($typePenilai, $nomorLpj, $nomorRegistrasi, $tanggal);
|
||||
|
||||
|
||||
// Simpan atau update ke tabel Penilai
|
||||
$penilaiLP = Penilai::updateOrCreate(
|
||||
[
|
||||
'permohonan_id' => $nomorRegis['id'],
|
||||
'dokument_id' => $nomorRegis['dokument_id']
|
||||
],
|
||||
[
|
||||
'type' => $typePenilai,
|
||||
$fieldToUpdate => $penilaiJson,
|
||||
'type_penilai' => $typePenilai,
|
||||
'created_at' => $this->parseTimestamp($tanggal),
|
||||
'updated_at' => $this->parseTimestamp($tanggal),
|
||||
]
|
||||
);
|
||||
|
||||
// Simpan ke tabel Laporan
|
||||
Laporan::updateOrCreate(
|
||||
[
|
||||
'permohonan_id' => $penilaiLP->permohonan_id,
|
||||
'dokumen_jaminan_id' => $penilaiLP->dokument_id
|
||||
],
|
||||
[
|
||||
'nomor_laporan' => $nomorLaporan,
|
||||
'created_at' => $this->parseTimestamp($tanggal),
|
||||
'updated_at' => $this->parseTimestamp($tanggal)
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
$this->command->info("Berhasil simpan data penilai untuk nomor LPJ: {$nomorLpj}");
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::error("Error pada nomor LPJ {$nomorLpj}: " . $e->getMessage());
|
||||
$errorCount++;
|
||||
$errorDebitureIds[] = $nomorLpj;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private function getNomorRegistrasiPermohonan($nomorLpj, array &$cache)
|
||||
{
|
||||
if (isset($cache[$nomorLpj])) {
|
||||
return $cache[$nomorLpj];
|
||||
}
|
||||
|
||||
$permohonan = Permohonan::where('nomor_lpj', $nomorLpj)->first();
|
||||
|
||||
if (!$permohonan) {
|
||||
$cache[$nomorLpj] = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
$dokumenJaminan = DokumenJaminan::where('permohonan_id', $permohonan->id)->first();
|
||||
|
||||
$result = [
|
||||
'id' => $permohonan->id,
|
||||
'dokument_id' => $dokumenJaminan ? $dokumenJaminan->id : null,
|
||||
'nomor_registrasi' => $permohonan->nomor_registrasi
|
||||
];
|
||||
|
||||
$cache[$nomorLpj] = $result;
|
||||
|
||||
return $result;
|
||||
}
|
||||
private function groupRowsByLpj(array $rows): array
|
||||
{
|
||||
$grouped = [];
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$nomorLpj = $row['mig_nomor_lpj'] ?? null;
|
||||
|
||||
if (!empty($nomorLpj)) {
|
||||
$grouped[$nomorLpj][] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
return $grouped;
|
||||
}
|
||||
|
||||
private function checkTypePenilai($type)
|
||||
{
|
||||
$data = [
|
||||
'MAK' => 'memo',
|
||||
'STD' => 'standar',
|
||||
'SPL' => 'sederhana',
|
||||
'RHP' => 'call-report',
|
||||
'RAP' => 'rap',
|
||||
'PRG' => 'resume',
|
||||
];
|
||||
|
||||
return $data[$type];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private function cekJenisPenilai(array $groupRows)
|
||||
{
|
||||
// Urutkan grup berdasarkan mig_urutan_seq
|
||||
usort($groupRows, function ($a, $b) {
|
||||
return ($a['mig_urutan_seq'] ?? 999) <=> ($b['mig_urutan_seq'] ?? 999);
|
||||
});
|
||||
|
||||
// Inisialisasi struktur JSON
|
||||
$penilaiJson = [
|
||||
'luas_tanah' => null,
|
||||
'nilai_tanah_1' => null,
|
||||
'nilai_tanah_2' => null,
|
||||
'sarana_pelengkap_penilai' => null,
|
||||
'nilai_sarana_pelengkap_1' => null,
|
||||
'nilai_sarana_pelengkap_2' => null,
|
||||
'total_nilai_pasar_wajar' => null,
|
||||
'likuidasi' => null,
|
||||
'likuidasi_nilai_1' => null,
|
||||
'likuidasi_nilai_2' => null,
|
||||
'asuransi_luas_bangunan' => null,
|
||||
'asuransi_nilai_1' => null,
|
||||
'asuransi_nilai_2' => "0",
|
||||
'npw_tambahan' => []
|
||||
];
|
||||
|
||||
// Ambil mainRow (urutan pertama)
|
||||
$mainRow = null;
|
||||
foreach ($groupRows as $row) {
|
||||
if (($row['mig_urutan_seq'] ?? '') == 1) {
|
||||
$mainRow = $row;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Jika tidak ada mainRow, ambil baris pertama sebagai fallback
|
||||
if (!$mainRow && !empty($groupRows[0])) {
|
||||
$mainRow = $groupRows[0];
|
||||
}
|
||||
|
||||
if ($mainRow) {
|
||||
$penilaiJson['total_nilai_pasar_wajar'] = $mainRow['mig_nilai_total_nilai_pasar'] ?? null;
|
||||
$penilaiJson['likuidasi'] = $mainRow['mig_nilai_likudasi'] ?? null;
|
||||
|
||||
// Hitung likuidasi nilai 2 jika ada total dan persen likuidasi
|
||||
$totalPasarWajar = (int)str_replace('.', '', $mainRow['mig_nilai_total_nilai_pasar'] ?? 0);
|
||||
$persenLikuidasi = (int)($mainRow['mig_nilai_likudasi'] ?? 0);
|
||||
$penilaiJson['likuidasi_nilai_1'] = $mainRow['mig_nilai_total_nilai_pasar'] ?? null;
|
||||
$penilaiJson['likuidasi_nilai_2'] = number_format(
|
||||
$totalPasarWajar * ($persenLikuidasi / 100),
|
||||
0,
|
||||
'',
|
||||
''
|
||||
);
|
||||
|
||||
// Isi data utama hanya untuk urutan 1
|
||||
$penilaiJson['luas_tanah'] = $mainRow['mig_nilai_satuan'] ?? null;
|
||||
$penilaiJson['nilai_tanah_1'] = $mainRow['mig_harga_satuan'] ?? null;
|
||||
$penilaiJson['nilai_tanah_2'] = number_format(
|
||||
(int)str_replace('.', '', $mainRow['mig_nilai_satuan'] ?? 0) *
|
||||
(int)str_replace('.', '', $mainRow['mig_harga_satuan'] ?? 0),
|
||||
0,
|
||||
'',
|
||||
''
|
||||
);
|
||||
}
|
||||
|
||||
// Proses tambahan (urutan > 1)
|
||||
foreach ($groupRows as $row) {
|
||||
// Skip baris dengan urutan_seq = 1 karena sudah diproses
|
||||
if (($row['mig_urutan_seq'] ?? '') == 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Hanya proses jika mig_urutan_seq ada
|
||||
$urutan = $row['mig_urutan_seq'] ?? '';
|
||||
if (empty($urutan)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Tambahkan ke npw_tambahan
|
||||
$penilaiJson['npw_tambahan'][] = [
|
||||
'name' => $row['mig_keterangan'] ?? 'Luas Bangunan Tambahan',
|
||||
'luas' => $row['mig_nilai_satuan'] ?? null,
|
||||
'nilai_1' => $row['mig_harga_satuan'] ?? null,
|
||||
'nilai_2' => number_format(
|
||||
(int)str_replace('.', '', $row['mig_nilai_satuan'] ?? 0) *
|
||||
(int)str_replace('.', '', $row['mig_harga_satuan'] ?? 0),
|
||||
0,
|
||||
'',
|
||||
''
|
||||
)
|
||||
];
|
||||
}
|
||||
|
||||
// Kosongkan npw_tambahan jika kosong
|
||||
if (empty($penilaiJson['npw_tambahan'])) {
|
||||
$penilaiJson['npw_tambahan'] = [];
|
||||
}
|
||||
|
||||
return json_encode($penilaiJson, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
||||
}
|
||||
|
||||
private function convertToRoman($month)
|
||||
{
|
||||
$roman = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X', 'XI', 'XII'];
|
||||
return $month >= 1 && $month <= 12 ? $roman[$month - 1] : '';
|
||||
}
|
||||
|
||||
private function generateNomorLaporan($typePenilai, $nomorLpj, $nomorRegistrasi, $tanggal)
|
||||
{
|
||||
// Mapping type_penilai ke singkatan laporan
|
||||
$laporanMap = [
|
||||
'memo' => 'MEMO',
|
||||
'standar' => 'LPJ',
|
||||
'sederhana' => 'LPJ',
|
||||
'call_report' => 'CALL',
|
||||
'rap' => 'RAP',
|
||||
'resume' => 'RESUME'
|
||||
];
|
||||
|
||||
// Dapatkan tahun dan bulan dari tanggal
|
||||
$date = \Carbon\Carbon::parse($tanggal);
|
||||
$kodeCabang = '001'; // bisa diambil dari user atau parameter lain jika dinamis
|
||||
$tahun = substr($date->year, -2); // 2024 → 24
|
||||
$bulan = $this->convertToRoman($date->month); // 7 → VII
|
||||
|
||||
// Format akhir nomor registrasi (PJ-XXX)
|
||||
$nomorDebiturAkhir = substr($nomorRegistrasi, -4); // PJ-2251 → 2251
|
||||
|
||||
return sprintf(
|
||||
"%s/%s/%s/%s/%s/%s",
|
||||
$kodeCabang,
|
||||
$nomorLpj,
|
||||
$laporanMap[$typePenilai] ?? strtoupper($typePenilai),
|
||||
"PJ-" . $nomorDebiturAkhir,
|
||||
$bulan,
|
||||
$tahun
|
||||
);
|
||||
}
|
||||
|
||||
private function parseTimestamp(?string $timestamp): ?string
|
||||
{
|
||||
try {
|
||||
if ($timestamp) {
|
||||
// Cek jika format hanya tanggal (Y-m-d)
|
||||
if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $timestamp)) {
|
||||
return \Carbon\Carbon::createFromFormat('Y-m-d', $timestamp)
|
||||
->startOfDay()
|
||||
->toDateTimeString();
|
||||
}
|
||||
// Format lengkap (Y-m-d H:i:s)
|
||||
return \Carbon\Carbon::createFromFormat('Y-m-d H:i:s', $timestamp)->toDateTimeString();
|
||||
}
|
||||
return null;
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memparsing timestamp: ' . $timestamp . '. Pesan: ' . $e->getMessage());
|
||||
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);
|
||||
}
|
||||
}
|
||||
376
database/seeders/MigrationPermohonanSeeder.php
Normal file
376
database/seeders/MigrationPermohonanSeeder.php
Normal file
@@ -0,0 +1,376 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Modules\Lpj\Models\Permohonan;
|
||||
use Modules\Lpj\Models\Debiture;
|
||||
use Modules\Basicdata\Models\Branch;
|
||||
use Modules\Usermanagement\Models\User;
|
||||
|
||||
class MigrationPermohonanSeeder extends Seeder
|
||||
{
|
||||
protected $errorLogFile = __DIR__ . '/csv/permohonan/mig_permohonan_extenal_error.csv';
|
||||
|
||||
public function run()
|
||||
{
|
||||
// Bersihkan file error sebelum mulai
|
||||
$this->initializeErrorLog();
|
||||
|
||||
$filePath = realpath(__DIR__ . '/csv/permohonan/mig_permohonan_external.csv');
|
||||
|
||||
if (!$filePath) {
|
||||
Log::error('File CSV tidak ditemukan: ' . __DIR__ . '/csv/permohonan/mig_permohonan_external.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;
|
||||
$branchCache = [];
|
||||
$debitureCache = [];
|
||||
$totalData = 0;
|
||||
$currentRow = 0;
|
||||
$batchCount = 0;
|
||||
|
||||
// Hitung total data
|
||||
while (fgetcsv($handle, 0, '~') !== false) {
|
||||
$totalData++;
|
||||
}
|
||||
|
||||
rewind($handle);
|
||||
fgetcsv($handle, 0, '~'); // Lewati header
|
||||
|
||||
while (($data = fgetcsv($handle, 0, '~')) !== false) {
|
||||
if (count($data) != count($header)) {
|
||||
$nomorJaminan = $data[array_search('mig_mst_jaminan_nomor_jaminan', $header)] ?? '-';
|
||||
$this->logError($nomorJaminan, 'Jumlah kolom tidak sesuai');
|
||||
continue;
|
||||
}
|
||||
|
||||
$rows[] = array_combine($header, $data);
|
||||
$currentRow++;
|
||||
// print_r($rows);
|
||||
if (count($rows) >= $batchSize) {
|
||||
$batchCount++;
|
||||
$this->command->info("Memproses batch ke-{$batchCount} ({$currentRow}/{$totalData})");
|
||||
$this->processBatch($rows, $branchCache, $debitureCache, $totalData, $batchCount);
|
||||
$rows = [];
|
||||
}
|
||||
}
|
||||
|
||||
// print_r($rows);
|
||||
|
||||
if (!empty($rows)) {
|
||||
$batchCount++;
|
||||
$this->command->info("Memproses batch ke-{$batchCount} ({$currentRow}/{$totalData})");
|
||||
$this->processBatch($rows, $branchCache, $debitureCache, $totalData, $batchCount);
|
||||
}
|
||||
|
||||
fclose($handle);
|
||||
|
||||
$this->command->info("Migrasi selesai. Total data diproses: $totalData.");
|
||||
}
|
||||
|
||||
private function processBatch(array $rows, array &$branchCache, array &$debitureCache, int $totalData, int $batchCount)
|
||||
{
|
||||
$userData = [];
|
||||
foreach ($rows as $index => $row) {
|
||||
try {
|
||||
$nomorJaminan = $row['mig_mst_jaminan_nomor_jaminan'] ?? '-';
|
||||
|
||||
// Cek apakah sudah diproses
|
||||
$existingRecord = Permohonan::where('nomor_registrasi', $row['mig_mst_jaminan_nomor_jaminan'])->first();
|
||||
if ($existingRecord && $existingRecord->processed_at) {
|
||||
$this->command->info("Data sudah diproses: $nomorJaminan");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ambil branch_id
|
||||
$branchId = $this->getBranchId($row['mig_mst_jaminan_kd_cabang'] ?? null, $branchCache);
|
||||
// if (!$branchId) {
|
||||
// $this->logError($branchId, 'Cabang tidak ditemukan');
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// Ambil Debitur ID
|
||||
$debitureId = $this->getDebiturId($row['mig_mst_jaminan_kd_debitur_seq'], $debitureCache);
|
||||
if (!$debitureId) {
|
||||
$this->logError($nomorJaminan, 'Debitur tidak ditemukan');
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ambil User IDs
|
||||
$userId = $this->getUserId($row['mig_mst_jaminan_nama_ao'], $branchCache, true);
|
||||
|
||||
// jika external matikan
|
||||
// $approved1Id = $this->getUserId($row['mig_mst_lpj_user_approved_1'], $branchCache, false);
|
||||
// $approved2Id = $this->getUserId($row['mig_mst_lpj_user_approved_2'], $branchCache, false);
|
||||
|
||||
// // Ambil user IDs berdasarkan NIK
|
||||
$userIdUpdate = $this->getUserIdData($row['mig_mst_jaminan_user_create'] ?? null, $userData)['id'];
|
||||
$userIdOtorisasi = $this->getUserIdData($row['mig_mst_jaminan_user_oto'] ?? null, $userData)['id'];
|
||||
|
||||
// jika external matikan
|
||||
// if (!$userIdUpdate || !$userIdOtorisasi) {
|
||||
// $this->logError($userIdUpdate, 'Salah satu user tidak ditemukan');
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// Mapping field user
|
||||
$mapUser = [
|
||||
'created_by' => $userIdUpdate,
|
||||
'updated_by' => $userIdUpdate,
|
||||
'authorized_by' => $userIdOtorisasi,
|
||||
];
|
||||
|
||||
// jika external matikan
|
||||
// if (!$userId || !$approved1Id || !$approved2Id) {
|
||||
// $this->logError($userId, 'Salah satu user tidak ditemukan');
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// Mapping data
|
||||
$jenisFasilitas = $this->checkJenisFasilitas($row['mig_mst_jaminan_kd_jenis_fas_seq']);
|
||||
$tujuanPenilaian = $this->checkTujuanPenilaian($row['mig_mst_jaminan_kd_tujuan_seq']);
|
||||
$regionId = $this->checkRegion($row['mig_mst_kode_kelompok_region']);
|
||||
|
||||
|
||||
$nomor_lpj = isset($row['mig_mst_lpj_nomor_lpj']) ? $row['mig_mst_lpj_nomor_lpj'] : '';
|
||||
$nomor_lpj = is_numeric($nomor_lpj) ? (int)$nomor_lpj : 0;
|
||||
|
||||
$jenisPenilaian = $row['mig_internal_or_external'] == 1 ? 2 : 1;
|
||||
|
||||
// Simpan data
|
||||
Permohonan::create([
|
||||
'nomor_registrasi' => $nomorJaminan,
|
||||
'tanggal_permohonan' => $this->parseDate($row['tanggal_permohonan']),
|
||||
'user_id' => $userId['id'],
|
||||
'branch_id' => $branchId,
|
||||
'tujuan_penilaian_id' => $tujuanPenilaian,
|
||||
'debiture_id' => $debitureId,
|
||||
'jenis_fasilitas_kredit_id' => $jenisFasilitas,
|
||||
'nilai_plafond_id' => 2,
|
||||
'status' => 'done',
|
||||
// jika external matikan
|
||||
// 'approval_eo' => $approved2Id['id'] ?? 0,
|
||||
// 'approval_eo_at' => $this->parseTimestamp($row['mig_mst_lpj_tgl_approved_2']),
|
||||
// 'approval_dd' => 0,
|
||||
// 'approval_dd_at' => null,
|
||||
// 'approval_so' => $approved1Id['id'] ?? 0,
|
||||
// 'approval_so_at' => $this->parseTimestamp($row['mig_mst_lpj_tgl_approved_1']),
|
||||
// end external matikan
|
||||
'keterangan' => $row['mig_mst_jaminan_catatan'] ?? null,
|
||||
'status_bayar' => 'sudah_bayar',
|
||||
'created_at' => $this->parseTimestamp($row['mig_mst_jaminan_tgl_create']),
|
||||
'updated_at' => $this->parseTimestamp($row['mig_mst_jaminan_tgl_update']),
|
||||
'mig_kd_debitur_seq' => $row['mig_mst_jaminan_kd_debitur_seq'],
|
||||
'nomor_lpj' => $nomor_lpj,
|
||||
'region_id' => $regionId,
|
||||
'jenis_penilaian_id' => $jenisPenilaian,
|
||||
'authorized_by' => $mapUser['authorized_by'],
|
||||
'created_by' => $mapUser['created_by'],
|
||||
'updated_by' => $mapUser['updated_by'],
|
||||
'mig_nama_ao' => $row['mig_mst_jaminan_nama_ao'],
|
||||
'is_mig' => 1
|
||||
]);
|
||||
|
||||
$this->command->info("Proses data permohonan $nomorJaminan (" . ($index + 1) . '/' . count($rows) . " pada batch ke-$batchCount)");
|
||||
|
||||
} catch (\Exception $e) {
|
||||
$nomorJaminan = $row['mig_mst_jaminan_nomor_jaminan'] ?? '-';
|
||||
$this->logError($nomorJaminan, "Error eksepsi: " . $e->getMessage());
|
||||
continue;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function getUserIdData(?string $code, array &$cache): array
|
||||
{
|
||||
if (!$code) {
|
||||
return ['id' => null, 'branch_id' => null];
|
||||
}
|
||||
|
||||
if (isset($cache[$code])) {
|
||||
return $cache[$code];
|
||||
}
|
||||
|
||||
$user = User::where('nik', $code)->first();
|
||||
|
||||
if ($user) {
|
||||
$cache[$code] = ['id' => $user->id, 'branch_id' => $user->branch_id];
|
||||
return $cache[$code];
|
||||
}
|
||||
|
||||
return ['id' => null, 'branch_id' => null];
|
||||
}
|
||||
|
||||
private function getUserId(string $value, array &$cache, bool $includeBranch = false): ?array
|
||||
{
|
||||
if (isset($cache[$value])) {
|
||||
return $cache[$value];
|
||||
}
|
||||
|
||||
$user = null;
|
||||
|
||||
if ($includeBranch) {
|
||||
$user = User::whereRaw('LOWER(name) = ?', [strtolower($value)])->first();
|
||||
} else {
|
||||
$user = User::where('nik', $value)->first();
|
||||
}
|
||||
|
||||
if ($user) {
|
||||
$result = ['id' => $user->id];
|
||||
if ($includeBranch) {
|
||||
$result['branch_id'] = $user->branch_id;
|
||||
}
|
||||
$cache[$value] = $result;
|
||||
return $result;
|
||||
}
|
||||
|
||||
return ['id' => null, 'branch_id' => null];
|
||||
}
|
||||
|
||||
private function getDebiturId(string $code, array &$cache): ?int
|
||||
{
|
||||
if (isset($cache[$code])) {
|
||||
return $cache[$code];
|
||||
}
|
||||
|
||||
$debitur = Debiture::where('mig_kd_debitur_seq', $code)->first();
|
||||
|
||||
if ($debitur) {
|
||||
$cache[$code] = $debitur->id;
|
||||
return $debitur->id;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
private function getBranchId(?string $code, array &$cache): ?int
|
||||
{
|
||||
if (!$code) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isset($cache[$code])) {
|
||||
return $cache[$code];
|
||||
}
|
||||
|
||||
$branch = Branch::where('code', $code)->first();
|
||||
|
||||
if ($branch) {
|
||||
$cache[$code] = $branch->id;
|
||||
return $branch->id;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
private function checkJenisFasilitas($code): int
|
||||
{
|
||||
$mapping = [
|
||||
161337594516 => 1,
|
||||
161337598118 => 14,
|
||||
155739382483 => 7,
|
||||
2 => 9,
|
||||
153568936592 => 10,
|
||||
155737674431 => 11,
|
||||
161337561199 => 12,
|
||||
1 => 13,
|
||||
];
|
||||
|
||||
return $mapping[$code] ?? 0;
|
||||
}
|
||||
|
||||
private function checkTujuanPenilaian($code): int
|
||||
{
|
||||
$mapping = [
|
||||
1 => 1,
|
||||
2 => 2,
|
||||
3 => 9,
|
||||
4 => 10,
|
||||
5 => 8,
|
||||
6 => 3,
|
||||
];
|
||||
|
||||
return $mapping[$code] ?? 1;
|
||||
}
|
||||
|
||||
private function checkRegion($code): int
|
||||
{
|
||||
$mapping = [
|
||||
'01' => 1,
|
||||
'02' => 2,
|
||||
'04' => 3,
|
||||
'07' => 4,
|
||||
'06' => 5,
|
||||
];
|
||||
|
||||
return $mapping[$code] ?? 1;
|
||||
}
|
||||
|
||||
private function parseDate(?string $date): ?string
|
||||
{
|
||||
try {
|
||||
return $date ? \Carbon\Carbon::createFromFormat('Y-m-d', $date)->toDateString() : null;
|
||||
} catch (\Exception $e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private function parseTimestamp(?string $timestamp): ?string
|
||||
{
|
||||
try {
|
||||
if ($timestamp) {
|
||||
// Cek jika format hanya tanggal (Y-m-d)
|
||||
if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $timestamp)) {
|
||||
return \Carbon\Carbon::createFromFormat('Y-m-d', $timestamp)
|
||||
->startOfDay()
|
||||
->toDateTimeString();
|
||||
}
|
||||
// Format lengkap (Y-m-d H:i:s)
|
||||
return \Carbon\Carbon::createFromFormat('Y-m-d H:i:s', $timestamp)->toDateTimeString();
|
||||
}
|
||||
return null;
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memparsing timestamp: ' . $timestamp . '. Pesan: ' . $e->getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private function initializeErrorLog()
|
||||
{
|
||||
$file = $this->errorLogFile;
|
||||
|
||||
// Hapus file lama jika ada
|
||||
if (file_exists($file)) {
|
||||
unlink($file);
|
||||
}
|
||||
|
||||
// Buat file baru dengan header
|
||||
$handle = fopen($file, 'w');
|
||||
fputcsv($handle, ['mig_mst_jaminan_nomor_jaminan', 'Error']);
|
||||
fclose($handle);
|
||||
}
|
||||
|
||||
private function logError($nomorJaminan, string $message)
|
||||
{
|
||||
Log::error("Error migrasi permohonan [$nomorJaminan]: $message");
|
||||
|
||||
// Tulis ke file error
|
||||
$handle = fopen($this->errorLogFile, 'a');
|
||||
fputcsv($handle, [$nomorJaminan, $message]);
|
||||
fclose($handle);
|
||||
}
|
||||
}
|
||||
16
database/seeders/PosisiKavlingSeeder.php
Normal file
16
database/seeders/PosisiKavlingSeeder.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class PosisiKavlingSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
// $this->call([]);
|
||||
}
|
||||
}
|
||||
16
database/seeders/PosisiUnitSeeder.php
Normal file
16
database/seeders/PosisiUnitSeeder.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class PosisiUnitSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
// $this->call([]);
|
||||
}
|
||||
}
|
||||
16
database/seeders/SaranaPelengkapSeeder.php
Normal file
16
database/seeders/SaranaPelengkapSeeder.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class SaranaPelengkapSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
// $this->call([]);
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ namespace Modules\Lpj\Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use Modules\Lpj\Models\Teams;
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
class TeamsSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
@@ -12,14 +12,6 @@ class TeamsSeeder extends Seeder
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
Teams::insert([
|
||||
[
|
||||
'regions_id' => 1,
|
||||
'code' => 'T01',
|
||||
'name' => 'Team 1',
|
||||
'created_at' => now(),
|
||||
'updated_at' => now()
|
||||
]
|
||||
]);
|
||||
DB::unprepared(file_get_contents(__DIR__ . '/sql/teams.sql'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,36 @@ class TujuanPenilaianKJPPSeeder extends Seeder
|
||||
'status' => 1,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now()
|
||||
]
|
||||
],
|
||||
[
|
||||
'code' => 'TPK05',
|
||||
'name' => 'Penilaian Ulang Jaminan / Review Tahunan',
|
||||
'status' => 1,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now()
|
||||
],
|
||||
[
|
||||
'code' => 'TPK06',
|
||||
'name' => 'Lelang',
|
||||
'status' => 1,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now()
|
||||
],
|
||||
[
|
||||
'code' => 'TPK07',
|
||||
'name' => 'Permohonan Baru',
|
||||
'status' => 1,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now()
|
||||
],
|
||||
[
|
||||
'code' => 'TPK08',
|
||||
'name' => 'Penambahan Fasilitas / Jaminan',
|
||||
'status' => 1,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now()
|
||||
],
|
||||
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,38 @@ class TujuanPenilaianSeeder extends Seeder
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
'deleted_at' => null,
|
||||
],
|
||||
[
|
||||
'code' => 'TP0007',
|
||||
'name' => 'Jual Beli',
|
||||
'status' => 1,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
'deleted_at' => null,
|
||||
],
|
||||
[
|
||||
'code' => 'TP0008',
|
||||
'name' => 'KPR eks BPPN',
|
||||
'status' => 1,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
'deleted_at' => null,
|
||||
],
|
||||
[
|
||||
'code' => 'TP0009',
|
||||
'name' => 'Penambahan Fasilitas / Jaminan',
|
||||
'status' => 1,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now()
|
||||
],
|
||||
[
|
||||
'code' => 'TP00010',
|
||||
'name' => 'Penukaran Jaminan',
|
||||
'status' => 1,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now()
|
||||
]
|
||||
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
10
database/seeders/sql/fasilitas_objek.sql
Normal file
10
database/seeders/sql/fasilitas_objek.sql
Normal file
@@ -0,0 +1,10 @@
|
||||
INSERT INTO `fasilitas_objek` (`id`, `code`, `name`, `status`, `authorized_status`, `created_at`, `updated_at`, `authorized_at`, `authorized_by`, `deleted_at`, `created_by`, `updated_by`, `deleted_by`) VALUES
|
||||
(1, 'FU001', 'Tempat Ibadah', 1, NULL, '2024-11-28 18:57:35', '2024-11-28 18:57:35', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(2, 'FU002', 'Rumah Sakit', 1, NULL, '2024-11-28 18:57:50', '2024-11-28 18:57:50', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(3, 'FU003', 'Sekolah', 1, NULL, '2024-11-28 18:58:05', '2024-11-28 18:58:05', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(4, 'FU004', 'Kantor Pemerintahan', 1, NULL, '2024-11-28 18:58:27', '2024-11-28 18:58:27', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(5, 'FU005', 'Stasiun Kereta', 1, NULL, '2024-11-28 18:58:49', '2024-11-28 18:58:49', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(6, 'FU006', 'Terminal Bus', 1, NULL, '2024-11-28 18:59:09', '2024-11-28 18:59:09', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(7, 'FU007', 'Bandara', 1, NULL, '2024-11-28 18:59:26', '2024-11-28 18:59:26', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(8, 'FU009', 'Pos Polisi', 1, NULL, '2024-11-28 18:59:50', '2024-11-28 18:59:50', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(9, 'FU010', 'Lainnya', 1, NULL, '2024-11-28 19:00:07', '2024-11-28 19:00:07', NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
4
database/seeders/sql/gol_mas_sekitar.sql
Normal file
4
database/seeders/sql/gol_mas_sekitar.sql
Normal file
@@ -0,0 +1,4 @@
|
||||
INSERT INTO `gol_mas_sekitar` (`id`, `code`, `name`, `status`, `authorized_status`, `created_at`, `updated_at`, `authorized_at`, `authorized_by`, `deleted_at`, `created_by`, `updated_by`, `deleted_by`) VALUES
|
||||
(1, 'GMS001', 'Menengah', 1, NULL, '2024-11-05 00:36:23', '2024-11-05 00:36:23', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(2, 'GMS002', 'Menengah Bawah', 1, NULL, '2024-11-05 00:36:35', '2024-11-05 00:36:35', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(3, 'GMS003', 'Menengah Atas', 1, NULL, '2024-11-05 00:36:48', '2024-11-05 00:36:48', NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
6
database/seeders/sql/jenis_bangunan.sql
Normal file
6
database/seeders/sql/jenis_bangunan.sql
Normal file
@@ -0,0 +1,6 @@
|
||||
INSERT INTO `jenis_bangunan` (`id`, `code`, `name`, `status`, `authorized_status`, `created_at`, `updated_at`, `authorized_at`, `authorized_by`, `deleted_at`, `created_by`, `updated_by`, `deleted_by`) VALUES
|
||||
(1, 'JB001', 'Rumah', 1, NULL, '2024-11-04 21:43:16', '2024-11-04 21:43:16', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(2, 'JB002', 'Ruko', 1, NULL, '2024-11-04 21:43:28', '2024-11-04 21:43:28', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(3, 'JB003', 'Gudang', 1, NULL, '2024-11-04 21:43:41', '2024-11-04 21:43:41', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(4, 'JB004', 'Pabrik', 1, NULL, '2024-11-04 21:43:53', '2024-11-04 21:43:53', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(5, 'JB005', 'Lainnya', 1, NULL, '2024-11-04 21:44:08', '2024-11-04 21:44:08', NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
@@ -1,29 +1,44 @@
|
||||
INSERT INTO jenis_jaminan VALUES
|
||||
(1, 'JJ001', 'Tanah', 'tanah', '[\"tanah\", \"lingkungan\", \"fakta\"]', '[\"JLJ001\",\"JLJ003\",\"JLJ004\",\"JLJ005\",\"JLJ006\",\"JLJ022\"]', 1, '2024-12-06 09:16:02', '2024-12-06 09:16:02', NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(2, 'JJ002', 'Unit Apartemen', 'unit-apartemen', '[\"apartemen-kantor\", \"lingkungan\", \"fakta\", \"informasi\"]', '[\"JLJ001\",\"JLJ003\",\"JLJ004\",\"JLJ006\",\"JLJ007\",\"JLJ022\",\"JLJ024\"]', 1, '2024-12-06 09:16:02', '2024-12-06 09:16:02', NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(3, 'JJ003', 'Kawasan Industrial / Komersil / Residensial - Perumahan', 'kawasan-industrial-komersil-residensial-perumahan', '[\"tanah\", \"bangunan\", \"lingkungan\", \"fakta\", \"informasi\"]', '[\"JLJ001\",\"JLJ003\",\"JLJ004\",\"JLJ006\",\"JLJ007\",\"JLJ008\",\"JLJ022\"]', 1, '2024-12-06 09:16:02', '2024-12-06 09:16:02', NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(4, 'JJ004', 'Mall', 'mall', 'null', '[\"JLJ001\",\"JLJ003\",\"JLJ004\",\"JLJ006\",\"JLJ007\",\"JLJ009\",\"JLJ012\",\"JLJ013\",\"JLJ014\",\"JLJ015\",\"JLJ021\",\"JLJ022\"]', 1, '2024-12-06 09:16:02', '2024-12-06 09:16:02', NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(5, 'JJ005', 'Pabrik', 'pabrik', 'null', '[\"JLJ001\",\"JLJ003\",\"JLJ004\",\"JLJ006\",\"JLJ007\",\"JLJ009\",\"JLJ011\"]', 1, '2024-12-06 09:16:02', '2024-12-06 09:16:02', NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(6, 'JJ006', 'Emas dan Perak', 'emas-dan-perak', 'null', '[\"JLJ001\",\"JLJ007\",\"JLJ014\",\"JLJ022\"]', 1, '2024-12-06 09:16:02', '2024-12-06 09:16:02', NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(7, 'JJ007', 'Alat Berat', 'alat-berat', 'null', '[\"JLJ004\"]', 1, '2024-12-06 09:16:02', '2024-12-06 09:16:02', NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(8, 'JJ008', 'Rumah Tinggal', 'rumah-tinggal', '[\"tanah\", \"bangunan\", \"lingkungan\", \"fakta\", \"informasi\"]', '[\"JLJ001\",\"JLJ003\",\"JLJ004\",\"JLJ006\",\"JLJ007\",\"JLJ009\",\"JLJ024\"]', 1, '2024-12-06 09:16:02', '2024-12-06 09:16:02', NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(9, 'JJ009', 'Full Properti', 'full-properti', '[\"tanah\", \"bangunan\", \"informasi\"]', '[\"JLJ001\",\"JLJ006\",\"JLJ007\",\"JLJ009\"]', 1, '2024-12-06 09:16:02', '2024-12-10 22:07:46', NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(10, 'JJ010', 'Gudang', 'gudang', '[\"tanah\", \"bangunan\", \"lingkungan\", \"fakta\", \"informasi\"]', '[\"JLJ001\",\"JLJ003\",\"JLJ007\",\"JLJ009\",\"JLJ024\"]', 1, '2024-12-06 09:16:02', '2024-12-06 09:16:02', NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(11, 'JJ011', 'Unit Kios', 'unit-kios', '[\"apartemen-kantor\", \"lingkungan\", \"fakta\", \"informasi\"]', '[\"JLJ001\",\"JLJ007\",\"JLJ009\",\"JLJ024\"]', 1, '2024-12-06 09:16:02', '2024-12-06 09:16:02', NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(12, 'JJ012', 'Gedung Mall', 'gedung-mall', '[\"tanah\", \"bangunan\", \"lingkungan\", \"fakta\", \"informasi\"]', '[\"JLJ001\",\"JLJ007\",\"JLJ009\"]', 1, '2024-12-06 09:16:02', '2024-12-06 09:16:02', NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(13, 'JJ013', 'Tanah Bangunan', 'tanah-bangunan', '[\"tanah\", \"bangunan\"]', '[\"JLJ001\",\"JLJ003\",\"JLJ005\",\"JLJ007\",\"JLJ009\",\"JLJ022\",\"JLJ024\"]', 1, '2024-12-06 09:16:02', '2024-12-06 09:16:02', NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(14, 'JJ014', 'Apartemen', 'apartemen', '[\"apartemen-kantor\", \"lingkungan\", \"fakta\", \"informasi\"]', '[\"JLJ001\",\"JLJ003\",\"JLJ022\",\"JLJ024\"]', 1, '2024-12-06 09:16:02', '2024-12-06 09:16:02', NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(15, 'JJ015', 'Ruko', 'ruko', '[\"tanah\", \"bangunan\"]', '[\"JLJ001\",\"JLJ003\",\"JLJ007\",\"JLJ022\"]', 1, '2024-12-06 09:16:02', '2024-12-06 09:16:02', NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(16, 'JJ016', 'Mesin Tekstil', 'mesin-tekstil', '[\"mesin\"]', '[\"JLJ011\",\"JLJ022\"]', 1, '2024-12-06 09:16:02', '2024-12-06 09:16:02', NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(17, 'JJ017', 'Mesin', 'mesin', '[\"mesin\"]', '[\"JLJ011\",\"JLJ022\"]', 1, '2024-12-06 09:16:02', '2024-12-06 09:16:02', NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(18, 'JJ018', 'Mesin Tenun Tekstil', 'mesin-tenun-tekstil', '[\"mesin\"]', '[\"JLJ011\",\"JLJ022\"]', 1, '2024-12-06 09:16:02', '2024-12-06 09:16:02', NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(19, 'JJ019', 'Penilaian Bisnis', 'penilaian-bisnis', '[\"fakta\", \"informasi\"]', '[\"JLJ001\",\"JLJ007\",\"JLJ014\"]', 1, '2024-12-10 02:34:01', '2024-12-10 02:34:01', NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(20, 'JJ020', 'Penilaian Tanah dan Bangunan', 'penilaian-tanah-dan-bangunan', '[\"tanah\", \"bangunan\"]', '[\"JLJ001\",\"JLJ003\",\"JLJ007\"]', 1, '2024-12-10 02:34:54', '2024-12-10 02:34:54', NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(21, 'JJ021', 'Penilaian Mesin', 'penilaian-mesin', '[\"mesin\"]', '[\"JLJ011\",\"JLJ022\"]', 1, '2024-12-10 03:00:13', '2024-12-10 03:00:13', NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(22, 'JJ022', 'Penilian Kapal dan Pesawat', 'penilian-kapal-dan-pesawat', '[\"kapal\", \"pesawat\"]', '[\"JLJ011\",\"JLJ022\"]', 1, '2024-12-10 03:01:00', '2024-12-10 03:01:00', NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(23, 'JJ023', 'Tanah Kosong', 'tanah-kosong', '[\"tanah\"]', '[\"JLJ001\",\"JLJ003\",\"JLJ007\",\"JLJ022\"]', 1, '2024-12-10 03:18:24', '2024-12-10 03:18:24', NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(24, 'JJ024', 'Tanah Kosong untuk dikembangkan', 'tanah-kosong-untuk-dikembangkan', '[\"tanah\"]', '[\"JLJ001\",\"JLJ003\",\"JLJ007\",\"JLJ022\"]', 1, '2024-12-10 03:19:03', '2024-12-10 03:19:03', NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(25, 'JJ025', 'Bisnis', 'bisnis', '[\"informasi\", \"lingkungan\"]', '[\"JLJ001\",\"JLJ007\"]', 1, '2024-12-10 22:09:26', '2024-12-10 22:09:26', NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(26, 'JJ026', 'Properti Sederhana', 'properti-sederhana', '[\"lingkungan\", \"tanah\"]', '[\"JLJ001\",\"JLJ007\"]', 1, '2024-12-10 22:10:01', '2024-12-10 22:10:01', NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(27, 'JJ027', 'Bangunan', 'bangunan', '[\"bangunan\"]', '[\"JLJ003\",\"JLJ007\"]', 1, '2024-12-12 08:13:41', '2024-12-12 08:13:41', NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(28, 'JJ028', 'Kendaraan Bermotor', 'kendaraan-bermotor', '[\"kendaraan\"]', '[\"JLJ022\"]', 1, '2024-12-12 08:15:51', '2024-12-12 08:15:51', NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
|
||||
INSERT INTO `jenis_jaminan` (`id`, `code`, `name`, `slug`, `form_kategori`, `jenis_legalitas_jaminan_id`, `status`, `created_at`, `updated_at`, `authorized_at`, `authorized_status`, `deleted_at`, `created_by`, `updated_by`, `deleted_by`, `authorized_by`) VALUES
|
||||
(1, 'JJ001', 'Tanah kosong', 'tanah-kosong', '[\"tanah\", \"lingkungan\", \"fakta\", \"informasi\"]', '[\"JLJ001\",\"JLJ003\",\"JLJ004\",\"JLJ005\",\"JLJ006\",\"JLJ022\"]', NULL, NULL, '2024-12-20 00:15:07', NULL, 't', NULL, NULL, 1, NULL, NULL),
|
||||
(2, 'JJ002', 'Unit Apartemen', 'unit-apartemen', '[\"apartemen-kantor\", \"lingkungan\", \"fakta\", \"informasi\"]', '[\"JLJ001\",\"JLJ003\",\"JLJ004\",\"JLJ006\",\"JLJ007\",\"JLJ022\",\"JLJ024\"]', NULL, NULL, '2024-12-03 03:38:02', NULL, 'r', NULL, NULL, 1, NULL, NULL),
|
||||
(3, 'JJ003', 'Kawasan Industrial / Komersil / Residensial - Perumahan', 'kawasan-industrial-komersil-residensial-perumahan', '[\"tanah\", \"bangunan\", \"lingkungan\", \"fakta\", \"informasi\"]', '[\"JLJ001\",\"JLJ003\",\"JLJ004\",\"JLJ005\",\"JLJ007\",\"JLJ008\",\"JLJ009\",\"JLJ022\",\"JLJ024\",\"JLJ039\",\"JLJ040\"]', NULL, NULL, '2025-03-10 19:34:58', NULL, 'k', NULL, NULL, 1, NULL, NULL),
|
||||
(4, 'JJ004', 'Unit Kios', 'unit-kios', '[\"tanah\", \"bangunan\"]', '[\"JLJ001\",\"JLJ003\",\"JLJ004\",\"JLJ006\",\"JLJ007\",\"JLJ009\",\"JLJ010\",\"JLJ022\"]', NULL, NULL, '2024-12-03 01:57:55', NULL, 'g', '2024-12-03 01:57:55', NULL, 1, 1, NULL),
|
||||
(6, 'JJ005', 'Mall', 'mall', '[\"tanah\", \"bangunan\", \"lingkungan\", \"fakta\", \"informasi\"]', '[\"JLJ001\",\"JLJ003\",\"JLJ004\",\"JLJ006\",\"JLJ007\",\"JLJ009\",\"JLJ012\",\"JLJ013\",\"JLJ014\",\"JLJ015\",\"JLJ021\",\"JLJ022\"]', 1, '2024-09-11 00:51:36', '2024-12-16 19:48:40', NULL, NULL, NULL, 1, 1, NULL, NULL),
|
||||
(7, 'JJ006', 'Pabrik', 'pabrik', '[\"tanah\", \"bangunan\", \"lingkungan\", \"fakta\", \"informasi\"]', '[\"JLJ001\",\"JLJ003\",\"JLJ004\",\"JLJ006\",\"JLJ007\",\"JLJ009\",\"JLJ011\"]', 1, '2024-10-23 22:27:56', '2024-12-16 19:48:54', NULL, NULL, NULL, 1, 1, NULL, NULL),
|
||||
(8, 'JJ007', 'Emas dan Perak', 'emas-dan-perak', NULL, '[\"JLJ008\",\"JLJ014\",\"JLJ022\"]', 1, '2024-12-02 02:40:42', '2024-12-02 02:40:58', NULL, NULL, '2024-12-02 02:40:58', 4, 4, 4, NULL),
|
||||
(9, 'JJ008', 'Emas dan Perak', 'emas-dan-perak', NULL, '[\"JLJ008\",\"JLJ014\",\"JLJ022\"]', 1, '2024-12-02 02:41:39', '2024-12-02 02:47:44', NULL, NULL, '2024-12-02 02:47:44', 4, 4, 4, NULL),
|
||||
(10, 'JJ009', 'Emas dan Perak', 'emas-dan-perak', NULL, '[\"JLJ001\",\"JLJ007\",\"JLJ014\",\"JLJ022\"]', 1, '2024-12-02 02:49:32', '2024-12-02 02:49:32', NULL, NULL, NULL, 4, 4, NULL, NULL),
|
||||
(11, 'JJ010', 'Alat Berat', 'alat-berat', 'null', '[\"JLJ004\",\"JLJ011\"]', 1, '2024-12-03 00:59:14', '2024-12-30 23:36:25', NULL, NULL, '2024-12-30 23:36:25', 1, 1, 1, NULL),
|
||||
(12, 'JJ011', 'Rumah Tinggal', 'rumah-tinggal', '[\"tanah\", \"bangunan\", \"lingkungan\", \"fakta\", \"informasi\"]', '[\"JLJ001\",\"JLJ003\",\"JLJ004\",\"JLJ006\",\"JLJ007\",\"JLJ009\",\"JLJ022\",\"JLJ024\"]', 1, '2024-12-03 01:12:23', '2024-12-19 00:11:01', NULL, NULL, NULL, 1, 1, NULL, NULL),
|
||||
(13, 'JJ012', 'Pabrik', 'pabrik', '[\"tanah\", \"bangunan\", \"lingkungan\", \"fakta\", \"informasi\"]', '[\"JLJ001\",\"JLJ006\",\"JLJ007\",\"JLJ009\"]', 1, '2024-12-03 01:55:14', '2024-12-03 01:55:14', NULL, NULL, NULL, 1, 1, NULL, NULL),
|
||||
(14, 'JJ013', 'Gudang', 'gudang', '[\"tanah\", \"bangunan\", \"lingkungan\", \"fakta\", \"informasi\"]', '[\"JLJ001\",\"JLJ003\",\"JLJ007\",\"JLJ009\",\"JLJ022\",\"JLJ024\"]', 1, '2024-12-03 01:56:09', '2025-01-22 02:13:30', NULL, NULL, NULL, 1, 1, NULL, NULL),
|
||||
(15, 'JJ014', 'Unit Kios', 'unit-kios', '[\"apartemen-kantor\", \"lingkungan\", \"fakta\", \"informasi\"]', '[\"JLJ001\",\"JLJ007\",\"JLJ009\",\"JLJ024\"]', 1, '2024-12-03 01:58:32', '2024-12-03 04:20:22', NULL, NULL, NULL, 1, 1, NULL, NULL),
|
||||
(16, 'JJ015', 'Gedung Mall', 'gedung-mall', '[\"tanah\", \"bangunan\", \"lingkungan\", \"fakta\", \"informasi\"]', '[\"JLJ001\",\"JLJ007\",\"JLJ009\"]', 1, '2024-12-03 01:59:41', '2024-12-03 01:59:41', NULL, NULL, NULL, 1, 1, NULL, NULL),
|
||||
(17, 'JJ016', 'Tanah Bangunan', 'tanah-bangunan', '[\"tanah\", \"bangunan\", \"lingkungan\", \"fakta\", \"informasi\"]', '[\"JLJ001\",\"JLJ003\",\"JLJ005\",\"JLJ007\",\"JLJ009\",\"JLJ022\",\"JLJ024\",\"JLJ039\",\"JLJ040\"]', 1, '2024-12-03 02:01:20', '2025-03-10 19:35:15', NULL, NULL, NULL, 1, 1, NULL, NULL),
|
||||
(18, 'JJ017', 'Apartemen', 'apartemen', '[\"apartemen-kantor\", \"lingkungan\", \"fakta\", \"informasi\"]', '[\"JLJ001\",\"JLJ003\",\"JLJ022\",\"JLJ024\"]', 1, '2024-12-03 04:24:14', '2024-12-03 22:35:05', NULL, NULL, NULL, 1, 1, NULL, NULL),
|
||||
(19, 'JJ018', 'Ruko/Rukan', 'rukorukan', '[\"tanah\", \"bangunan\", \"lingkungan\", \"fakta\", \"informasi\"]', '[\"JLJ001\",\"JLJ003\",\"JLJ007\",\"JLJ022\"]', 1, '2024-12-03 19:33:17', '2024-12-16 01:54:36', NULL, NULL, NULL, 1, 1, NULL, NULL),
|
||||
(20, 'JJ019', 'Unit Kantor', 'unit-kantor', '[\"apartemen-kantor\", \"lingkungan\", \"fakta\", \"informasi\"]', '[\"JLJ001\",\"JLJ003\",\"JLJ005\"]', 1, '2024-12-16 01:56:38', '2024-12-16 19:51:00', NULL, NULL, NULL, 1, 1, NULL, NULL),
|
||||
(21, 'JJ020', 'Pesawat', 'pesawat', '[\"pesawat\"]', '[\"JLJ001\",\"JLJ004\"]', 1, '2024-12-16 01:58:21', '2024-12-16 01:58:21', NULL, NULL, NULL, 1, 1, NULL, NULL),
|
||||
(22, 'JJ021', 'SPBU', 'spbu', '[\"tanah\", \"bangunan\", \"lingkungan\", \"fakta\", \"informasi\"]', '[\"JLJ001\",\"JLJ003\",\"JLJ005\"]', 1, '2024-12-16 01:59:22', '2024-12-16 01:59:22', NULL, NULL, NULL, 1, 1, NULL, NULL),
|
||||
(23, 'JJ022', 'Alat Berat', 'alat-berat', '[\"alat-berat\"]', '[\"JLJ004\",\"JLJ006\",\"JLJ011\"]', 1, '2024-12-30 23:37:10', '2024-12-30 23:45:54', NULL, NULL, NULL, 1, 1, NULL, NULL),
|
||||
(24, 'JJ023', 'Lainnya', 'lainnya', '[\"tanah\", \"bangunan\"]', '[\"JLJ001\",\"JLJ007\"]', 1, '2025-03-05 21:30:11', '2025-03-05 21:30:11', NULL, NULL, NULL, 1, 1, NULL, NULL),
|
||||
(25, 'JJ024', 'Hotel', 'hotel', '[\"bangunan\", \"tanah\"]', '[\"JLJ001\",\"JLJ003\",\"JLJ006\",\"JLJ007\",\"JLJ008\",\"JLJ009\",\"JLJ011\",\"JLJ013\",\"JLJ014\",\"JLJ015\",\"JLJ016\",\"JLJ017\",\"JLJ020\",\"JLJ021\",\"JLJ022\",\"JLJ024\",\"JLJ028\",\"JLJ036\"]', 1, '2025-03-09 02:01:45', '2025-03-09 02:01:45', NULL, NULL, NULL, 1, 1, NULL, NULL),
|
||||
(26, 'JJ025', 'Kendaraan', 'kendaraan', '[\"kendaraan\"]', 'null', 1, '2025-04-18 05:42:13', '2025-04-18 05:42:13', NULL, NULL, NULL, 1, 1, NULL, NULL),
|
||||
(27, 'JJ026', 'Mesin', 'mesin', 'null', 'null', 1, '2025-04-18 05:45:21', '2025-04-18 05:45:21', NULL, NULL, NULL, 1, 1, NULL, NULL),
|
||||
(28, 'JJ027', 'Barang Elektronik', 'barang-elektronik', 'null', 'null', 1, '2025-04-18 05:47:28', '2025-04-18 05:47:28', NULL, NULL, NULL, 1, 1, NULL, NULL),
|
||||
(29, 'JJ028', 'Furniture', 'furniture', 'null', 'null', 1, '2025-04-18 05:49:22', '2025-04-18 05:49:22', NULL, NULL, NULL, 1, 1, NULL, NULL),
|
||||
(30, 'JJ029', 'Perlengkapan', 'perlengkapan', 'null', 'null', 1, '2025-04-18 05:51:00', '2025-04-18 05:51:00', NULL, NULL, NULL, 1, 1, NULL, NULL),
|
||||
(31, 'JJ030', 'Persediaan Barang', 'persediaan-barang', 'null', 'null', 1, '2025-04-18 05:52:08', '2025-04-18 05:52:08', NULL, NULL, NULL, 1, 1, NULL, NULL),
|
||||
(32, 'JJ031', 'Kapal', 'kapal', 'null', 'null', 1, '2025-04-18 05:53:26', '2025-04-18 05:53:26', NULL, NULL, NULL, 1, 1, NULL, NULL),
|
||||
(33, 'JJ032', 'Deposito Berjangka', 'deposito-berjangka', 'null', 'null', 1, '2025-04-18 05:57:44', '2025-04-18 05:57:44', NULL, NULL, NULL, 1, 1, NULL, NULL),
|
||||
(34, 'JJ033', 'Sertifikat Deposito', 'sertifikat-deposito', 'null', 'null', 1, '2025-04-18 05:58:57', '2025-04-18 05:58:57', NULL, NULL, NULL, 1, 1, NULL, NULL),
|
||||
(35, 'JJ034', 'Rekening Giro / Tabungan', 'rekening-giro-tabungan', 'null', 'null', 1, '2025-04-18 05:59:56', '2025-04-18 05:59:56', NULL, NULL, NULL, 1, 1, NULL, NULL),
|
||||
(36, 'JJ035', 'Barang Dagangan', 'barang-dagangan', 'null', 'null', 1, '2025-04-18 06:03:51', '2025-04-18 06:03:51', NULL, NULL, NULL, 1, 1, NULL, NULL),
|
||||
(37, 'JJ036', 'Piutang Dagang', 'piutang-dagang', 'null', 'null', 1, '2025-04-18 06:04:59', '2025-04-18 06:04:59', NULL, NULL, NULL, 1, 1, NULL, NULL),
|
||||
(38, 'JJ037', 'Jaminan Pribadi', 'jaminan-pribadi', 'null', 'null', 1, '2025-04-18 06:05:57', '2025-04-18 06:05:57', NULL, NULL, NULL, 1, 1, NULL, NULL),
|
||||
(39, 'JJ038', 'Jaminan Perusahaan', 'jaminan-perusahaan', 'null', 'null', 1, '2025-04-18 06:06:53', '2025-04-18 06:06:53', NULL, NULL, NULL, 1, 1, NULL, NULL),
|
||||
(40, 'JJ039', 'Resi Gudang', 'resi-gudang', 'null', 'null', 1, '2025-04-18 06:07:41', '2025-04-18 06:07:41', NULL, NULL, NULL, 1, 1, NULL, NULL),
|
||||
(41, 'JJ040', 'Surat Berharga dan Saham', 'surat-berharga-dan-saham', 'null', 'null', 1, '2025-04-18 06:08:32', '2025-04-18 06:08:32', NULL, NULL, NULL, 1, 1, NULL, NULL),
|
||||
(42, 'JJ041', 'Tanah Kavling (Kerjasama)', 'tanah-kavling-kerjasama', 'null', 'null', 1, '2025-04-18 06:09:31', '2025-04-18 06:09:31', NULL, NULL, NULL, 1, 1, NULL, NULL);
|
||||
|
||||
10
database/seeders/sql/jenis_kapal.sql
Normal file
10
database/seeders/sql/jenis_kapal.sql
Normal file
@@ -0,0 +1,10 @@
|
||||
INSERT INTO `jenis_kapal` (`id`, `code`, `name`, `status`, `authorized_status`, `created_at`, `updated_at`, `authorized_at`, `authorized_by`, `deleted_at`, `created_by`, `updated_by`, `deleted_by`) VALUES
|
||||
(1, 'JK001', 'Fishing Boat', 1, NULL, '2024-11-28 18:33:01', '2024-11-28 18:33:01', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(2, 'JK002', 'Tugboat', 1, NULL, '2024-11-28 18:33:55', '2024-11-28 18:33:55', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(3, 'JK003', 'Tongkang', 1, NULL, '2024-11-28 18:34:15', '2024-11-28 18:34:15', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(4, 'JK004', 'Self Propelled Oil Barge', 1, NULL, '2024-11-28 18:34:30', '2024-11-28 18:34:30', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(5, 'JK005', 'Dredger', 1, NULL, '2024-11-28 18:34:49', '2024-11-28 18:34:49', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(6, 'JK006', 'General Cargo', 1, NULL, '2024-11-28 18:35:09', '2024-11-28 18:35:09', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(7, 'JK007', 'Container Ship', 1, NULL, '2024-11-28 18:35:35', '2024-11-28 18:35:35', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(8, 'JK008', 'Oli Tangker', 1, NULL, '2024-11-28 18:36:04', '2024-11-28 18:36:04', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(9, 'JK009', 'Passenger Ship', 1, NULL, '2024-11-28 18:36:40', '2024-11-28 18:36:40', NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
7
database/seeders/sql/jenis_kendaraan.sql
Normal file
7
database/seeders/sql/jenis_kendaraan.sql
Normal file
@@ -0,0 +1,7 @@
|
||||
INSERT INTO `jenis_kendaraan` (`id`, `code`, `name`, `status`, `authorized_status`, `created_at`, `updated_at`, `authorized_at`, `authorized_by`, `deleted_at`, `created_by`, `updated_by`, `deleted_by`) VALUES
|
||||
(1, 'JK001', 'Mobil Penumpang', 1, NULL, '2024-11-28 02:18:01', '2024-11-28 02:18:01', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(2, 'JK002', 'Mobil Bus', 1, NULL, '2024-11-28 02:18:15', '2024-11-28 02:18:15', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(3, 'JK003', 'Mobil Barang', 1, NULL, '2024-11-28 02:18:36', '2024-11-28 02:18:36', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(4, 'JK004', 'Sepeda Motor', 1, NULL, '2024-11-28 02:18:51', '2024-11-28 02:18:51', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(5, 'JK005', 'Kendaraan Khusus', 1, NULL, '2024-11-28 02:19:18', '2024-11-28 02:19:18', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(6, 'JK006', 'Truk', 1, NULL, '2024-11-28 02:19:34', '2024-11-28 02:19:34', NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
@@ -21,4 +21,33 @@ INSERT INTO `jenis_legalitas_jaminan` (`code`, `created_at`, `custom_field`, `cu
|
||||
('JLJ020', '2024-12-06 09:04:50', NULL, NULL, NULL, 'Rate Kamar pertipe, Jumlah Kamar, Luas Kamar Pertipe', 'rate-kamar-pertipe-jumlah-kamar-luas-kamar-pertipe', 1, '2024-12-06 09:04:50'),
|
||||
('JLJ021', '2024-12-06 09:04:50', NULL, NULL, NULL, 'Analisis Kompetitor', 'analisis-kompetitor', 1, '2024-12-06 09:04:50'),
|
||||
('JLJ022', '2024-12-06 09:04:50', NULL, NULL, NULL, 'Bukti Bayar', 'bukti-bayar', 1, '2024-12-06 09:04:50'),
|
||||
('JLJ024', '2024-12-06 09:04:50', NULL, NULL, NULL, 'PPJB', 'ppjb', 1, '2024-12-06 09:04:50');
|
||||
('JLJ024', '2024-12-06 09:04:50', NULL, NULL, NULL, 'PPJB', 'ppjb', 1, '2024-12-06 09:04:50'),
|
||||
('JLJ025', '2024-12-06 09:04:50', NULL, NULL, NULL, 'LOKASI JAMINAN', 'lokasi-jaminan', 1, '2024-12-06 09:04:50'),
|
||||
('JLJ026', '2024-12-06 09:04:50', NULL, NULL, NULL, 'KEPEMILIKAN', 'kepemilikan', 1, '2024-12-06 09:04:50'),
|
||||
('JLJ027', '2024-12-06 09:04:50', NULL, NULL, NULL, 'STATUS KEPEMILIKAN, HUBUNGAN DAN PENGHUNI', 'status-kepemilikan-hubungan-dan-penghuni', 1, '2024-12-06 09:04:50'),
|
||||
('JLJ028', '2024-12-06 09:04:50', NULL, NULL, NULL, 'ANALISA TANAH DAN BANGUNAN', 'analisa-tanah-dan-bangunan', 1, '2024-12-06 09:04:50'),
|
||||
('JLJ029', '2024-12-06 09:04:50', NULL, NULL, NULL, 'SARANA PELENGKAP DAN LINGKUNGAN', 'sarana-pelengkap-dan-lingkungan', 1, '2024-12-06 09:04:50'),
|
||||
('JLJ030', '2024-12-06 09:04:50', NULL, NULL, NULL, 'STATUS PEMILIKAN', 'status-pemilikan', 1, '2024-12-06 09:04:50'),
|
||||
('JLJ031', '2024-12-06 09:04:50', NULL, NULL, NULL, 'KONDISI DAN SARANA PELENGKAP KENDARAAN', 'kondisi-dan-sarana-pelengkap-kendaraan', 1, '2024-12-06 09:04:50'),
|
||||
('JLJ032', '2024-12-06 09:04:50', NULL, NULL, NULL, 'BARANG YANG DIPERIKSA', 'barang-yang-diperiksa', 1, '2024-12-06 09:04:50'),
|
||||
('JLJ033', '2024-12-06 09:04:50', NULL, NULL, NULL, 'LOKASI, TEMPAT DAN STATUS TEMPAT PENYIMPANAN BARANG', 'lokasi-tempat-dan-status-tempat-penyimpanan-barang', 1, '2024-12-06 09:04:50'),
|
||||
('JLJ034', '2024-12-06 09:04:50', NULL, NULL, NULL, 'KONDISI DAN DOKUMENTASI PENYIMPANAN BARANG', 'kondisi-dan-dokumentasi-penyimpanan-barang', 1, '2024-12-06 09:04:50'),
|
||||
('JLJ035', '2024-12-06 09:04:50', NULL, NULL, NULL, 'KONDISI / SISTEM PENGAMANAN DAN LINGKUNGAN TEMPAT PENYIMPANAN BARANG', 'kondisi-sistem-pengamanan-dan-lingkungan-tempat-penyimpanan-barang', 1, '2024-12-06 09:04:50'),
|
||||
('JLJ036', '2024-12-06 09:04:50', NULL, NULL, NULL, 'KONDISI MESIN', 'kondisi-mesin', 1, '2024-12-06 09:04:50'),
|
||||
('JLJ037', '2024-12-06 09:04:50', NULL, NULL, NULL, 'CATATAN', 'catatan', 1, '2024-12-06 09:04:50'),
|
||||
('JLJ038', '2024-12-06 09:04:50', NULL, NULL, NULL, 'EMAS', 'emas', 1, '2024-12-06 09:04:50'),
|
||||
('JLJ039', '2024-12-06 09:04:50', NULL, NULL, NULL, 'ALAT BERAT', 'alat-berat', 1, '2024-12-06 09:04:50'),
|
||||
('JLJ040', '2024-12-06 09:04:50', NULL, NULL, NULL, 'DEPOSITO', 'deposito', 1, '2024-12-06 09:04:50'),
|
||||
('JLJ041', '2024-12-06 09:04:50', NULL, NULL, NULL, 'BARANG DAGANGAN', 'barang-dagangan', 1, '2024-12-06 09:04:50'),
|
||||
('JLJ042', '2024-12-06 09:04:50', NULL, NULL, NULL, 'PIUTANG DAGANG', 'piutang-dagang', 1, '2024-12-06 09:04:50'),
|
||||
('JLJ043', '2024-12-06 09:04:50', NULL, NULL, NULL, 'JAMINAN PRIBADI', 'jaminan-pribadi', 1, '2024-12-06 09:04:50'),
|
||||
('JLJ044', '2024-12-06 09:04:50', NULL, NULL, NULL, 'JAMINAN PERUSAHAAN', 'jaminan-perusahaan', 1, '2024-12-06 09:04:50'),
|
||||
('JLJ045', '2024-12-06 09:04:50', NULL, NULL, NULL, 'RESI GUDANG', 'resi-gudang', 1, '2024-12-06 09:04:50'),
|
||||
('JLJ046', '2024-12-06 09:04:50', NULL, NULL, NULL, 'Surat Berharga dan Saham', 'surat-berharga-dan-saham', 1, '2024-12-06 09:04:50'),
|
||||
('JLJ047', '2024-12-06 09:04:50', NULL, NULL, NULL, 'Tanah dan Bangunan (Kerjasama)', 'tanah-dan-bangunan-kerjasama', 1, '2024-12-06 09:04:50'),
|
||||
('JLJ048', '2024-12-06 09:04:50', NULL, NULL, NULL, 'Tanah Kavling (Kerjasama)', 'tanah-kavling-kerjasama', 1, '2024-12-06 09:04:50'),
|
||||
('JLJ049', '2024-12-06 09:04:50', NULL, NULL, NULL, 'JENIS KAPAL DAN STATUS KEPEMILIKAN', 'jenis-kapal-dan-status-kepemilikan', 1, '2024-12-06 09:04:50'),
|
||||
('JLJ050', '2024-12-06 09:04:50', NULL, NULL, NULL, 'KONDISI DAN SARANA PELENGKAP KAPAL', 'kondisi-dan-sarana-pelengkap-kapal', 1, '2024-12-06 09:04:50'),
|
||||
('JLJ051', '2024-12-06 09:04:50', NULL, NULL, NULL, 'REKENING GIRO / TABUNGAN', 'rekening-giro-tabungan', 1, '2024-12-06 09:04:50'),
|
||||
('JLJ052', '2024-12-06 09:04:50', NULL, NULL, NULL, 'DATA TANAH', 'data-tanah', 1, '2024-12-06 09:04:50'),
|
||||
('JLJ053', '2024-12-06 09:04:50', NULL, NULL, NULL, 'DATA BANGUNAN', 'data-bangunan', 1, '2024-12-06 09:04:50');
|
||||
|
||||
7
database/seeders/sql/jenis_pesawat.sql
Normal file
7
database/seeders/sql/jenis_pesawat.sql
Normal file
@@ -0,0 +1,7 @@
|
||||
INSERT INTO `jenis_pesawat` (`id`, `code`, `name`, `status`, `authorized_status`, `created_at`, `updated_at`, `authorized_at`, `authorized_by`, `deleted_at`, `created_by`, `updated_by`, `deleted_by`) VALUES
|
||||
(1, 'JP001', 'Penumpang Komersil', 1, NULL, '2024-11-28 18:37:59', '2024-11-28 18:37:59', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(2, 'JP002', 'Milliter', 1, NULL, '2024-11-28 18:38:13', '2024-11-28 18:38:13', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(3, 'JP003', 'Cargo', 1, NULL, '2024-11-28 18:38:26', '2024-11-28 18:38:26', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(4, 'JP004', 'Helikopter', 1, NULL, '2024-11-28 18:38:39', '2024-11-28 18:38:39', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(5, 'JP005', 'Pribadi', 1, NULL, '2024-11-28 18:38:56', '2024-11-28 18:38:56', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(6, 'JP006', 'Lainnya', 1, NULL, '2024-11-28 18:39:13', '2024-11-28 18:39:13', NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
2
database/seeders/sql/jenis_unit.sql
Normal file
2
database/seeders/sql/jenis_unit.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
INSERT INTO `jenis_unit` (`id`, `code`, `name`, `status`, `authorized_status`, `created_at`, `updated_at`, `authorized_at`, `authorized_by`, `deleted_at`, `created_by`, `updated_by`, `deleted_by`) VALUES
|
||||
(1, 'JU001', 'H', 1, NULL, '2024-11-28 18:54:44', '2024-11-28 18:54:44', NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
5
database/seeders/sql/ketinggian_tanah.sql
Normal file
5
database/seeders/sql/ketinggian_tanah.sql
Normal file
@@ -0,0 +1,5 @@
|
||||
INSERT INTO `ketinggian_tanah` (`id`, `code`, `name`, `status`, `authorized_status`, `created_at`, `updated_at`, `authorized_at`, `authorized_by`, `deleted_at`, `created_by`, `updated_by`, `deleted_by`) VALUES
|
||||
(2, 'KT001', 'Sama Dengan Jalan', 1, NULL, '2024-11-05 00:28:23', '2024-11-05 00:28:23', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(3, 'KT002', 'Lebih Tinggi', 1, NULL, '2024-11-05 00:28:50', '2024-11-25 21:20:57', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(4, 'KT004', 'Lebih Rendah', 1, NULL, '2024-11-05 00:31:20', '2024-11-25 21:21:05', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(5, 'KT005', 'Bervariasi', 1, NULL, '2024-11-05 00:31:48', '2024-11-05 00:31:48', NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
7
database/seeders/sql/kondisi_bangunan.sql
Normal file
7
database/seeders/sql/kondisi_bangunan.sql
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
INSERT INTO `kondisi_bangunan` (`id`, `code`, `name`, `status`, `authorized_status`, `created_at`, `updated_at`, `authorized_at`, `authorized_by`, `deleted_at`, `created_by`, `updated_by`, `deleted_by`) VALUES
|
||||
(2, 'KB001', 'Cukup Terawat', 1, NULL, '2024-11-05 00:32:53', '2024-11-05 00:32:53', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(3, 'KB002', 'Kurang Terawat', 1, NULL, '2024-11-05 00:33:08', '2024-11-05 00:33:08', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(4, 'KB003', 'Tidak Terawat', 1, NULL, '2024-11-05 00:33:24', '2024-11-05 00:33:24', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(5, 'KB004', 'Hancur/Tidak Layak Ditinggali', 1, NULL, '2024-11-05 00:33:55', '2024-11-05 00:33:55', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(6, 'KB005', 'Terawat', 1, NULL, '2025-03-07 02:47:03', '2025-03-07 02:47:03', NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
5
database/seeders/sql/kondisi_fisik_tanah.sql
Normal file
5
database/seeders/sql/kondisi_fisik_tanah.sql
Normal file
@@ -0,0 +1,5 @@
|
||||
INSERT INTO `kondisi_fisik_tanah` (`id`, `code`, `name`, `status`, `authorized_status`, `created_at`, `updated_at`, `authorized_at`, `authorized_by`, `deleted_at`, `created_by`, `updated_by`, `deleted_by`) VALUES
|
||||
(1, 'KFT001', 'Tanah Darat', 1, NULL, '2024-11-04 21:41:58', '2024-11-04 21:41:58', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(2, 'KFT002', 'Sawah', 1, NULL, '2024-11-04 21:42:11', '2024-11-04 21:42:11', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(3, 'KFT003', 'Urukan', 1, NULL, '2024-11-04 21:42:24', '2024-11-04 21:42:24', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(4, 'KFT004', 'Bukit', 1, NULL, '2024-11-04 21:42:38', '2024-11-04 21:42:38', NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
5
database/seeders/sql/kontur_tanah.sql
Normal file
5
database/seeders/sql/kontur_tanah.sql
Normal file
@@ -0,0 +1,5 @@
|
||||
INSERT INTO `kontur_tanah` (`id`, `code`, `name`, `status`, `authorized_status`, `created_at`, `updated_at`, `authorized_at`, `authorized_by`, `deleted_at`, `created_by`, `updated_by`, `deleted_by`) VALUES
|
||||
(1, 'KT001', 'Rata', 1, NULL, '2024-11-04 21:31:11', '2024-11-04 21:31:11', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(2, 'KT002', 'Tidak Rata', 1, NULL, '2024-11-04 21:31:25', '2024-11-04 21:31:25', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(3, 'KT003', 'Berbukit', 1, NULL, '2024-11-04 21:37:07', '2024-11-04 21:37:07', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(4, 'KT004', 'Bergelombang', 1, NULL, '2024-11-04 21:37:27', '2024-11-04 21:37:27', NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
4
database/seeders/sql/lalu_lintas_lokasi.sql
Normal file
4
database/seeders/sql/lalu_lintas_lokasi.sql
Normal file
@@ -0,0 +1,4 @@
|
||||
INSERT INTO `lalu_lintas_lokasi` (`id`, `code`, `name`, `status`, `authorized_status`, `created_at`, `updated_at`, `authorized_at`, `authorized_by`, `deleted_at`, `created_by`, `updated_by`, `deleted_by`) VALUES
|
||||
(1, 'LD001', 'Satu Arah', 1, NULL, '2025-01-22 23:23:31', '2025-01-22 23:23:31', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(2, 'LD002', 'Dua Arah - Satu Jalur', 1, NULL, '2025-01-22 23:23:46', '2025-01-22 23:23:46', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(3, 'LD003', 'Dua Arah - Dua Jalur', 1, NULL, '2025-01-22 23:24:04', '2025-01-22 23:24:04', NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
4
database/seeders/sql/lantai.sql
Normal file
4
database/seeders/sql/lantai.sql
Normal file
@@ -0,0 +1,4 @@
|
||||
INSERT INTO `lantai` (`id`, `code`, `name`, `status`, `authorized_status`, `created_at`, `updated_at`, `authorized_at`, `authorized_by`, `deleted_at`, `created_by`, `updated_by`, `deleted_by`) VALUES
|
||||
(1, 'LU001', 'Rendah', 1, NULL, '2024-11-05 02:06:00', '2024-11-05 02:06:00', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(3, 'LU003', 'Tinggi', 1, NULL, '2024-11-05 02:06:35', '2024-11-05 02:06:35', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(4, 'LU002', 'Menengah', 1, NULL, '2024-11-05 02:07:02', '2024-11-05 02:07:02', NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
4
database/seeders/sql/merupakan_daerah.sql
Normal file
4
database/seeders/sql/merupakan_daerah.sql
Normal file
@@ -0,0 +1,4 @@
|
||||
INSERT INTO `merupakan_daerah` (`id`, `code`, `name`, `status`, `authorized_status`, `created_at`, `updated_at`, `authorized_at`, `authorized_by`, `deleted_at`, `created_by`, `updated_by`, `deleted_by`) VALUES
|
||||
(1, 'MD001', 'Bebas Banjir', 1, NULL, '2024-11-28 18:56:17', '2024-11-28 18:56:17', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(2, 'MD002', 'Rawan Banjir', 1, NULL, '2024-11-28 18:56:37', '2024-11-28 18:56:37', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(3, 'MD003', 'Sering Banjir', 1, NULL, '2024-11-28 18:56:56', '2024-11-28 18:56:56', NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
3
database/seeders/sql/model_alat_berat.sql
Normal file
3
database/seeders/sql/model_alat_berat.sql
Normal file
@@ -0,0 +1,3 @@
|
||||
INSERT INTO `model_alat_berat` (`id`, `code`, `name`, `status`, `authorized_status`, `created_at`, `updated_at`, `authorized_at`, `authorized_by`, `deleted_at`, `created_by`, `updated_by`, `deleted_by`) VALUES
|
||||
(1, 'MA001', 'Excavator', 1, NULL, '2024-11-28 02:13:48', '2024-11-28 02:13:48', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(2, 'MA002', 'Grader', 1, NULL, '2024-11-28 02:14:02', '2024-11-28 02:14:02', NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
8
database/seeders/sql/perkerasan_jalan.sql
Normal file
8
database/seeders/sql/perkerasan_jalan.sql
Normal file
@@ -0,0 +1,8 @@
|
||||
INSERT INTO `perkerasan_jalan` (`id`, `code`, `name`, `status`, `authorized_status`, `created_at`, `updated_at`, `authorized_at`, `authorized_by`, `deleted_at`, `created_by`, `updated_by`, `deleted_by`) VALUES
|
||||
(1, 'PJ001', 'Aspal', 1, NULL, '2024-12-09 02:25:15', '2024-12-09 02:25:15', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(2, 'PJ002', 'Beton', 1, NULL, '2024-12-09 02:25:28', '2024-12-09 02:25:28', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(3, 'PJ003', 'Conblock', 1, NULL, '2024-12-09 02:25:44', '2024-12-09 02:25:44', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(4, 'PJ004', 'Sirtu', 1, NULL, '2024-12-09 02:25:56', '2024-12-09 02:25:56', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(5, 'PJ006', 'Belum ada perkerasan', 1, NULL, '2024-12-09 02:26:13', '2024-12-09 02:26:13', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(6, 'PJ007', 'Semen', 1, NULL, '2024-12-20 00:23:31', '2024-12-20 00:23:31', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(7, 'PJ008', 'Lainnya', 1, NULL, '2024-12-20 00:23:45', '2024-12-20 00:23:45', NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
6
database/seeders/sql/posisi_kavling.sql
Normal file
6
database/seeders/sql/posisi_kavling.sql
Normal file
@@ -0,0 +1,6 @@
|
||||
INSERT INTO `posisi_kavling` (`id`, `code`, `name`, `status`, `authorized_status`, `created_at`, `updated_at`, `authorized_at`, `authorized_by`, `deleted_at`, `created_by`, `updated_by`, `deleted_by`) VALUES
|
||||
(1, 'PK001', 'Badan', 1, NULL, '2024-11-04 21:38:18', '2024-11-04 21:38:18', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(2, 'PK002', 'Pojok', 1, NULL, '2024-11-04 21:38:29', '2024-11-04 21:38:29', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(3, 'PK003', 'Hook', 1, NULL, '2024-11-04 21:38:38', '2024-11-04 21:38:38', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(4, 'PK004', 'Kuldesak', 1, NULL, '2024-11-04 21:38:59', '2024-11-04 21:38:59', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(5, 'PK005', 'Lainnya', 1, NULL, '2024-11-04 21:39:47', '2024-11-04 21:39:47', NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
4
database/seeders/sql/posisi_unit.sql
Normal file
4
database/seeders/sql/posisi_unit.sql
Normal file
@@ -0,0 +1,4 @@
|
||||
INSERT INTO `posisi_unit` (`id`, `code`, `name`, `status`, `authorized_status`, `created_at`, `updated_at`, `authorized_at`, `authorized_by`, `deleted_at`, `created_by`, `updated_by`, `deleted_by`) VALUES
|
||||
(1, 'PU001', 'Tengah/Badan', 1, NULL, '2024-12-09 18:28:41', '2024-12-09 18:28:41', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(2, 'PU002', 'Pojok', 1, NULL, '2024-12-09 18:28:58', '2024-12-09 18:28:58', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(3, 'PU003', 'Tusuk Sate', 1, NULL, '2024-12-09 18:29:14', '2024-12-09 18:29:14', NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
10
database/seeders/sql/sarana_pelengkap.sql
Normal file
10
database/seeders/sql/sarana_pelengkap.sql
Normal file
@@ -0,0 +1,10 @@
|
||||
INSERT INTO `sarana_pelengkap` (`id`, `code`, `name`, `status`, `authorized_status`, `created_at`, `updated_at`, `authorized_at`, `authorized_by`, `deleted_at`, `created_by`, `updated_by`, `deleted_by`) VALUES
|
||||
(1, 'SP001', 'Pagar', 1, NULL, '2024-11-04 21:53:34', '2024-11-04 21:53:34', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(2, 'SP002', 'Perkerasan', 1, NULL, '2024-11-04 21:53:50', '2024-11-04 21:53:50', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(3, 'SP003', 'Kanopi', 1, NULL, '2024-11-04 21:54:13', '2024-11-04 21:54:13', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(5, 'SP004', 'Air', 1, NULL, '2024-11-04 21:54:57', '2024-11-04 21:54:57', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(6, 'SP005', 'Listrik', 1, NULL, '2024-11-04 21:55:13', '2024-11-04 21:55:13', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(7, 'SP006', 'kolam renang', 1, NULL, '2024-12-15 19:25:09', '2024-12-15 19:25:09', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(8, 'SP007', 'carport', 1, NULL, '2024-12-15 19:25:58', '2024-12-15 19:25:58', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(9, 'SP008', 'teras', 1, NULL, '2024-12-15 19:26:38', '2024-12-15 19:26:38', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(10, 'SP009', 'Lainnya', 1, NULL, '2024-12-15 19:26:50', '2024-12-15 19:26:50', NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
4
database/seeders/sql/sifat_bangunan.sql
Normal file
4
database/seeders/sql/sifat_bangunan.sql
Normal file
@@ -0,0 +1,4 @@
|
||||
INSERT INTO `sifat_bangunan` (`id`, `code`, `name`, `status`, `authorized_status`, `created_at`, `updated_at`, `authorized_at`, `authorized_by`, `deleted_at`, `created_by`, `updated_by`, `deleted_by`) VALUES
|
||||
(1, 'SB001', 'Permanen', 1, NULL, '2024-11-05 00:09:46', '2024-11-05 00:09:46', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(2, 'SB002', 'Semi Permanen', 1, NULL, '2024-11-05 00:10:03', '2024-11-05 00:10:03', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(3, 'SB003', 'Tidak Permanen', 1, NULL, '2024-11-05 00:10:22', '2024-11-05 00:10:22', NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
70
database/seeders/sql/spek_bangunan.sql
Normal file
70
database/seeders/sql/spek_bangunan.sql
Normal file
@@ -0,0 +1,70 @@
|
||||
INSERT INTO `spek_bangunan` (`id`, `code`, `name`, `spek_kategori_bangunan_id`, `status`, `authorized_status`, `created_at`, `updated_at`, `authorized_at`, `authorized_by`, `deleted_at`, `created_by`, `updated_by`, `deleted_by`) VALUES
|
||||
(1, 'SPB001', 'Tapak Beton', 3, 1, NULL, '2024-11-05 20:22:33', '2024-11-05 20:22:33', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(4, 'SPB002', 'Batu Kali', 3, 1, NULL, '2024-11-05 20:39:42', '2024-11-05 20:39:42', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(5, 'SPB003', 'Lainnya', 3, 1, NULL, '2024-11-05 20:39:58', '2024-11-05 20:39:58', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(6, 'SPB004', 'Beton Bertulang', 4, 1, NULL, '2024-11-05 20:40:43', '2024-11-05 20:40:43', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(7, 'SPB005', 'Lainnya', 4, 1, NULL, '2024-11-05 20:41:01', '2024-11-05 20:41:01', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(8, 'SPB006', 'Dak Beton', 5, 1, NULL, '2024-11-05 20:42:12', '2024-11-05 20:42:12', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(9, 'SPB007', 'Kayu (Atap Asbes)', 5, 1, NULL, '2024-11-05 21:25:05', '2024-11-05 21:25:05', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(10, 'SPB008', 'Kayu (Atap Genteng)', 5, 1, NULL, '2024-11-05 21:25:36', '2024-11-05 21:25:36', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(11, 'SPB009', 'Baja Ringan (Atap Asbes)', 5, 1, NULL, '2024-11-05 21:26:28', '2024-11-05 21:26:28', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(12, 'SPB010', 'Baja Ringan (Atap Genteng)', 5, 1, NULL, '2024-11-05 21:28:43', '2024-11-05 21:28:43', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(13, 'SPB011', 'Lainnya', 5, 1, NULL, '2024-11-05 21:29:07', '2024-11-05 21:29:07', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(15, 'SPB012', 'Asbes', 6, 1, NULL, '2024-11-05 21:30:39', '2024-11-05 21:30:39', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(16, 'SPB013', 'Dak Beton', 6, 1, NULL, '2024-11-05 21:39:28', '2024-11-05 21:39:28', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(17, 'SPB014', 'Fibreglass', 6, 1, NULL, '2024-11-05 21:42:05', '2024-11-05 21:42:05', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(18, 'SPB015', 'Ganteng Tanah Liat', 6, 1, NULL, '2024-11-05 21:42:27', '2024-11-05 21:42:27', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(19, 'SPB016', 'Genteng Beton', 6, 1, NULL, '2024-11-05 21:42:46', '2024-11-05 21:42:46', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(20, 'SPB017', 'Genteng Metal', 6, 1, NULL, '2024-11-05 21:43:16', '2024-11-05 21:43:16', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(21, 'SPB018', 'Seng Gelombang', 6, 1, NULL, '2024-11-05 21:43:48', '2024-11-05 21:43:48', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(22, 'SPB019', 'Spandek', 6, 1, NULL, '2024-11-05 21:44:21', '2024-11-05 21:44:21', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(23, 'SPB020', 'PVC', 6, 1, NULL, '2024-11-05 21:44:37', '2024-11-05 21:44:37', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(24, 'SPB021', 'Genteng Keramik', 6, 1, NULL, '2024-11-05 21:44:58', '2024-11-05 21:44:58', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(25, 'SPB022', 'Lainnya', 6, 1, NULL, '2024-11-05 21:45:15', '2024-11-05 21:45:15', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(26, 'SPB023', 'Asbes', 7, 1, NULL, '2024-11-05 21:45:57', '2024-11-05 21:45:57', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(27, 'SPB024', 'Beton Ekspos', 7, 1, NULL, '2024-11-05 21:46:30', '2024-11-05 21:46:30', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(28, 'SPB025', 'GRC', 7, 1, NULL, '2024-11-05 21:46:46', '2024-11-05 21:46:46', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(29, 'SPB026', 'Gypsum', 7, 1, NULL, '2024-11-05 21:46:59', '2024-11-05 21:46:59', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(30, 'SPB027', 'Triplek', 7, 1, NULL, '2024-11-05 21:47:19', '2024-11-05 21:47:19', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(31, 'SPB028', 'Lambreserring', 7, 1, NULL, '2024-11-05 21:47:57', '2024-11-05 21:47:57', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(32, 'SPB029', 'Lainnya', 7, 1, NULL, '2024-11-05 21:48:11', '2024-11-05 21:48:11', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(34, 'SPB031', 'Batako', 8, 1, NULL, '2024-11-05 21:49:34', '2024-11-05 21:49:34', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(35, 'SPB032', 'Bata Merah', 8, 1, NULL, '2024-11-05 21:49:49', '2024-11-05 21:49:49', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(36, 'SPB033', 'Bata Ringan', 8, 1, NULL, '2024-11-05 21:50:06', '2024-11-05 21:50:06', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(37, 'SPB034', 'Gypsumboard 2 Muka', 8, 1, NULL, '2024-11-05 21:50:39', '2024-11-05 21:50:39', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(38, 'SPB035', 'Rooster Bata', 8, 1, NULL, '2024-11-05 21:50:58', '2024-11-05 21:50:58', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(39, 'SPB036', 'Lainnya', 8, 1, NULL, '2024-11-05 21:51:37', '2024-11-05 21:51:37', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(41, 'SPB038', 'Dilapisi Cat', 9, 1, NULL, '2024-11-05 21:52:34', '2024-11-05 21:52:34', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(42, 'SPB039', 'Dilapis Batu Alam', 9, 1, NULL, '2024-11-05 21:53:02', '2024-11-05 21:53:02', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(43, 'SPB040', 'Dilapis Keramik', 9, 1, NULL, '2024-11-05 21:54:44', '2024-11-05 21:54:44', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(44, 'SPB041', 'Dilapis Marmer Lokal', 9, 1, NULL, '2024-11-05 21:55:04', '2024-11-05 21:55:04', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(45, 'SPB042', 'Dilapis Marmer Import', 9, 1, NULL, '2024-11-05 21:55:26', '2024-11-05 21:55:26', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(46, 'SPB043', 'Dilapis Granit', 9, 1, NULL, '2024-11-05 21:57:24', '2024-11-05 21:57:24', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(47, 'SPB044', 'Dilapis Wallpaper', 9, 1, NULL, '2024-11-05 21:57:43', '2024-11-05 21:57:43', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(48, 'SPB045', 'Lainnya', 9, 1, NULL, '2024-11-05 21:58:00', '2024-11-05 21:58:00', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(49, 'SPB046', 'Pintu Panil', 10, 1, NULL, '2024-11-05 21:58:32', '2024-11-05 21:58:32', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(50, 'SPB048', 'Pintu Kayu Panil', 10, 1, NULL, '2024-11-05 21:59:45', '2024-11-05 21:59:45', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(51, 'SPB049', 'Pntu Kayu Double Triplek', 10, 1, NULL, '2024-11-05 22:00:16', '2024-11-05 22:00:16', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(52, 'SPB050', 'Pntu Kaca RK Alumunium', 10, 1, NULL, '2024-11-05 22:01:13', '2024-11-05 22:01:13', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(53, 'SPB051', 'Pntu Kaca RK Alumunium', 10, 1, NULL, '2024-11-05 23:08:03', '2024-11-05 23:08:03', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(54, 'SPB052', 'Pintu Kaca Tempered Floor', 10, 1, NULL, '2024-11-05 23:08:39', '2024-11-05 23:08:39', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(55, 'SPB053', 'Pntu KM UPVC/PVC', 10, 1, NULL, '2024-11-05 23:09:10', '2024-11-05 23:09:10', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(56, 'SPB054', 'Pintu Garasi Kayu', 10, 1, NULL, '2024-11-05 23:09:46', '2024-11-05 23:09:46', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(57, 'SPB055', 'Pintu Garasi Besi', 10, 1, NULL, '2024-11-05 23:10:09', '2024-11-05 23:10:09', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(58, 'SPB056', 'Jendela Kaca RK Kayu', 10, 1, NULL, '2024-11-05 23:10:39', '2024-11-05 23:10:39', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(59, 'SPB057', 'Jendela Kaca RK Alumunium', 10, 1, NULL, '2024-11-05 23:13:05', '2024-11-05 23:13:05', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(60, 'SPB058', 'Jendela Kaca Stopsol 8mm Curtail w All', 10, 1, NULL, '2024-11-05 23:14:32', '2024-11-05 23:14:32', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(61, 'SPB059', 'Jendela Kaca Tempered Frameless', 10, 1, NULL, '2024-11-05 23:15:57', '2024-11-05 23:15:57', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(62, 'SPB060', 'Lainnya', 10, 1, NULL, '2024-11-05 23:20:37', '2024-11-05 23:20:37', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(63, 'SPB061', 'Granit/Homogenus Tile', 11, 1, NULL, '2024-11-05 23:21:51', '2024-11-05 23:21:51', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(64, 'SPB062', 'Granit Import', 11, 1, NULL, '2024-11-05 23:22:19', '2024-11-05 23:22:19', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(65, 'SPB063', 'Karpet', 11, 1, NULL, '2024-11-05 23:22:41', '2024-11-05 23:22:41', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(66, 'SPB064', 'Keramik', 11, 1, NULL, '2024-11-05 23:23:11', '2024-11-05 23:23:11', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(67, 'SPB065', 'Marmer Import', 11, 1, NULL, '2024-11-05 23:24:26', '2024-11-05 23:24:26', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(68, 'SPB066', 'Mozaik', 11, 1, NULL, '2024-11-05 23:24:43', '2024-11-05 23:24:43', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(69, 'SPB067', 'Rabat Beton (Semen Ekspose)', 11, 1, NULL, '2024-11-05 23:25:10', '2024-11-05 23:25:10', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(70, 'SPB068', 'Parkit Jati', 11, 1, NULL, '2024-11-05 23:27:59', '2024-11-05 23:27:59', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(71, 'SPB069', 'Teraso', 11, 1, NULL, '2024-11-05 23:28:14', '2024-11-05 23:28:14', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(72, 'SPB070', 'Vynil', 11, 1, NULL, '2024-11-05 23:28:42', '2024-11-05 23:28:42', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(73, 'SPB071', 'Lainnya', 11, 1, NULL, '2024-11-05 23:29:29', '2024-11-05 23:29:29', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(74, 'SPB030', 'Baja', 4, 1, NULL, '2024-12-29 21:45:39', '2024-12-29 21:45:39', NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
10
database/seeders/sql/spek_kategori_bangunan.sql
Normal file
10
database/seeders/sql/spek_kategori_bangunan.sql
Normal file
@@ -0,0 +1,10 @@
|
||||
INSERT INTO `spek_kategori_bangunan` (`id`, `code`, `name`, `status`, `authorized_status`, `created_at`, `updated_at`, `authorized_at`, `authorized_by`, `deleted_at`, `created_by`, `updated_by`, `deleted_by`) VALUES
|
||||
(3, 'KB001', 'Pondasi', 1, NULL, '2024-11-05 01:10:30', '2024-11-05 01:10:30', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(4, 'KB002', 'Struktur', 1, NULL, '2024-11-05 01:10:56', '2024-11-05 01:10:56', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(5, 'KB003', 'Rangka Atap', 1, NULL, '2024-11-05 01:11:20', '2024-11-05 01:11:20', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(6, 'KB004', 'Tutup Atap', 1, NULL, '2024-11-05 01:11:38', '2024-11-05 01:11:38', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(7, 'KB005', 'Plafond', 1, NULL, '2024-11-05 01:11:56', '2024-11-05 01:11:56', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(8, 'KB006', 'Dinding', 1, NULL, '2024-11-05 01:45:06', '2024-11-05 01:45:06', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(9, 'KB007', 'Pelapis Dinding', 1, NULL, '2024-11-05 01:45:36', '2024-11-05 01:45:36', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(10, 'KB008', 'Pintu Jendela', 1, NULL, '2024-11-05 01:46:06', '2024-11-05 01:46:06', NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(11, 'KB009', 'Lantai', 1, NULL, '2024-11-05 01:46:46', '2024-11-05 01:46:46', NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user