fix pbg task add toggle and rab krk dlh
This commit is contained in:
@@ -9,3 +9,8 @@ exit
|
|||||||
(new App\Jobs\ScrapingDataJob())->handle();
|
(new App\Jobs\ScrapingDataJob())->handle();
|
||||||
(new App\Jobs\ScrapingDataJob())->handle();
|
(new App\Jobs\ScrapingDataJob())->handle();
|
||||||
exit
|
exit
|
||||||
|
exit
|
||||||
|
BigdataResume::generateResumeData(253,2025,"simbg");
|
||||||
|
exit
|
||||||
|
BigdataResume::generateResumeData(253,2025,"simbg");
|
||||||
|
exit
|
||||||
|
|||||||
17
.npm/_logs/2025-08-19T05_29_08_290Z-debug-0.log
Normal file
17
.npm/_logs/2025-08-19T05_29_08_290Z-debug-0.log
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
0 verbose cli /usr/bin/node /usr/bin/npm
|
||||||
|
1 info using npm@10.8.2
|
||||||
|
2 info using node@v18.20.8
|
||||||
|
3 silly config load:file:/usr/lib/node_modules/npm/npmrc
|
||||||
|
4 silly config load:file:/var/www/.npmrc
|
||||||
|
5 silly config load:file:/usr/etc/npmrc
|
||||||
|
6 verbose title npm run build
|
||||||
|
7 verbose argv "run" "build"
|
||||||
|
8 verbose logfile logs-max:10 dir:/var/www/.npm/_logs/2025-08-19T05_29_08_290Z-
|
||||||
|
9 verbose logfile /var/www/.npm/_logs/2025-08-19T05_29_08_290Z-debug-0.log
|
||||||
|
10 silly logfile done cleaning log files
|
||||||
|
11 verbose cwd /var/www
|
||||||
|
12 verbose os Linux 6.6.87.2-microsoft-standard-WSL2
|
||||||
|
13 verbose node v18.20.8
|
||||||
|
14 verbose npm v10.8.2
|
||||||
|
15 verbose exit 0
|
||||||
|
16 info ok
|
||||||
@@ -42,11 +42,11 @@ class BigDataResumeController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
$data_settings = DataSetting::all();
|
$data_settings = DataSetting::all();
|
||||||
if($data_settings->isEmpty()){
|
$target_pad = 0;
|
||||||
return response()->json(['message' => 'No data setting found']);
|
if($data_settings->where('key', 'TARGET_PAD')->first()){
|
||||||
|
$target_pad = floatval($data_settings->where('key', 'TARGET_PAD')->first()->value ?? 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
$target_pad = floatval(optional($data_settings->where('key', 'TARGET_PAD')->first())->value);
|
|
||||||
$realisasi_terbit_pbg_sum = $big_data_resume->issuance_realization_pbg_sum;
|
$realisasi_terbit_pbg_sum = $big_data_resume->issuance_realization_pbg_sum;
|
||||||
$realisasi_terbit_pbg_count = $big_data_resume->issuance_realization_pbg_count;
|
$realisasi_terbit_pbg_count = $big_data_resume->issuance_realization_pbg_count;
|
||||||
$menunggu_klik_dpmptsp_sum = $big_data_resume->waiting_click_dpmptsp_sum;
|
$menunggu_klik_dpmptsp_sum = $big_data_resume->waiting_click_dpmptsp_sum;
|
||||||
@@ -107,7 +107,7 @@ class BigDataResumeController extends Controller
|
|||||||
$business_krk_count = $big_data_resume->business_krk_count;
|
$business_krk_count = $big_data_resume->business_krk_count;
|
||||||
$non_business_rab_count = $big_data_resume->non_business_rab_count;
|
$non_business_rab_count = $big_data_resume->non_business_rab_count;
|
||||||
$non_business_krk_count = $big_data_resume->non_business_krk_count;
|
$non_business_krk_count = $big_data_resume->non_business_krk_count;
|
||||||
$non_business_dlh_count = $big_data_resume->non_business_dlh_count;
|
$business_dlh_count = $big_data_resume->business_dlh_count;
|
||||||
|
|
||||||
$result = [
|
$result = [
|
||||||
'target_pad' => [
|
'target_pad' => [
|
||||||
@@ -167,7 +167,7 @@ class BigDataResumeController extends Controller
|
|||||||
'business_krk_count' => $business_krk_count,
|
'business_krk_count' => $business_krk_count,
|
||||||
'non_business_rab_count' => $non_business_rab_count,
|
'non_business_rab_count' => $non_business_rab_count,
|
||||||
'non_business_krk_count' => $non_business_krk_count,
|
'non_business_krk_count' => $non_business_krk_count,
|
||||||
'non_business_dlh_count' => $non_business_dlh_count
|
'business_dlh_count' => $business_dlh_count
|
||||||
];
|
];
|
||||||
return response()->json($result);
|
return response()->json($result);
|
||||||
}catch(\Exception $e){
|
}catch(\Exception $e){
|
||||||
@@ -336,9 +336,15 @@ class BigDataResumeController extends Controller
|
|||||||
return $pdf->download('laporan-pimpinan.pdf');
|
return $pdf->download('laporan-pimpinan.pdf');
|
||||||
}
|
}
|
||||||
private function response_empty_resume(){
|
private function response_empty_resume(){
|
||||||
|
$data_settings = DataSetting::all();
|
||||||
|
$target_pad = 0;
|
||||||
|
if($data_settings->where('key', 'TARGET_PAD')->first()){
|
||||||
|
$target_pad = floatval($data_settings->where('key', 'TARGET_PAD')->first()->value ?? 0);
|
||||||
|
}
|
||||||
|
|
||||||
$result = [
|
$result = [
|
||||||
'target_pad' => [
|
'target_pad' => [
|
||||||
'sum' => 0,
|
'sum' => $target_pad,
|
||||||
'percentage' => 100,
|
'percentage' => 100,
|
||||||
],
|
],
|
||||||
'tata_ruang' => [
|
'tata_ruang' => [
|
||||||
|
|||||||
@@ -132,39 +132,48 @@ class PbgTaskController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
$validated = $request->validate([
|
$validated = $request->validate([
|
||||||
'name' => 'required|string|max:255',
|
'name' => 'nullable|string|max:255',
|
||||||
'owner_name' => 'required|string|max:255',
|
'owner_name' => 'nullable|string|max:255',
|
||||||
'application_type' => ['nullable', new Enum(PbgTaskApplicationTypes::class)],
|
'application_type' => ['nullable', new Enum(PbgTaskApplicationTypes::class)],
|
||||||
'condition' => 'required|string|max:255',
|
'condition' => 'nullable|string|max:255',
|
||||||
'registration_number' => 'required|string|max:255',
|
'registration_number' => 'nullable|string|max:255',
|
||||||
'document_number' => 'required|string|max:255',
|
'document_number' => 'nullable|string|max:255',
|
||||||
'status' => ['nullable', new Enum(PbgTaskStatus::class)],
|
'status' => ['nullable', new Enum(PbgTaskStatus::class)],
|
||||||
'address' => 'required|string|max:255',
|
'address' => 'nullable|string|max:255',
|
||||||
'slf_status_name' => 'nullable|string|max:255',
|
'slf_status_name' => 'nullable|string|max:255',
|
||||||
'function_type' => 'required|string|max:255',
|
'function_type' => 'nullable|string|max:255',
|
||||||
'consultation_type' => 'required|string|max:255',
|
'consultation_type' => 'nullable|string|max:255',
|
||||||
'due_date' => 'nullable|date|after_or_equal:today',
|
'due_date' => 'nullable|date',
|
||||||
|
'is_valid' => 'nullable|boolean',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$statusLabel = $validated['status'] !== null ? PbgTaskStatus::getLabel($validated['status']) : null;
|
$statusLabel = $validated['status'] !== null ? PbgTaskStatus::getLabel($validated['status']) : null;
|
||||||
$applicationLabel = $validated['application_type'] !== null ? PbgTaskApplicationTypes::getLabel($validated['application_type']) : null;
|
$applicationLabel = $validated['application_type'] !== null ? PbgTaskApplicationTypes::getLabel($validated['application_type']) : null;
|
||||||
|
|
||||||
$pbg_task->update([
|
// Prepare update data - only include fields that are actually provided
|
||||||
'name' => $validated['name'],
|
$updateData = [];
|
||||||
'owner_name' => $validated['owner_name'],
|
|
||||||
'application_type' => $validated['application_type'],
|
foreach ($validated as $key => $value) {
|
||||||
'application_type_name' => $applicationLabel, // Automatically set application_type_name
|
if ($value !== null || $request->has($key)) {
|
||||||
'condition' => $validated['condition'],
|
$updateData[$key] = $value;
|
||||||
'registration_number' => $validated['registration_number'],
|
}
|
||||||
'document_number' => $validated['document_number'],
|
}
|
||||||
'status' => $validated['status'],
|
|
||||||
'status_name' => $statusLabel, // Automatically set status_name
|
// Handle special cases for labels
|
||||||
'address' => $validated['address'],
|
if (isset($updateData['status'])) {
|
||||||
'slf_status_name' => $validated['slf_status_name'],
|
$updateData['status_name'] = $statusLabel;
|
||||||
'function_type' => $validated['function_type'],
|
}
|
||||||
'consultation_type' => $validated['consultation_type'],
|
|
||||||
'due_date' => $validated['due_date'],
|
if (isset($updateData['application_type'])) {
|
||||||
]);
|
$updateData['application_type_name'] = $applicationLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle is_valid specifically
|
||||||
|
if ($request->has('is_valid')) {
|
||||||
|
$updateData['is_valid'] = $validated['is_valid'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$pbg_task->update($updateData);
|
||||||
return response()->json([
|
return response()->json([
|
||||||
"success"=> true,
|
"success"=> true,
|
||||||
"message"=> "Data berhasil diubah",
|
"message"=> "Data berhasil diubah",
|
||||||
|
|||||||
@@ -34,9 +34,9 @@ class BigdataResume extends Model
|
|||||||
'process_in_technical_office_sum',
|
'process_in_technical_office_sum',
|
||||||
'business_rab_count',
|
'business_rab_count',
|
||||||
'business_krk_count',
|
'business_krk_count',
|
||||||
|
'business_dlh_count',
|
||||||
'non_business_rab_count',
|
'non_business_rab_count',
|
||||||
'non_business_krk_count',
|
'non_business_krk_count',
|
||||||
'non_business_dlh_count',
|
|
||||||
'resume_type',
|
'resume_type',
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -155,6 +155,41 @@ class BigdataResume extends Model
|
|||||||
')
|
')
|
||||||
->value('total_count') ?? 0;
|
->value('total_count') ?? 0;
|
||||||
|
|
||||||
|
// Non-Business DLH count - for each non-business task with data_type=5:
|
||||||
|
// if any status != 1 then return 1, if all status = 1 then return 0, then sum all
|
||||||
|
$business_dlh_count = DB::table('pbg_task')
|
||||||
|
->where(function ($q) {
|
||||||
|
$q->where(function ($q2) {
|
||||||
|
$q2->where(function ($q3) {
|
||||||
|
$q3->whereRaw("LOWER(TRIM(function_type)) LIKE ?", ['%fungsi usaha%'])
|
||||||
|
->whereRaw("LOWER(TRIM(function_type)) LIKE ?", ['%sebagai tempat usaha%']);
|
||||||
|
})
|
||||||
|
->orWhereNull('function_type');
|
||||||
|
})
|
||||||
|
->whereIn("status", PbgTaskStatus::getNonVerified());
|
||||||
|
})
|
||||||
|
->whereYear('task_created_at', $year)
|
||||||
|
->whereExists(function ($query) {
|
||||||
|
$query->select(DB::raw(1))
|
||||||
|
->from('pbg_task_detail_data_lists')
|
||||||
|
->whereColumn('pbg_task_detail_data_lists.pbg_task_uuid', 'pbg_task.uuid')
|
||||||
|
->where('pbg_task_detail_data_lists.data_type', 5);
|
||||||
|
})
|
||||||
|
->selectRaw('
|
||||||
|
SUM(
|
||||||
|
CASE
|
||||||
|
WHEN EXISTS (
|
||||||
|
SELECT 1 FROM pbg_task_detail_data_lists ptddl
|
||||||
|
WHERE ptddl.pbg_task_uuid = pbg_task.uuid
|
||||||
|
AND ptddl.data_type = 5
|
||||||
|
AND ptddl.status != 1
|
||||||
|
) THEN 1
|
||||||
|
ELSE 0
|
||||||
|
END
|
||||||
|
) as total_count
|
||||||
|
')
|
||||||
|
->value('total_count') ?? 0;
|
||||||
|
|
||||||
// Non-Business RAB count - for each non-business task with data_type=3:
|
// Non-Business RAB count - for each non-business task with data_type=3:
|
||||||
// if any status != 1 then return 1, if all status = 1 then return 0, then sum all
|
// if any status != 1 then return 1, if all status = 1 then return 0, then sum all
|
||||||
$non_business_rab_count = DB::table('pbg_task')
|
$non_business_rab_count = DB::table('pbg_task')
|
||||||
@@ -225,61 +260,55 @@ class BigdataResume extends Model
|
|||||||
')
|
')
|
||||||
->value('total_count') ?? 0;
|
->value('total_count') ?? 0;
|
||||||
|
|
||||||
// Non-Business DLH count - for each non-business task with data_type=5:
|
|
||||||
// if any status != 1 then return 1, if all status = 1 then return 0, then sum all
|
|
||||||
$non_business_dlh_count = DB::table('pbg_task')
|
// Debug: Check if there are non-verified tasks and their retribution data
|
||||||
->where(function ($q) {
|
$debug_non_verified = PbgTask::whereIn('status', PbgTaskStatus::getNonVerified())
|
||||||
$q->where(function ($q2) {
|
|
||||||
$q2->where(function ($q3) {
|
|
||||||
$q3->whereRaw("LOWER(TRIM(function_type)) NOT LIKE ?", ['%fungsi usaha%'])
|
|
||||||
->whereRaw("LOWER(TRIM(function_type)) NOT LIKE ?", ['%sebagai tempat usaha%']);
|
|
||||||
})
|
|
||||||
->orWhereNull('function_type');
|
|
||||||
})
|
|
||||||
->whereIn("status", PbgTaskStatus::getNonVerified());
|
|
||||||
})
|
|
||||||
->whereYear('task_created_at', $year)
|
->whereYear('task_created_at', $year)
|
||||||
->whereExists(function ($query) {
|
->with('pbg_task_retributions')
|
||||||
$query->select(DB::raw(1))
|
->get();
|
||||||
->from('pbg_task_detail_data_lists')
|
|
||||||
->whereColumn('pbg_task_detail_data_lists.pbg_task_uuid', 'pbg_task.uuid')
|
\Log::info('Non-verified tasks debug', [
|
||||||
->where('pbg_task_detail_data_lists.data_type', 5);
|
'year' => $year,
|
||||||
})
|
'non_verified_statuses' => PbgTaskStatus::getNonVerified(),
|
||||||
->selectRaw('
|
'tasks_count' => $debug_non_verified->count(),
|
||||||
SUM(
|
'tasks_with_retribution' => $debug_non_verified->filter(fn($task) => $task->pbg_task_retributions)->count(),
|
||||||
CASE
|
'sample_retribution_values' => $debug_non_verified->take(3)->map(fn($task) => [
|
||||||
WHEN EXISTS (
|
'uuid' => $task->uuid,
|
||||||
SELECT 1 FROM pbg_task_detail_data_lists ptddl
|
'status' => $task->status,
|
||||||
WHERE ptddl.pbg_task_uuid = pbg_task.uuid
|
'has_retribution' => !is_null($task->pbg_task_retributions),
|
||||||
AND ptddl.data_type = 5
|
'retribution_value' => $task->pbg_task_retributions?->nilai_retribusi_bangunan ?? 'NULL'
|
||||||
AND ptddl.status != 1
|
])
|
||||||
) THEN 1
|
]);
|
||||||
ELSE 0
|
|
||||||
END
|
|
||||||
) as total_count
|
|
||||||
')
|
|
||||||
->value('total_count') ?? 0;
|
|
||||||
|
|
||||||
// Get sum values using proper aggregation to handle multiple retributions
|
// Get sum values using proper aggregation to handle multiple retributions
|
||||||
$stats = PbgTask::leftJoin('pbg_task_retributions as ptr', 'pbg_task.uuid', '=', 'ptr.pbg_task_uid')
|
$stats = PbgTask::leftJoin('pbg_task_retributions as ptr', 'pbg_task.uuid', '=', 'ptr.pbg_task_uid')
|
||||||
->whereYear('pbg_task.task_created_at', $year)
|
->whereYear('pbg_task.task_created_at', $year)
|
||||||
->selectRaw("
|
->selectRaw("
|
||||||
SUM(CASE WHEN pbg_task.status in (".implode(',', PbgTaskStatus::getVerified()).") THEN ptr.nilai_retribusi_bangunan ELSE 0 END) AS verified_total,
|
SUM(CASE WHEN pbg_task.status in (".implode(',', PbgTaskStatus::getVerified()).") THEN COALESCE(ptr.nilai_retribusi_bangunan, 0) ELSE 0 END) AS verified_total,
|
||||||
SUM(CASE WHEN pbg_task.status in (".implode(',', PbgTaskStatus::getNonVerified()).") THEN ptr.nilai_retribusi_bangunan ELSE 0 END) AS non_verified_total,
|
SUM(CASE WHEN pbg_task.status in (".implode(',', PbgTaskStatus::getNonVerified()).") THEN COALESCE(ptr.nilai_retribusi_bangunan, 0) ELSE 0 END) AS non_verified_total,
|
||||||
SUM(CASE WHEN (LOWER(TRIM(pbg_task.function_type)) LIKE '%fungsi usaha%'
|
SUM(CASE WHEN (LOWER(TRIM(pbg_task.function_type)) LIKE '%fungsi usaha%'
|
||||||
OR LOWER(TRIM(pbg_task.function_type)) LIKE '%sebagai tempat usaha%')
|
OR LOWER(TRIM(pbg_task.function_type)) LIKE '%sebagai tempat usaha%')
|
||||||
AND pbg_task.status in (".implode(',', PbgTaskStatus::getNonVerified()).") THEN ptr.nilai_retribusi_bangunan ELSE 0 END) AS business_total,
|
AND pbg_task.status in (".implode(',', PbgTaskStatus::getNonVerified()).") THEN COALESCE(ptr.nilai_retribusi_bangunan, 0) ELSE 0 END) AS business_total,
|
||||||
SUM(CASE WHEN (LOWER(TRIM(pbg_task.function_type)) NOT LIKE '%fungsi usaha%'
|
SUM(CASE WHEN (LOWER(TRIM(pbg_task.function_type)) NOT LIKE '%fungsi usaha%'
|
||||||
AND LOWER(TRIM(pbg_task.function_type)) NOT LIKE '%sebagai tempat usaha%'
|
AND LOWER(TRIM(pbg_task.function_type)) NOT LIKE '%sebagai tempat usaha%'
|
||||||
AND pbg_task.status in (".implode(',', PbgTaskStatus::getNonVerified())."))
|
AND pbg_task.status in (".implode(',', PbgTaskStatus::getNonVerified())."))
|
||||||
OR (pbg_task.function_type IS NULL AND pbg_task.status in (".implode(',', PbgTaskStatus::getNonVerified()).")) THEN ptr.nilai_retribusi_bangunan ELSE 0 END) AS non_business_total,
|
OR (pbg_task.function_type IS NULL AND pbg_task.status in (".implode(',', PbgTaskStatus::getNonVerified()).")) THEN COALESCE(ptr.nilai_retribusi_bangunan, 0) ELSE 0 END) AS non_business_total,
|
||||||
SUM(CASE WHEN pbg_task.status in (".implode(',', PbgTaskStatus::getWaitingClickDpmptsp()).") THEN ptr.nilai_retribusi_bangunan ELSE 0 END) AS waiting_click_dpmptsp_total,
|
SUM(CASE WHEN pbg_task.status in (".implode(',', PbgTaskStatus::getWaitingClickDpmptsp()).") THEN COALESCE(ptr.nilai_retribusi_bangunan, 0) ELSE 0 END) AS waiting_click_dpmptsp_total,
|
||||||
SUM(CASE WHEN pbg_task.status in (".implode(',', PbgTaskStatus::getIssuanceRealizationPbg()).") THEN ptr.nilai_retribusi_bangunan ELSE 0 END) AS issuance_realization_pbg_total,
|
SUM(CASE WHEN pbg_task.status in (".implode(',', PbgTaskStatus::getIssuanceRealizationPbg()).") THEN COALESCE(ptr.nilai_retribusi_bangunan, 0) ELSE 0 END) AS issuance_realization_pbg_total,
|
||||||
SUM(CASE WHEN pbg_task.status in (".implode(',', PbgTaskStatus::getProcessInTechnicalOffice()).") THEN ptr.nilai_retribusi_bangunan ELSE 0 END) AS process_in_technical_office_total,
|
SUM(CASE WHEN pbg_task.status in (".implode(',', PbgTaskStatus::getProcessInTechnicalOffice()).") THEN COALESCE(ptr.nilai_retribusi_bangunan, 0) ELSE 0 END) AS process_in_technical_office_total,
|
||||||
SUM(CASE WHEN pbg_task.status in (".implode(',', PbgTaskStatus::getPotention()).") THEN ptr.nilai_retribusi_bangunan ELSE 0 END) AS potention_total
|
SUM(CASE WHEN pbg_task.status in (".implode(',', PbgTaskStatus::getPotention()).") THEN COALESCE(ptr.nilai_retribusi_bangunan, 0) ELSE 0 END) AS potention_total,
|
||||||
|
COUNT(CASE WHEN pbg_task.status in (".implode(',', PbgTaskStatus::getNonVerified()).") THEN 1 END) AS non_verified_tasks_count,
|
||||||
|
COUNT(CASE WHEN pbg_task.status in (".implode(',', PbgTaskStatus::getNonVerified()).") AND ptr.nilai_retribusi_bangunan IS NOT NULL THEN 1 END) AS non_verified_with_retribution_count
|
||||||
")
|
")
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
|
\Log::info('Stats calculation result', [
|
||||||
|
'non_verified_total' => $stats->non_verified_total ?? 'NULL',
|
||||||
|
'non_verified_tasks_count' => $stats->non_verified_tasks_count ?? 'NULL',
|
||||||
|
'non_verified_with_retribution_count' => $stats->non_verified_with_retribution_count ?? 'NULL'
|
||||||
|
]);
|
||||||
|
|
||||||
$service_google_sheet = app(ServiceGoogleSheet::class);
|
$service_google_sheet = app(ServiceGoogleSheet::class);
|
||||||
|
|
||||||
return self::create([
|
return self::create([
|
||||||
@@ -305,9 +334,9 @@ class BigdataResume extends Model
|
|||||||
'process_in_technical_office_sum' => $stats->process_in_technical_office_total ?? 0.00,
|
'process_in_technical_office_sum' => $stats->process_in_technical_office_total ?? 0.00,
|
||||||
'business_rab_count' => $business_rab_count,
|
'business_rab_count' => $business_rab_count,
|
||||||
'business_krk_count' => $business_krk_count,
|
'business_krk_count' => $business_krk_count,
|
||||||
|
'business_dlh_count' => $business_dlh_count,
|
||||||
'non_business_rab_count' => $non_business_rab_count,
|
'non_business_rab_count' => $non_business_rab_count,
|
||||||
'non_business_krk_count' => $non_business_krk_count,
|
'non_business_krk_count' => $non_business_krk_count,
|
||||||
'non_business_dlh_count' => $non_business_dlh_count,
|
|
||||||
'resume_type' => $resume_type,
|
'resume_type' => $resume_type,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ class PbgTask extends Model
|
|||||||
'consultation_type',
|
'consultation_type',
|
||||||
'due_date',
|
'due_date',
|
||||||
'land_certificate_phase',
|
'land_certificate_phase',
|
||||||
'task_created_at'
|
'task_created_at',
|
||||||
|
'is_valid'
|
||||||
];
|
];
|
||||||
|
|
||||||
public function pbg_task_retributions(){
|
public function pbg_task_retributions(){
|
||||||
|
|||||||
@@ -143,54 +143,208 @@ class PbgTaskDetail extends Model
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to clean and convert latitude/longitude values
|
||||||
|
*/
|
||||||
|
private static function cleanCoordinate($value): ?float
|
||||||
|
{
|
||||||
|
if ($value === null || $value === '' || $value === '?' || $value === '-') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert to string and trim whitespace
|
||||||
|
$stringValue = trim((string) $value);
|
||||||
|
|
||||||
|
// Check for common invalid values
|
||||||
|
if (in_array($stringValue, ['', '?', '-', 'null', 'NULL', 'N/A', '0,'], true)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove degree symbol and other non-numeric characters except minus and decimal point
|
||||||
|
$cleaned = preg_replace('/[^\d.-]/', '', $stringValue);
|
||||||
|
|
||||||
|
// Check if cleaned value is empty or just a hyphen
|
||||||
|
if ($cleaned === '' || $cleaned === '-' || $cleaned === '.') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate if it's a valid number and within reasonable coordinate bounds
|
||||||
|
if (is_numeric($cleaned)) {
|
||||||
|
$coordinate = (float) $cleaned;
|
||||||
|
|
||||||
|
// Basic validation for reasonable coordinate ranges
|
||||||
|
// Latitude: -90 to 90, Longitude: -180 to 180
|
||||||
|
if ($coordinate >= -180 && $coordinate <= 180) {
|
||||||
|
return $coordinate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to clean and convert integer values
|
||||||
|
*/
|
||||||
|
private static function cleanIntegerValue($value): int
|
||||||
|
{
|
||||||
|
if ($value === null || $value === '' || $value === '?') {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert to string and trim whitespace
|
||||||
|
$stringValue = trim((string) $value);
|
||||||
|
|
||||||
|
// Check for common invalid values
|
||||||
|
if (in_array($stringValue, ['', '?', '-', 'null', 'NULL', 'N/A'], true)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove any non-numeric characters except minus
|
||||||
|
$cleaned = preg_replace('/[^\d-]/', '', $stringValue);
|
||||||
|
|
||||||
|
// Check if cleaned value is empty or just invalid characters
|
||||||
|
if ($cleaned === '' || $cleaned === '-') {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate if it's a valid number
|
||||||
|
if (is_numeric($cleaned)) {
|
||||||
|
return (int) $cleaned;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to clean and convert numeric values
|
||||||
|
*/
|
||||||
|
private static function cleanNumericValue($value, bool $nullable = false): ?float
|
||||||
|
{
|
||||||
|
if ($value === null || $value === '' || $value === '?') {
|
||||||
|
return $nullable ? null : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert to string and trim whitespace
|
||||||
|
$stringValue = trim((string) $value);
|
||||||
|
|
||||||
|
// Check for common invalid values
|
||||||
|
if (in_array($stringValue, ['', '?', '-', 'null', 'NULL', 'N/A'], true)) {
|
||||||
|
return $nullable ? null : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove any non-numeric characters except minus and decimal point
|
||||||
|
$cleaned = preg_replace('/[^\d.-]/', '', $stringValue);
|
||||||
|
|
||||||
|
// Check if cleaned value is empty or just invalid characters
|
||||||
|
if ($cleaned === '' || $cleaned === '-' || $cleaned === '.') {
|
||||||
|
return $nullable ? null : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate if it's a valid number
|
||||||
|
if (is_numeric($cleaned)) {
|
||||||
|
return (float) $cleaned;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $nullable ? null : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to handle date parsing with fallback
|
||||||
|
*/
|
||||||
|
private static function parseDate($date): ?string
|
||||||
|
{
|
||||||
|
if (!$date || $date === '?' || $date === 'null') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return Carbon::parse($date)->format('Y-m-d');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to handle datetime parsing with fallback
|
||||||
|
*/
|
||||||
|
private static function parseDateTime($datetime): ?string
|
||||||
|
{
|
||||||
|
if (!$datetime || $datetime === '?' || $datetime === 'null') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return Carbon::parse($datetime)->format('Y-m-d H:i:s');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create or update PbgTaskDetail from API response
|
* Create or update PbgTaskDetail from API response
|
||||||
*/
|
*/
|
||||||
public static function createFromApiResponse(array $data, string $pbgTaskUuid): self
|
public static function createFromApiResponse(array $data, string $pbgTaskUuid): self
|
||||||
{
|
{
|
||||||
$detailData = [
|
$detailData = [
|
||||||
|
// Foreign key relationship - string, required
|
||||||
'pbg_task_uid' => $pbgTaskUuid,
|
'pbg_task_uid' => $pbgTaskUuid,
|
||||||
'uid' => $data['uid'] ?? null,
|
|
||||||
'nik' => $data['nik'] ?? null,
|
// Basic information
|
||||||
'type_card' => $data['type_card'] ?? null,
|
'uid' => $data['uid'] ?? "N/A", // string, unique, required
|
||||||
'ownership' => $data['ownership'] ?? null,
|
'nik' => isset($data['nik']) && $data['nik'] !== '' && $data['nik'] !== '?' ? $data['nik'] : null, // string, nullable
|
||||||
'owner_name' => $data['owner_name'] ?? null,
|
'type_card' => isset($data['type_card']) && $data['type_card'] !== '' && $data['type_card'] !== '?' ? $data['type_card'] : null, // string, nullable
|
||||||
'ward_id' => $data['ward_id'] ?? null,
|
'ownership' => $data['ownership'] ?? null, // string, nullable
|
||||||
'ward_name' => $data['ward_name'] ?? null,
|
'owner_name' => $data['owner_name'] ?? "N/A", // string, required
|
||||||
'district_id' => $data['district_id'] ?? null,
|
|
||||||
'district_name' => $data['district_name'] ?? null,
|
// Owner location information - all required
|
||||||
'regency_id' => $data['regency_id'] ?? null,
|
'ward_id' => self::cleanIntegerValue($data['ward_id'] ?? 0), // bigInteger, required
|
||||||
'regency_name' => $data['regency_name'] ?? null,
|
'ward_name' => $data['ward_name'] ?? "N/A", // string, required
|
||||||
'province_id' => $data['province_id'] ?? null,
|
'district_id' => self::cleanIntegerValue($data['district_id'] ?? 0), // integer, required
|
||||||
'province_name' => $data['province_name'] ?? null,
|
'district_name' => $data['district_name'] ?? "N/A", // string, required
|
||||||
'address' => $data['address'] ?? null,
|
'regency_id' => self::cleanIntegerValue($data['regency_id'] ?? 0), // integer, required
|
||||||
'owner_email' => $data['owner_email'] ?? null,
|
'regency_name' => $data['regency_name'] ?? "N/A", // string, required
|
||||||
'owner_phone' => $data['owner_phone'] ?? null,
|
'province_id' => self::cleanIntegerValue($data['province_id'] ?? 0), // integer, required
|
||||||
'user' => $data['user'] ?? null,
|
'province_name' => $data['province_name'] ?? "N/A", // string, required
|
||||||
'name' => $data['name'] ?? null,
|
'address' => $data['address'] ?? "N/A", // text, required
|
||||||
'email' => $data['email'] ?? null,
|
|
||||||
'phone' => $data['phone'] ?? null,
|
// Owner contact information - required
|
||||||
'user_nik' => $data['user_nik'] ?? null,
|
'owner_email' => $data['owner_email'] ?? "N/A", // string, required
|
||||||
'user_province_id' => $data['user_province_id'] ?? null,
|
'owner_phone' => $data['owner_phone'] ?? "N/A", // string, required
|
||||||
'user_province_name' => $data['user_province_name'] ?? null,
|
|
||||||
'user_regency_id' => $data['user_regency_id'] ?? null,
|
// User information - all required
|
||||||
'user_regency_name' => $data['user_regency_name'] ?? null,
|
'user' => self::cleanIntegerValue($data['user'] ?? 0), // integer, required
|
||||||
'user_district_id' => $data['user_district_id'] ?? null,
|
'name' => $data['name'] ?? "N/A", // string, required
|
||||||
'user_district_name' => $data['user_district_name'] ?? null,
|
'email' => $data['email'] ?? "N/A", // string, required
|
||||||
'user_address' => $data['user_address'] ?? null,
|
'phone' => $data['phone'] ?? "N/A", // string, required
|
||||||
'status' => $data['status'] ?? null,
|
'user_nik' => $data['user_nik'] ?? "N/A", // string, required
|
||||||
'status_name' => $data['status_name'] ?? null,
|
|
||||||
'slf_status' => $data['slf_status'] ?? null,
|
// User location information - all required
|
||||||
'slf_status_name' => $data['slf_status_name'] ?? null,
|
'user_province_id' => self::cleanIntegerValue($data['user_province_id'] ?? 0), // integer, required
|
||||||
'sppst_status' => $data['sppst_status'] ?? null,
|
'user_province_name' => $data['user_province_name'] ?? "N/A", // string, required
|
||||||
'sppst_file' => $data['sppst_file'] ?? null,
|
'user_regency_id' => self::cleanIntegerValue($data['user_regency_id'] ?? 0), // integer, required
|
||||||
'sppst_status_name' => $data['sppst_status_name'] ?? null,
|
'user_regency_name' => $data['user_regency_name'] ?? "N/A", // string, required
|
||||||
'file_pbg' => $data['file_pbg'] ?? null,
|
'user_district_id' => self::cleanIntegerValue($data['user_district_id'] ?? 0), // integer, required
|
||||||
'file_pbg_date' => isset($data['file_pbg_date']) ? Carbon::parse($data['file_pbg_date'])->format('Y-m-d') : null,
|
'user_district_name' => $data['user_district_name'] ?? "N/A", // string, required
|
||||||
'due_date' => isset($data['due_date']) ? Carbon::parse($data['due_date'])->format('Y-m-d') : null,
|
'user_address' => $data['user_address'] ?? "N/A", // text, required
|
||||||
'start_date' => isset($data['start_date']) ? Carbon::parse($data['start_date'])->format('Y-m-d') : null,
|
|
||||||
'document_number' => $data['document_number'] ?? null,
|
// Status information
|
||||||
'registration_number' => $data['registration_number'] ?? null,
|
'status' => self::cleanIntegerValue($data['status'] ?? 0), // integer, required
|
||||||
|
'status_name' => $data['status_name'] ?? "N/A", // string, required
|
||||||
|
'slf_status' => isset($data['slf_status']) && is_numeric($data['slf_status']) ? (int) $data['slf_status'] : null, // integer, nullable
|
||||||
|
'slf_status_name' => $data['slf_status_name'] ?? null, // string, nullable
|
||||||
|
'sppst_status' => self::cleanIntegerValue($data['sppst_status'] ?? 0), // integer, required
|
||||||
|
'sppst_file' => $data['sppst_file'] ?? null, // string, nullable
|
||||||
|
'sppst_status_name' => $data['sppst_status_name'] ?? "N/A", // string, required
|
||||||
|
|
||||||
|
// Files and documents
|
||||||
|
'file_pbg' => $data['file_pbg'] ?? null, // string, nullable
|
||||||
|
'file_pbg_date' => self::parseDate($data['file_pbg_date'] ?? null), // date, nullable
|
||||||
|
'due_date' => self::parseDate($data['due_date'] ?? null), // date, nullable
|
||||||
|
'start_date' => self::parseDate($data['start_date'] ?? null) ?? now()->format('Y-m-d'), // date, required
|
||||||
|
'document_number' => $data['document_number'] ?? null, // string, nullable
|
||||||
|
'registration_number' => $data['registration_number'] ?? "N/A", // string, required
|
||||||
|
|
||||||
|
// Application information - all nullable
|
||||||
'function_type' => $data['function_type'] ?? null,
|
'function_type' => $data['function_type'] ?? null,
|
||||||
'application_type' => $data['application_type'] ?? null,
|
'application_type' => $data['application_type'] ?? null,
|
||||||
'application_type_name' => $data['application_type_name'] ?? null,
|
'application_type_name' => $data['application_type_name'] ?? null,
|
||||||
@@ -198,52 +352,74 @@ class PbgTaskDetail extends Model
|
|||||||
'condition' => $data['condition'] ?? null,
|
'condition' => $data['condition'] ?? null,
|
||||||
'prototype' => $data['prototype'] ?? null,
|
'prototype' => $data['prototype'] ?? null,
|
||||||
'permanency' => $data['permanency'] ?? null,
|
'permanency' => $data['permanency'] ?? null,
|
||||||
'building_type' => $data['building_type'] ?? null,
|
|
||||||
|
// Building information - all nullable
|
||||||
|
'building_type' => isset($data['building_type']) && is_numeric($data['building_type']) ? (int) $data['building_type'] : null, // integer, nullable
|
||||||
'building_type_name' => $data['building_type_name'] ?? null,
|
'building_type_name' => $data['building_type_name'] ?? null,
|
||||||
'building_purpose' => $data['building_purpose'] ?? null,
|
'building_purpose' => $data['building_purpose'] ?? null,
|
||||||
'building_use' => $data['building_use'] ?? null,
|
'building_use' => $data['building_use'] ?? null,
|
||||||
'occupancy' => $data['occupancy'] ?? null,
|
'occupancy' => $data['occupancy'] ?? null,
|
||||||
'name_building' => $data['name_building'] ?? null,
|
'name_building' => $data['name_building'] ?? null,
|
||||||
'total_area' => $data['total_area'] ?? null,
|
|
||||||
'area' => $data['area'] ?? null,
|
// Building dimensions and specifications
|
||||||
'area_type' => $data['area_type'] ?? null,
|
'total_area' => self::cleanNumericValue($data['total_area'] ?? 0), // decimal(10,2), required
|
||||||
'height' => $data['height'] ?? null,
|
'area' => self::cleanNumericValue($data['area'] ?? null, true), // decimal(10,2), nullable
|
||||||
'floor' => $data['floor'] ?? null,
|
'area_type' => $data['area_type'] ?? null, // string, nullable
|
||||||
'floor_area' => $data['floor_area'] ?? 0,
|
'height' => self::cleanNumericValue($data['height'] ?? 0), // decimal(8,2), required
|
||||||
'basement' => $data['basement'] ?? null,
|
'floor' => self::cleanIntegerValue($data['floor'] ?? 0), // integer, required
|
||||||
'basement_height' => $data['basement_height'] ?? 0,
|
'floor_area' => self::cleanNumericValue($data['floor_area'] ?? null, true), // decimal(10,2), nullable
|
||||||
'basement_area' => $data['basement_area'] ?? 0,
|
'basement' => isset($data['basement']) && $data['basement'] !== '' && $data['basement'] !== '?' ? $data['basement'] : null, // string, nullable
|
||||||
'unit' => $data['unit'] ?? null,
|
'basement_height' => self::cleanNumericValue($data['basement_height'] ?? null, true), // decimal(8,2), nullable
|
||||||
'prev_retribution' => $data['prev_retribution'] ?? 0,
|
'basement_area' => self::cleanNumericValue($data['basement_area'] ?? 0), // decimal(10,2), required
|
||||||
'prev_pbg' => $data['prev_pbg'] ?? null,
|
'unit' => isset($data['unit']) && is_numeric($data['unit']) ? (int) $data['unit'] : null, // integer, nullable
|
||||||
'prev_total_area' => $data['prev_total_area'] ?? 0,
|
|
||||||
'koefisien_dasar_bangunan' => $data['koefisien_dasar_bangunan'] ?? 0,
|
// Previous information
|
||||||
'koefisien_lantai_bangunan' => $data['koefisien_lantai_bangunan'] ?? 0,
|
'prev_retribution' => self::cleanNumericValue($data['prev_retribution'] ?? null, true), // decimal(15,2), nullable
|
||||||
'koefisien_lantai_hijau' => $data['koefisien_lantai_hijau'] ?? 0,
|
'prev_pbg' => $data['prev_pbg'] ?? null, // string, nullable
|
||||||
'koefisien_tapak_basement' => $data['koefisien_tapak_basement'] ?? 0,
|
'prev_total_area' => self::cleanNumericValue($data['prev_total_area'] ?? null, true), // decimal(10,2), nullable
|
||||||
'ketinggian_bangunan' => $data['ketinggian_bangunan'] ?? 0,
|
|
||||||
|
// Coefficients - all nullable, decimal(8,4)
|
||||||
|
'koefisien_dasar_bangunan' => self::cleanNumericValue($data['koefisien_dasar_bangunan'] ?? null, true),
|
||||||
|
'koefisien_lantai_bangunan' => self::cleanNumericValue($data['koefisien_lantai_bangunan'] ?? null, true),
|
||||||
|
'koefisien_lantai_hijau' => self::cleanNumericValue($data['koefisien_lantai_hijau'] ?? null, true),
|
||||||
|
'koefisien_tapak_basement' => self::cleanNumericValue($data['koefisien_tapak_basement'] ?? null, true),
|
||||||
|
'ketinggian_bangunan' => self::cleanNumericValue($data['ketinggian_bangunan'] ?? null, true), // decimal(8,2), nullable
|
||||||
|
|
||||||
|
// Road information - all nullable
|
||||||
'jalan_arteri' => $data['jalan_arteri'] ?? null,
|
'jalan_arteri' => $data['jalan_arteri'] ?? null,
|
||||||
'jalan_kolektor' => $data['jalan_kolektor'] ?? null,
|
'jalan_kolektor' => $data['jalan_kolektor'] ?? null,
|
||||||
'jalan_bangunan' => $data['jalan_bangunan'] ?? null,
|
'jalan_bangunan' => $data['jalan_bangunan'] ?? null,
|
||||||
'gsb' => $data['gsb'] ?? null,
|
'gsb' => self::cleanNumericValue($data['gsb'] ?? null, true), // decimal(8,2), nullable
|
||||||
'kkr_number' => $data['kkr_number'] ?? null,
|
'kkr_number' => $data['kkr_number'] ?? null, // string, nullable
|
||||||
|
|
||||||
|
// Unit data as JSON - nullable
|
||||||
'unit_data' => $data['unit_data'] ?? null,
|
'unit_data' => $data['unit_data'] ?? null,
|
||||||
'is_mbr' => $data['is_mbr'] ?? false,
|
|
||||||
'code' => $data['code'] ?? null,
|
// Additional flags
|
||||||
'building_ward_id' => $data['building_ward_id'] ?? null,
|
'is_mbr' => (bool) ($data['is_mbr'] ?? false), // boolean, default false
|
||||||
'building_ward_name' => $data['building_ward_name'] ?? null,
|
'code' => $data['code'] ?? "N/A", // string, required
|
||||||
'building_district_id' => $data['building_district_id'] ?? null,
|
|
||||||
'building_district_name' => $data['building_district_name'] ?? null,
|
// Building location information - all required
|
||||||
'building_regency_id' => $data['building_regency_id'] ?? null,
|
'building_ward_id' => self::cleanIntegerValue($data['building_ward_id'] ?? 0), // bigInteger, required
|
||||||
'building_regency_name' => $data['building_regency_name'] ?? null,
|
'building_ward_name' => $data['building_ward_name'] ?? "N/A", // string, required
|
||||||
'building_province_id' => $data['building_province_id'] ?? null,
|
'building_district_id' => self::cleanIntegerValue($data['building_district_id'] ?? 0), // integer, required
|
||||||
'building_province_name' => $data['building_province_name'] ?? null,
|
'building_district_name' => $data['building_district_name'] ?? "N/A", // string, required
|
||||||
'building_address' => $data['building_address'] ?? null,
|
'building_regency_id' => self::cleanIntegerValue($data['building_regency_id'] ?? 0), // integer, required
|
||||||
'latitude' => $data['latitude'] ?? null,
|
'building_regency_name' => $data['building_regency_name'] ?? "N/A", // string, required
|
||||||
'longitude' => $data['longitude'] ?? null,
|
'building_province_id' => self::cleanIntegerValue($data['building_province_id'] ?? 0), // integer, required
|
||||||
|
'building_province_name' => $data['building_province_name'] ?? "N/A", // string, required
|
||||||
|
'building_address' => $data['building_address'] ?? "N/A", // text, required
|
||||||
|
|
||||||
|
// Coordinates - decimal(15,8), nullable
|
||||||
|
'latitude' => self::cleanCoordinate($data['latitude'] ?? null),
|
||||||
|
'longitude' => self::cleanCoordinate($data['longitude'] ?? null),
|
||||||
|
|
||||||
|
// Additional files - nullable
|
||||||
'building_photo' => $data['building_photo'] ?? null,
|
'building_photo' => $data['building_photo'] ?? null,
|
||||||
'pbg_parent' => $data['pbg_parent'] ?? null,
|
'pbg_parent' => $data['pbg_parent'] ?? null,
|
||||||
'api_created_at' => isset($data['created_at']) ? Carbon::parse($data['created_at'])->format('Y-m-d H:i:s') : null,
|
|
||||||
|
// Original created_at from API - nullable
|
||||||
|
'api_created_at' => self::parseDateTime($data['created_at'] ?? null),
|
||||||
];
|
];
|
||||||
|
|
||||||
return static::updateOrCreate(
|
return static::updateOrCreate(
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('pbg_task', function (Blueprint $table) {
|
||||||
|
$table->boolean('is_valid')->default(true)->after('status');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('pbg_task', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('is_valid');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('bigdata_resumes', function (Blueprint $table) {
|
||||||
|
$table->renameColumn('non_business_dlh_count', 'business_dlh_count');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('bigdata_resumes', function (Blueprint $table) {
|
||||||
|
$table->renameColumn('business_dlh_count', 'non_business_dlh_count');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -3,6 +3,21 @@ import GlobalConfig, { addThousandSeparators } from "../global-config.js";
|
|||||||
import InitDatePicker from "../utils/InitDatePicker.js";
|
import InitDatePicker from "../utils/InitDatePicker.js";
|
||||||
|
|
||||||
class BigData {
|
class BigData {
|
||||||
|
// Helper function to safely access nested object properties with default values
|
||||||
|
safeGet(obj, path, defaultValue = 0) {
|
||||||
|
try {
|
||||||
|
return path.split(".").reduce((current, key) => {
|
||||||
|
return current &&
|
||||||
|
current[key] !== null &&
|
||||||
|
current[key] !== undefined
|
||||||
|
? current[key]
|
||||||
|
: defaultValue;
|
||||||
|
}, obj);
|
||||||
|
} catch (error) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
try {
|
try {
|
||||||
new InitDatePicker(
|
new InitDatePicker(
|
||||||
@@ -25,6 +40,14 @@ class BigData {
|
|||||||
try {
|
try {
|
||||||
this.resumeBigData = await this.getBigDataResume(filterDate);
|
this.resumeBigData = await this.getBigDataResume(filterDate);
|
||||||
|
|
||||||
|
// Ensure resumeBigData is not null/undefined
|
||||||
|
if (!this.resumeBigData) {
|
||||||
|
this.resumeBigData = {};
|
||||||
|
console.warn(
|
||||||
|
"No data received, using empty object with default values"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
this.initChartTargetPAD(filterDate);
|
this.initChartTargetPAD(filterDate);
|
||||||
this.initChartUsaha();
|
this.initChartUsaha();
|
||||||
this.initChartNonUsaha();
|
this.initChartNonUsaha();
|
||||||
@@ -43,6 +66,8 @@ class BigData {
|
|||||||
this.initChartNonBusinessDLH();
|
this.initChartNonBusinessDLH();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
// Initialize with empty data if there's an error
|
||||||
|
this.resumeBigData = {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,14 +117,24 @@ class BigData {
|
|||||||
document
|
document
|
||||||
.querySelectorAll(".document-total.chart-target-pad")
|
.querySelectorAll(".document-total.chart-target-pad")
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
|
const sum = this.safeGet(
|
||||||
|
this.resumeBigData,
|
||||||
|
"target_pad.sum",
|
||||||
|
0
|
||||||
|
);
|
||||||
element.innerText = `Rp.${addThousandSeparators(
|
element.innerText = `Rp.${addThousandSeparators(
|
||||||
this.resumeBigData.target_pad.sum.toString()
|
sum.toString()
|
||||||
)}`;
|
)}`;
|
||||||
});
|
});
|
||||||
document
|
document
|
||||||
.querySelectorAll(".small-percentage.chart-target-pad")
|
.querySelectorAll(".small-percentage.chart-target-pad")
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
element.innerText = `${this.resumeBigData.target_pad.percentage}%`;
|
const percentage = this.safeGet(
|
||||||
|
this.resumeBigData,
|
||||||
|
"target_pad.percentage",
|
||||||
|
0
|
||||||
|
);
|
||||||
|
element.innerText = `${percentage}%`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
initChartTotalPotensi() {
|
initChartTotalPotensi() {
|
||||||
@@ -108,44 +143,68 @@ class BigData {
|
|||||||
document
|
document
|
||||||
.querySelectorAll(".document-count.chart-total-potensi")
|
.querySelectorAll(".document-count.chart-total-potensi")
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
// element.innerText = `${countAll}`;
|
const count = this.safeGet(
|
||||||
element.innerText = `${this.resumeBigData.total_potensi.count}`;
|
this.resumeBigData,
|
||||||
|
"total_potensi.count",
|
||||||
|
0
|
||||||
|
);
|
||||||
|
element.innerText = `${count}`;
|
||||||
});
|
});
|
||||||
document
|
document
|
||||||
.querySelectorAll(".document-total.chart-total-potensi")
|
.querySelectorAll(".document-total.chart-total-potensi")
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
|
const sum = this.safeGet(
|
||||||
|
this.resumeBigData,
|
||||||
|
"total_potensi.sum",
|
||||||
|
0
|
||||||
|
);
|
||||||
element.innerText = `Rp.${addThousandSeparators(
|
element.innerText = `Rp.${addThousandSeparators(
|
||||||
// this.bigTotalPotensi.toString()
|
sum.toString()
|
||||||
this.resumeBigData.total_potensi.sum.toString()
|
|
||||||
)}`;
|
)}`;
|
||||||
});
|
});
|
||||||
document
|
document
|
||||||
.querySelectorAll(".small-percentage.chart-total-potensi")
|
.querySelectorAll(".small-percentage.chart-total-potensi")
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
// element.innerText = `${this.resultPercentage}%`;
|
const percentage = this.safeGet(
|
||||||
element.innerText = `${this.resumeBigData.total_potensi.percentage}%`;
|
this.resumeBigData,
|
||||||
|
"total_potensi.percentage",
|
||||||
|
0
|
||||||
|
);
|
||||||
|
element.innerText = `${percentage}%`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
initChartVerificationDocuments() {
|
initChartVerificationDocuments() {
|
||||||
document
|
document
|
||||||
.querySelectorAll(".document-count.chart-berkas-terverifikasi")
|
.querySelectorAll(".document-count.chart-berkas-terverifikasi")
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
// element.innerText = `${this.dataVerification.count}`;
|
const count = this.safeGet(
|
||||||
element.innerText = `${this.resumeBigData.verified_document.count}`;
|
this.resumeBigData,
|
||||||
|
"verified_document.count",
|
||||||
|
0
|
||||||
|
);
|
||||||
|
element.innerText = `${count}`;
|
||||||
});
|
});
|
||||||
document
|
document
|
||||||
.querySelectorAll(".document-total.chart-berkas-terverifikasi")
|
.querySelectorAll(".document-total.chart-berkas-terverifikasi")
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
|
const sum = this.safeGet(
|
||||||
|
this.resumeBigData,
|
||||||
|
"verified_document.sum",
|
||||||
|
0
|
||||||
|
);
|
||||||
element.innerText = `Rp.${addThousandSeparators(
|
element.innerText = `Rp.${addThousandSeparators(
|
||||||
// this.bigTotalVerification.toString()
|
sum.toString()
|
||||||
this.resumeBigData.verified_document.sum.toString()
|
|
||||||
)}`;
|
)}`;
|
||||||
});
|
});
|
||||||
document
|
document
|
||||||
.querySelectorAll(".small-percentage.chart-berkas-terverifikasi")
|
.querySelectorAll(".small-percentage.chart-berkas-terverifikasi")
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
// element.innerText = `${this.percetageResultVerification}%`;
|
const percentage = this.safeGet(
|
||||||
element.innerText = `${this.resumeBigData.verified_document.percentage}%`;
|
this.resumeBigData,
|
||||||
|
"verified_document.percentage",
|
||||||
|
0
|
||||||
|
);
|
||||||
|
element.innerText = `${percentage}%`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
initChartNonVerificationDocuments() {
|
initChartNonVerificationDocuments() {
|
||||||
@@ -154,17 +213,25 @@ class BigData {
|
|||||||
".document-count.chart-berkas-belum-terverifikasi"
|
".document-count.chart-berkas-belum-terverifikasi"
|
||||||
)
|
)
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
// element.innerText = `${this.dataNonVerification.count}`;
|
const count = this.safeGet(
|
||||||
element.innerText = `${this.resumeBigData.non_verified_document.count}`;
|
this.resumeBigData,
|
||||||
|
"non_verified_document.count",
|
||||||
|
0
|
||||||
|
);
|
||||||
|
element.innerText = `${count}`;
|
||||||
});
|
});
|
||||||
document
|
document
|
||||||
.querySelectorAll(
|
.querySelectorAll(
|
||||||
".document-total.chart-berkas-belum-terverifikasi"
|
".document-total.chart-berkas-belum-terverifikasi"
|
||||||
)
|
)
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
|
const sum = this.safeGet(
|
||||||
|
this.resumeBigData,
|
||||||
|
"non_verified_document.sum",
|
||||||
|
0
|
||||||
|
);
|
||||||
element.innerText = `Rp.${addThousandSeparators(
|
element.innerText = `Rp.${addThousandSeparators(
|
||||||
// this.bigTotalNonVerification.toString()
|
sum.toString()
|
||||||
this.resumeBigData.non_verified_document.sum.toString()
|
|
||||||
)}`;
|
)}`;
|
||||||
});
|
});
|
||||||
document
|
document
|
||||||
@@ -172,52 +239,80 @@ class BigData {
|
|||||||
".small-percentage.chart-berkas-belum-terverifikasi"
|
".small-percentage.chart-berkas-belum-terverifikasi"
|
||||||
)
|
)
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
// element.innerText = `${this.percentageResultNonVerification}%`;
|
const percentage = this.safeGet(
|
||||||
element.innerText = `${this.resumeBigData.non_verified_document.percentage}%`;
|
this.resumeBigData,
|
||||||
|
"non_verified_document.percentage",
|
||||||
|
0
|
||||||
|
);
|
||||||
|
element.innerText = `${percentage}%`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
initChartUsaha() {
|
initChartUsaha() {
|
||||||
document
|
document
|
||||||
.querySelectorAll(".document-count.chart-business")
|
.querySelectorAll(".document-count.chart-business")
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
// element.innerText = `${this.dataBusiness.count}`;
|
const count = this.safeGet(
|
||||||
element.innerText = `${this.resumeBigData.business_document.count}`;
|
this.resumeBigData,
|
||||||
|
"business_document.count",
|
||||||
|
0
|
||||||
|
);
|
||||||
|
element.innerText = `${count}`;
|
||||||
});
|
});
|
||||||
document
|
document
|
||||||
.querySelectorAll(".document-total.chart-business")
|
.querySelectorAll(".document-total.chart-business")
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
|
const sum = this.safeGet(
|
||||||
|
this.resumeBigData,
|
||||||
|
"business_document.sum",
|
||||||
|
0
|
||||||
|
);
|
||||||
element.innerText = `Rp.${addThousandSeparators(
|
element.innerText = `Rp.${addThousandSeparators(
|
||||||
// this.bigTotalBusiness.toString()
|
sum.toString()
|
||||||
this.resumeBigData.business_document.sum.toString()
|
|
||||||
)}`;
|
)}`;
|
||||||
});
|
});
|
||||||
document
|
document
|
||||||
.querySelectorAll(".small-percentage.chart-business")
|
.querySelectorAll(".small-percentage.chart-business")
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
// element.innerText = `${this.percentageResultBusiness}%`;
|
const percentage = this.safeGet(
|
||||||
element.innerText = `${this.resumeBigData.business_document.percentage}%`;
|
this.resumeBigData,
|
||||||
|
"business_document.percentage",
|
||||||
|
0
|
||||||
|
);
|
||||||
|
element.innerText = `${percentage}%`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
initChartNonUsaha() {
|
initChartNonUsaha() {
|
||||||
document
|
document
|
||||||
.querySelectorAll(".document-count.chart-non-business")
|
.querySelectorAll(".document-count.chart-non-business")
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
// element.innerText = `${this.dataNonBusiness.count}`;
|
const count = this.safeGet(
|
||||||
element.innerText = `${this.resumeBigData.non_business_document.count}`;
|
this.resumeBigData,
|
||||||
|
"non_business_document.count",
|
||||||
|
0
|
||||||
|
);
|
||||||
|
element.innerText = `${count}`;
|
||||||
});
|
});
|
||||||
document
|
document
|
||||||
.querySelectorAll(".document-total.chart-non-business")
|
.querySelectorAll(".document-total.chart-non-business")
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
|
const sum = this.safeGet(
|
||||||
|
this.resumeBigData,
|
||||||
|
"non_business_document.sum",
|
||||||
|
0
|
||||||
|
);
|
||||||
element.innerText = `Rp.${addThousandSeparators(
|
element.innerText = `Rp.${addThousandSeparators(
|
||||||
// this.bigTotalNonBusiness.toString()
|
sum.toString()
|
||||||
this.resumeBigData.non_business_document.sum.toString()
|
|
||||||
)}`;
|
)}`;
|
||||||
});
|
});
|
||||||
document
|
document
|
||||||
.querySelectorAll(".small-percentage.chart-non-business")
|
.querySelectorAll(".small-percentage.chart-non-business")
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
// element.innerText = `${this.percentageResultNonBusiness}%`;
|
const percentage = this.safeGet(
|
||||||
element.innerText = `${this.resumeBigData.non_business_document.percentage}%`;
|
this.resumeBigData,
|
||||||
|
"non_business_document.percentage",
|
||||||
|
0
|
||||||
|
);
|
||||||
|
element.innerText = `${percentage}%`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
initChartKekuranganPotensi() {
|
initChartKekuranganPotensi() {
|
||||||
@@ -229,129 +324,226 @@ class BigData {
|
|||||||
document
|
document
|
||||||
.querySelectorAll(".document-total.chart-kekurangan-potensi")
|
.querySelectorAll(".document-total.chart-kekurangan-potensi")
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
|
const sum = this.safeGet(
|
||||||
|
this.resumeBigData,
|
||||||
|
"kekurangan_potensi.sum",
|
||||||
|
0
|
||||||
|
);
|
||||||
element.innerText = `Rp.${addThousandSeparators(
|
element.innerText = `Rp.${addThousandSeparators(
|
||||||
// this.totalKekuranganPotensi.toString()
|
sum.toString()
|
||||||
this.resumeBigData.kekurangan_potensi.sum.toString()
|
|
||||||
)}`;
|
)}`;
|
||||||
});
|
});
|
||||||
document
|
document
|
||||||
.querySelectorAll(".small-percentage.chart-kekurangan-potensi")
|
.querySelectorAll(".small-percentage.chart-kekurangan-potensi")
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
// element.innerText = `${this.percentageKekuranganPotensi}%`;
|
const percentage = this.safeGet(
|
||||||
element.innerText = `${this.resumeBigData.kekurangan_potensi.percentage}%`;
|
this.resumeBigData,
|
||||||
|
"kekurangan_potensi.percentage",
|
||||||
|
0
|
||||||
|
);
|
||||||
|
element.innerText = `${percentage}%`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
initChartRealisasiTerbitPBG() {
|
initChartRealisasiTerbitPBG() {
|
||||||
document
|
document
|
||||||
.querySelectorAll(".document-count.chart-realisasi-tebit-pbg")
|
.querySelectorAll(".document-count.chart-realisasi-tebit-pbg")
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
// element.innerText = `${this.dataCountRealisasiTerbit}`;
|
const count = this.safeGet(
|
||||||
element.innerText = `${this.resumeBigData.realisasi_terbit.count}`;
|
this.resumeBigData,
|
||||||
|
"realisasi_terbit.count",
|
||||||
|
0
|
||||||
|
);
|
||||||
|
element.innerText = `${count}`;
|
||||||
});
|
});
|
||||||
document
|
document
|
||||||
.querySelectorAll(".document-total.chart-realisasi-tebit-pbg")
|
.querySelectorAll(".document-total.chart-realisasi-tebit-pbg")
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
|
const sum = this.safeGet(
|
||||||
|
this.resumeBigData,
|
||||||
|
"realisasi_terbit.sum",
|
||||||
|
0
|
||||||
|
);
|
||||||
element.innerText = `Rp.${addThousandSeparators(
|
element.innerText = `Rp.${addThousandSeparators(
|
||||||
// this.dataSumRealisasiTerbit
|
sum.toString()
|
||||||
this.resumeBigData.realisasi_terbit.sum.toString()
|
|
||||||
)}`;
|
)}`;
|
||||||
});
|
});
|
||||||
document
|
document
|
||||||
.querySelectorAll(".small-percentage.chart-realisasi-tebit-pbg")
|
.querySelectorAll(".small-percentage.chart-realisasi-tebit-pbg")
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
element.innerText = `${this.resumeBigData.realisasi_terbit.percentage}%`;
|
const percentage = this.safeGet(
|
||||||
|
this.resumeBigData,
|
||||||
|
"realisasi_terbit.percentage",
|
||||||
|
0
|
||||||
|
);
|
||||||
|
element.innerText = `${percentage}%`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
initChartMenungguKlikDPMPTSP() {
|
initChartMenungguKlikDPMPTSP() {
|
||||||
document
|
document
|
||||||
.querySelectorAll(".document-count.chart-menunggu-klik-dpmptsp")
|
.querySelectorAll(".document-count.chart-menunggu-klik-dpmptsp")
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
// element.innerText = `${this.dataCountMenungguKlikDPMPTSP}`;
|
const count = this.safeGet(
|
||||||
element.innerText = `${this.resumeBigData.menunggu_klik_dpmptsp.count}`;
|
this.resumeBigData,
|
||||||
|
"menunggu_klik_dpmptsp.count",
|
||||||
|
0
|
||||||
|
);
|
||||||
|
element.innerText = `${count}`;
|
||||||
});
|
});
|
||||||
document
|
document
|
||||||
.querySelectorAll(".document-total.chart-menunggu-klik-dpmptsp")
|
.querySelectorAll(".document-total.chart-menunggu-klik-dpmptsp")
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
|
const sum = this.safeGet(
|
||||||
|
this.resumeBigData,
|
||||||
|
"menunggu_klik_dpmptsp.sum",
|
||||||
|
0
|
||||||
|
);
|
||||||
element.innerText = `Rp.${addThousandSeparators(
|
element.innerText = `Rp.${addThousandSeparators(
|
||||||
// this.dataSumMenungguKlikDPMPTSP
|
sum.toString()
|
||||||
this.resumeBigData.menunggu_klik_dpmptsp.sum.toString()
|
|
||||||
)}`;
|
)}`;
|
||||||
});
|
});
|
||||||
document
|
document
|
||||||
.querySelectorAll(".small-percentage.chart-menunggu-klik-dpmptsp")
|
.querySelectorAll(".small-percentage.chart-menunggu-klik-dpmptsp")
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
element.innerText = `${this.resumeBigData.menunggu_klik_dpmptsp.percentage}%`;
|
const percentage = this.safeGet(
|
||||||
|
this.resumeBigData,
|
||||||
|
"menunggu_klik_dpmptsp.percentage",
|
||||||
|
0
|
||||||
|
);
|
||||||
|
element.innerText = `${percentage}%`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
initChartProsesDinasTeknis() {
|
initChartProsesDinasTeknis() {
|
||||||
document
|
document
|
||||||
.querySelectorAll(".document-count.chart-proses-dinas-teknis")
|
.querySelectorAll(".document-count.chart-proses-dinas-teknis")
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
// element.innerText = `${this.dataCountProsesDinasTeknis}`;
|
const count = this.safeGet(
|
||||||
element.innerText = `${this.resumeBigData.proses_dinas_teknis.count}`;
|
this.resumeBigData,
|
||||||
|
"proses_dinas_teknis.count",
|
||||||
|
0
|
||||||
|
);
|
||||||
|
element.innerText = `${count}`;
|
||||||
});
|
});
|
||||||
document
|
document
|
||||||
.querySelectorAll(".document-total.chart-proses-dinas-teknis")
|
.querySelectorAll(".document-total.chart-proses-dinas-teknis")
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
|
const sum = this.safeGet(
|
||||||
|
this.resumeBigData,
|
||||||
|
"proses_dinas_teknis.sum",
|
||||||
|
0
|
||||||
|
);
|
||||||
element.innerText = `Rp.${addThousandSeparators(
|
element.innerText = `Rp.${addThousandSeparators(
|
||||||
// this.dataSumProsesDinasTeknis
|
sum.toString()
|
||||||
this.resumeBigData.proses_dinas_teknis.sum.toString()
|
|
||||||
)}`;
|
)}`;
|
||||||
});
|
});
|
||||||
document
|
document
|
||||||
.querySelectorAll(".small-percentage.chart-proses-dinas-teknis")
|
.querySelectorAll(".small-percentage.chart-proses-dinas-teknis")
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
element.innerText = `${this.resumeBigData.proses_dinas_teknis.percentage}%`;
|
const percentage = this.safeGet(
|
||||||
|
this.resumeBigData,
|
||||||
|
"proses_dinas_teknis.percentage",
|
||||||
|
0
|
||||||
|
);
|
||||||
|
element.innerText = `${percentage}%`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
initChartPotensiTataRuang() {
|
initChartPotensiTataRuang() {
|
||||||
document
|
document
|
||||||
.querySelectorAll(".document-count.chart-potensi-tata-ruang")
|
.querySelectorAll(".document-count.chart-potensi-tata-ruang")
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
element.innerText = `${this.resumeBigData.tata_ruang.count}`;
|
const count = this.safeGet(
|
||||||
|
this.resumeBigData,
|
||||||
|
"tata_ruang.count",
|
||||||
|
0
|
||||||
|
);
|
||||||
|
element.innerText = `${count}`;
|
||||||
});
|
});
|
||||||
document
|
document
|
||||||
.querySelectorAll(".document-total.chart-potensi-tata-ruang")
|
.querySelectorAll(".document-total.chart-potensi-tata-ruang")
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
|
const sum = this.safeGet(
|
||||||
|
this.resumeBigData,
|
||||||
|
"tata_ruang.sum",
|
||||||
|
0
|
||||||
|
);
|
||||||
element.innerText = `Rp.${addThousandSeparators(
|
element.innerText = `Rp.${addThousandSeparators(
|
||||||
this.resumeBigData.tata_ruang.sum.toString()
|
sum.toString()
|
||||||
)}`;
|
)}`;
|
||||||
});
|
});
|
||||||
document
|
document
|
||||||
.querySelectorAll(".small-percentage.chart-potensi-tata-ruang")
|
.querySelectorAll(".small-percentage.chart-potensi-tata-ruang")
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
element.innerText = `${this.resumeBigData.tata_ruang.percentage}%`;
|
const percentage = this.safeGet(
|
||||||
|
this.resumeBigData,
|
||||||
|
"tata_ruang.percentage",
|
||||||
|
0
|
||||||
|
);
|
||||||
|
element.innerText = `${percentage}%`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
initChartBusinessRAB() {
|
initChartBusinessRAB() {
|
||||||
document.querySelectorAll("#business-rab-count").forEach((element) => {
|
document.querySelectorAll("#business-rab-count").forEach((element) => {
|
||||||
element.innerText = `${this.resumeBigData.business_rab_count}`;
|
const count = this.safeGet(
|
||||||
|
this.resumeBigData,
|
||||||
|
"business_rab_count",
|
||||||
|
0
|
||||||
|
);
|
||||||
|
element.innerText = `${count}`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
initChartBusinessKRK() {
|
initChartBusinessKRK() {
|
||||||
document.querySelectorAll("#business-krk-count").forEach((element) => {
|
document.querySelectorAll("#business-krk-count").forEach((element) => {
|
||||||
element.innerText = `${this.resumeBigData.business_krk_count}`;
|
const count = this.safeGet(
|
||||||
|
this.resumeBigData,
|
||||||
|
"business_krk_count",
|
||||||
|
0
|
||||||
|
);
|
||||||
|
element.innerText = `${count}`;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
initChartBusinessDLH() {
|
||||||
|
document.querySelectorAll("#business-dlh-count").forEach((element) => {
|
||||||
|
const count = this.safeGet(
|
||||||
|
this.resumeBigData,
|
||||||
|
"business_dlh_count",
|
||||||
|
0
|
||||||
|
);
|
||||||
|
element.innerText = `${count}`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
initChartNonBusinessRAB() {
|
initChartNonBusinessRAB() {
|
||||||
document
|
document
|
||||||
.querySelectorAll("#non-business-rab-count")
|
.querySelectorAll("#non-business-rab-count")
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
element.innerText = `${this.resumeBigData.non_business_rab_count}`;
|
const count = this.safeGet(
|
||||||
|
this.resumeBigData,
|
||||||
|
"non_business_rab_count",
|
||||||
|
0
|
||||||
|
);
|
||||||
|
element.innerText = `${count}`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
initChartNonBusinessKRK() {
|
initChartNonBusinessKRK() {
|
||||||
document
|
document
|
||||||
.querySelectorAll("#non-business-krk-count")
|
.querySelectorAll("#non-business-krk-count")
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
element.innerText = `${this.resumeBigData.non_business_krk_count}`;
|
const count = this.safeGet(
|
||||||
|
this.resumeBigData,
|
||||||
|
"non_business_krk_count",
|
||||||
|
0
|
||||||
|
);
|
||||||
|
element.innerText = `${count}`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
initChartNonBusinessDLH() {
|
initChartNonBusinessDLH() {
|
||||||
document
|
document
|
||||||
.querySelectorAll("#non-business-dlh-count")
|
.querySelectorAll("#non-business-dlh-count")
|
||||||
.forEach((element) => {
|
.forEach((element) => {
|
||||||
element.innerText = `${this.resumeBigData.non_business_dlh_count}`;
|
const count = this.safeGet(
|
||||||
|
this.resumeBigData,
|
||||||
|
"non_business_dlh_count",
|
||||||
|
0
|
||||||
|
);
|
||||||
|
element.innerText = `${count}`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ class PbgTaskAssignments {
|
|||||||
this.initTablePbgTaskAssignments();
|
this.initTablePbgTaskAssignments();
|
||||||
this.handleUpdateData();
|
this.handleUpdateData();
|
||||||
this.initDatePicker();
|
this.initDatePicker();
|
||||||
|
this.initIsValidToggle();
|
||||||
}
|
}
|
||||||
|
|
||||||
initDatePicker() {
|
initDatePicker() {
|
||||||
@@ -20,6 +21,30 @@ class PbgTaskAssignments {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initIsValidToggle() {
|
||||||
|
const checkbox = document.getElementById("is_valid");
|
||||||
|
const statusText = document.querySelector(".status-text");
|
||||||
|
const statusDescription = statusText?.nextElementSibling;
|
||||||
|
|
||||||
|
if (checkbox && statusText) {
|
||||||
|
checkbox.addEventListener("change", function () {
|
||||||
|
if (this.checked) {
|
||||||
|
statusText.textContent = "Data Valid";
|
||||||
|
if (statusDescription) {
|
||||||
|
statusDescription.textContent =
|
||||||
|
"Data telah diverifikasi dan sesuai";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
statusText.textContent = "Data Tidak Valid";
|
||||||
|
if (statusDescription) {
|
||||||
|
statusDescription.textContent =
|
||||||
|
"Data perlu diverifikasi atau diperbaiki";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
initTablePbgTaskAssignments() {
|
initTablePbgTaskAssignments() {
|
||||||
let tableContainer = document.getElementById(
|
let tableContainer = document.getElementById(
|
||||||
"table-pbg-task-assignments"
|
"table-pbg-task-assignments"
|
||||||
@@ -92,6 +117,12 @@ class PbgTaskAssignments {
|
|||||||
formData.forEach((value, key) => {
|
formData.forEach((value, key) => {
|
||||||
formObject[key] = value;
|
formObject[key] = value;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Handle checkbox properly - ensure boolean value is sent
|
||||||
|
const isValidCheckbox = document.getElementById("is_valid");
|
||||||
|
if (isValidCheckbox) {
|
||||||
|
formObject["is_valid"] = isValidCheckbox.checked ? 1 : 0;
|
||||||
|
}
|
||||||
fetch(form.action, {
|
fetch(form.action, {
|
||||||
method: "PUT", // Ensure your Laravel route is set to accept PUT requests
|
method: "PUT", // Ensure your Laravel route is set to accept PUT requests
|
||||||
body: JSON.stringify(formObject), // Convert form data to JSON
|
body: JSON.stringify(formObject), // Convert form data to JSON
|
||||||
|
|||||||
@@ -1,6 +1,102 @@
|
|||||||
// PBG Task Show Page Styles
|
// PBG Task Show Page Styles
|
||||||
// Custom styles for data lists display (List Layout)
|
// Custom styles for data lists display (List Layout)
|
||||||
|
|
||||||
|
// Enhanced checkbox styling for is_valid field
|
||||||
|
.form-check.form-switch {
|
||||||
|
padding-left: 0;
|
||||||
|
|
||||||
|
.form-check-input {
|
||||||
|
width: 3.25rem;
|
||||||
|
height: 1.75rem;
|
||||||
|
border-radius: 1rem;
|
||||||
|
background-color: #dc3545;
|
||||||
|
border: none;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-left: 0;
|
||||||
|
|
||||||
|
// Remove default browser styling
|
||||||
|
-webkit-appearance: none;
|
||||||
|
-moz-appearance: none;
|
||||||
|
appearance: none;
|
||||||
|
|
||||||
|
&:checked {
|
||||||
|
background-color: #28a745;
|
||||||
|
box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
box-shadow: 0 0 0 0.2rem rgba(93, 135, 255, 0.25);
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(:checked) {
|
||||||
|
background-color: #dc3545;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The toggle circle
|
||||||
|
&::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 0.125rem;
|
||||||
|
left: 0.125rem;
|
||||||
|
width: 1.5rem;
|
||||||
|
height: 1.5rem;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 50%;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Animation for checked state
|
||||||
|
&:checked::before {
|
||||||
|
transform: translateX(1.5rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-check-label {
|
||||||
|
margin-left: 1rem;
|
||||||
|
cursor: pointer;
|
||||||
|
padding-left: 0;
|
||||||
|
|
||||||
|
.status-text {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 1rem;
|
||||||
|
color: #2c3e50;
|
||||||
|
transition: color 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
small {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
margin-top: 0.25rem;
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Status indicator styling
|
||||||
|
.status-validation-container {
|
||||||
|
background: #f8f9fa;
|
||||||
|
border: 1px solid #e9ecef;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 1rem;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
|
||||||
|
&.valid {
|
||||||
|
background: #d4edda;
|
||||||
|
border-color: #c3e6cb;
|
||||||
|
color: #155724;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.invalid {
|
||||||
|
background: #f8d7da;
|
||||||
|
border-color: #f5c6cb;
|
||||||
|
color: #721c24;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.data-list-section {
|
.data-list-section {
|
||||||
.section-header {
|
.section-header {
|
||||||
border-bottom: 2px solid #f8f9fa;
|
border-bottom: 2px solid #f8f9fa;
|
||||||
|
|||||||
@@ -100,15 +100,15 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position: absolute; top: 50px; left: 900px; width: 200px; height: 200px; ">
|
<div style="position: absolute; top: 50px; left: 900px; width: 200px; height: 200px; ">
|
||||||
<x-custom-circle title="RAB dan Gambar" size="medium" style="background-color: #c23c3c;float:left;margin-left:250px;"
|
<x-custom-circle title="RAB dan Gambar" size="medium" style="background-color: #c248a7;float:left;margin-left:250px;"
|
||||||
visible_data="true" data_id="business-rab-count" data_count="0"
|
visible_data="true" data_id="non-business-rab-count" data_count="0"
|
||||||
document_url="{{ route('web-spatial-plannings.index', ['menu_id' => $menus->where('url','web-spatial-plannings.index')->first()->id]) }}"
|
document_url="{{ route('web-spatial-plannings.index', ['menu_id' => $menus->where('url','web-spatial-plannings.index')->first()->id]) }}"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position: absolute; top: 160px; left: 900px; width: 200px; height: 200px; ">
|
<div style="position: absolute; top: 160px; left: 900px; width: 200px; height: 200px; ">
|
||||||
<x-custom-circle title="KRK" size="medium" style="background-color: #295040;float:left;margin-left:250px;"
|
<x-custom-circle title="KRK" size="medium" style="background-color: #295040;float:left;margin-left:250px;"
|
||||||
visible_data="true" data_id="business-krk-count" data_count="0"
|
visible_data="true" data_id="non-business-krk-count" data_count="0"
|
||||||
document_url="{{ route('web-spatial-plannings.index', ['menu_id' => $menus->where('url','web-spatial-plannings.index')->first()->id]) }}"
|
document_url="{{ route('web-spatial-plannings.index', ['menu_id' => $menus->where('url','web-spatial-plannings.index')->first()->id]) }}"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -123,22 +123,22 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position: absolute; top: 350px; left: 900px; width: 200px; height: 200px; ">
|
<div style="position: absolute; top: 350px; left: 900px; width: 200px; height: 200px; ">
|
||||||
<x-custom-circle title="RAB dan Gambar" size="medium" style="background-color: #ad4343;float:left;margin-left:250px;"
|
<x-custom-circle title="RAB dan Gambar" size="medium" style="background-color: #c248a7;float:left;margin-left:250px;"
|
||||||
visible_data="true" data_id="non-business-rab-count" data_count="0"
|
visible_data="true" data_id="business-rab-count" data_count="0"
|
||||||
document_url="{{ route('web-spatial-plannings.index', ['menu_id' => $menus->where('url','web-spatial-plannings.index')->first()->id]) }}"
|
document_url="{{ route('web-spatial-plannings.index', ['menu_id' => $menus->where('url','web-spatial-plannings.index')->first()->id]) }}"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position: absolute; top: 460px; left: 900px; width: 200px; height: 200px; ">
|
<div style="position: absolute; top: 460px; left: 900px; width: 200px; height: 200px; ">
|
||||||
<x-custom-circle title="KRK" size="medium" style="background-color: #51db51;float:left;margin-left:250px;"
|
<x-custom-circle title="KRK" size="medium" style="background-color: #1d8b1d;float:left;margin-left:250px;"
|
||||||
visible_data="true" data_id="non-business-krk-count" data_count="0"
|
visible_data="true" data_id="business-krk-count" data_count="0"
|
||||||
document_url="{{ route('web-spatial-plannings.index', ['menu_id' => $menus->where('url','web-spatial-plannings.index')->first()->id]) }}"
|
document_url="{{ route('web-spatial-plannings.index', ['menu_id' => $menus->where('url','web-spatial-plannings.index')->first()->id]) }}"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position: absolute; top: 570px; left: 900px; width: 200px; height: 200px; ">
|
<div style="position: absolute; top: 570px; left: 900px; width: 200px; height: 200px; ">
|
||||||
<x-custom-circle title="DLH" size="medium" style="background-color: #331d04;float:left;margin-left:250px;"
|
<x-custom-circle title="DLH" size="medium" style="background-color: #351d02;float:left;margin-left:250px;"
|
||||||
visible_data="true" data_id="non-business-dlh-count" data_count="0"
|
visible_data="true" data_id="business-dlh-count" data_count="0"
|
||||||
document_url="{{ route('web-spatial-plannings.index', ['menu_id' => $menus->where('url','web-spatial-plannings.index')->first()->id]) }}"
|
document_url="{{ route('web-spatial-plannings.index', ['menu_id' => $menus->where('url','web-spatial-plannings.index')->first()->id]) }}"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ class="authentication-bg"
|
|||||||
<div class="row align-items-center g-0">
|
<div class="row align-items-center g-0">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="mx-auto mb-4 text-center">
|
<div class="mx-auto mb-4 text-center">
|
||||||
<img src="/images/simbg-dputr.png" alt="auth" height="250" class="mt-5 mb-3" />
|
<img src="{{ asset('images/simbg-dputr.png') }}" alt="auth" height="250" class="mt-5 mb-3" />
|
||||||
|
|
||||||
<h2 class="fs-22 lh-base">Service Unavailable!</h2>
|
<h2 class="fs-22 lh-base">Service Unavailable!</h2>
|
||||||
<p class="text-muted mt-1 mb-4">Our site is currently undergoing scheduled maintenance.<br /> Please check back later.</p>
|
<p class="text-muted mt-1 mb-4">Our site is currently undergoing scheduled maintenance.<br /> Please check back later.</p>
|
||||||
|
|||||||
@@ -4,22 +4,45 @@
|
|||||||
|
|
||||||
@include('layouts.partials/page-title', ['title' => 'Home', 'subtitle' => 'Home'])
|
@include('layouts.partials/page-title', ['title' => 'Home', 'subtitle' => 'Home'])
|
||||||
|
|
||||||
<div className="container d-flex justify-content-center align-items-center min-vh-100 bg-light">
|
<div class="container-fluid bg-gradient-primary">
|
||||||
<div className="col-lg-8 col-md-10 col-sm-12">
|
<div class="container">
|
||||||
<div className="card shadow-lg rounded-3 p-4">
|
<div class="row justify-content-center">
|
||||||
<div className="card-body text-center">
|
<div class="col-lg-10 col-xl-8">
|
||||||
<h1 className="card-title text-primary">Selamat Datang di SIBEDAS PBG!</h1>
|
<div class="card border-0 shadow-lg">
|
||||||
<p className="card-text text-secondary mt-3">
|
<div class="card-body">
|
||||||
Sistem Informasi Berbasis Data (SIBEDAS) adalah sebuah sistem yang dirancang untuk mengelola dan mengolah data pegawai secara efektif dan efisien.
|
<div class="text-center mb-4">
|
||||||
Dengan teknologi modern, SIBEDAS memungkinkan pegawai untuk mendata, melihat, dan memanipulasi informasi pegawai dengan mudah.
|
<h1 class="display-4 fw-bold text-secondary mb-3">
|
||||||
|
<i class="fas fa-building me-3"></i>SIBEDAS PBG
|
||||||
|
</h1>
|
||||||
|
<div class="bg-secondary" style="height: 3px; width: 80px; margin: 0 auto;"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="bg-light rounded-3 p-4 mb-4">
|
||||||
|
<h5 class="text-secondary fw-semibold mb-3">
|
||||||
|
<i class="fas fa-info-circle text-primary me-2"></i>Tentang Aplikasi
|
||||||
|
</h5>
|
||||||
|
<p class="text-secondary mb-0 lh-lg">
|
||||||
|
Aplikasi SIBEDAS PBG merupakan sistem pendukung yang dirancang untuk membantu pimpinan dalam melakukan pengawasan dan monitoring terhadap berkas pengajuan Persetujuan Bangunan Gedung (PBG) yang tercatat di SIMBG.
|
||||||
</p>
|
</p>
|
||||||
<p className="card-text text-secondary">
|
</div>
|
||||||
PBG (Pegawai Badan Kepegawaian) merupakan unit kerja yang bertanggung jawab atas administrasi kepegawaian.
|
|
||||||
Melalui SIBEDAS PBG, proses manajemen data pegawai menjadi lebih terstruktur, transparan, dan mudah diakses kapan saja.
|
<div class="bg-light rounded-3 p-4">
|
||||||
|
<h5 class="text-secondary fw-semibold mb-3">
|
||||||
|
<i class="fas fa-chart-line text-success me-2"></i>Manfaat & Keunggulan
|
||||||
|
</h5>
|
||||||
|
<p class="text-secondary mb-0 lh-lg">
|
||||||
|
Melalui SIBEDAS PBG, pimpinan dapat memantau secara langsung status perkembangan setiap berkas, mengidentifikasi pengajuan yang belum selesai, dan memastikan tindak lanjut penyelesaian dilakukan tepat waktu. Pengawasan yang lebih terstruktur, cepat, dan akurat ini tidak hanya meningkatkan kualitas pelayanan kepada masyarakat, tetapi juga mendukung tercapainya target Pendapatan Asli Daerah (PAD) melalui optimalisasi penyelesaian berkas PBG.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
@endsection
|
@endsection
|
||||||
@@ -26,7 +26,7 @@ class="authentication-bg"
|
|||||||
</a> -->
|
</a> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<img src="/images/simbg-dputr.png" alt="auth" height="250" class="mt-5 mb-3" />
|
<img src="{{ asset('images/simbg-dputr.png') }}" alt="dputr logo" height="250" class="mt-5 mb-3" />
|
||||||
|
|
||||||
<h2 class="fs-22 lh-base">Page Not Found !</h2>
|
<h2 class="fs-22 lh-base">Page Not Found !</h2>
|
||||||
<p class="text-muted mt-1 mb-4">The page you're trying to reach seems to have gone <br /> missing in the digital wilderness.</p>
|
<p class="text-muted mt-1 mb-4">The page you're trying to reach seems to have gone <br /> missing in the digital wilderness.</p>
|
||||||
|
|||||||
@@ -80,10 +80,24 @@
|
|||||||
<label for="due_date" class="form-label">Due Date</label>
|
<label for="due_date" class="form-label">Due Date</label>
|
||||||
<input type="text" class="form-control" id="datepicker_due_date" name="due_date" value="{{$data->due_date}}">
|
<input type="text" class="form-control" id="datepicker_due_date" name="due_date" value="{{$data->due_date}}">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="mb-3">
|
||||||
<label for="task_created_at" class="form-label">Task Created At</label>
|
<label for="task_created_at" class="form-label">Task Created At</label>
|
||||||
<input type="datetime-local" class="form-control" id="task_created_at" name="task_created_at" value="{{$data->task_created_at}}" disabled>
|
<input type="datetime-local" class="form-control" id="task_created_at" name="task_created_at" value="{{$data->task_created_at}}" disabled>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Status Validasi Data</label>
|
||||||
|
<div class="form-check form-switch">
|
||||||
|
<input class="form-check-input" type="checkbox" role="switch" id="is_valid" name="is_valid" value="1" {{ $data->is_valid ? 'checked' : '' }}>
|
||||||
|
<label class="form-check-label" for="is_valid">
|
||||||
|
<span class="status-text">{{ $data->is_valid ? 'Data Valid' : 'Data Tidak Valid' }}</span>
|
||||||
|
<small class="text-muted d-block">
|
||||||
|
{{ $data->is_valid ? 'Data telah diverifikasi dan sesuai' : 'Data perlu diverifikasi atau diperbaiki' }}
|
||||||
|
</small>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<!-- Hidden input to ensure false value is sent when unchecked -->
|
||||||
|
<input type="hidden" name="is_valid" value="0">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|||||||
Reference in New Issue
Block a user