diff --git a/app/Exports/KertasKerjaExport.php b/app/Exports/KertasKerjaExport.php index c931d47..57c61c6 100644 --- a/app/Exports/KertasKerjaExport.php +++ b/app/Exports/KertasKerjaExport.php @@ -3,72 +3,270 @@ namespace Modules\Lpj\Exports; use Maatwebsite\Excel\Concerns\FromCollection; -use Maatwebsite\Excel\Concerns\WithColumnFormatting; +// use Maatwebsite\Excel\Concerns\WithColumnFormatting; +use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; use Maatwebsite\Excel\Concerns\WithHeadings; -use Maatwebsite\Excel\Concerns\WithMapping; -use PhpOffice\PhpSpreadsheet\Style\NumberFormat; +use Maatwebsite\Excel\Concerns\WithStyles; +use Maatwebsite\Excel\Concerns\WithColumnWidths; +use Maatwebsite\Excel\Concerns\WithEvents; +use Maatwebsite\Excel\Events\AfterSheet; -class KertasKerjaExport implements WithColumnFormatting, WithHeadings, FromCollection, WithMapping +class KertasKerjaExport implements FromCollection, WithHeadings, WithStyles, WithColumnWidths, WithEvents { protected $data; - public function __construct($data) + protected $headerInfo; + + public function __construct($data, $headerInfo) { $this->data = $data; + $this->headerInfo = $headerInfo; } public function collection() { - return collect([ - [ - 'Pendekatan pasar', - 'Nama Pemilik Aset', - '', - ], - [ - 'Metode Perbandingan Data Pasar', - 'Nama Pemberi Tugas: ', - '', - '', - ], - [ - 'Tanggal Penilaian: ', - 'Lokasi: ', - '', - '', - ], - [ - 'No.', - 'Objek Penilaian', - 'Data Pembanding 1', - 'Data Pembanding 2', - 'Data Pembanding 3' - ], - ]); - } + $rows = []; - // Tambahkan method map() - public function map($row): array - { - return $row; + $nomor = 1; + $fields = [ + 'jenis_aset' => 'Jenis Aset', + 'luas_tanah' => 'Luas Tanah (M²)', + 'luas_bangunan' => 'Luas Bangunan (M²)', + 'harga' => 'Harga Transaksi/Penawaran', + 'tanggal_penawaran' => 'Tanggal Penawaran/Transaksi', + 'diskon' => 'Diskon %', + 'esitmasi_harga' => 'Esitmasi Harga Transaksi (Rp)', + 'no_telepon' => 'Telepon Contact Person', + 'nama_nara_sumbr' => 'Nama Nara Sumber', + 'status_nara_sumbr' => 'Status Nara Sumber', + 'waktu_transaksi' => 'Waktu Transaksi/Penawaran', + 'alamat' => 'Alamat Titik Gps', + 'jalan' => 'Jalan', + 'desa' => 'Desa/Kelurahan', + 'kecamatan' => 'Kecamatan', + 'kabupaten' => 'Kabupaten', + 'provinsi' => 'Provinsi', + + 'jarak_pembanding' => 'Jarak Pembanding dengan Objek', + 'elevasi' => 'Estimasi Ranking Tanah', + 'peruntukan' => 'Estiamsi Rangkin Bangunan' + + ]; + + foreach ($fields as $key => $label) { + $rows[] = [ + $nomor++, + $label, + $this->data['objek'][$key] ?? '', + $this->data['pembanding1'][$key] ?? '', + $this->data['pembanding2'][$key] ?? '', + $this->data['pembanding3'][$key] ?? '' + ]; + } + + // B. Perhitungan Penyesuaian + $rows[] = ['']; + $rows[] = ['']; + $rows[] = ['B. Estimasi Nilai Tanah Pembanding dengan Teknik Penyisaan Tanah untuk mendapatkan per meter persegi estimasi Nilai Tanah Pembanding']; + $rows[] = ['No.','Uraian', 'Objek Penilaian', 'Data Pembanding 1', 'Data Pembanding 2', 'Data Pembanding 3']; + $nostimasi = 1; + $filedEstimasi = [ + 'estimasi' => 'Estimasi Biaya Pengganti Baru Bangunan (Rp)', + 'estimasi_spl' => 'Estimasi Biaya Pengganti Baru SPL (Rp)', + 'penyusutan' => 'Penyusutan Fisik Banguna', + + 'a' => 'a. rincian ttipe bangunan (MAPPI)', + 'b' => 'b. umur ekonomis (MAPPI)', + 'c' => 'c. estimasi Tahun tahun visual dengan mempertimbangkan renovasi', + 'd' => 'd. Sehingga sisa umur efektif', + 'e' => 'e. kondisi bagunan', + 'f' => 'f.sehinggan penyusutan fisik', + 'penyusutan_fungsi' => 'Penyusutan fungsi Bangunan (%)', + 'penyusutan_ekonomi' => 'Penyusutan Ekonomi Bangunan (%)', + 'total_penyusutan' => 'Total Penyusutan (%)', + 'estimasi_nilai' => 'Estimasi Nilai Bangunan dan SPL (Rp)', + 'estimasi_tanah' => 'Estimasi Nilai Tanah Pembanding (Rp)', + 'estimasi_nilai' => 'Estimasi Nilai Tanah Pembanding (Rp)', + ]; + + foreach ($filedEstimasi as $key => $label) { + $rows[] = [ + $nostimasi++, + $label, + $this->data['estimasi'][$key] ?? '', + $this->data['estimasi1'][$key] ?? '', + $this->data['estimasi2'][$key] ?? '', + $this->data['estimasi3'][$key] ?? '' + + ]; + } + + + $row[] = ['']; + $row[] = ['']; + $rows[] = ['INDIKASI NILAI TANAHATAS OBJEK PENILAIAN']; + + $indikasi=[ + 'luas_tanah' => 'Luas Tanah ', + 'indikasi_per' => 'INDIKASI TANAH PER M2 (RP/M2)', + 'indikasi_total' => 'INDIKASI TANAH TOTAL(RP)', + 'varian' => 'VARIANT(%)', + ]; + + foreach ($indikasi as $key => $label) { + $rows[] = [ + $label, + $this->data['indikasi'][$key] ?? '', + ]; + } + + + // C. Peta Lokasi + $rows[] = ['']; + $rows[] = ['']; + $rows[] = ['C. Peta Lokasi']; + $rows[] = [$this->data['foto_objek']['foto_objek_peta'] ?? '']; + + // D. Foto Objek dan Data Pembanding + $rows[] = ['']; + $rows[] = ['D. Foto Objek dan Data Pembanding']; + $rows[] = [ + $this->data['foto_objek1']['foto_objek'] ?? '', + $this->data['foto_objek2']['foto_objek'] ?? '', + '', '', '' + ]; + + // E. Foto Objek + $rows[] = ['']; + $rows[] = ['E. Foto Objek']; + $rows[] = [ + $this->data['foto']['foto_objek'] ?? '', + $this->data['foto']['foto_objek'] ?? '', + '', '', '' + ]; + + return collect($rows); } public function headings(): array - { - return []; - } - - public function columnFormats(): array { return [ - 'A' => NumberFormat::FORMAT_NUMBER, - 'C' => NumberFormat::FORMAT_NUMBER, - 'D' => NumberFormat::FORMAT_NUMBER, - 'F' => NumberFormat::FORMAT_NUMBER, - 'G' => NumberFormat::FORMAT_NUMBER, - 'P' => NumberFormat::FORMAT_DATE_DATETIME, - 'Q' => NumberFormat::FORMAT_DATE_DATETIME + ['KERTAS KERJA PENILAIAN'], + ['Pendekatan Pasar'], + ['Metode Perbandingan Data Pasar'], + ['Tanggal Penilaian: ' . ($this->headerInfo['tanggal_penilaian'] ?? '')], + ['Nama Pemilik Aset: ' . ($this->headerInfo['nama_pemilik'] ?? '')], + ['Nama Pemberi Tugas: ' . ($this->headerInfo['nama_pemberi_tugas'] ?? '')], + ['Lokasi: ' . ($this->headerInfo['lokasi_lengkap'] ?? '')], + ['Nama Debitur: ' . ($this->headerInfo['nama_debitur'] ?? '')], + [''], + ['A. INFORMASI UMUM'], + ['No.','Uraian', 'Objek Penilaian', 'Data Pembanding 1', 'Data Pembanding 2', 'Data Pembanding 3'] + + ]; } + public function registerEvents(): array + { + return [ + AfterSheet::class => function (AfterSheet $event) { + // Styling untuk header utama + + + // Styling untuk setiap section header + $sectionRows = [10, 34, 56, 46, 52]; // Sesuaikan dengan posisi setiap section + foreach ($sectionRows as $row) { + $event->sheet->getStyle("A{$row}:F{$row}")->getFill() + ->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID) + ->getStartColor()->setRGB('E2EFDA'); + } + + // Merge cells untuk headers + $event->sheet->mergeCells('A1:E1'); + $event->sheet->mergeCells('A2:E2'); + $event->sheet->mergeCells('A4:E4'); + $event->sheet->mergeCells('A5:E5'); + $event->sheet->mergeCells('A6:E6'); + $event->sheet->mergeCells('A7:E7'); + $event->sheet->mergeCells('A8:E8'); + + // Alignment + $event->sheet->getStyle('A1:E8')->getAlignment() + ->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_LEFT); + } + ]; + } + public function columnWidths(): array + { + return [ + 'A' => 5, + 'B' => 30, + 'C' => 30, + 'D' => 30, + 'E' => 30, + 'F' => 30, + ]; + } + + public function styles(Worksheet $sheet) + { + return [ + // Style for the main header + + // Style for section headers + 10 => ['font' => ['bold' => true]], // A. Informasi Umum + 34 => ['font' => ['bold' => true]], // B. Estimasi Nilai Tanah + 35 => ['font' => ['bold' => true]], // C. Peta Lokasi + 57 => ['font' => ['bold' => true]], // D. Foto Objek dan Pembanding + 60 => ['font' => ['bold' => true]], // E. Foto Objek + + // Default styling for columns + 'A:J' => [ + 'alignment' => ['horizontal' => 'left', 'vertical' => 'center'], + 'wrapText' => true, + ], + + // Style for other sections (like photo and map sections) + + // Style for the other headers + 'A11:F11' => [ + 'font' => ['bold' => true], + 'fill' => ['fillType' => 'solid', 'color' => ['rgb' => 'E2EFDA']], + 'borders' => [ + 'allBorders' => [ + 'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN + ] + ] + ], + 'A12:F31' => [ + 'borders' => [ + 'allBorders' => [ + 'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN + ] + ] + ], + + + 'A35:F35' => [ + 'font' => ['bold' => true], + 'fill' => ['fillType' => 'solid', 'color' => ['rgb' => 'E2EFDA']], + 'borders' => [ + 'allBorders' => [ + 'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN + ] + ] + ], + 'A35:F49' => [ + 'borders' => [ + 'allBorders' => [ + 'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN + ] + ] + ], + + // end header + ]; + } + } diff --git a/app/Http/Controllers/PenilaiController.php b/app/Http/Controllers/PenilaiController.php index 48b2635..11f5b8c 100644 --- a/app/Http/Controllers/PenilaiController.php +++ b/app/Http/Controllers/PenilaiController.php @@ -192,131 +192,19 @@ class PenilaiController extends Controller ]); } - public function kertas_kerja() + public function kertas_kerja($id, $jeniJaminan) { - $data = [ - [ - 'Pendekatan pasar', - 'Nama Pemilik Aset', - '', - ], - [ - 'Metode Perbandingan Data Pasar', - 'Nama Pemberi Tugas: ', - '', - '', - ], - [ - 'Tanggal Penilaian: ', - 'Lokasi: ', - '', - '', - ], - [ - 'No.', - 'Objek Penilaian', - 'Data Pembanding 1', - 'Data Pembanding 2', - 'Data Pembanding 3' - ],[ - '1', - 'Jenis Aset', - 'Pembanding 1', - 'Pembanding 1', - 'Pembanding 1' - ], - [ - '2', - 'Luas Tanah', - 'Pembanding 2', - 'Pembanding 2', - 'Pembanding 2' - ], - [ - '3', - 'Penawaran/Transaksi', - '', - 'Pembanding 3', - 'Pembanding 3' - ], - [ - '4', - 'Harga penawaran/Transaksi', - '', - 'Pembanding 3', - 'Pembanding 3' - ],[ - '5', - 'Nomor Telepon', - '', - 'Pembanding 3', - 'Pembanding 3' - ], - [ - '6', - 'Estimasi Harga Transaksi', - '', - 'Pembanding 3', - 'Pembanding 3' - ], - [ - '7', - 'Nama Nara sumber', - '', - 'Pembanding 3', - 'Pembanding 3' - ], - [ - '8', - 'Status Nara sumber', - '', - 'Pembanding 3', - 'Pembanding 3' - ], - [ - '9', - 'Waktu Penawaran/Transaksi', - '', - 'Pembanding 3', - 'Pembanding 3' - ], - [ - '10', - 'Titik GPS', - '', - 'Pembanding 3', - ], - [ - '11', - 'Alamat', - '', - 'Pembanding 3', - 'Pembanding 3' - ], - [ - '12', - 'Jarak Pembanding dengan Objek (m)', - '', - 'Pembanding 3', - 'Pembanding 3' - ], - [ - '13', - 'Estimasi Rangking Tanah', - '', - 'Pembanding 3', - 'Pembanding 3' - ], - [ - '14', - 'Estimasi Rangking Bangunan', - '', - 'Pembanding 3', - 'Pembanding 3' - ] + $data = Inspeksi::where('permohonan_id', $id)->where('jenis_jaminan_id', $jaminanId)->first(); + $headerInfo = [ + 'tanggal_penilaian' => '', + 'nama_pemilik' => '', + 'nama_pemberi_tugas' => '', + 'lokasi_lengkap' => '', + 'nama_debitur' => '' ]; - return Excel::download(new KertasKerjaExport($data), 'kertas-kerja.xlsx'); + + return Excel::download(new KertasKerjaExport($data, $headerInfo), 'kertas-kerja.xlsx'); } diff --git a/app/Http/Controllers/PenilaianController.php b/app/Http/Controllers/PenilaianController.php index 0d4c94a..5515aaa 100644 --- a/app/Http/Controllers/PenilaianController.php +++ b/app/Http/Controllers/PenilaianController.php @@ -353,39 +353,92 @@ class PenilaianController extends Controller { $type = $request->route('type'); - $header = ''; - - switch ($type) { - case 'pelaporan': - $header = 'Pelaporan'; - break; - case 'pembayaran': - $header = 'Pembayaran'; - break; - case 'pembatalan': - $header = 'Pembatalan'; - break; - case 'sla': - $header = 'SLA'; - break; - default: - $header = 'Pelaporan'; - break; - } + $headers = [ + 'pelaporan' => 'Pelaporan', + 'pembayaran' => 'Pembayaran', + 'pembatalan' => 'Pembatalan', + 'sla' => 'SLA', + ]; + + $header = $headers[$type] ?? 'Pelaporan'; return view('lpj::penilaian.otorisator.index', compact('header')); } - public function show($id) + public function show($id, $type) + { + $headers = [ + 'Pelaporan' => 'Pelaporan', + 'Pembayaran' => 'Pembayaran', + 'Pembatalan' => 'Pembatalan', + 'SLA' => 'SLA', + ]; + + $header = $headers[$type] ?? 'Pelaporan'; + $permohonan = Permohonan::find($id); + + return view('lpj::penilaian.otorisator.show', compact('permohonan', 'header')); + } + + public function otorisatorUpdate($id, $context) { $permohonan = Permohonan::find($id); + if (!$permohonan) { + return response()->json([ + 'message' => 'Data permohonan tidak ditemukan.' + ], 404); + } - return view('lpj::penilaian.otorisator.show', compact('permohonan')); + switch (strtolower($context)) { + case 'pembayaran': + + $newStatus = $permohonan->status_bayar === 'sudah_bayar' ? 'belum_bayar' : 'sudah_bayar'; + + $permohonan->update([ + 'status_bayar' => $newStatus + ]); + break; + + case 'pembatalan': + + $permohonan->update([ + 'authorized_status' => 1, + ]); + break; + + case 'pelaporan': + + $permohonan->update([ + 'status' => 'disetujui', + ]); + break; + + case 'sla': + + $permohonan->update([ + 'status' => 'order', + ]); + break; + + default: + + return response()->json([ + 'message' => 'Konteks otorisasi tidak valid.' + ], 400); + } + + + return response()->json([ + 'message' => 'Otorisasi berhasil dilakukan.', + 'data' => $permohonan + ]); } + + public function dataForAuthorization(Request $request, $otorisator) { @@ -394,22 +447,14 @@ class PenilaianController extends Controller } - $status = ''; - - switch ($otorisator) { - case 'Pelaporan': - $status = 'proses paparan'; - break; - case 'Pembayaran': - $status = 'proses'; - break; - case 'Pembatalan': - $status = 'order'; - break; - default: - $status = ''; - break; - } + // Tentukan status berdasarkan otorisator + $status = match ($otorisator) { + 'Pelaporan' => 'proses laporan', + 'Pembayaran' => 'proses', + 'Pembatalan' => 'proses', + 'SLA' => 'proses', + default => '', + }; $query = Permohonan::query(); @@ -432,11 +477,18 @@ class PenilaianController extends Controller if (!empty($otorisator)) { if ($status == 'proses') { $query->whereIn('status_bayar', ['sudah_bayar', 'belum_bayar']); - } else { - $query->whereRaw('LOWER(status) = ?', [strtolower($status)]); } + // else { + // $query->whereRaw('LOWER(status) = ?', [strtolower($status)]); + // } } + // Filter berdasarkan region user yang login + $query->whereHas('region.teams.teamsUsers', function ($q) { + $q->where('user_id', Auth::id()); + }); + + // Sorting berdasarkan sortField dan sortOrder if ($request->has('sortOrder') && !empty($request->get('sortOrder'))) { $order = $request->get('sortOrder'); @@ -464,7 +516,8 @@ class PenilaianController extends Controller $filteredRecords = $query->count(); // Ambil data dengan relasi - $data = $query->with(['user', 'debiture', 'branch', 'tujuanPenilaian'])->get(); + $data = $query->with(['user', 'debiture', 'branch', 'tujuanPenilaian', 'region.teams.teamsUsers'])->get(); + // Hitung jumlah halaman $pageCount = ceil($totalRecords / $size); diff --git a/app/Http/Controllers/SurveyorController.php b/app/Http/Controllers/SurveyorController.php index 3931aa2..f20ee1e 100644 --- a/app/Http/Controllers/SurveyorController.php +++ b/app/Http/Controllers/SurveyorController.php @@ -283,7 +283,7 @@ class SurveyorController extends Controller ? json_decode($inspeksi->foto_form, true) : []; - $formatFotojson = $existingData; // Start with existing data + $formatFotojson = $existingData; // Process each photo category foreach ($photoCategories as $category => $fields) { @@ -566,9 +566,26 @@ class SurveyorController extends Controller $pembandingCount = count($request->input('address_pembanding', [])); $fotoPembanding = $request->file('foto_objek_pembanding') ?? []; + $existingData = null; + if ($request->has('permohonan_id') && $request->has('jenis_jaminan_id')) { + $inspeksi = Inspeksi::where('permohonan_id', $request->input('permohonan_id')) + ->where('jenis_jaminan_id', $request->input('jenis_jaminan_id')) + ->first(); + + if ($inspeksi) { + $existingData = $inspeksi->data_pembanding ?? []; + } + } + for ($i = 0; $i < $pembandingCount; $i++) { $pembanding = $this->formatSinglePembanding($request, $i); + + $existingFoto = null; + if ($existingData && isset($existingData[$i]['foto_objek'])) { + $existingFoto = $existingData[$i]['foto_objek']; + } + // Penanganan foto pembanding if (isset($fotoPembanding[$i]) && $fotoPembanding[$i]->isValid()) { $pembanding['foto_objek'] = $this->handleupdateOrDeleteFile( @@ -576,6 +593,8 @@ class SurveyorController extends Controller 'pembanding', "pembanding_{$i}" ); + } else { + $pembanding['foto_objek'] = $existingFoto; } $dataPembanding[] = $pembanding; @@ -583,6 +602,36 @@ class SurveyorController extends Controller return $dataPembanding; } + + + private function formatSinglePembanding($request, $index) + { + $fields = [ + 'address', 'village_code', 'district_code', 'city_code', 'province_code', + 'tahun', 'luas_tanah', 'luas_bangunan', 'tahun_bangunan', + 'status_nara_sumber', 'harga', 'harga_diskon', 'diskon', 'total', 'nama_nara_sumber', + 'peruntukan', 'penawaran_transaksi', 'nomor_tlp', + 'kordinat_lat', 'kordinat_lng', 'jenis_aset','foto_objek' + ]; + + $pembanding = []; + foreach ($fields as $field) { + $inputName = "{$field}_pembanding"; + $inputValue = $request->input($inputName); + + // Pastikan input adalah array dan index valid + if (is_array($inputValue) && isset($inputValue[$index])) { + $pembanding[$field] = $inputValue[$index]; + } else { + $pembanding[$field] = null; + } + } + + + return $pembanding; + } + + private function handleupdateOrDeleteFile($file, $type, $prefix) { @@ -605,45 +654,137 @@ class SurveyorController extends Controller } - private function formatSinglePembanding($request, $index) - { - $fields = [ - 'address', 'village_code', 'district_code', 'city_code', 'province_code', - 'tahun', 'luas_tanah', 'luas_bangunan', 'tahun_bangunan', - 'status_nara_sumber', 'harga', 'harga_diskon', 'diskon','total','nama_nara_sumber', - 'peruntukan', 'penawaran_transaksi', 'nomor_tlp', - 'kordinat_lat', 'kordinat_lng', 'jenis_aset', - ]; - - $pembanding = []; - foreach ($fields as $field) { - $inputName = "{$field}_pembanding"; - $pembanding[$field] = $request->input($inputName)[$index] ?? null; - } - - // Inisialisasi foto_objek sebagai null - $pembanding['foto_objek'] = null; - - return $pembanding; - } - private function formatObjekPenilaian($request) { $fields = [ 'address', 'village_code', 'district_code', 'city_code', 'province_code', - 'tahun', 'luas_tanah', 'luas_bangunan', 'tahun_bangunan', + 'luas_tanah', 'luas_tanah_bagunan', 'total', 'diskon', 'harga_diskon', 'status_nara_sumber', 'harga', 'nama_nara_sumber', - 'peruntukan', 'penawaran_transaksi', 'nomor_tlp', 'kordinat_lat', 'kordinat_lng', 'jenis_aset', ]; + + $inspeksi = Inspeksi::where('permohonan_id', $request->input('permohonan_id')) + ->where('jenis_jaminan_id', $request->input('jenis_jaminan_id')) + ->first(); + + if ($inspeksi) { + $needsSave = false; + + // Handle foto_form + $fotoForm = json_decode($inspeksi->foto_form, true) ?: []; + if (!isset($fotoForm['object_jaminan'])) { + $fotoForm['object_jaminan'] = [['foto_objek' => null]]; + $needsSave = true; + } + + // Handle data_form + $dataForm = json_decode($inspeksi->data_form, true) ?: []; + + // Inisialisasi struktur data jika belum ada + if(!isset($dataForm['bangunan'])) { + $dataForm['bangunan'] = []; + $needsSave = true; + } + + if(!isset($dataForm['tanah'])) { + $dataForm['tanah'] = []; + $needsSave = true; + } + + if (!isset($dataForm['asset'])) { + $dataForm['asset'] = []; + $needsSave = true; + } + + // Update data dengan mempertahankan struktur sesuai/tidak sesuai + foreach ($fields as $field) { + if ($request->filled($field)) { + $newValue = $request->input($field); + + // Fields untuk tanah + if (in_array($field, ['luas_tanah'])) { + $cekLuas = $dataForm['tanah']['luas_tanah'] == 'sesuai' ? 'sesuai' : 'tidak sesuai'; + $dataForm['tanah'][$field][$cekLuas] = $newValue; + } + // Fields untuk bangunan + else if (in_array($field, ['luas_tanah_bagunan'])) { - $objekPenilaian = array_reduce($fields, function ($carry, $field) use ($request) { - $carry[$field] = $request->input($field); - return $carry; - }, ['foto_objek' => null]); + $cekBanguan = $dataForm['bangunan']['luas_tanah_bagunan'] == 'sesuai' ? 'sesuai' : 'tidak sesuai'; + $dataForm['bangunan'][$field][$cekBanguan] = $newValue; + } + // Fields untuk alamat dalam asset + else if (in_array($field, ['address', 'village_code', 'district_code', 'city_code', 'province_code'])) { + if (!isset($dataForm['asset']['alamat'])) { + $dataForm['asset']['alamat'] = []; + } + + $alamatStatus = $dataForm['asset']['alamat'] == 'sesuai' ? 'sesuai' : 'tidak sesuai'; + if (!isset($dataForm['asset']['alamat'][$alamatStatus])) { + $dataForm['asset']['alamat'][$alamatStatus] = []; + } + + $dataForm['asset']['alamat'][$alamatStatus][$field] = $newValue; + } + // Jenis asset dalam asset + else if ($field === 'jenis_asset') { + $assetStatus = $request->input('asset_status', 'sesuai'); + $dataForm['asset']['jenis_asset'] = [ + $assetStatus => $newValue + ]; + } + // Fields lainnya dalam asset + else { + $dataForm['asset'][$field] = $newValue; + } + + $needsSave = true; + } + } + + if ($needsSave) { + $inspeksi->foto_form = json_encode($fotoForm); + $inspeksi->data_form = json_encode($dataForm); + $inspeksi->save(); + } + + $existingFoto = $fotoForm['object_jaminan'][0]['foto_objek'] ?? null; + + // Gabungkan data dari tanah, bangunan, dan asset + $objekPenilaian = array_merge( + ['foto_objek' => $existingFoto], + $dataForm['tanah'] ?? [], + $dataForm['bangunan'] ?? [], + array_reduce($fields, function ($carry, $field) use ($request, $dataForm) { + if (isset($dataForm['asset'][$field])) { + if (is_array($dataForm['asset'][$field])) { + if (isset($dataForm['asset'][$field]['sesuai'])) { + $carry[$field] = $dataForm['asset'][$field]['sesuai']; + } elseif (isset($dataForm['asset'][$field]['tidak sesuai'])) { + $carry[$field] = $dataForm['asset'][$field]['tidak sesuai']; + } + } else { + $carry[$field] = $dataForm['asset'][$field]; + } + } else { + $carry[$field] = $request->input($field); + } + return $carry; + }, []) + ); + + } else { + // Inisialisasi data baru + $objekPenilaian = array_reduce($fields, function ($carry, $field) use ($request) { + $carry[$field] = $request->input($field); + return $carry; + }, ['foto_objek' => null]); + } + return $objekPenilaian; } + + private function saveInspeksi($formattedData) { @@ -676,13 +817,36 @@ class SurveyorController extends Controller $objekPenilaian = $this->formatObjekPenilaian($request); if ($request->hasFile('foto_objek')) { - $objekPenilaian['foto_objek'] = $this->handleupdateOrDeleteFile( + $newFoto = $this->handleupdateOrDeleteFile( $request->file('foto_objek'), $request['type'] = 'pembanding', 'objek_penilaian' ); + + // Update foto_form + $inspeksi = Inspeksi::where('permohonan_id', $request->input('permohonan_id')) + ->where('jenis_jaminan_id', $request->input('jenis_jaminan_id')) + ->first(); + + if ($inspeksi) { + $fotoForm = json_decode($inspeksi->foto_form, true) ?: []; + if (!isset($fotoForm['object_jaminan'])) { + $fotoForm['object_jaminan'] = []; + } + if (empty($fotoForm['object_jaminan'])) { + $fotoForm['object_jaminan'][] = ['foto_objek' => $newFoto]; + } else { + $fotoForm['object_jaminan'][0]['foto_objek'] = $newFoto; + } + + $inspeksi->foto_form = json_encode($fotoForm); + $inspeksi->save(); + } + + $objekPenilaian['foto_objek'] = $newFoto; } + $formattedData = [ 'permohonan_id' => $request->input('permohonan_id'), 'type' => $request->input('type'), @@ -698,7 +862,7 @@ class SurveyorController extends Controller return response()->json([ 'success' => true, 'message' => 'Data berhasil disimpan', - 'data' => $objekPenilaian + 'data' => $formattedData ], 200); } catch (\Exception $e) { @@ -747,7 +911,7 @@ class SurveyorController extends Controller // Jika alamat tidak sesuai, override dengan kode dari alamat - $cekAlamat = $forminspeksi['asset']['alamat']['tidak sesuai'] ?? null; + $cekAlamat = $forminspeksi['asset']['alamat']['tidak sesuai'] ?? null; if ($cekAlamat) { $provinceCode = $cekAlamat['province_code'] ?? $provinceCode; diff --git a/app/Http/Requests/FormSurveyorRequest.php b/app/Http/Requests/FormSurveyorRequest.php index f56063f..02c3d8a 100644 --- a/app/Http/Requests/FormSurveyorRequest.php +++ b/app/Http/Requests/FormSurveyorRequest.php @@ -524,26 +524,26 @@ class FormSurveyorRequest extends FormRequest 'permohonan_id' => 'required', 'type' => 'required', 'debitur_perwakilan' => 'required|array', - 'jenis_asset_name' => 'nullable', + 'jenis_asset_name' => 'nullable|', 'jenis_asset' => 'required', - 'jenis_asset_tidak_sesuai' => 'nullable', + 'jenis_asset_tidak_sesuai' => 'nullable|string', 'alamat_sesuai' => 'required', - 'alamat_tidak_sesuai' => 'nullable', + 'alamat_tidak_sesuai' => 'nullable|string', 'hub_cadeb' => 'required', - 'hub_cadeb_sesuai' => 'nullable', - 'hub_cadeb_tidak_sesuai' => 'nullable', + 'hub_cadeb_sesuai' => 'nullable|string', + 'hub_cadeb_tidak_sesuai' => 'nullable|string', 'hub_cadeb_penghuni' => 'required', - 'hub_cadeb_penghuni_sesuai' => 'nullable', - 'hub_penghuni_tidak_sesuai' => 'nullable', + 'hub_cadeb_penghuni_sesuai' => 'nullable|string', + 'hub_penghuni_tidak_sesuai' => 'nullable|string', - 'address' => 'nullable', - 'village_code' => 'nullable', - 'district_code' => 'nullable', - 'city_code' => 'nullable', - 'province_code' => 'nullable', - 'kordinat_lng' => 'nullable', - 'kordinat_lat' => 'nullable', + 'address' => 'nullable|string', + 'village_code' => 'nullable|string', + 'district_code' => 'nullable|string', + 'city_code' => 'nullable|string', + 'province_code' => 'nullable|string', + 'kordinat_lng' => 'nullable|string', + 'kordinat_lat' => 'nullable|string', ]; } diff --git a/database/seeders/KJPPSeeder.php b/database/seeders/KJPPSeeder.php index 4f7396d..a32e1a7 100644 --- a/database/seeders/KJPPSeeder.php +++ b/database/seeders/KJPPSeeder.php @@ -4,14 +4,315 @@ namespace Modules\Lpj\Database\Seeders; use Illuminate\Database\Seeder; use Illuminate\Support\Facades\DB; +use Maatwebsite\Excel\Facades\Excel; +use Illuminate\Support\Str; +use Modules\Lpj\Models\KJPP; +use Modules\Lpj\Models\JenisJaminan; +use Modules\Lpj\Models\IjinUsaha; +use Modules\Location\Models\City; +use Modules\Location\Models\District; +use Modules\Location\Models\Village; class KJPPSeeder extends Seeder { /** * Run the database seeds. */ + public function run(): void { - DB::unprepared(file_get_contents(__DIR__ . '/sql/kjpp.sql')); + $filePath = __DIR__ . '/list-update-kjpp.xlsx'; + // DB::unprepared(file_get_contents(__DIR__ . '/kjpp.sql')); + + if (!file_exists($filePath)) { + $this->command->error('File excel tidak ditemukan di: ' . $filePath); + return; + } + + $this->command->info('Membaca file Excel...'); + + try { + // Baca excel dan tampilkan raw data + $collection = Excel::toCollection(null, $filePath)->first(); + // Debug: Tampilkan jumlah baris + $this->command->info('Total baris: ' . $collection->count()); + + // Debug: Tampilkan 3 baris pertama (header) + // $this->command->info('Header data:'); + // foreach($collection->take(3) as $index => $row) { + // $this->command->info("Baris $index: " . print_r($row->toArray(), true)); + // } + + // Skip 3 baris header + $data = $collection->skip(3); + + + // Proses setiap baris + foreach ($data as $index => $row) { + $this->command->info("Memproses baris ke-$index:"); + + // Debug: Tampilkan data mentah + // $this->command->info('Raw data: ' . print_r($row->toArray(), true)); + + // Skip jika baris kosong + if (empty($row[2])) { + $this->command->warn("Baris $index dilewati karena nama KJPP kosong"); + continue; + } + + + $locationData = $this->checkKota($row[5]); + + $jenisUsaha = $this->checkJenisUsaha($row[18]); + $jenisAsset = $this->checkJenisAsset($row[19]); + + $detail_email_kantor = $this->checkDanJadikanJson($row[8]); + $nama_pic_reviewer = $this->checkDanJadikanJson($row[11]); + $nomor_hp_pic_reviewer = $this->checkDanJadikanJson($row[12]); + $detail_nama_pic_admin = $this->checkDanJadikanJson($row[13]); + + $nomor_hp_pic_admin = $this->checkDanJadikanJson($row[14]); + $nama_pic_marketing = $this->checkDanJadikanJson($row[15]); + + + $nomor_hp_pic_marketing = $this->checkDanJadikanJson($row[16]); + + + try { + $dataToInsert = [ + 'code' => $this->generateKJPPCode(), + 'name' => $row[2], + 'jenis_kantor' => "Kantor " . $row[3], + 'nomor_ijin_usaha' => $row[4], + 'province_code' => $locationData['province'], + 'city_code' => $locationData['city'], + 'district_code' => $locationData['district'], + 'village_code' => $locationData['village'], + 'address' => $row[7], + 'postal_code' => $locationData['postal_code'], + 'nomor_telepon_kantor' => $row[8], + 'email_kantor' => $detail_email_kantor, + 'detail_email_kantor' => $detail_email_kantor, + 'nama_pimpinan' => $row[9], + 'nomor_hp_pimpinan' => $row[10], + 'nama_pic_reviewer' => $nama_pic_reviewer, + 'detail_nama_pic_reviewer' => $nama_pic_reviewer, + 'nomor_hp_pic_reviewer' => $nomor_hp_pic_reviewer, + 'detail_nomor_hp_pic_reviewer' => $nomor_hp_pic_reviewer, + + 'nama_pic_admin' => $detail_nama_pic_admin, + 'detail_nama_pic_admin' => $detail_nama_pic_admin, + 'nomor_hp_pic_admin' => $nomor_hp_pic_admin, + 'detail_nomor_hp_pic_admin' => $nomor_hp_pic_admin, + 'nama_pic_marketing' => $nama_pic_marketing, + 'detail_nama_pic_marketing' => $nama_pic_marketing, + 'nomor_hp_pic_marketing' => $nomor_hp_pic_marketing[0], + 'detail_nomor_hp_pic_marketing' => $nomor_hp_pic_marketing, + 'ijin_usaha_id' => json_encode($jenisUsaha), + 'jenis_aset_id' => json_encode($jenisAsset), + 'attachment' => null, + ]; + + + + + // Simpan ke database + KJPP::create($dataToInsert); + + $this->command->info("Berhasil menyimpan data baris $index"); + + } catch (\Exception $e) { + $this->command->error("Error pada baris $index: " . $e->getMessage()); + // Lanjut ke baris berikutnya + continue; + } + } + + $this->command->info('Selesai import data KJPP!'); + + } catch (\Exception $e) { + $this->command->error('Error utama: ' . $e->getMessage()); + $this->command->error('Stack trace: ' . $e->getTraceAsString()); + } + } + + private function generateKJPPCode() +{ + do { + $code = 'K' . str_pad(rand(1, 99999), 5, '0', STR_PAD_LEFT); + } while (KJPP::where('code', $code)->exists()); + + return $code; +} + +public function checkKota($data) +{ + try { + $city = null; + if ($data) { + // Bersihkan data dan ubah ke uppercase + $cleanData = trim(strtoupper($data)); + + $possibleNames = [ + 'KAB. ' . $cleanData, + 'KOTA ' . $cleanData, + 'KAB. ADM. ' . $cleanData, + 'KOTA ADM. ' . $cleanData, + $cleanData + ]; + + $city = City::whereIn(DB::raw('UPPER(name)'), $possibleNames)->first(); + + if ($city) { + // Cari district berdasarkan city_code + $district = District::where('city_code', $city->code)->first(); + if (!$district) { + return null; + } + + $village = Village::where('district_code', $district->code)->first(); + if (!$village) { + + return null; + } + return [ + 'province' => $city->province_code, + 'city' => $city->code, + 'district' => $district->code, + 'village' => $village->code, + 'postal_code' => $village->postal_code + ]; + } else{ + return null; + } + } + + return null; + + } catch (\Exception $e) { + $this->command->error(" ❌ Error: " . $e->getMessage()); + return null; } } + +public function checkJenisAsset($data) +{ + try { + if (!$data) return []; + + // Bersihkan dan ubah ke lowercase + $cleanData = trim(strtolower($data)); + + // Pisahkan berdasarkan koma, titik koma, dan spasi + $assets = preg_split('/[;,]+|\\s+/', $cleanData); + + // Daftar asset yang valid di database + $validAssets = JenisJaminan::pluck('code')->toArray(); + $assetIds = []; + + foreach ($assets as $asset) { + // Hapus spasi di awal dan akhir + $asset = trim($asset); + + // Cek jika ada tanda kurung + if (preg_match('/\((.*?)\)/', $asset, $matches)) { + // Ambil isi dalam tanda kurung dan pisahkan + $insideParentheses = explode(',', $matches[1]); + foreach ($insideParentheses as $insideAsset) { + $insideAsset = trim($insideAsset); + // Cari di database + $jenisAsset = JenisJaminan::whereRaw('LOWER(name) = ?', [$insideAsset])->first(); + if ($jenisAsset && in_array($jenisAsset->code, $validAssets)) { + $assetIds[] = $jenisAsset->code; + } + } + } + + // Cek jenis aset utama (tanpa tanda kurung) + $jenisAsset = JenisJaminan::whereRaw('LOWER(name) = ?', [$asset])->first(); + if ($jenisAsset && in_array($jenisAsset->code, $validAssets)) { + $assetIds[] = $jenisAsset->code; + + } + } + + // Menghilangkan duplikat jika ada + $assetIds = array_unique($assetIds); + + // Sort array untuk konsistensi + sort($assetIds); + + return $assetIds; + + } catch (\Exception $e) { + $this->command->error(" ❌ Error pada checkJenisAsset: " . $e->getMessage()); + return []; + } +} + + +public function checkJenisUsaha($data) +{ + try { + if (!$data) return []; + + // Bersihkan dan ubah ke lowercase + $cleanData = trim(strtolower($data)); + + // Pisahkan berdasarkan koma, titik koma, atau garis miring + $usahas = preg_split('/[\s,;\/]+/', $cleanData); + + // Ambil daftar valid usaha dari database + $validUsaha = IjinUsaha::pluck('code')->toArray(); + $usahaIds = []; + + foreach ($usahas as $usaha) { + // Hapus spasi di awal dan akhir + $usaha = trim($usaha); + + // Cari jenis usaha di database + $jenisUsaha = IjinUsaha::whereRaw('LOWER(name) = ?', [$usaha])->first(); + + if ($jenisUsaha && in_array($jenisUsaha->code, $validUsaha)) { + $usahaIds[] = $jenisUsaha->code; + } + } + + // Menghilangkan duplikat jika ada + $usahaIds = array_unique($usahaIds); + + // Sort array untuk konsistensi + sort($usahaIds); + + return $usahaIds; + + } catch (\Exception $e) { + $this->command->error(" ❌ Error pada checkJenisUsaha: " . $e->getMessage()); + return []; + } +} + + +// Fungsi untuk memisahkan dan mengonversi data menjadi array JSON +function checkDanJadikanJson($input) { + + $input = trim($input); + + // memisahkan berdasarkan "/", ";", "dan", atau baris baru ("\n") + $separatedData = preg_split('/\s*\/\s*|\s*;\s*|\s*dan\s*|\s*\n\s*/i', $input); + + + $cleanedData = array_map(function($item) { + return trim($item); + }, $separatedData); + + $cleanedData = array_filter($cleanedData, function($item) { + return !empty($item); + }); + + return json_encode(array_values($cleanedData)); +} + + + +} diff --git a/database/seeders/list-update-kjpp.xlsx b/database/seeders/list-update-kjpp.xlsx new file mode 100644 index 0000000..89329e9 Binary files /dev/null and b/database/seeders/list-update-kjpp.xlsx differ diff --git a/resources/views/penilaian/otorisator/index.blade.php b/resources/views/penilaian/otorisator/index.blade.php index 1743f8e..56a8c90 100644 --- a/resources/views/penilaian/otorisator/index.blade.php +++ b/resources/views/penilaian/otorisator/index.blade.php @@ -1,16 +1,18 @@ @extends('layouts.main') @section('breadcrumbs') - {{ Breadcrumbs::render('otorisator.'. strtolower($header)) }} + {{ Breadcrumbs::render('otorisator.' . strtolower($header)) }} @endsection @section('content')
-
+

- Daftar {{$header}} + Daftar {{ $header }}

@@ -27,46 +29,56 @@
- +
- - - - - - - - + + + + + + + + - - + @if ($header == 'Pembayaran') + + @endif + + +
- - - Nomor Registrasi - - - Tanggal Permohonan - - - User Pemohon - - - Cabang Pemohon - - - Debitur - - - Tujuan Penilaian - -
+ + + Nomor Registrasi + + + Tanggal Permohonan + + + User Pemohon + + + Cabang Pemohon + + + Debitur + + + Tujuan Penilaian + + Action
+ Status Bayar + + Action
-