update data pemanding dan otorisator, pembuatan seeder kjpp mengunakan exel

This commit is contained in:
majid
2024-12-11 17:34:51 +07:00
parent 5dc95d3339
commit bb1ad785a5
14 changed files with 1136 additions and 766 deletions

View File

@@ -353,39 +353,92 @@ class PenilaianController extends Controller
{ {
$type = $request->route('type'); $type = $request->route('type');
$header = ''; $headers = [
'pelaporan' => 'Pelaporan',
switch ($type) { 'pembayaran' => 'Pembayaran',
case 'pelaporan': 'pembatalan' => 'Pembatalan',
$header = 'Pelaporan'; 'sla' => 'SLA',
break; ];
case 'pembayaran':
$header = 'Pembayaran'; $header = $headers[$type] ?? 'Pelaporan';
break;
case 'pembatalan':
$header = 'Pembatalan';
break;
case 'sla':
$header = 'SLA';
break;
default:
$header = 'Pelaporan';
break;
}
return view('lpj::penilaian.otorisator.index', compact('header')); 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); $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) public function dataForAuthorization(Request $request, $otorisator)
{ {
@@ -394,22 +447,14 @@ class PenilaianController extends Controller
} }
$status = ''; // Tentukan status berdasarkan otorisator
$status = match ($otorisator) {
switch ($otorisator) { 'Pelaporan' => 'proses laporan',
case 'Pelaporan': 'Pembayaran' => 'proses',
$status = 'proses paparan'; 'Pembatalan' => 'proses',
break; 'SLA' => 'proses',
case 'Pembayaran': default => '',
$status = 'proses'; };
break;
case 'Pembatalan':
$status = 'order';
break;
default:
$status = '';
break;
}
$query = Permohonan::query(); $query = Permohonan::query();
@@ -432,11 +477,18 @@ class PenilaianController extends Controller
if (!empty($otorisator)) { if (!empty($otorisator)) {
if ($status == 'proses') { if ($status == 'proses') {
$query->whereIn('status_bayar', ['sudah_bayar', 'belum_bayar']); $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 // Sorting berdasarkan sortField dan sortOrder
if ($request->has('sortOrder') && !empty($request->get('sortOrder'))) { if ($request->has('sortOrder') && !empty($request->get('sortOrder'))) {
$order = $request->get('sortOrder'); $order = $request->get('sortOrder');
@@ -464,7 +516,8 @@ class PenilaianController extends Controller
$filteredRecords = $query->count(); $filteredRecords = $query->count();
// Ambil data dengan relasi // 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 // Hitung jumlah halaman
$pageCount = ceil($totalRecords / $size); $pageCount = ceil($totalRecords / $size);

View File

@@ -282,7 +282,7 @@ class SurveyorController extends Controller
? json_decode($inspeksi->foto_form, true) ? json_decode($inspeksi->foto_form, true)
: []; : [];
$formatFotojson = $existingData; // Start with existing data $formatFotojson = $existingData;
// Process each photo category // Process each photo category
foreach ($photoCategories as $category => $fields) { foreach ($photoCategories as $category => $fields) {
@@ -558,9 +558,26 @@ class SurveyorController extends Controller
$pembandingCount = count($request->input('address_pembanding', [])); $pembandingCount = count($request->input('address_pembanding', []));
$fotoPembanding = $request->file('foto_objek_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++) { for ($i = 0; $i < $pembandingCount; $i++) {
$pembanding = $this->formatSinglePembanding($request, $i); $pembanding = $this->formatSinglePembanding($request, $i);
$existingFoto = null;
if ($existingData && isset($existingData[$i]['foto_objek'])) {
$existingFoto = $existingData[$i]['foto_objek'];
}
// Penanganan foto pembanding // Penanganan foto pembanding
if (isset($fotoPembanding[$i]) && $fotoPembanding[$i]->isValid()) { if (isset($fotoPembanding[$i]) && $fotoPembanding[$i]->isValid()) {
$pembanding['foto_objek'] = $this->handleupdateOrDeleteFile( $pembanding['foto_objek'] = $this->handleupdateOrDeleteFile(
@@ -568,6 +585,8 @@ class SurveyorController extends Controller
'pembanding', 'pembanding',
"pembanding_{$i}" "pembanding_{$i}"
); );
} else {
$pembanding['foto_objek'] = $existingFoto;
} }
$dataPembanding[] = $pembanding; $dataPembanding[] = $pembanding;
@@ -575,6 +594,36 @@ class SurveyorController extends Controller
return $dataPembanding; 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) private function handleupdateOrDeleteFile($file, $type, $prefix)
{ {
@@ -597,45 +646,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) private function formatObjekPenilaian($request)
{ {
$fields = [ $fields = [
'address', 'village_code', 'district_code', 'city_code', 'province_code', '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', 'status_nara_sumber', 'harga', 'nama_nara_sumber',
'peruntukan', 'penawaran_transaksi', 'nomor_tlp',
'kordinat_lat', 'kordinat_lng', 'jenis_aset', '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) { $cekBanguan = $dataForm['bangunan']['luas_tanah_bagunan'] == 'sesuai' ? 'sesuai' : 'tidak sesuai';
$carry[$field] = $request->input($field); $dataForm['bangunan'][$field][$cekBanguan] = $newValue;
return $carry; }
}, ['foto_objek' => null]); // 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; return $objekPenilaian;
} }
private function saveInspeksi($formattedData) private function saveInspeksi($formattedData)
{ {
@@ -668,13 +809,36 @@ class SurveyorController extends Controller
$objekPenilaian = $this->formatObjekPenilaian($request); $objekPenilaian = $this->formatObjekPenilaian($request);
if ($request->hasFile('foto_objek')) { if ($request->hasFile('foto_objek')) {
$objekPenilaian['foto_objek'] = $this->handleupdateOrDeleteFile( $newFoto = $this->handleupdateOrDeleteFile(
$request->file('foto_objek'), $request->file('foto_objek'),
$request['type'] = 'pembanding', $request['type'] = 'pembanding',
'objek_penilaian' '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 = [ $formattedData = [
'permohonan_id' => $request->input('permohonan_id'), 'permohonan_id' => $request->input('permohonan_id'),
'type' => $request->input('type'), 'type' => $request->input('type'),
@@ -690,7 +854,7 @@ class SurveyorController extends Controller
return response()->json([ return response()->json([
'success' => true, 'success' => true,
'message' => 'Data berhasil disimpan', 'message' => 'Data berhasil disimpan',
'data' => $objekPenilaian 'data' => $formattedData
], 200); ], 200);
} catch (\Exception $e) { } catch (\Exception $e) {
@@ -739,7 +903,7 @@ class SurveyorController extends Controller
// Jika alamat tidak sesuai, override dengan kode dari alamat // 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) { if ($cekAlamat) {
$provinceCode = $cekAlamat['province_code'] ?? $provinceCode; $provinceCode = $cekAlamat['province_code'] ?? $provinceCode;

View File

@@ -524,26 +524,26 @@ class FormSurveyorRequest extends FormRequest
'permohonan_id' => 'required', 'permohonan_id' => 'required',
'type' => 'required', 'type' => 'required',
'debitur_perwakilan' => 'required|array', 'debitur_perwakilan' => 'required|array',
'jenis_asset_name' => 'nullable', 'jenis_asset_name' => 'nullable|',
'jenis_asset' => 'required', 'jenis_asset' => 'required',
'jenis_asset_tidak_sesuai' => 'nullable', 'jenis_asset_tidak_sesuai' => 'nullable|string',
'alamat_sesuai' => 'required', 'alamat_sesuai' => 'required',
'alamat_tidak_sesuai' => 'nullable', 'alamat_tidak_sesuai' => 'nullable|string',
'hub_cadeb' => 'required', 'hub_cadeb' => 'required',
'hub_cadeb_sesuai' => 'nullable', 'hub_cadeb_sesuai' => 'nullable|string',
'hub_cadeb_tidak_sesuai' => 'nullable', 'hub_cadeb_tidak_sesuai' => 'nullable|string',
'hub_cadeb_penghuni' => 'required', 'hub_cadeb_penghuni' => 'required',
'hub_cadeb_penghuni_sesuai' => 'nullable', 'hub_cadeb_penghuni_sesuai' => 'nullable|string',
'hub_penghuni_tidak_sesuai' => 'nullable', 'hub_penghuni_tidak_sesuai' => 'nullable|string',
'address' => 'nullable', 'address' => 'nullable|string',
'village_code' => 'nullable', 'village_code' => 'nullable|string',
'district_code' => 'nullable', 'district_code' => 'nullable|string',
'city_code' => 'nullable', 'city_code' => 'nullable|string',
'province_code' => 'nullable', 'province_code' => 'nullable|string',
'kordinat_lng' => 'nullable', 'kordinat_lng' => 'nullable|string',
'kordinat_lat' => 'nullable', 'kordinat_lat' => 'nullable|string',
]; ];
} }

View File

@@ -4,14 +4,271 @@ namespace Modules\Lpj\Database\Seeders;
use Illuminate\Database\Seeder; use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB; 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 class KJPPSeeder extends Seeder
{ {
/** /**
* Run the database seeds. * Run the database seeds.
*/ */
public function run(): void public function run(): void
{ {
DB::unprepared(file_get_contents(__DIR__ . '/kjpp.sql')); $filePath = __DIR__ . '/LISTsatsa.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, null, function($reader) {
$reader->setActiveSheetIndex(1);
})->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);
// Debug: Tampilkan jumlah data setelah skip header
$this->command->info('Total data setelah skip header: ' . $data->count());
// 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[17]);
$jenisAsset = $this->checkJenisAsset($row[18]);
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[6],
'postal_code' => $locationData['postal_code'],
'nomor_telepon_kantor' => $row[7],
'email_kantor' => $row[8],
'detail_email_kantor' => json_encode($row[8]),
'nama_pimpinan' => $row[9],
'nomor_hp_pimpinan' => $row[10],
'nama_pic_reviewer' => json_encode($row[11]),
'detail_nama_pic_reviewer' => json_encode($row[11]),
'nomor_hp_pic_reviewer' => json_encode($row[12]),
'detail_nomor_hp_pic_reviewer' => json_encode($row[12]),
'nama_pic_admin' => $row[13],
'detail_nama_pic_admin' => json_encode($row[13]),
'nomor_hp_pic_admin' => json_encode($row[14]),
'detail_nomor_hp_pic_admin' => json_encode($row[14]),
'nama_pic_marketing' => json_encode($row[15]),
'detail_nama_pic_marketing' => json_encode($row[15]),
'nomor_hp_pic_marketing' => json_encode($row[16]),
'detail_nomor_hp_pic_marketing' => json_encode($row[16]),
'ijin_usaha_id' => json_encode($jenisUsaha),
'jenis_aset_id' => json_encode($jenisAsset),
'attachment' => null,
];
// Debug: Tampilkan data yang akan diinsert
$this->command->info('Data yang akan disimpan: ' . print_r($dataToInsert, true));
// 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
$assets = array_map('trim', explode(',', $cleanData));
// Daftar asset yang valid di database
$validAssets = JenisJaminan::pluck('code')->toArray();
$assetIds = [];
foreach ($assets as $asset) {
// Cari di database dengan lowercase
$jenisAsset = JenisJaminan::whereRaw('LOWER(name) = ?', [$asset])->first();
if ($jenisAsset && in_array($jenisAsset->code, $validAssets)) {
$assetIds[] = $jenisAsset->code;
$this->command->info(" ✅ Jenis Asset ditemukan: " . $jenisAsset->name);
}
// Hilangkan warning untuk yang tidak ditemukan
}
// 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 jika ada
$usahas = array_map('trim', explode(',', $cleanData));
// Daftar usaha yang valid di database
$validUsaha = IjinUsaha::pluck('code')->toArray();
$usahaIds = [];
foreach ($usahas as $usaha) {
// Cari di database dengan lowercase
$jenisUsaha = IjinUsaha::whereRaw('LOWER(name) = ?', [$usaha])->first();
if ($jenisUsaha && in_array($jenisUsaha->code, $validUsaha)) {
$usahaIds[] = $jenisUsaha->code;
$this->command->info(" ✅ Jenis Usaha ditemukan: " . $jenisUsaha->name);
}
// Hilangkan warning untuk yang tidak ditemukan
}
// Menghilangkan duplikat jika ada
$usahaIds = array_unique($usahaIds);
// Sort array untuk konsistensi
sort($usahaIds);
return $usahaIds;
} catch (\Exception $e) {
return [];
}
}
} }

View File

@@ -1,16 +1,18 @@
@extends('layouts.main') @extends('layouts.main')
@section('breadcrumbs') @section('breadcrumbs')
{{ Breadcrumbs::render('otorisator.'. strtolower($header)) }} {{ Breadcrumbs::render('otorisator.' . strtolower($header)) }}
@endsection @endsection
@section('content') @section('content')
<div class="w-full grid gap-5 lg:gap-7.5 mx-auto"> <div class="w-full grid gap-5 lg:gap-7.5 mx-auto">
<div class="card pb-2.5"> <div class="card pb-2.5">
<div class=" card-grid min-w-full" data-datatable="false" data-datatable-page-size="5" data-datatable-state-save="false" id="permohonan-table" data-api-url="{{ route('otorisator.datatables', ['otorisator' => $header ]) }}"> <div class=" card-grid min-w-full" data-datatable="false" data-datatable-page-size="5"
data-datatable-state-save="false" id="permohonan-table"
data-api-url="{{ route('otorisator.datatables', ['otorisator' => $header]) }}">
<div class="card-header py-5 flex-wrap"> <div class="card-header py-5 flex-wrap">
<h3 class="card-title"> <h3 class="card-title">
Daftar {{$header}} Daftar {{ $header }}
</h3> </h3>
<div class="flex flex-wrap gap-2 lg:gap-5"> <div class="flex flex-wrap gap-2 lg:gap-5">
<div class="flex"> <div class="flex">
@@ -27,46 +29,56 @@
<div class="card-body"> <div class="card-body">
<div class="scrollable-x-auto"> <div class="scrollable-x-auto">
<table class="table table-auto table-border align-middle text-gray-700 font-medium text-sm" data-datatable-table="true"> <table class="table table-auto table-border align-middle text-gray-700 font-medium text-sm"
data-datatable-table="true">
<thead> <thead>
<tr> <tr>
<th class="w-14"> <th class="w-14">
<input class="checkbox checkbox-sm" data-datatable-check="true" type="checkbox"/> <input class="checkbox checkbox-sm" data-datatable-check="true" type="checkbox" />
</th> </th>
<th class="min-w-[150px]" data-datatable-column="nomor_registrasi"> <th class="min-w-[150px]" data-datatable-column="nomor_registrasi">
<span class="sort"> <span class="sort-label"> Nomor Registrasi </span> <span class="sort"> <span class="sort-label"> Nomor Registrasi </span>
<span class="sort-icon"> </span> </span> <span class="sort-icon"> </span> </span>
</th> </th>
<th class="min-w-[150px]" data-datatable-column="tanggal_permohonan"> <th class="min-w-[150px]" data-datatable-column="tanggal_permohonan">
<span class="sort"> <span class="sort-label"> Tanggal Permohonan </span> <span class="sort"> <span class="sort-label"> Tanggal Permohonan </span>
<span class="sort-icon"> </span> </span> <span class="sort-icon"> </span> </span>
</th> </th>
<th class="min-w-[150px]" data-datatable-column="user_id"> <th class="min-w-[150px]" data-datatable-column="user_id">
<span class="sort"> <span class="sort-label"> User Pemohon </span> <span class="sort"> <span class="sort-label"> User Pemohon </span>
<span class="sort-icon"> </span> </span> <span class="sort-icon"> </span> </span>
</th> </th>
<th class="min-w-[150px]" data-datatable-column="branch_id"> <th class="min-w-[150px]" data-datatable-column="branch_id">
<span class="sort"> <span class="sort-label"> Cabang Pemohon </span> <span class="sort"> <span class="sort-label"> Cabang Pemohon </span>
<span class="sort-icon"> </span> </span> <span class="sort-icon"> </span> </span>
</th> </th>
<th class="min-w-[150px]" data-datatable-column="debitur_id"> <th class="min-w-[150px]" data-datatable-column="debitur_id">
<span class="sort"> <span class="sort-label"> Debitur </span> <span class="sort"> <span class="sort-label"> Debitur </span>
<span class="sort-icon"> </span> </span> <span class="sort-icon"> </span> </span>
</th> </th>
<th class="min-w-[150px]" data-datatable-column="tujuan_penilaian_id"> <th class="min-w-[150px]" data-datatable-column="tujuan_penilaian_id">
<span class="sort"> <span class="sort-label"> Tujuan Penilaian </span> <span class="sort"> <span class="sort-label"> Tujuan Penilaian </span>
<span class="sort-icon"> </span> </span> <span class="sort-icon"> </span> </span>
</th> </th>
<th class="min-w-[50px] text-center" data-datatable-column="actions">Action</th> @if ($header == 'Pembayaran')
</tr> <th class="min-w-[150px]" data-datatable-column="tujuan_penilaian_id">
<span class="sort"> <span class="sort-label"> Status Bayar </span>
<span class="sort-icon"> </span> </span>
</th>
@endif
<th class="min-w-[50px] text-center" data-datatable-column="actions">Action</th>
</tr>
</thead> </thead>
</table> </table>
</div> </div>
<div class="card-footer justify-center md:justify-between flex-col md:flex-row gap-3 text-gray-600 text-2sm font-medium"> <div
class="card-footer justify-center md:justify-between flex-col md:flex-row gap-3 text-gray-600 text-2sm font-medium">
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
Show Show
<select class="select select-sm w-16" data-datatable-size="true" name="perpage"> </select> per page <select class="select select-sm w-16" data-datatable-size="true" name="perpage"> </select> per
page
</div> </div>
<div class="flex items-center gap-4"> <div class="flex items-center gap-4">
<span data-datatable-info="true"> </span> <span data-datatable-info="true"> </span>
@@ -83,9 +95,8 @@
@push('scripts') @push('scripts')
<script> <script>
function otorisator(){ function otorisator() {
Swal.fire({ Swal.fire({
title: 'Are you sure?', title: 'Are you sure?',
text: "You won't be able to revert this!", text: "You won't be able to revert this!",
@@ -119,10 +130,11 @@
<script type="module"> <script type="module">
const element = document.querySelector('#permohonan-table'); const element = document.querySelector('#permohonan-table');
const searchInput = document.getElementById('search'); const searchInput = document.getElementById('search');
const dataHeader = @json($header);
const apiUrl = element.getAttribute('data-api-url'); const apiUrl = element.getAttribute('data-api-url');
@@ -170,14 +182,43 @@
return `${data.tujuan_penilaian.name}`; return `${data.tujuan_penilaian.name}`;
}, },
}, },
...(dataHeader === 'Pembayaran' && {
status_bayar: {
title: 'Status Bayar',
render: (item, data) => {
const status = data.status_bayar.replace(/_/g,
' ');
const statusClass = data.status_bayar === 'belum_bayar' ? 'text-red-600' :
'text-green-600';
return `<span class="text-md font-bold ${statusClass} uppercase">
${status}
</span>`;
},
},
}),
actions: { actions: {
title: 'Status', title: 'Status',
render: (item, data) => { render: (item, data) => {
return `<div class="flex flex-nowrap justify-center"> if (data.status != 'proses laporan' && dataHeader != 'Pelaporan') {
<a class="btn btn-sm btn-icon btn-clear btn-warning " href="otorisator/show/${data.id}"> return `<div class="flex flex-nowrap justify-center">
<a class="btn btn-sm btn-icon btn-clear btn-warning " href="otorisator/show/${data.id}/${dataHeader}">
<i class="ki-outline ki-eye"></i> <i class="ki-outline ki-eye"></i>
</a> </a>
<a class="btn btn-sm btn-icon btn-clear btn-primary " onclick="otorisatorData(${data.id})">
<i class="ki-filled ki-double-check"></i>
</a>
</div>`; </div>`;
} else {
return `<div class="flex flex-nowrap justify-center">
<a class="btn btn-sm btn-icon btn-clear btn-success" onclick="showLoadingSwal('Masih Menunggu proses selesai dari penilai...')">
<i class="ki-filled ki-watch"></i>
</a>
</div>`
}
}, },
} }
}, },
@@ -185,10 +226,65 @@
let dataTable = new KTDataTable(element, dataTableOptions); let dataTable = new KTDataTable(element, dataTableOptions);
// Custom search functionality // Custom search functionality
searchInput.addEventListener('input', function () { searchInput.addEventListener('input', function() {
const searchValue = this.value.trim(); const searchValue = this.value.trim();
dataTable.search(searchValue, true); dataTable.search(searchValue, true);
}); });
</script> </script>
<script>
function otorisatorData(dataId) {
const dataHeader = @json($header);
Swal.fire({
title: 'Apakah Anda yakin?',
text: `Untuk melakukan otorisator ${dataHeader}!`,
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: 'Ya, Lanjutkan!',
cancelButtonText: 'Batal',
}).then((result) => {
if (result.isConfirmed) {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}'
},
});
$.ajax({
url: `/otorisator/otorisator/${dataId}/${dataHeader}`,
type: 'POST',
success: (response) => {
Swal.fire('Berhasil!', 'Data berhasil diotorisasi.', 'success').then(() => {
window.location.reload();
});
console.log(response);
},
error: (error) => {
console.error('Error:', error);
Swal.fire('Gagal!', 'Terjadi kesalahan saat melakukan otorisator.',
'error');
}
});
}
});
}
function showLoadingSwal(message, duration = 5000) {
Swal.fire({
title: message,
allowOutsideClick: false,
didOpen: () => {
Swal.showLoading();
},
timer: duration, // Durasi dalam milidetik
timerProgressBar: true, // Menampilkan progres bar timer
}).then((result) => {
if (result.dismiss === Swal.DismissReason.timer) {
console.log('Dialog loading otomatis ditutup.');
}
});
}
</script>
@endpush @endpush

View File

@@ -1,193 +1,67 @@
@extends('layouts.main') @extends('layouts.main')
{{-- @section('breadcrumbs') @section('breadcrumbs')
{{ Breadcrumbs::render(request()->route()->getName()) }} {{ Breadcrumbs::render(request()->route()->getName(), $permohonan->id, $header) }}
@endsection --}} @endsection
@section('content') @section('content')
<div class="w-full grid gap-5 lg:gap-7.5 mx-auto"> <div class="w-full grid gap-5 lg:gap-7.5 mx-auto">
<div class="card">
<div class="card-header" id="advanced_settings_appearance"> @php
<h3 class="card-title"> $dataHeader = strtolower($header ?? '');
Data Permohonan @endphp
</h3>
@include('lpj::component.detail-jaminan', ['backLink' => 'otorisator.'. $dataHeader . '.index'])
<div>
<div>
<button onclick="otorisatorData({{ $permohonan->id }})" type="button" class="btn btn-primary">
<i class="ki-filled ki-double-check"></i>
Otorisator {{ $header ?? '' }}
</button>
</div> </div>
<div class="card-body lg:py-7.5 grid grid-cols-3">
<div class="mb-5">
<h3 class="text-md font-medium text-gray-900">
Nomor Register Permohonan:
</h3>
<span class="text-2sm text-gray-700">
{{ $permohonan->nomor_registrasi }}
</span>
</div>
<div class="mb-5">
<h3 class="text-md font-medium text-gray-900">
Pemohon:
</h3>
<span class="text-2sm text-gray-700">
{{ $permohonan->user->nik }} | {{ $permohonan->user->name }} | {{ $permohonan->user->branch->name }}
</span>
</div>
<div class="mb-5">
<h3 class="text-md font-medium text-gray-900">
Tujan Permohonan:
</h3>
<span class="text-2sm text-gray-700">
{{ $permohonan->tujuanPenilaian->name }}
</span>
</div>
</div>
</div>
<div class="card min-w-full">
<div class="card-header">
<h3 class="card-title">
Detail Debutur
</h3>
</div>
<div class="card-table scrollable-x-auto pb-3">
<div class="grid grid-cols-1 xl:grid-cols-2 gap-5 lg:gap-7.5">
<div class="col-span-1">
<table class="table align-middle text-sm text-gray-500">
<tr>
<td class="py-2 text-gray-600 font-normal">
Name
</td>
<td class="py-2 text-gray-800 font-normaltext-sm">
{{ $permohonan->debiture->name ?? "" }}
</td>
</tr>
<tr>
<td class="py-3">
Email
</td>
<td class="py-3 text-gray-700 text-2sm font-normal">
{{ $permohonan->debiture->email ?? "" }}
</td>
</tr>
<tr>
<td class="py-3">
Phone
</td>
<td class="py-3 text-gray-700 text-2sm font-normal">
{{ $permohonan->debiture->phone ?? "" }}
</td>
</tr>
<tr>
<td class="py-3 text-gray-600 font-normal">
Address
</td>
<td class="py-3 text-gray-700 text-sm font-normal">
{{ $permohonan->debiture->address ?? "" }}
</td>
</tr>
<tr>
<td class="py-3 text-gray-600 font-normal">
&nbsp;
</td>
<td class="py-3 text-gray-700 text-sm font-normal">
{{ $permohonan->debiture->village->name ?? "" }}, {{ $permohonan->debiture->district->name ?? "" }}, {{ $permohonan->debiture->city->name ?? "" }}, {{ $permohonan->debiture->province->name ?? "" }} - {{ $permohonan->debiture->village->postal_code ?? "" }}
</td>
</tr>
</table>
</div>
<div class="col-span-1">
<table class="table align-middle text-sm text-gray-500">
<tr>
<td class="py-3 text-gray-600 font-normal">
Cabang
</td>
<td class="py-2 text-gray-800 font-normaltext-sm">
{{ $permohonan->debiture->branch->name ?? "" }}
</td>
</tr>
<tr>
<td class="py-3 text-gray-600 font-normal">
CIF
</td>
<td class="py-2 text-gray-800 font-normaltext-sm">
{{ $permohonan->debiture->cif ?? "" }}
</td>
</tr>
<tr>
<td class="py-3 text-gray-600 font-normal">
Nomor Rekening
</td>
<td class="py-3 text-gray-700 text-sm font-normal">
{{ $permohonan->debiture->nomor_rekening ?? "" }}
</td>
</tr>
<tr>
<td class="py-3">
NPWP
</td>
<td class="py-3 text-gray-700 text-2sm font-normal">
{{ $permohonan->debiture->npwp ?? "" }}
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<div class="card min-w-full">
<div class="card-header">
<h3 class="card-title">
Laporan
</h3>
</div>
</div>
<div class="card">
<form id="approveForm" action="{{ route('authorization.update', $permohonan->id) }}" method="POST">
<input type="hidden" name="_method" value="PUT">
@csrf
<div class="card-body lg:py-7.5">
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label class="form-label max-w-56">
Catatan
</label>
<div class="flex flex-wrap items-baseline w-full">
<textarea class="textarea" rows="3" type="number" id="address" name="address"></textarea>
</div>
</div>
</div>
<div class="card-footer flex justify-end">
<button onclick="return otorisator()" type="button" name="status" value="preregister" class="btn btn-success">
Approve
</button>
</div>
</form>
</div> </div>
</div> </div>
@endsection @endsection
@push('scripts') @push('scripts')
<script>
function otorisatorData(dataId) {
const dataHeader = {!! json_encode($header ?? '') !!};
Swal.fire({
<script> title: 'Apakah Anda yakin?',
function otorisator(){ text: `Untuk melakukan otorisator ${dataHeader}!`,
Swal.fire({ icon: 'warning',
title: 'Are you sure?', showCancelButton: true,
text: "You won't be able to revert this!", confirmButtonColor: '#3085d6',
icon: 'warning', cancelButtonColor: '#d33',
showCancelButton: true, confirmButtonText: 'Ya, Lanjutkan!',
confirmButtonColor: '#3085d6', cancelButtonText: 'Batal',
cancelButtonColor: '#d33', }).then((result) => {
confirmButtonText: 'Yes!' if (result.isConfirmed) {
}).then((result) => { $.ajaxSetup({
if (result.isConfirmed) { headers: {
document.getElementById('approveForm').submit(); 'X-CSRF-TOKEN': '{{ csrf_token() }}'
} },
}) });
} $.ajax({
</script> url: `/otorisator/otorisator/${dataId}/${dataHeader}`,
type: 'POST',
success: (response) => {
Swal.fire('Berhasil!', 'Data berhasil diotorisasi.', 'success').then(() => {
window.location.reload();
});
console.log(response);
},
error: (error) => {
console.error('Error:', error);
Swal.fire('Gagal!', 'Terjadi kesalahan saat melakukan otorisator.',
'error');
}
});
}
});
}
</script>
@endpush @endpush

View File

@@ -112,11 +112,16 @@
</tr> </tr>
<tr> <tr>
<td class="px-4 py-2">Luas Tanah ()</td> <td class="px-4 py-2">Luas Tanah ()</td>
@php
$cekLuas = $inspectionData['tanah']['luas_tanah'] == 'sesuai' ? 'sesuai' :'tidak sesuai';
@endphp
<td class="px-4 py-2"> <td class="px-4 py-2">
<input type="text" name="luas_tanah" class="input number-format" <input type="text" name="luas_tanah" class="input number-format"
value="{{ $inspectionData['tanah']['luas_tanah']['tidak sesuai'] ?? ($inspectionData['tanah']['luas_tanah']['sesuai'] ?? '') }}"> value="{{ $inspectionData['tanah']['luas_tanah']['sesuai'] ?? $inspectionData['tanah']['luas_tanah']['tidak sesuai'] ?? '' }}">
</td> </td>
<td class="px-4 py-2"> <td class="px-4 py-2">
<input type="text" name="luas_tanah_pembanding[]" <input type="text" name="luas_tanah_pembanding[]"
class="input number-format"> class="input number-format">
</td> </td>
@@ -124,8 +129,9 @@
<tr> <tr>
<td class="px-4 py-2">Luas Bangunan ()</td> <td class="px-4 py-2">Luas Bangunan ()</td>
<td class="px-4 py-2"> <td class="px-4 py-2">
<input type="text" name="luas_tanah_bagunan" class="input number-format" <input type="text" name="luas_tanah_bagunan" class="input number-format"
value="{{ $inspectionData['bangunan']['luas_tanah_bagunan']['tidak sesuai'] ?? ($inspectionData['bangunan']['luas_tanah_bagunan']['sesuai'] ?? '') }}"> value="{{ $inspectionData['bangunan']['luas_tanah_bagunan']['sesuai'] ?? $inspectionData['bangunan']['luas_tanah_bagunan']['tidak sesuai'] ?? '' }}">
</td> </td>
<td class="px-4 py-2"> <td class="px-4 py-2">
<input type="text" name="luas_bangunan_pembanding[]" <input type="text" name="luas_bangunan_pembanding[]"
@@ -141,8 +147,8 @@
<tr> <tr>
<td class="px-4 py-2">Status Narasumber</td> <td class="px-4 py-2">Status Narasumber</td>
<td class="px-4 py-2"> <td class="px-4 py-2">
<input type="text" name="nama_nara_sumber" class="input" <input type="text" name="status_nara_sumber" class="input"
value="{{ $inspectionData['nama_nara_sumber'] ?? '' }}"> value="{{ $inspectionData['asset']['status_nara_sumber'] ?? '' }}">
</td> </td>
<td class="px-4 py-2"> <td class="px-4 py-2">
<input type="text" name="status_nara_sumber_pembanding[]" <input type="text" name="status_nara_sumber_pembanding[]"
@@ -153,7 +159,7 @@
<td class="px-4 py-2">Nama Narasumber</td> <td class="px-4 py-2">Nama Narasumber</td>
<td class="px-4 py-2"> <td class="px-4 py-2">
<input type="text" name="nama_nara_sumber" class="input" <input type="text" name="nama_nara_sumber" class="input"
value="{{ $inspectionData['nama_nara_sumber'] ?? '' }}"> value="{{ $inspectionData['asset']['nama_nara_sumber'] ?? '' }}">
</td> </td>
<td class="px-4 py-2"> <td class="px-4 py-2">
<input type="text" name="nama_nara_sumber_pembanding[]" <input type="text" name="nama_nara_sumber_pembanding[]"
@@ -358,7 +364,7 @@
<td class="px-4 py-2">Harga</td> <td class="px-4 py-2">Harga</td>
<td class="px-4 py-2"> <td class="px-4 py-2">
<input type="text" name="harga" class="input currency-format" <input type="text" name="harga" class="input currency-format"
value="{{ $inspectionData['harga'] ?? '' }}"> value="{{ $inspectionData['asset']['harga'] ?? '' }}">
</td> </td>
<td class="px-4 py-2"> <td class="px-4 py-2">
<input type="text" name="harga_pembanding[]" <input type="text" name="harga_pembanding[]"
@@ -368,8 +374,8 @@
<tr> <tr>
<td class="px-4 py-2">Diskon</td> <td class="px-4 py-2">Diskon</td>
<td class="px-4 py-2"> <td class="px-4 py-2">
<input type="text" name="harga" class="input currency-format" <input type="text" name="diskon" class="input currency-format"
value="{{ $inspectionData['diskon'] ?? '' }}"> value="{{ $inspectionData['asset']['diskon'] ?? '' }}">
</td> </td>
<td class="px-4 py-2"> <td class="px-4 py-2">
<input type="text" name="diskon_pembanding[]" <input type="text" name="diskon_pembanding[]"
@@ -380,7 +386,7 @@
<td class="px-4 py-2">Total</td> <td class="px-4 py-2">Total</td>
<td class="px-4 py-2"> <td class="px-4 py-2">
<input type="text" name="total" class="input currency-format" <input type="text" name="total" class="input currency-format"
value="{{ $inspectionData['total'] ?? '' }}"> value="{{ $inspectionData['asset']['total'] ?? '' }}">
</td> </td>
<td class="px-4 py-2"> <td class="px-4 py-2">
<input type="text" name="total_pembanding[]" <input type="text" name="total_pembanding[]"
@@ -391,7 +397,7 @@
<td class="px-4 py-2">Harga Setelah Diskon</td> <td class="px-4 py-2">Harga Setelah Diskon</td>
<td class="px-4 py-2"> <td class="px-4 py-2">
<input type="text" name="harga_diskon" class="input currency-format" <input type="text" name="harga_diskon" class="input currency-format"
value="{{ $inspectionData['harga_diskon'] ?? '' }}"> value="{{ $inspectionData['asset']['harga_diskon'] ?? '' }}">
</td> </td>
<td class="px-4 py-2"> <td class="px-4 py-2">
<input type="text" name="harga_diskon_pembanding[]" <input type="text" name="harga_diskon_pembanding[]"
@@ -417,43 +423,64 @@
</div> </div>
</div> </div>
<!-- Loading Overlay -->
<div id="loadingOverlay" class="fixed inset-0 bg-black bg-opacity-50 hidden items-center justify-center z-50">
<div class="bg-white p-4 rounded-lg">
<div class="loader"></div>
<p class="mt-2 text-center">Sedang memproses...</p>
</div>
</div>
@endsection @endsection
@push('scripts') @push('scripts')
@include('lpj::surveyor.js.utils')
<script> <script>
let columnCount = 1; let columnCount = 1;
// Fungsi calculate prices yang diperbaiki
function calculatePrices(index) {
const hargaInput = document.getElementsByName('harga_pembanding[]')[index];
const diskonInput = document.getElementsByName('diskon_pembanding[]')[index];
const totalInput = document.getElementsByName('total_pembanding[]')[index];
const hargaDiskonInput = document.getElementsByName('harga_diskon_pembanding[]')[index];
if (hargaInput && diskonInput && totalInput && hargaDiskonInput) {
// Ambil nilai numerik dari input
const harga = parseFloat(hargaInput.value.replace(/[^\d]/g, '') || '0');
const diskon = parseFloat(diskonInput.value.replace(/[^\d]/g, '') || '0');
// Hitung total dan harga setelah diskon
const total = harga;
const hargaSetelahDiskon = harga - (harga * (diskon / 100));
// Update nilai dengan format currency
if (totalInput) totalInput.value = formatCurrency(total.toString());
if (hargaDiskonInput) hargaDiskonInput.value = formatCurrency(hargaSetelahDiskon.toString());
}
}
// Update fungsi fillPembandingData
function fillPembandingData(data, index) { function fillPembandingData(data, index) {
if (!data) return; if (!data) return;
// Helper function untuk mengisi nilai input array dengan aman
function setArrayInputValue(name, value, index) { function setArrayInputValue(name, value, index) {
const element = document.getElementsByName(name)[index]; const element = document.getElementsByName(name)[index];
if (element) { if (element) {
if (element.tagName === "SELECT") { if (element.tagName === "SELECT") {
// Jika elemen adalah select, set selected value
const options = Array.from(element.options); const options = Array.from(element.options);
const optionToSelect = options.find(option => option.value === value); const optionToSelect = options.find(option => option.value === value);
if (optionToSelect) { if (optionToSelect) {
optionToSelect.selected = true; optionToSelect.selected = true;
} else { } else {
element.selectedIndex = 0; // Pilih default jika tidak ditemukan element.selectedIndex = 0;
} }
} else { } else {
// Jika elemen bukan select, langsung set value // Format currency untuk input harga
element.value = value || ''; if (name.includes('harga') || name.includes('total') || name.includes('diskon')) {
element.value = formatCurrency(value ? value.toString() : '0');
} else {
element.value = value || '';
}
} }
} }
} }
// Isi data pembanding
const inputs = { const inputs = {
'jenis_aset_pembanding[]': data.jenis_aset, 'jenis_aset_pembanding[]': data.jenis_aset,
'luas_tanah_pembanding[]': data.luas_tanah, 'luas_tanah_pembanding[]': data.luas_tanah,
@@ -471,15 +498,13 @@
'harga_diskon_pembanding[]': data.harga_diskon, 'harga_diskon_pembanding[]': data.harga_diskon,
'total_pembanding[]': data.total, 'total_pembanding[]': data.total,
'diskon_pembanding[]': data.diskon, 'diskon_pembanding[]': data.diskon,
}; };
// Isi semua input fields
Object.entries(inputs).forEach(([name, value]) => { Object.entries(inputs).forEach(([name, value]) => {
setArrayInputValue(name, value, index); setArrayInputValue(name, value, index);
}); });
// Handle foto pembanding jika ada // Handle foto objek
if (data.foto_objek) { if (data.foto_objek) {
const imageId = `uploadedImage${index + 2}`; const imageId = `uploadedImage${index + 2}`;
const preview = document.getElementById(imageId); const preview = document.getElementById(imageId);
@@ -488,15 +513,59 @@
preview.classList.remove('hidden'); preview.classList.remove('hidden');
} }
} }
// Handle lokasi secara berurutan
if (data.province_code) {
setTimeout(() => {
getCity(data.province_code, index + 1).then(() => {
if (data.city_code) {
setArrayInputValue('city_code_pembanding[]', data.city_code, index);
getDistrict(data.city_code, index + 1).then(() => {
if (data.district_code) {
setArrayInputValue('district_code_pembanding[]', data
.district_code, index);
getVillage(data.district_code, index + 1).then(() => {
if (data.village_code) {
setArrayInputValue('village_code_pembanding[]',
data.village_code, index);
}
});
}
});
}
});
}, 100);
}
// Hitung harga setelah data terisi
setTimeout(() => calculatePrices(index), 200);
}
// Update event listener untuk input harga dan diskon
function initializePriceCalculation() {
document.querySelectorAll('[name="harga_pembanding[]"], [name="diskon_pembanding[]"]').forEach((input) => {
input.addEventListener('input', function() {
const inputs = document.getElementsByName(this.name);
const index = Array.from(inputs).indexOf(this);
calculatePrices(index);
});
});
} }
// Event listener dengan pengecekan data
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
try { try {
const inspectionData = {!! isset($inspectionData) ? json_encode($inspectionData) : 'null' !!}; const inspectionData = {!! isset($inspectionData) ? json_encode($inspectionData) : 'null' !!};
const comparisons = {!! isset($comparisons) ? json_encode($comparisons) : 'null' !!}; const comparisons = {!! isset($comparisons) ? json_encode($comparisons) : 'null' !!};
console.log('inspectionData:', inspectionData);
console.log('comparisons:', comparisons);
initializeFirstPembandingListeners();
ensureLocationEventListeners();
initializePriceCalculation();
if (comparisons) { if (comparisons) {
comparisons.data_pembanding.forEach((comparison, index) => { comparisons.data_pembanding.forEach((comparison, index) => {
if (index > 0) { if (index > 0) {
@@ -513,30 +582,26 @@
} }
}); });
function addColumn() { function addColumn() {
columnCount++; columnCount++;
const table = document.getElementById('dataTable'); const table = document.getElementById('dataTable');
const headerRow = table.querySelector('thead tr'); const headerRow = table.querySelector('thead tr');
const bodyRows = table.querySelectorAll('tbody tr'); const bodyRows = table.querySelectorAll('tbody tr');
// Add header
const newHeader = document.createElement('th'); const newHeader = document.createElement('th');
newHeader.className = 'px-4 py-3 min-w-[250px]'; newHeader.className = 'px-4 py-3 min-w-[250px]';
newHeader.textContent = `Data Pembanding ${columnCount}`; newHeader.textContent = `Data Pembanding ${columnCount}`;
headerRow.appendChild(newHeader); headerRow.appendChild(newHeader);
// Add cells to each row
bodyRows.forEach(row => { bodyRows.forEach(row => {
const newCell = document.createElement('td'); const newCell = document.createElement('td');
newCell.className = 'px-4 py-2'; newCell.className = 'px-4 py-2';
const lastInputCell = row.querySelector('td:last-child'); const firstInputCell = row.querySelector('td:last-child');
if (lastInputCell) { if (firstInputCell) {
const clonedContent = lastInputCell.innerHTML; const clonedContent = firstInputCell.innerHTML;
newCell.innerHTML = clonedContent; newCell.innerHTML = clonedContent;
// Update IDs and names for the new cell
const inputs = newCell.querySelectorAll('input, select, textarea'); const inputs = newCell.querySelectorAll('input, select, textarea');
inputs.forEach((input) => { inputs.forEach((input) => {
if (input.type === 'file') { if (input.type === 'file') {
@@ -552,41 +617,63 @@
} }
} }
// Menangani select alamat
if (input.tagName === 'SELECT') { if (input.tagName === 'SELECT') {
const oldId = input.id; const baseId = input.id.replace(/_\d+$/, '').replace('_pembanding', '');
const newId = `${oldId}_${columnCount}`; const newId = `${baseId}_pembanding_${columnCount}`;
input.id = newId; input.id = newId;
// Menambahkan event listener untuk select alamat if (input.name.includes('jenis_aset')) {
if (oldId.includes('city')) { const originalOptions = document.querySelector(
'select[name="jenis_aset_pembanding[]"]').innerHTML;
input.innerHTML = originalOptions;
} else if (!input.id.includes('province')) {
// Reset opsi untuk select lokasi
input.innerHTML = `<option value="">Pilih ${
input.id.includes('city') ? 'Kota/Kabupaten' :
input.id.includes('district') ? 'Kecamatan' :
'Desa/Kelurahan'
}</option>`;
}
if (input.id.includes('province')) {
input.onchange = function() {
handleProvinceChange(this);
};
} else if (input.id.includes('city')) {
input.onchange = function() { input.onchange = function() {
handleCityChange(this); handleCityChange(this);
}; };
} else if (oldId.includes('district')) { } else if (input.id.includes('district')) {
input.onchange = function() { input.onchange = function() {
handleDistrictChange(this); handleDistrictChange(this);
}; };
} }
} }
// Clear values if (input.type !== 'file' && input.tagName !== 'SELECT') {
if (input.type !== 'file') {
input.value = ''; input.value = '';
} }
if (input.classList.contains('currency-format')) {
input.addEventListener('input', function() {
formatCurrency(this);
});
}
if (input.classList.contains('number-format')) {
input.addEventListener('input', function() {
formatNumber(this);
});
}
}); });
} }
row.appendChild(newCell); row.appendChild(newCell);
}); });
updateRemoveButtonVisibility(); updateRemoveButtonVisibility();
reinitializeEventListeners();
} }
function updateDynamicId(currentId, columnCount) {
return `${currentId.split('_')[0]}_${'code_pembanding'}_${columnCount}`;
}
function removeColumn() { function removeColumn() {
if (columnCount > 1) { if (columnCount > 1) {
@@ -609,166 +696,36 @@
} }
} }
function fillComparisonData(comparison, index) {
Object.entries(comparison).forEach(([key, value]) => {
if (key === 'foto_objek') {
const imageId = `uploadedImage${index + 1}`;
const preview = document.getElementById(imageId);
if (preview && value) {
preview.src = `{{ asset('storage/pembanding/') }}/${value}`;
preview.classList.remove('hidden');
}
} else {
const input = document.querySelector(`[name="${key}_pembanding[]"]:nth-of-type(${index})`);
if (input) {
input.value = value;
}
}
});
}
function previewImage(input, imageId) {
const preview = document.getElementById(imageId);
if (input.files && input.files[0]) {
const reader = new FileReader();
reader.onload = function(e) {
preview.src = e.target.result;
preview.classList.remove('hidden');
}
reader.readAsDataURL(input.files[0]);
}
}
function formatCurrency(input) {
let value = input.value.replace(/[^\d]/g, '');
value = new Intl.NumberFormat('id-ID').format(value);
input.value = value;
}
function formatNumber(input) {
let value = input.value.replace(/[^\d.]/g, '');
input.value = value;
}
function initializeEventListeners() { function initializeEventListeners() {
// Button event listeners
document.getElementById('addColumnBtn').addEventListener('click', addColumn); document.getElementById('addColumnBtn').addEventListener('click', addColumn);
document.getElementById('removeColumnBtn').addEventListener('click', removeColumn); document.getElementById('removeColumnBtn').addEventListener('click', removeColumn);
// Form submission
reinitializeEventListeners(); reinitializeEventListeners();
} }
function reinitializeEventListeners() { function reinitializeEventListeners() {
// Currency format // Event listener yang sudah ada
document.querySelectorAll('.currency-format').forEach(input => { document.querySelectorAll('.currency-format').forEach(input => {
input.addEventListener('input', function() { input.addEventListener('input', function() {
formatCurrency(this); formatCurrency(this);
}); });
}); });
// Number format
document.querySelectorAll('.number-format').forEach(input => { document.querySelectorAll('.number-format').forEach(input => {
input.addEventListener('input', function() { input.addEventListener('input', function() {
formatNumber(this); formatNumber(this);
}); });
}); });
// Tambahkan kalkulasi harga
initializePriceCalculation();
// Location event listeners
ensureLocationEventListeners();
} }
function submitData() {
const loadingOverlay = document.getElementById('loadingOverlay');
loadingOverlay.classList.remove('hidden');
loadingOverlay.classList.add('flex');
const form = document.querySelector('form');
const formData = new FormData(form);
console.log('Form data entries:', Array.from(formData.entries()));
$.ajax({
url: '{{ route('surveyor.storeDataPembanding') }}',
type: 'POST',
data: formData,
processData: false,
contentType: false,
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}'
},
success: function(result) {
if (result.success) {
Swal.fire({
title: 'Berhasil!',
text: result.message,
icon: 'success',
confirmButtonText: 'OK'
}).then((result) => {
if (result.isConfirmed) {
window.location.href =
'{{ route('surveyor.show', ['id' => $permohonan->id]) }}';
}
console.log(result);
});
} else {
Swal.fire({
title: 'Error!',
text: result.message || 'Terjadi kesalahan',
icon: 'error',
confirmButtonText: 'OK'
});
}
},
error: function(xhr, status, error) {
console.error('Error:', error);
Swal.fire({
title: 'Error!',
text: 'Terjadi kesalahan pada server',
icon: 'error',
confirmButtonText: 'OK'
});
},
complete: function() {
loadingOverlay.classList.add('hidden');
loadingOverlay.classList.remove('flex');
}
});
}
function loadIdSelectAddres(inputs) {
const data = [
'province_code_pembanding',
'city_code_pembanding',
'district_code_pembanding',
'village_code_pembanding'
]
}
document.addEventListener('DOMContentLoaded', function() {
// Inisialisasi event listener untuk data pembanding pertama
initializeFirstPembandingListeners();
try {
const inspectionData = {!! isset($inspectionData) ? json_encode($inspectionData) : 'null' !!};
const comparisons = {!! isset($comparisons) ? json_encode($comparisons) : 'null' !!};
if (comparisons) {
comparisons.data_pembanding.forEach((comparison, index) => {
if (index > 0) {
addColumn();
}
fillPembandingData(comparison, index);
});
}
updateRemoveButtonVisibility();
initializeEventListeners();
} catch (error) {
console.error('Error initializing form:', error);
}
});
function initializeFirstPembandingListeners() { function initializeFirstPembandingListeners() {
// Event listener untuk province pembanding pertama
const firstProvinceSelect = document.getElementById('province_code_pembanding'); const firstProvinceSelect = document.getElementById('province_code_pembanding');
if (firstProvinceSelect) { if (firstProvinceSelect) {
firstProvinceSelect.addEventListener('change', function() { firstProvinceSelect.addEventListener('change', function() {
@@ -779,7 +736,6 @@
}); });
} }
// Event listener untuk city pembanding pertama
const firstCitySelect = document.getElementById('city_code_pembanding'); const firstCitySelect = document.getElementById('city_code_pembanding');
if (firstCitySelect) { if (firstCitySelect) {
firstCitySelect.addEventListener('change', function() { firstCitySelect.addEventListener('change', function() {
@@ -790,7 +746,6 @@
}); });
} }
// Event listener untuk district pembanding pertama
const firstDistrictSelect = document.getElementById('district_code_pembanding'); const firstDistrictSelect = document.getElementById('district_code_pembanding');
if (firstDistrictSelect) { if (firstDistrictSelect) {
firstDistrictSelect.addEventListener('change', function() { firstDistrictSelect.addEventListener('change', function() {
@@ -802,11 +757,30 @@
} }
} }
function ensureLocationEventListeners() {
document.querySelectorAll('[id^="province_code_pembanding"]').forEach(select => {
select.onchange = function() {
handleProvinceChange(this);
};
});
document.querySelectorAll('[id^="city_code_pembanding"]').forEach(select => {
select.onchange = function() {
handleCityChange(this);
};
});
document.querySelectorAll('[id^="district_code_pembanding"]').forEach(select => {
select.onchange = function() {
handleDistrictChange(this);
};
});
}
function handleProvinceChange(provinceSelect) { function handleProvinceChange(provinceSelect) {
const provinceId = provinceSelect.value; const provinceId = provinceSelect.value;
let columnIndex; let columnIndex;
// Cek apakah ini pembanding pertama atau tambahan
if (provinceSelect.id === 'province_code_pembanding') { if (provinceSelect.id === 'province_code_pembanding') {
columnIndex = 1; columnIndex = 1;
} else { } else {
@@ -853,7 +827,6 @@
const response = await fetch(`/locations/cities/province/${provinceId}`); const response = await fetch(`/locations/cities/province/${provinceId}`);
const data = await response.json(); const data = await response.json();
// Pilih dropdown berdasarkan index
const cityDropdown = columnIndex === 1 ? const cityDropdown = columnIndex === 1 ?
document.getElementById('city_code_pembanding') : document.getElementById('city_code_pembanding') :
document.getElementById(`city_code_pembanding_${columnIndex}`); document.getElementById(`city_code_pembanding_${columnIndex}`);
@@ -910,41 +883,60 @@
} }
} }
function submitData() {
showLoadingSwal('Mengirim data ke server...');
const form = document.querySelector('form');
const formData = new FormData(form);
function resetDropdown(elementId, placeholder) { console.log('Form data entries:', Array.from(formData.entries()));
const dropdown = document.getElementById(elementId);
dropdown.innerHTML = `<option value="">${placeholder}</option>`; $.ajax({
url: '{{ route('surveyor.storeDataPembanding') }}',
type: 'POST',
data: formData,
processData: false,
contentType: false,
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}'
},
success: function(result) {
hideLoadingSwal();
console.log(result);
if (result.success) {
Swal.fire({
title: 'Berhasil!',
text: result.message,
icon: 'success',
confirmButtonText: 'OK'
}).then((result) => {
if (result.isConfirmed) {
window.location.href =
'{{ route('surveyor.show', ['id' => $permohonan->id]) }}';
}
});
} else {
Swal.fire({
title: 'Error!',
text: result.message || 'Terjadi kesalahan',
icon: 'error',
confirmButtonText: 'OK'
});
}
},
error: function(xhr, status, error) {
hideLoadingSwal();
console.error('Error:', error);
Swal.fire({
title: 'Error!',
text: 'Terjadi kesalahan pada server',
icon: 'error',
confirmButtonText: 'OK'
});
}
});
} }
</script> </script>
<style>
.loader {
border: 4px solid #f3f3f3;
border-radius: 50%;
border-top: 4px solid #3498db;
width: 40px;
height: 40px;
animation: spin 1s linear infinite;
margin: 0 auto;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.scrollable-x-auto {
overflow-x: auto;
max-width: 100%;
}
.table {
min-width: 100%;
}
</style>
@endpush @endpush

View File

@@ -268,9 +268,7 @@
function submitDenah() { function submitDenah() {
const loadingOverlay = document.getElementById('loadingOverlay'); showLoadingSwal('Mengirim data ke server...');
loadingOverlay.classList.remove('hidden');
loadingOverlay.classList.add('flex');
const formElement = $('#formDenah')[0]; const formElement = $('#formDenah')[0];
const formData = new FormData(formElement); const formData = new FormData(formElement);
@@ -286,6 +284,7 @@
}, },
success: function(response) { success: function(response) {
if (response.success) { if (response.success) {
hideLoadingSwal();
Swal.fire({ Swal.fire({
title: 'Berhasil!', title: 'Berhasil!',
text: response.message, text: response.message,
@@ -319,36 +318,14 @@
console.log('Status:', status); console.log('Status:', status);
console.log('Response:', xhr.responseText); console.log('Response:', xhr.responseText);
console.log(errors); console.log(errors);
hideLoadingSwal();
toastrErrorBuild(error); toastrErrorBuild(error);
}, },
complete: function() {
loadingOverlay.classList.add('hidden');
loadingOverlay.classList.remove('flex');
}
}); });
} }
</script> </script>
@include('lpj::surveyor.js.utils')
@endpush @endpush
<style>
.loader {
border: 4px solid #f3f3f3;
border-radius: 50%;
border-top: 4px solid #3498db;
width: 40px;
height: 40px;
animation: spin 1s linear infinite;
margin: 0 auto;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>

View File

@@ -33,7 +33,7 @@
<div class="flex flex-wrap items-baseline w-full"> <div class="flex flex-wrap items-baseline w-full">
@foreach ($permohonan->debiture->documents as $dokumen) @foreach ($permohonan->debiture->documents as $dokumen)
<span class="text-2sm text-gray-700"> <span class="text-2sm text-gray-700">
{{formatAlamat($dokumen->pemilik)}} {{ formatAlamat($dokumen->pemilik) }}
</span> </span>
@endforeach @endforeach
</div> </div>
@@ -118,8 +118,7 @@
</div> </div>
<!-- Delete button to remove photo --> <!-- Delete button to remove photo -->
<button type="button" class="btn btn-danger btn-sm delete-btn" <button type="button" class="btn btn-danger btn-sm delete-btn" id="btnDelete">
id="btnDelete">
<i class="ki-filled ki-trash"></i> <i class="ki-filled ki-trash"></i>
</button> </button>
</div> </div>
@@ -190,9 +189,8 @@
</label> </label>
<div class="flex flex-wrap items-baseline w-full"> <div class="flex flex-wrap items-baseline w-full">
<img id="foto_rute_lainnya-preview-{{ $index }}" <img id="foto_rute_lainnya-preview-{{ $index }}"
src="{{ asset('storage/' . $photo['foto_rute_lainnya']) }}" src="{{ asset('storage/' . $photo['foto_rute_lainnya']) }}" alt="Foto Rute "
alt="Foto Rute " class="mt-2 max-w-full h-auto" class="mt-2 max-w-full h-auto" style="width: 30rem;">
style="width: 30rem;">
<div class="flex flex-col lg:flex-row gap-2 w-full"> <div class="flex flex-col lg:flex-row gap-2 w-full">
<div class="flex flex-wrap items-baseline px-2"> <div class="flex flex-wrap items-baseline px-2">
@@ -260,7 +258,6 @@
['label' => 'Tampak Samping Kiri', 'index' => 1], ['label' => 'Tampak Samping Kiri', 'index' => 1],
['label' => 'Tampak Samping Kanan', 'index' => 2], ['label' => 'Tampak Samping Kanan', 'index' => 2],
['label' => 'Nomor Rumah/Unit', 'index' => 3], ['label' => 'Nomor Rumah/Unit', 'index' => 3],
]; ];
} elseif ($kategori === 'apartemen-kantor') { } elseif ($kategori === 'apartemen-kantor') {
$objekViews = [ $objekViews = [
@@ -332,35 +329,34 @@
@if (count($objekViews) > 0) @if (count($objekViews) > 0)
@foreach ($objekViews as $view) @foreach ($objekViews as $view)
<div class="flex flex-wrap gap-4 {{ !$loop->first ? 'mt-2' : '' }}"> <div class="flex flex-wrap gap-4 {{ !$loop->first ? 'mt-2' : '' }}">
<div class="flex w-full gap-4"> <div class="flex w-full gap-4">
<label class="form-label max-w-56"><span <label class="form-label max-w-56"><span
class="form-label">{{ $view['label'] }}</span></label> class="form-label">{{ $view['label'] }}</span></label>
<input type="hidden" class="form-control" <input type="hidden" class="form-control"
name="name_objek[]" value="{{ $view['label'] }}" /> name="name_objek[]" value="{{ $view['label'] }}" />
<div class="w-full grid gap-5"> <div class="w-full grid gap-5">
<img id="foto_object_jaminan_preview_{{ $view['index'] }}" <img id="foto_object_jaminan_preview_{{ $view['index'] }}"
src="{{ isset($formFoto['object_jaminan'][$view['index']]['foto_objek']) ? asset('storage/' . $formFoto['object_jaminan'][$view['index']]['foto_objek']) : '' }}" src="{{ isset($formFoto['object_jaminan'][$view['index']]['foto_objek']) ? asset('storage/' . $formFoto['object_jaminan'][$view['index']]['foto_objek']) : '' }}"
alt="{{ $view['label'] }}" class="mb-2 h-auto" alt="{{ $view['label'] }}" class="mb-2 h-auto"
style="{{ isset($formFoto['object_jaminan'][$view['index']]['foto_objek']) ? 'width: 30rem;' : 'display: none;' }}"
style="{{ isset($formFoto['object_jaminan'][$view['index']]['foto_objek']) ? 'width: 30rem;' : 'display: none;' }}" onerror="this.style.display='none';" />
onerror="this.style.display='none';" /> <div class="input-group w-full flex gap-2">
<div class="input-group w-full flex gap-2"> <input type="file" name="foto_objek[]"
<input type="file" name="foto_objek[]" class="file-input file-input-bordered w-full"
class="file-input file-input-bordered w-full" accept="image/*" capture="camera"
accept="image/*" capture="camera" onchange="previewImage(this, 'foto_object_jaminan_preview_{{ $view['index'] }}')">
onchange="previewImage(this, 'foto_object_jaminan_preview_{{ $view['index'] }}')"> <button type="button" id="btnCamera"
<button type="button" id="btnCamera" class="btn btn-light"
class="btn btn-light" data-modal-toggle="#cameraModal">
data-modal-toggle="#cameraModal"> <i class="ki-outline ki-abstract-33"></i> Camera
<i class="ki-outline ki-abstract-33"></i> Camera </button>
</button> </div>
<textarea name="deskripsi_objek[]" class="textarea" rows="3" placeholder="Deskripsi">{{ isset($formFoto['object_jaminan'][$view['index']]) ? str_replace($view['label'] . ': ', '', $formFoto['object_jaminan'][$view['index']]['deskripsi_objek']) : '' }}</textarea>
</div> </div>
<textarea name="deskripsi_objek[]" class="textarea" rows="3" placeholder="Deskripsi">{{ isset($formFoto['object_jaminan'][$view['index']]) ? str_replace($view['label'] . ': ', '', $formFoto['object_jaminan'][$view['index']]['deskripsi_objek']) : '' }}</textarea>
</div> </div>
<span class="alert text-danger text-sm"></span>
</div> </div>
<span class="alert text-danger text-sm"></span>
</div>
@endforeach @endforeach
@endif @endif
@@ -596,24 +592,17 @@
</form> </form>
</div> </div>
<div id="loadingOverlay" class="fixed inset-0 bg-black bg-opacity-50 hidden items-center justify-center z-50">
<div class="bg-white p-4 rounded-lg">
<div class="loader"></div>
<p class="mt-2 text-center">Sedang memproses...</p>
</div>
</div>
<!-- Modal Kamera --> <!-- Modal Kamera -->
@include('lpj::surveyor.components.modal-kamera') @include('lpj::surveyor.components.modal-kamera')
@endsection @endsection
@include('lpj::surveyor.js.fotojs') @include('lpj::surveyor.js.fotojs')
@include('lpj::surveyor.js.utils')
@push('scripts') @push('scripts')
<script> <script>
function submitFoto() { function submitFoto() {
const loadingOverlay = document.getElementById('loadingOverlay'); showLoadingSwal('Mengirim data ke server...');
loadingOverlay.classList.remove('hidden');
loadingOverlay.classList.add('flex');
const formElement = $('#formFoto')[0]; const formElement = $('#formFoto')[0];
const formData = new FormData(formElement); const formData = new FormData(formElement);
@@ -630,6 +619,7 @@
}, },
success: function(response) { success: function(response) {
if (response.success) { if (response.success) {
hideLoadingSwal();
Swal.fire({ Swal.fire({
title: 'Berhasil!', title: 'Berhasil!',
text: response.message, text: response.message,
@@ -644,6 +634,7 @@
}); });
} else { } else {
hideLoadingSwal();
Swal.fire({ Swal.fire({
title: 'Error!', title: 'Error!',
text: response.message || 'Terjadi kesalahan', text: response.message || 'Terjadi kesalahan',
@@ -652,8 +643,6 @@
}); });
} }
console.log(response); console.log(response);
}, },
error: function(xhr, status, error) { error: function(xhr, status, error) {
let errors = xhr.responseJSON?.errors; let errors = xhr.responseJSON?.errors;
@@ -663,41 +652,11 @@
$(`#error-${key}`).text(value[0]); $(`#error-${key}`).text(value[0]);
}); });
} }
console.error('Terjadi error:', error); // Menampilkan pesan error di konsol hideLoadingSwal();
console.log('Status:', status);
console.log('Response:', xhr.responseText);
console.log(errors);
toastrErrorBuild(error); toastrErrorBuild(error);
},
complete: function() {
// Re-enable the button and hide the spinner
loadingOverlay.classList.add('hidden');
loadingOverlay.classList.remove('flex');
} }
}); });
} }
</script> </script>
@include('lpj::surveyor.js.camera-editor') @include('lpj::surveyor.js.camera-editor')
@endpush @endpush
<style>
.loader {
border: 4px solid #f3f3f3;
border-radius: 50%;
border-top: 4px solid #3498db;
width: 40px;
height: 40px;
animation: spin 1s linear infinite;
margin: 0 auto;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>

View File

@@ -57,8 +57,8 @@
@foreach ($forminspeksi['asset']['debitur_perwakilan'] as $key => $item) @foreach ($forminspeksi['asset']['debitur_perwakilan'] as $key => $item)
<div class="perwakilan flex flex-wrap w-full items-baseline gap-2 "> <div class="perwakilan flex flex-wrap w-full items-baseline gap-2 ">
<input type="text" class="input form-control" name="debitur_perwakilan[]" <input type="text" class="input form-control" name="debitur_perwakilan[]"
value="{{ old('debitur_perwakilan.' . $key, $item) }}" value="{{ old('debitur_perwakilan.' . $key, $item) }}"
placeholder="Masukkan Debitur/Perwakilan"/> placeholder="Masukkan Debitur/Perwakilan" />
<button type="button" class="btn btn-danger btn-outline btn-xs remove-btn">Hapus</button> <button type="button" class="btn btn-danger btn-outline btn-xs remove-btn">Hapus</button>
</div> </div>
@endforeach @endforeach
@@ -67,9 +67,9 @@
<div id="perwakilan" class="flex flex-wrap items-baseline w-full gap-5"> <div id="perwakilan" class="flex flex-wrap items-baseline w-full gap-5">
<div class="perwakilan flex flex-wrap w-full items-baseline gap-2 "> <div class="perwakilan flex flex-wrap w-full items-baseline gap-2 ">
<input type="text" class="input form-control" name="debitur_perwakilan[]" <input type="text" class="input form-control" name="debitur_perwakilan[]"
value="{{ old('debitur_perwakilan') }}" placeholder="Masukkan Debitur/Perwakilan"/> value="{{ old('debitur_perwakilan') }}" placeholder="Masukkan Debitur/Perwakilan" />
<button type="button" class="btn btn-danger btn-outline btn-xs remove-btn" <button type="button" class="btn btn-danger btn-outline btn-xs remove-btn"
style="display: none">Hapus style="display: none">Hapus
</button> </button>
</div> </div>
</div> </div>
@@ -125,13 +125,13 @@
<div class="grid grid-cols-3 md:grid-cols-3 gap-4 mt-2"> <div class="grid grid-cols-3 md:grid-cols-3 gap-4 mt-2">
<label class="form-label flex items-center gap-3 text-nowrap"> <label class="form-label flex items-center gap-3 text-nowrap">
<input onclick="toggleFieldVisibility('jenis_asset', 'jenis_asset', ['tidak sesuai'])" <input onclick="toggleFieldVisibility('jenis_asset', 'jenis_asset', ['tidak sesuai'])"
type="radio" class="radio" name="jenis_asset" value="sesuai" type="radio" class="radio" name="jenis_asset" value="sesuai"
{{ isset($forminspeksi['asset']['jenis_asset']['sesuai']) ? 'checked' : '' }}> {{ isset($forminspeksi['asset']['jenis_asset']['sesuai']) ? 'checked' : '' }}>
<span class="ml-2">Ya</span> <span class="ml-2">Ya</span>
</label> </label>
<label class="form-label flex items-center gap-2.5 text-nowrap"> <label class="form-label flex items-center gap-2.5 text-nowrap">
<input onclick="toggleFieldVisibility('jenis_asset', 'jenis_asset', ['tidak sesuai'])" <input onclick="toggleFieldVisibility('jenis_asset', 'jenis_asset', ['tidak sesuai'])"
type="radio" class="radio" name="jenis_asset" value="tidak sesuai" type="radio" class="radio" name="jenis_asset" value="tidak sesuai"
{{ isset($forminspeksi['asset']['jenis_asset']['tidak sesuai']) ? 'checked' : '' }}> {{ isset($forminspeksi['asset']['jenis_asset']['tidak sesuai']) ? 'checked' : '' }}>
<span class="ml-2">Tidak</span> <span class="ml-2">Tidak</span>
</label> </label>
@@ -143,9 +143,9 @@
$selectedValue = $forminspeksi['asset']['jenis_asset'][$statusKey] ?? null; $selectedValue = $forminspeksi['asset']['jenis_asset'][$statusKey] ?? null;
@endphp @endphp
<div id="jenis_asset" class="flex items-baseline gap-2" <div id="jenis_asset" class="flex items-baseline gap-2"
style="{{ isset($selectedValue) === 'tidak sesuai' ? '' : 'display: none;' }}"> style="{{ isset($selectedValue) === 'tidak sesuai' ? '' : 'display: none;' }}">
<select id="jenis_asset_tidak_sesuai" class="input w-full" <select id="jenis_asset_tidak_sesuai" class="input w-full"
name="jenis_asset_tidak_sesuai"> name="jenis_asset_tidak_sesuai">
<option value="">Select Jenis asset</option> <option value="">Select Jenis asset</option>
@if (isset($basicData['jenisJaminan'])) @if (isset($basicData['jenisJaminan']))
@foreach ($basicData['jenisJaminan'] as $item) @foreach ($basicData['jenisJaminan'] as $item)
@@ -179,13 +179,13 @@
<div class="grid grid-cols-3 md:grid-cols-3 gap-4 mt-2"> <div class="grid grid-cols-3 md:grid-cols-3 gap-4 mt-2">
<label class="form-label flex items-center gap-3 text-nowrap"> <label class="form-label flex items-center gap-3 text-nowrap">
<input onclick="updateAlamatFields('sesuai')" type="radio" class="radio" <input onclick="updateAlamatFields('sesuai')" type="radio" class="radio"
name="alamat_sesuai" value="sesuai" name="alamat_sesuai" value="sesuai"
{{ old('jenis_asset', isset($forminspeksi['asset']['alamat']['sesuai'])) ? 'checked' : '' }}> {{ old('jenis_asset', isset($forminspeksi['asset']['alamat']['sesuai'])) ? 'checked' : '' }}>
<span class="ml-2">Ya</span> <span class="ml-2">Ya</span>
</label> </label>
<label class="form-label flex items-center gap-3 text-nowrap"> <label class="form-label flex items-center gap-3 text-nowrap">
<input onclick="updateAlamatFields('tidak sesuai')" type="radio" class="radio" <input onclick="updateAlamatFields('tidak sesuai')" type="radio" class="radio"
name="alamat_sesuai" value="tidak sesuai" name="alamat_sesuai" value="tidak sesuai"
{{ old('jenis_asset', isset($forminspeksi['asset']['alamat']['tidak sesuai'])) ? 'checked' : '' }}> {{ old('jenis_asset', isset($forminspeksi['asset']['alamat']['tidak sesuai'])) ? 'checked' : '' }}>
<span class="ml-2">Tidak</span> <span class="ml-2">Tidak</span>
</label> </label>
@@ -200,13 +200,13 @@
@endphp @endphp
<div id="alamat_form" class="grid gap-2 mt-5" <div id="alamat_form" class="grid gap-2 mt-5"
style="{{ isset($address) ? '' : 'display: none;' }}"> style="{{ isset($address) ? '' : 'display: none;' }}">
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5 w-full"> <div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5 w-full">
<label for="address" class="form-label max-w-56">Jl.</label> <label for="address" class="form-label max-w-56">Jl.</label>
<div class="flex flex-wrap items-baseline w-full"> <div class="flex flex-wrap items-baseline w-full">
<input type="text" id="address" name="address" class="input w-full" <input type="text" id="address" name="address" class="input w-full"
placeholder="Masukkan Jl." placeholder="Masukkan Jl."
value="{{ isset($forminspeksi['asset']['alamat']['tidak sesuai']['address']) value="{{ isset($forminspeksi['asset']['alamat']['tidak sesuai']['address'])
? $forminspeksi['asset']['alamat']['tidak sesuai']['address'] ? $forminspeksi['asset']['alamat']['tidak sesuai']['address']
: (isset($forminspeksi['asset']['alamat']['sesuai']['address']) : (isset($forminspeksi['asset']['alamat']['sesuai']['address'])
? $forminspeksi['asset']['alamat']['sesuai']['address'] ? $forminspeksi['asset']['alamat']['sesuai']['address']
@@ -222,12 +222,11 @@
<option value="">Select Province</option> <option value="">Select Province</option>
@foreach ($provinces as $province) @foreach ($provinces as $province)
<option value="{{ $province->code }}" <option value="{{ $province->code }}"
@if ( @if (
(isset($cekAlamat['province_code']) && $cekAlamat['province_code'] == $province->code) || (isset($cekAlamat['province_code']) && $cekAlamat['province_code'] == $province->code) ||
(!isset($cekAlamat['province_code']) && isset($debitur->province_code) && $debitur->province_code == $province->code) (!isset($cekAlamat['province_code']) &&
) isset($debitur->province_code) &&
selected $debitur->province_code == $province->code)) selected @endif>
@endif>
{{ $province->name }} {{ $province->name }}
</option> </option>
@endforeach @endforeach
@@ -243,15 +242,11 @@
@if (isset($cities)) @if (isset($cities))
@foreach ($cities as $city) @foreach ($cities as $city)
<option value="{{ $city->code }}" <option value="{{ $city->code }}"
@if ( @if (
(isset($cekAlamat['city_code']) && $cekAlamat['city_code'] == $city->code) || (isset($cekAlamat['city_code']) && $cekAlamat['city_code'] == $city->code) ||
(!isset($cekAlamat['city_code']) && isset($debitur->city_code) && $debitur->city_code == $city->code) (!isset($cekAlamat['city_code']) && isset($debitur->city_code) && $debitur->city_code == $city->code)) selected @endif>
)
selected
@endif>
{{ $city->name }} {{ $city->name }}
</option> </option>
@endforeach @endforeach
@endif @endif
</select> </select>
@@ -268,15 +263,13 @@
@if (isset($districts)) @if (isset($districts))
@foreach ($districts as $district) @foreach ($districts as $district)
<option value="{{ $district->code }}" <option value="{{ $district->code }}"
@if ( @if (
(isset($cekAlamat['district_code']) && $cekAlamat['district_code'] == $district->code) || (isset($cekAlamat['district_code']) && $cekAlamat['district_code'] == $district->code) ||
(!isset($cekAlamat['district_code']) && isset($debitur->district_code) && $debitur->district_code == $district->code) (!isset($cekAlamat['district_code']) &&
) isset($debitur->district_code) &&
selected $debitur->district_code == $district->code)) selected @endif>
@endif>
{{ $district->name }} {{ $district->name }}
</option> </option>
@endforeach @endforeach
@endif @endif
@@ -292,15 +285,13 @@
@if (isset($villages)) @if (isset($villages))
@foreach ($villages as $village) @foreach ($villages as $village)
<option value="{{ $village->code }}" <option value="{{ $village->code }}"
@if ( @if (
(isset($cekAlamat['village_code']) && $cekAlamat['village_code'] == $village->code) || (isset($cekAlamat['village_code']) && $cekAlamat['village_code'] == $village->code) ||
(!isset($cekAlamat['village_code']) && isset($debitur->village_code) && $debitur->village_code == $village->code) (!isset($cekAlamat['village_code']) &&
) isset($debitur->village_code) &&
selected $debitur->village_code == $village->code)) selected @endif>
@endif>
{{ $village->name }} {{ $village->name }}
</option> </option>
@endforeach @endforeach
@endif @endif
@@ -327,14 +318,14 @@
<div id="perwakilan" class="flex items-baseline w-full gap-5"> <div id="perwakilan" class="flex items-baseline w-full gap-5">
<div class="grid grid-cols-2 gap-4 items-center w-full"> <div class="grid grid-cols-2 gap-4 items-center w-full">
<input class="input" type="text" placeholder="Masukan Koordinat Latitude" type="text" <input class="input" type="text" placeholder="Masukan Koordinat Latitude" type="text"
name="kordinat_lat" id="lat" name="kordinat_lat" id="lat"
value="{{ old('kordinat_lat', isset($forminspeksi['asset']['kordinat_lat']) ? $forminspeksi['asset']['kordinat_lat'] : '') }}"> value="{{ old('kordinat_lat', isset($forminspeksi['asset']['kordinat_lat']) ? $forminspeksi['asset']['kordinat_lat'] : '') }}">
<input class="input" type="text" placeholder="Masukan Koordinat Longitude" <input class="input" type="text" placeholder="Masukan Koordinat Longitude"
name="kordinat_lng" id="lng" name="kordinat_lng" id="lng"
value="{{ old('kordinat_lng', isset($forminspeksi['asset']['kordinat_lng']) ? $forminspeksi['asset']['kordinat_lng'] : '') }}"> value="{{ old('kordinat_lng', isset($forminspeksi['asset']['kordinat_lng']) ? $forminspeksi['asset']['kordinat_lng'] : '') }}">
</div> </div>
<a target="_blank" href="https://www.google.com/maps" type="button" <a target="_blank" href="https://www.google.com/maps" type="button"
class="btn btn-md btn-outline btn-primary"> class="btn btn-md btn-outline btn-primary">
<i class="ki-filled ki-map"></i>Ambil <i class="ki-filled ki-map"></i>Ambil
Kordinat</a> Kordinat</a>
</div> </div>
@@ -350,9 +341,9 @@
<div data-accordion="true"> <div data-accordion="true">
@foreach ($permohonan->debiture->documents as $dokumen) @foreach ($permohonan->debiture->documents as $dokumen)
<div class="accordion-item [&:not(:last-child)]:border-b border-b-gray-200" data-accordion-item="true" <div class="accordion-item [&:not(:last-child)]:border-b border-b-gray-200" data-accordion-item="true"
id="accordion_detail_jaminan"> id="accordion_detail_jaminan">
<button class="accordion-toggle py-4 group " <button class="accordion-toggle py-4 group "
data-accordion-toggle="#accordion_detail_jaminan_{{ $loop->index }}"> data-accordion-toggle="#accordion_detail_jaminan_{{ $loop->index }}">
<span class="text-base text-gray-900 font-medium"> <span class="text-base text-gray-900 font-medium">
Dokument Kepemilikan Dokument Kepemilikan
</span> </span>
@@ -365,7 +356,7 @@
<div class="accordion-content hidden" id="accordion_detail_jaminan_{{ $loop->index }}"> <div class="accordion-content hidden" id="accordion_detail_jaminan_{{ $loop->index }}">
<div class="card-table scrollable-x-auto pb-3"> <div class="card-table scrollable-x-auto pb-3">
<a href="{{ route('debitur.jaminan.bulk.download', ['id' => $permohonan->debiture->id, 'jaminan' => $dokumen->id]) }}" <a href="{{ route('debitur.jaminan.bulk.download', ['id' => $permohonan->debiture->id, 'jaminan' => $dokumen->id]) }}"
class="ml-6 btn btn-dark dark:btn-light"> class="ml-6 btn btn-dark dark:btn-light">
<i class="ki-outline ki-cloud-download"></i> Download Semua Dokumen <i class="ki-outline ki-cloud-download"></i> Download Semua Dokumen
</a> </a>
<table class="table align-middle text-sm text-gray-500"> <table class="table align-middle text-sm text-gray-500">
@@ -403,7 +394,7 @@
{{ $dokumen_nomor[$index] }}</span> {{ $dokumen_nomor[$index] }}</span>
@endif @endif
<a href="{{ route('debitur.jaminan.download', ['id' => $permohonan->debiture->id, 'dokumen' => $detail->id, 'index' => $index]) }}" <a href="{{ route('debitur.jaminan.download', ['id' => $permohonan->debiture->id, 'dokumen' => $detail->id, 'index' => $index]) }}"
class="flex-none badge badge-sm badge-outline mt-2 mr-2"> class="flex-none badge badge-sm badge-outline mt-2 mr-2">
{{ basename($dokumen) }} {{ basename($dokumen) }}
<i class="ki-filled ki-cloud-download"></i> <i class="ki-filled ki-cloud-download"></i>
</a> </a>
@@ -448,7 +439,7 @@
@foreach ($permohonan->debiture->documents as $dokumen) @foreach ($permohonan->debiture->documents as $dokumen)
{{ $dokumen->pemilik->hubungan_pemilik->name ?? '' }} {{ $dokumen->pemilik->hubungan_pemilik->name ?? '' }}
<input type="hidden" name="hub_cadeb_sesuai" <input type="hidden" name="hub_cadeb_sesuai"
value="{{ $dokumen->pemilik->hubungan_pemilik->name }}" id=""> value="{{ $dokumen->pemilik->hubungan_pemilik->name }}" id="">
@endforeach @endforeach
</div> </div>
@@ -477,7 +468,7 @@
@endphp @endphp
<select id="hub_cadeb_tidak_sesuai" class="input w-full" name="hub_cadeb_tidak_sesuai" <select id="hub_cadeb_tidak_sesuai" class="input w-full" name="hub_cadeb_tidak_sesuai"
style="{{ old('hub_cadeb_tidak_sesuai', $selectedData) ? '' : 'display: none;' }}"> style="{{ old('hub_cadeb_tidak_sesuai', $selectedData) ? '' : 'display: none;' }}">
<option value="">Select Hubungan Cadeb</option> <option value="">Select Hubungan Cadeb</option>
@if (isset($basicData['hubCadeb'])) @if (isset($basicData['hubCadeb']))
@foreach ($basicData['hubCadeb'] as $item) @foreach ($basicData['hubCadeb'] as $item)
@@ -508,8 +499,8 @@
@foreach ($permohonan->debiture->documents as $dokumen) @foreach ($permohonan->debiture->documents as $dokumen)
{{ $dokumen->penghuni->hubungan_penghuni->name ?? 'N/A' }} {{ $dokumen->penghuni->hubungan_penghuni->name ?? 'N/A' }}
<input type="hidden" name="hub_cadeb_penghuni_sesuai" <input type="hidden" name="hub_cadeb_penghuni_sesuai"
value="{{ isset($dokumen->penghuni->hubungan_penghuni->name) ?? '' }}" value="{{ isset($dokumen->penghuni->hubungan_penghuni->name) ?? '' }}"
id=""> id="">
@endforeach @endforeach
</div> </div>
@@ -520,7 +511,6 @@
<input <input
onclick="toggleFieldVisibility('hub_cadeb_penghuni','hub_penghuni_tidak_sesuai', ['tidak sesuai'])" onclick="toggleFieldVisibility('hub_cadeb_penghuni','hub_penghuni_tidak_sesuai', ['tidak sesuai'])"
type="radio" class="radio" name="hub_cadeb_penghuni" value="sesuai" type="radio" class="radio" name="hub_cadeb_penghuni" value="sesuai"
{{ old('hub_cadeb_penghuni', isset($forminspeksi['asset']['hub_cadeb_penghuni'])) ? 'checked' : '' }}> {{ old('hub_cadeb_penghuni', isset($forminspeksi['asset']['hub_cadeb_penghuni'])) ? 'checked' : '' }}>
<span class="ml-2">Ya</span> <span class="ml-2">Ya</span>
@@ -539,20 +529,19 @@
: 'tidak sesuai'; : 'tidak sesuai';
$selectedData = $forminspeksi['asset']['hub_cadeb_penghuni'][$statusKey] ?? null; $selectedData = $forminspeksi['asset']['hub_cadeb_penghuni'][$statusKey] ?? null;
@endphp @endphp
<select id="hub_penghuni_tidak_sesuai" <select id="hub_penghuni_tidak_sesuai" name="hub_penghuni_tidak_sesuai"
class="input w-full class="input w-full"
name=" hub_penghuni_tidak_sesuai" style="{{ old('hub_penghuni_tidak_sesuai', $selectedData) ? '' : 'display: none;' }}">
style="{{ old('hub_penghuni_tidak_sesuai', $selectedData) ? '' : 'display: none;' }}"> <option value="">Select Hubungan Cadeb</option>
<option value="">Select Hubungan Cadeb</option> @if (isset($basicData['hubPenghuni']))
@if (isset($basicData['hubPenghuni'])) @foreach ($basicData['hubPenghuni'] as $item)
@foreach ($basicData['hubPenghuni'] as $item) <option value="{{ $item->name }}"
<option value="{{ $item->name }}" {{ old('hub_penghuni_tidak_sesuai', $selectedData) == $item->name ? 'selected' : '' }}>
{{ old('hub_penghuni_tidak_sesuai', $selectedData) == $item->name ? 'selected' : '' }}> {{ $item->name }}
{{ $item->name }} </option>
</option>
@endforeach @endforeach
@endif @endif
</select> </select>
</div> </div>
<em id="error-hub_cadeb" class="alert text-danger text-sm"></em> <em id="error-hub_cadeb" class="alert text-danger text-sm"></em>
</div> </div>

View File

@@ -43,14 +43,6 @@
</div> </div>
</form> </form>
</div> </div>
<!-- Loading Overlay -->
<div id="loadingOverlay" class="fixed inset-0 bg-black bg-opacity-50 hidden items-center justify-center z-50">
<div class="bg-white p-4 rounded-lg">
<div class="loader"></div>
<p class="mt-2 text-center">Sedang memproses...</p>
</div>
</div>
@endsection @endsection
@push('scripts') @push('scripts')
@@ -178,15 +170,11 @@
function submitData() { function submitData() {
const loadingOverlay = document.getElementById('loadingOverlay'); showLoadingSwal('Mengirim data ke server...');
loadingOverlay.classList.remove('hidden');
loadingOverlay.classList.add('flex');
const form = document.querySelector('form'); const form = document.querySelector('form');
const formData = new FormData(form); const formData = new FormData(form);
console.log('Form data entries:', Array.from(formData.entries())); console.log('Form data entries:', Array.from(formData.entries()));
$.ajax({ $.ajax({
url: '{{ route('surveyor.store') }}', url: '{{ route('surveyor.store') }}',
type: 'POST', type: 'POST',
@@ -197,6 +185,7 @@
'X-CSRF-TOKEN': '{{ csrf_token() }}' 'X-CSRF-TOKEN': '{{ csrf_token() }}'
}, },
success: function(response) { success: function(response) {
hideLoadingSwal();
if (response.success) { if (response.success) {
Swal.fire({ Swal.fire({
title: 'Berhasil!', title: 'Berhasil!',
@@ -205,8 +194,8 @@
confirmButtonText: 'OK' confirmButtonText: 'OK'
}).then((response) => { }).then((response) => {
if (response.isConfirmed) { if (response.isConfirmed) {
window.location.href = // window.location.href =
'{{ route('surveyor.show', ['id' => $permohonan->id]) }}'; // '{{ route('surveyor.show', ['id' => $permohonan->id]) }}';
} }
}); });
} else { } else {
@@ -220,6 +209,7 @@
console.log(response); console.log(response);
}, },
error: function(xhr, status, error) { error: function(xhr, status, error) {
let errors = xhr.responseJSON?.errors; let errors = xhr.responseJSON?.errors;
$('.alert').text(''); $('.alert').text('');
if (errors) { if (errors) {
@@ -227,16 +217,12 @@
$(`#error-${key}`).text(value[0]); $(`#error-${key}`).text(value[0]);
}); });
} }
hideLoadingSwal();
console.error('Terjadi error:', error); // Menampilkan pesan error di konsol console.error('Terjadi error:', error); // Menampilkan pesan error di konsol
console.log('Status:', status); console.log('Status:', status);
console.log('Response:', xhr.responseText); console.log('Response:', xhr.responseText);
console.log(errors); console.log(errors);
toastrErrorBuild(error); toastrErrorBuild(error);
},
complete: function() {
// Re-enable the button and hide the spinner
loadingOverlay.classList.add('hidden');
loadingOverlay.classList.remove('flex');
} }
}); });
} }
@@ -349,45 +335,5 @@
}); });
} }
</script> </script>
@include('lpj::surveyor.js.utils')
@endpush @endpush
<style>
.loader {
border: 4px solid #f3f3f3;
border-radius: 50%;
border-top: 4px solid #3498db;
width: 40px;
height: 40px;
animation: spin 1s linear infinite;
margin: 0 auto;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
div[disabled] {
background-color: #f5f5f5;
color: #a0a0a0;
border: 1px solid #d1d1d1;
cursor: not-allowed;
pointer-events: none;
}
div[disabled]:hover {
background-color: #e8e8e8;
}
div.disabled-input {
opacity: 0.6;
transition: opacity 0.3s ease;
}
</style>

View File

@@ -0,0 +1,55 @@
<script>
function showLoadingSwal(message) {
Swal.fire({
title: message,
allowOutsideClick: false,
didOpen: () => {
Swal.showLoading();
}
});
}
function hideLoadingSwal() {
Swal.close();
}
function previewImage(input, imageId) {
const preview = document.getElementById(imageId);
if (input.files && input.files[0]) {
const reader = new FileReader();
reader.onload = function(e) {
preview.src = e.target.result;
preview.classList.remove('hidden');
}
reader.readAsDataURL(input.files[0]);
}
}
function formatNumber(input) {
let value = input.value.replace(/[^\d.]/g, '');
input.value = value;
}
function formatCurrency(value) {
if (!value) return '';
// Jika input adalah elemen, ambil nilainya
const numericValue = typeof value === 'string' ? value : value.value;
// Hapus semua karakter non-digit
const cleanValue = numericValue.toString().replace(/[^\d]/g, '');
// Format ke currency
const formattedValue = new Intl.NumberFormat('id-ID').format(cleanValue);
// Jika input adalah elemen, update nilainya
if (typeof value !== 'string') {
value.value = formattedValue;
}
return formattedValue;
}
</script>

View File

@@ -529,6 +529,10 @@
}); });
} }
Breadcrumbs::for('otorisator.show', function (BreadcrumbTrail $trail, $id, $type) {
$trail->push("Detail $type", route('otorisator.show', ['id' => $id, 'type' => $type]));
});
Breadcrumbs::for('laporan', function (BreadcrumbTrail $trail) { Breadcrumbs::for('laporan', function (BreadcrumbTrail $trail) {
$trail->push('Laporan', route('laporan.sederhana.index')); $trail->push('Laporan', route('laporan.sederhana.index'));

View File

@@ -496,15 +496,19 @@ Route::middleware(['auth'])->group(function () {
'type', 'type',
'pembayaran', 'pembayaran',
); );
Route::post('otorisator/{id}/{context}', [PenilaianController::class, 'otorisatorUpdate'])->name('otorisator.update');
Route::get('pembatalan', [PenilaianController::class, 'otorisator'])->name('pembatalan.index')->defaults( Route::get('pembatalan', [PenilaianController::class, 'otorisator'])->name('pembatalan.index')->defaults(
'type', 'type',
'pembatalan', 'pembatalan',
); );
Route::get('sla', [PenilaianController::class, 'otorisator'])->name('sla.index')->defaults('type', 'sla'); Route::get('sla', [PenilaianController::class, 'otorisator'])->name('sla.index')->defaults('type', 'sla');
Route::get('/datatables/{otorisator}', [PenilaianController::class, 'dataForAuthorization'])->name( Route::get('/datatables/{otorisator}', [PenilaianController::class, 'dataForAuthorization'])->name(
'datatables', 'datatables',
); );
Route::get('show/{id}', [PenilaianController::class, 'show'])->name('show'); Route::get('show/{id}/{type}', [PenilaianController::class, 'show'])->name('show');
}); });