fix pbg task add toggle and rab krk dlh

This commit is contained in:
arifal
2025-08-19 13:00:40 +07:00
parent d7e9f44b20
commit 2cbc4172da
17 changed files with 894 additions and 239 deletions

View File

@@ -9,3 +9,8 @@ exit
(new App\Jobs\ScrapingDataJob())->handle();
(new App\Jobs\ScrapingDataJob())->handle();
exit
exit
BigdataResume::generateResumeData(253,2025,"simbg");
exit
BigdataResume::generateResumeData(253,2025,"simbg");
exit

View 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

View File

@@ -42,11 +42,11 @@ class BigDataResumeController extends Controller
}
$data_settings = DataSetting::all();
if($data_settings->isEmpty()){
return response()->json(['message' => 'No data setting found']);
$target_pad = 0;
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_count = $big_data_resume->issuance_realization_pbg_count;
$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;
$non_business_rab_count = $big_data_resume->non_business_rab_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 = [
'target_pad' => [
@@ -167,7 +167,7 @@ class BigDataResumeController extends Controller
'business_krk_count' => $business_krk_count,
'non_business_rab_count' => $non_business_rab_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);
}catch(\Exception $e){
@@ -336,9 +336,15 @@ class BigDataResumeController extends Controller
return $pdf->download('laporan-pimpinan.pdf');
}
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 = [
'target_pad' => [
'sum' => 0,
'sum' => $target_pad,
'percentage' => 100,
],
'tata_ruang' => [

View File

@@ -132,39 +132,48 @@ class PbgTaskController extends Controller
}
$validated = $request->validate([
'name' => 'required|string|max:255',
'owner_name' => 'required|string|max:255',
'name' => 'nullable|string|max:255',
'owner_name' => 'nullable|string|max:255',
'application_type' => ['nullable', new Enum(PbgTaskApplicationTypes::class)],
'condition' => 'required|string|max:255',
'registration_number' => 'required|string|max:255',
'document_number' => 'required|string|max:255',
'condition' => 'nullable|string|max:255',
'registration_number' => 'nullable|string|max:255',
'document_number' => 'nullable|string|max:255',
'status' => ['nullable', new Enum(PbgTaskStatus::class)],
'address' => 'required|string|max:255',
'address' => 'nullable|string|max:255',
'slf_status_name' => 'nullable|string|max:255',
'function_type' => 'required|string|max:255',
'consultation_type' => 'required|string|max:255',
'due_date' => 'nullable|date|after_or_equal:today',
'function_type' => 'nullable|string|max:255',
'consultation_type' => 'nullable|string|max:255',
'due_date' => 'nullable|date',
'is_valid' => 'nullable|boolean',
]);
$statusLabel = $validated['status'] !== null ? PbgTaskStatus::getLabel($validated['status']) : null;
$applicationLabel = $validated['application_type'] !== null ? PbgTaskApplicationTypes::getLabel($validated['application_type']) : null;
$pbg_task->update([
'name' => $validated['name'],
'owner_name' => $validated['owner_name'],
'application_type' => $validated['application_type'],
'application_type_name' => $applicationLabel, // Automatically set application_type_name
'condition' => $validated['condition'],
'registration_number' => $validated['registration_number'],
'document_number' => $validated['document_number'],
'status' => $validated['status'],
'status_name' => $statusLabel, // Automatically set status_name
'address' => $validated['address'],
'slf_status_name' => $validated['slf_status_name'],
'function_type' => $validated['function_type'],
'consultation_type' => $validated['consultation_type'],
'due_date' => $validated['due_date'],
]);
// Prepare update data - only include fields that are actually provided
$updateData = [];
foreach ($validated as $key => $value) {
if ($value !== null || $request->has($key)) {
$updateData[$key] = $value;
}
}
// Handle special cases for labels
if (isset($updateData['status'])) {
$updateData['status_name'] = $statusLabel;
}
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([
"success"=> true,
"message"=> "Data berhasil diubah",

View File

@@ -34,9 +34,9 @@ class BigdataResume extends Model
'process_in_technical_office_sum',
'business_rab_count',
'business_krk_count',
'business_dlh_count',
'non_business_rab_count',
'non_business_krk_count',
'non_business_dlh_count',
'resume_type',
];
@@ -155,6 +155,41 @@ class BigdataResume extends Model
')
->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:
// 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')
@@ -225,61 +260,55 @@ class BigdataResume extends Model
')
->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')
->where(function ($q) {
$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());
})
// Debug: Check if there are non-verified tasks and their retribution data
$debug_non_verified = PbgTask::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;
->with('pbg_task_retributions')
->get();
\Log::info('Non-verified tasks debug', [
'year' => $year,
'non_verified_statuses' => PbgTaskStatus::getNonVerified(),
'tasks_count' => $debug_non_verified->count(),
'tasks_with_retribution' => $debug_non_verified->filter(fn($task) => $task->pbg_task_retributions)->count(),
'sample_retribution_values' => $debug_non_verified->take(3)->map(fn($task) => [
'uuid' => $task->uuid,
'status' => $task->status,
'has_retribution' => !is_null($task->pbg_task_retributions),
'retribution_value' => $task->pbg_task_retributions?->nilai_retribusi_bangunan ?? 'NULL'
])
]);
// 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')
->whereYear('pbg_task.task_created_at', $year)
->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::getNonVerified()).") THEN ptr.nilai_retribusi_bangunan ELSE 0 END) AS non_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 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%'
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%'
AND LOWER(TRIM(pbg_task.function_type)) NOT LIKE '%sebagai tempat usaha%'
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,
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::getIssuanceRealizationPbg()).") THEN ptr.nilai_retribusi_bangunan 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::getPotention()).") THEN ptr.nilai_retribusi_bangunan ELSE 0 END) AS potention_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 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 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 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 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();
\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);
return self::create([
@@ -305,9 +334,9 @@ class BigdataResume extends Model
'process_in_technical_office_sum' => $stats->process_in_technical_office_total ?? 0.00,
'business_rab_count' => $business_rab_count,
'business_krk_count' => $business_krk_count,
'business_dlh_count' => $business_dlh_count,
'non_business_rab_count' => $non_business_rab_count,
'non_business_krk_count' => $non_business_krk_count,
'non_business_dlh_count' => $non_business_dlh_count,
'resume_type' => $resume_type,
]);
}

View File

@@ -27,7 +27,8 @@ class PbgTask extends Model
'consultation_type',
'due_date',
'land_certificate_phase',
'task_created_at'
'task_created_at',
'is_valid'
];
public function pbg_task_retributions(){

View File

@@ -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
*/
public static function createFromApiResponse(array $data, string $pbgTaskUuid): self
{
$detailData = [
// Foreign key relationship - string, required
'pbg_task_uid' => $pbgTaskUuid,
'uid' => $data['uid'] ?? null,
'nik' => $data['nik'] ?? null,
'type_card' => $data['type_card'] ?? null,
'ownership' => $data['ownership'] ?? null,
'owner_name' => $data['owner_name'] ?? null,
'ward_id' => $data['ward_id'] ?? null,
'ward_name' => $data['ward_name'] ?? null,
'district_id' => $data['district_id'] ?? null,
'district_name' => $data['district_name'] ?? null,
'regency_id' => $data['regency_id'] ?? null,
'regency_name' => $data['regency_name'] ?? null,
'province_id' => $data['province_id'] ?? null,
'province_name' => $data['province_name'] ?? null,
'address' => $data['address'] ?? null,
'owner_email' => $data['owner_email'] ?? null,
'owner_phone' => $data['owner_phone'] ?? null,
'user' => $data['user'] ?? null,
'name' => $data['name'] ?? null,
'email' => $data['email'] ?? null,
'phone' => $data['phone'] ?? null,
'user_nik' => $data['user_nik'] ?? null,
'user_province_id' => $data['user_province_id'] ?? null,
'user_province_name' => $data['user_province_name'] ?? null,
'user_regency_id' => $data['user_regency_id'] ?? null,
'user_regency_name' => $data['user_regency_name'] ?? null,
'user_district_id' => $data['user_district_id'] ?? null,
'user_district_name' => $data['user_district_name'] ?? null,
'user_address' => $data['user_address'] ?? null,
'status' => $data['status'] ?? null,
'status_name' => $data['status_name'] ?? null,
'slf_status' => $data['slf_status'] ?? null,
'slf_status_name' => $data['slf_status_name'] ?? null,
'sppst_status' => $data['sppst_status'] ?? null,
'sppst_file' => $data['sppst_file'] ?? null,
'sppst_status_name' => $data['sppst_status_name'] ?? null,
'file_pbg' => $data['file_pbg'] ?? null,
'file_pbg_date' => isset($data['file_pbg_date']) ? Carbon::parse($data['file_pbg_date'])->format('Y-m-d') : null,
'due_date' => isset($data['due_date']) ? Carbon::parse($data['due_date'])->format('Y-m-d') : null,
'start_date' => isset($data['start_date']) ? Carbon::parse($data['start_date'])->format('Y-m-d') : null,
'document_number' => $data['document_number'] ?? null,
'registration_number' => $data['registration_number'] ?? null,
// Basic information
'uid' => $data['uid'] ?? "N/A", // string, unique, required
'nik' => isset($data['nik']) && $data['nik'] !== '' && $data['nik'] !== '?' ? $data['nik'] : null, // string, nullable
'type_card' => isset($data['type_card']) && $data['type_card'] !== '' && $data['type_card'] !== '?' ? $data['type_card'] : null, // string, nullable
'ownership' => $data['ownership'] ?? null, // string, nullable
'owner_name' => $data['owner_name'] ?? "N/A", // string, required
// Owner location information - all required
'ward_id' => self::cleanIntegerValue($data['ward_id'] ?? 0), // bigInteger, required
'ward_name' => $data['ward_name'] ?? "N/A", // string, required
'district_id' => self::cleanIntegerValue($data['district_id'] ?? 0), // integer, required
'district_name' => $data['district_name'] ?? "N/A", // string, required
'regency_id' => self::cleanIntegerValue($data['regency_id'] ?? 0), // integer, required
'regency_name' => $data['regency_name'] ?? "N/A", // string, required
'province_id' => self::cleanIntegerValue($data['province_id'] ?? 0), // integer, required
'province_name' => $data['province_name'] ?? "N/A", // string, required
'address' => $data['address'] ?? "N/A", // text, required
// Owner contact information - required
'owner_email' => $data['owner_email'] ?? "N/A", // string, required
'owner_phone' => $data['owner_phone'] ?? "N/A", // string, required
// User information - all required
'user' => self::cleanIntegerValue($data['user'] ?? 0), // integer, required
'name' => $data['name'] ?? "N/A", // string, required
'email' => $data['email'] ?? "N/A", // string, required
'phone' => $data['phone'] ?? "N/A", // string, required
'user_nik' => $data['user_nik'] ?? "N/A", // string, required
// User location information - all required
'user_province_id' => self::cleanIntegerValue($data['user_province_id'] ?? 0), // integer, required
'user_province_name' => $data['user_province_name'] ?? "N/A", // string, required
'user_regency_id' => self::cleanIntegerValue($data['user_regency_id'] ?? 0), // integer, required
'user_regency_name' => $data['user_regency_name'] ?? "N/A", // string, required
'user_district_id' => self::cleanIntegerValue($data['user_district_id'] ?? 0), // integer, required
'user_district_name' => $data['user_district_name'] ?? "N/A", // string, required
'user_address' => $data['user_address'] ?? "N/A", // text, required
// Status information
'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,
'application_type' => $data['application_type'] ?? null,
'application_type_name' => $data['application_type_name'] ?? null,
@@ -198,52 +352,74 @@ class PbgTaskDetail extends Model
'condition' => $data['condition'] ?? null,
'prototype' => $data['prototype'] ?? 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_purpose' => $data['building_purpose'] ?? null,
'building_use' => $data['building_use'] ?? null,
'occupancy' => $data['occupancy'] ?? null,
'name_building' => $data['name_building'] ?? null,
'total_area' => $data['total_area'] ?? null,
'area' => $data['area'] ?? null,
'area_type' => $data['area_type'] ?? null,
'height' => $data['height'] ?? null,
'floor' => $data['floor'] ?? null,
'floor_area' => $data['floor_area'] ?? 0,
'basement' => $data['basement'] ?? null,
'basement_height' => $data['basement_height'] ?? 0,
'basement_area' => $data['basement_area'] ?? 0,
'unit' => $data['unit'] ?? null,
'prev_retribution' => $data['prev_retribution'] ?? 0,
'prev_pbg' => $data['prev_pbg'] ?? null,
'prev_total_area' => $data['prev_total_area'] ?? 0,
'koefisien_dasar_bangunan' => $data['koefisien_dasar_bangunan'] ?? 0,
'koefisien_lantai_bangunan' => $data['koefisien_lantai_bangunan'] ?? 0,
'koefisien_lantai_hijau' => $data['koefisien_lantai_hijau'] ?? 0,
'koefisien_tapak_basement' => $data['koefisien_tapak_basement'] ?? 0,
'ketinggian_bangunan' => $data['ketinggian_bangunan'] ?? 0,
// Building dimensions and specifications
'total_area' => self::cleanNumericValue($data['total_area'] ?? 0), // decimal(10,2), required
'area' => self::cleanNumericValue($data['area'] ?? null, true), // decimal(10,2), nullable
'area_type' => $data['area_type'] ?? null, // string, nullable
'height' => self::cleanNumericValue($data['height'] ?? 0), // decimal(8,2), required
'floor' => self::cleanIntegerValue($data['floor'] ?? 0), // integer, required
'floor_area' => self::cleanNumericValue($data['floor_area'] ?? null, true), // decimal(10,2), nullable
'basement' => isset($data['basement']) && $data['basement'] !== '' && $data['basement'] !== '?' ? $data['basement'] : null, // string, nullable
'basement_height' => self::cleanNumericValue($data['basement_height'] ?? null, true), // decimal(8,2), nullable
'basement_area' => self::cleanNumericValue($data['basement_area'] ?? 0), // decimal(10,2), required
'unit' => isset($data['unit']) && is_numeric($data['unit']) ? (int) $data['unit'] : null, // integer, nullable
// Previous information
'prev_retribution' => self::cleanNumericValue($data['prev_retribution'] ?? null, true), // decimal(15,2), nullable
'prev_pbg' => $data['prev_pbg'] ?? null, // string, nullable
'prev_total_area' => self::cleanNumericValue($data['prev_total_area'] ?? null, true), // decimal(10,2), nullable
// 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_kolektor' => $data['jalan_kolektor'] ?? null,
'jalan_bangunan' => $data['jalan_bangunan'] ?? null,
'gsb' => $data['gsb'] ?? null,
'kkr_number' => $data['kkr_number'] ?? null,
'gsb' => self::cleanNumericValue($data['gsb'] ?? null, true), // decimal(8,2), nullable
'kkr_number' => $data['kkr_number'] ?? null, // string, nullable
// Unit data as JSON - nullable
'unit_data' => $data['unit_data'] ?? null,
'is_mbr' => $data['is_mbr'] ?? false,
'code' => $data['code'] ?? null,
'building_ward_id' => $data['building_ward_id'] ?? null,
'building_ward_name' => $data['building_ward_name'] ?? null,
'building_district_id' => $data['building_district_id'] ?? null,
'building_district_name' => $data['building_district_name'] ?? null,
'building_regency_id' => $data['building_regency_id'] ?? null,
'building_regency_name' => $data['building_regency_name'] ?? null,
'building_province_id' => $data['building_province_id'] ?? null,
'building_province_name' => $data['building_province_name'] ?? null,
'building_address' => $data['building_address'] ?? null,
'latitude' => $data['latitude'] ?? null,
'longitude' => $data['longitude'] ?? null,
// Additional flags
'is_mbr' => (bool) ($data['is_mbr'] ?? false), // boolean, default false
'code' => $data['code'] ?? "N/A", // string, required
// Building location information - all required
'building_ward_id' => self::cleanIntegerValue($data['building_ward_id'] ?? 0), // bigInteger, required
'building_ward_name' => $data['building_ward_name'] ?? "N/A", // string, required
'building_district_id' => self::cleanIntegerValue($data['building_district_id'] ?? 0), // integer, required
'building_district_name' => $data['building_district_name'] ?? "N/A", // string, required
'building_regency_id' => self::cleanIntegerValue($data['building_regency_id'] ?? 0), // integer, required
'building_regency_name' => $data['building_regency_name'] ?? "N/A", // string, required
'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,
'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(

View File

@@ -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');
});
}
};

View File

@@ -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');
});
}
};

View File

@@ -3,6 +3,21 @@ import GlobalConfig, { addThousandSeparators } from "../global-config.js";
import InitDatePicker from "../utils/InitDatePicker.js";
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() {
try {
new InitDatePicker(
@@ -25,6 +40,14 @@ class BigData {
try {
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.initChartUsaha();
this.initChartNonUsaha();
@@ -43,6 +66,8 @@ class BigData {
this.initChartNonBusinessDLH();
} catch (e) {
console.error(e);
// Initialize with empty data if there's an error
this.resumeBigData = {};
}
}
@@ -92,14 +117,24 @@ class BigData {
document
.querySelectorAll(".document-total.chart-target-pad")
.forEach((element) => {
const sum = this.safeGet(
this.resumeBigData,
"target_pad.sum",
0
);
element.innerText = `Rp.${addThousandSeparators(
this.resumeBigData.target_pad.sum.toString()
sum.toString()
)}`;
});
document
.querySelectorAll(".small-percentage.chart-target-pad")
.forEach((element) => {
element.innerText = `${this.resumeBigData.target_pad.percentage}%`;
const percentage = this.safeGet(
this.resumeBigData,
"target_pad.percentage",
0
);
element.innerText = `${percentage}%`;
});
}
initChartTotalPotensi() {
@@ -108,44 +143,68 @@ class BigData {
document
.querySelectorAll(".document-count.chart-total-potensi")
.forEach((element) => {
// element.innerText = `${countAll}`;
element.innerText = `${this.resumeBigData.total_potensi.count}`;
const count = this.safeGet(
this.resumeBigData,
"total_potensi.count",
0
);
element.innerText = `${count}`;
});
document
.querySelectorAll(".document-total.chart-total-potensi")
.forEach((element) => {
const sum = this.safeGet(
this.resumeBigData,
"total_potensi.sum",
0
);
element.innerText = `Rp.${addThousandSeparators(
// this.bigTotalPotensi.toString()
this.resumeBigData.total_potensi.sum.toString()
sum.toString()
)}`;
});
document
.querySelectorAll(".small-percentage.chart-total-potensi")
.forEach((element) => {
// element.innerText = `${this.resultPercentage}%`;
element.innerText = `${this.resumeBigData.total_potensi.percentage}%`;
const percentage = this.safeGet(
this.resumeBigData,
"total_potensi.percentage",
0
);
element.innerText = `${percentage}%`;
});
}
initChartVerificationDocuments() {
document
.querySelectorAll(".document-count.chart-berkas-terverifikasi")
.forEach((element) => {
// element.innerText = `${this.dataVerification.count}`;
element.innerText = `${this.resumeBigData.verified_document.count}`;
const count = this.safeGet(
this.resumeBigData,
"verified_document.count",
0
);
element.innerText = `${count}`;
});
document
.querySelectorAll(".document-total.chart-berkas-terverifikasi")
.forEach((element) => {
const sum = this.safeGet(
this.resumeBigData,
"verified_document.sum",
0
);
element.innerText = `Rp.${addThousandSeparators(
// this.bigTotalVerification.toString()
this.resumeBigData.verified_document.sum.toString()
sum.toString()
)}`;
});
document
.querySelectorAll(".small-percentage.chart-berkas-terverifikasi")
.forEach((element) => {
// element.innerText = `${this.percetageResultVerification}%`;
element.innerText = `${this.resumeBigData.verified_document.percentage}%`;
const percentage = this.safeGet(
this.resumeBigData,
"verified_document.percentage",
0
);
element.innerText = `${percentage}%`;
});
}
initChartNonVerificationDocuments() {
@@ -154,17 +213,25 @@ class BigData {
".document-count.chart-berkas-belum-terverifikasi"
)
.forEach((element) => {
// element.innerText = `${this.dataNonVerification.count}`;
element.innerText = `${this.resumeBigData.non_verified_document.count}`;
const count = this.safeGet(
this.resumeBigData,
"non_verified_document.count",
0
);
element.innerText = `${count}`;
});
document
.querySelectorAll(
".document-total.chart-berkas-belum-terverifikasi"
)
.forEach((element) => {
const sum = this.safeGet(
this.resumeBigData,
"non_verified_document.sum",
0
);
element.innerText = `Rp.${addThousandSeparators(
// this.bigTotalNonVerification.toString()
this.resumeBigData.non_verified_document.sum.toString()
sum.toString()
)}`;
});
document
@@ -172,52 +239,80 @@ class BigData {
".small-percentage.chart-berkas-belum-terverifikasi"
)
.forEach((element) => {
// element.innerText = `${this.percentageResultNonVerification}%`;
element.innerText = `${this.resumeBigData.non_verified_document.percentage}%`;
const percentage = this.safeGet(
this.resumeBigData,
"non_verified_document.percentage",
0
);
element.innerText = `${percentage}%`;
});
}
initChartUsaha() {
document
.querySelectorAll(".document-count.chart-business")
.forEach((element) => {
// element.innerText = `${this.dataBusiness.count}`;
element.innerText = `${this.resumeBigData.business_document.count}`;
const count = this.safeGet(
this.resumeBigData,
"business_document.count",
0
);
element.innerText = `${count}`;
});
document
.querySelectorAll(".document-total.chart-business")
.forEach((element) => {
const sum = this.safeGet(
this.resumeBigData,
"business_document.sum",
0
);
element.innerText = `Rp.${addThousandSeparators(
// this.bigTotalBusiness.toString()
this.resumeBigData.business_document.sum.toString()
sum.toString()
)}`;
});
document
.querySelectorAll(".small-percentage.chart-business")
.forEach((element) => {
// element.innerText = `${this.percentageResultBusiness}%`;
element.innerText = `${this.resumeBigData.business_document.percentage}%`;
const percentage = this.safeGet(
this.resumeBigData,
"business_document.percentage",
0
);
element.innerText = `${percentage}%`;
});
}
initChartNonUsaha() {
document
.querySelectorAll(".document-count.chart-non-business")
.forEach((element) => {
// element.innerText = `${this.dataNonBusiness.count}`;
element.innerText = `${this.resumeBigData.non_business_document.count}`;
const count = this.safeGet(
this.resumeBigData,
"non_business_document.count",
0
);
element.innerText = `${count}`;
});
document
.querySelectorAll(".document-total.chart-non-business")
.forEach((element) => {
const sum = this.safeGet(
this.resumeBigData,
"non_business_document.sum",
0
);
element.innerText = `Rp.${addThousandSeparators(
// this.bigTotalNonBusiness.toString()
this.resumeBigData.non_business_document.sum.toString()
sum.toString()
)}`;
});
document
.querySelectorAll(".small-percentage.chart-non-business")
.forEach((element) => {
// element.innerText = `${this.percentageResultNonBusiness}%`;
element.innerText = `${this.resumeBigData.non_business_document.percentage}%`;
const percentage = this.safeGet(
this.resumeBigData,
"non_business_document.percentage",
0
);
element.innerText = `${percentage}%`;
});
}
initChartKekuranganPotensi() {
@@ -229,129 +324,226 @@ class BigData {
document
.querySelectorAll(".document-total.chart-kekurangan-potensi")
.forEach((element) => {
const sum = this.safeGet(
this.resumeBigData,
"kekurangan_potensi.sum",
0
);
element.innerText = `Rp.${addThousandSeparators(
// this.totalKekuranganPotensi.toString()
this.resumeBigData.kekurangan_potensi.sum.toString()
sum.toString()
)}`;
});
document
.querySelectorAll(".small-percentage.chart-kekurangan-potensi")
.forEach((element) => {
// element.innerText = `${this.percentageKekuranganPotensi}%`;
element.innerText = `${this.resumeBigData.kekurangan_potensi.percentage}%`;
const percentage = this.safeGet(
this.resumeBigData,
"kekurangan_potensi.percentage",
0
);
element.innerText = `${percentage}%`;
});
}
initChartRealisasiTerbitPBG() {
document
.querySelectorAll(".document-count.chart-realisasi-tebit-pbg")
.forEach((element) => {
// element.innerText = `${this.dataCountRealisasiTerbit}`;
element.innerText = `${this.resumeBigData.realisasi_terbit.count}`;
const count = this.safeGet(
this.resumeBigData,
"realisasi_terbit.count",
0
);
element.innerText = `${count}`;
});
document
.querySelectorAll(".document-total.chart-realisasi-tebit-pbg")
.forEach((element) => {
const sum = this.safeGet(
this.resumeBigData,
"realisasi_terbit.sum",
0
);
element.innerText = `Rp.${addThousandSeparators(
// this.dataSumRealisasiTerbit
this.resumeBigData.realisasi_terbit.sum.toString()
sum.toString()
)}`;
});
document
.querySelectorAll(".small-percentage.chart-realisasi-tebit-pbg")
.forEach((element) => {
element.innerText = `${this.resumeBigData.realisasi_terbit.percentage}%`;
const percentage = this.safeGet(
this.resumeBigData,
"realisasi_terbit.percentage",
0
);
element.innerText = `${percentage}%`;
});
}
initChartMenungguKlikDPMPTSP() {
document
.querySelectorAll(".document-count.chart-menunggu-klik-dpmptsp")
.forEach((element) => {
// element.innerText = `${this.dataCountMenungguKlikDPMPTSP}`;
element.innerText = `${this.resumeBigData.menunggu_klik_dpmptsp.count}`;
const count = this.safeGet(
this.resumeBigData,
"menunggu_klik_dpmptsp.count",
0
);
element.innerText = `${count}`;
});
document
.querySelectorAll(".document-total.chart-menunggu-klik-dpmptsp")
.forEach((element) => {
const sum = this.safeGet(
this.resumeBigData,
"menunggu_klik_dpmptsp.sum",
0
);
element.innerText = `Rp.${addThousandSeparators(
// this.dataSumMenungguKlikDPMPTSP
this.resumeBigData.menunggu_klik_dpmptsp.sum.toString()
sum.toString()
)}`;
});
document
.querySelectorAll(".small-percentage.chart-menunggu-klik-dpmptsp")
.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() {
document
.querySelectorAll(".document-count.chart-proses-dinas-teknis")
.forEach((element) => {
// element.innerText = `${this.dataCountProsesDinasTeknis}`;
element.innerText = `${this.resumeBigData.proses_dinas_teknis.count}`;
const count = this.safeGet(
this.resumeBigData,
"proses_dinas_teknis.count",
0
);
element.innerText = `${count}`;
});
document
.querySelectorAll(".document-total.chart-proses-dinas-teknis")
.forEach((element) => {
const sum = this.safeGet(
this.resumeBigData,
"proses_dinas_teknis.sum",
0
);
element.innerText = `Rp.${addThousandSeparators(
// this.dataSumProsesDinasTeknis
this.resumeBigData.proses_dinas_teknis.sum.toString()
sum.toString()
)}`;
});
document
.querySelectorAll(".small-percentage.chart-proses-dinas-teknis")
.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() {
document
.querySelectorAll(".document-count.chart-potensi-tata-ruang")
.forEach((element) => {
element.innerText = `${this.resumeBigData.tata_ruang.count}`;
const count = this.safeGet(
this.resumeBigData,
"tata_ruang.count",
0
);
element.innerText = `${count}`;
});
document
.querySelectorAll(".document-total.chart-potensi-tata-ruang")
.forEach((element) => {
const sum = this.safeGet(
this.resumeBigData,
"tata_ruang.sum",
0
);
element.innerText = `Rp.${addThousandSeparators(
this.resumeBigData.tata_ruang.sum.toString()
sum.toString()
)}`;
});
document
.querySelectorAll(".small-percentage.chart-potensi-tata-ruang")
.forEach((element) => {
element.innerText = `${this.resumeBigData.tata_ruang.percentage}%`;
const percentage = this.safeGet(
this.resumeBigData,
"tata_ruang.percentage",
0
);
element.innerText = `${percentage}%`;
});
}
initChartBusinessRAB() {
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() {
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() {
document
.querySelectorAll("#non-business-rab-count")
.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() {
document
.querySelectorAll("#non-business-krk-count")
.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() {
document
.querySelectorAll("#non-business-dlh-count")
.forEach((element) => {
element.innerText = `${this.resumeBigData.non_business_dlh_count}`;
const count = this.safeGet(
this.resumeBigData,
"non_business_dlh_count",
0
);
element.innerText = `${count}`;
});
}
}

View File

@@ -10,6 +10,7 @@ class PbgTaskAssignments {
this.initTablePbgTaskAssignments();
this.handleUpdateData();
this.initDatePicker();
this.initIsValidToggle();
}
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() {
let tableContainer = document.getElementById(
"table-pbg-task-assignments"
@@ -92,6 +117,12 @@ class PbgTaskAssignments {
formData.forEach((value, key) => {
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, {
method: "PUT", // Ensure your Laravel route is set to accept PUT requests
body: JSON.stringify(formObject), // Convert form data to JSON

View File

@@ -1,6 +1,102 @@
// PBG Task Show Page Styles
// 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 {
.section-header {
border-bottom: 2px solid #f8f9fa;

View File

@@ -100,15 +100,15 @@
</div>
<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;"
visible_data="true" data_id="business-rab-count" data_count="0"
<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"
document_url="{{ route('web-spatial-plannings.index', ['menu_id' => $menus->where('url','web-spatial-plannings.index')->first()->id]) }}"
/>
</div>
<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;"
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]) }}"
/>
</div>
@@ -123,22 +123,22 @@
</div>
<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;"
visible_data="true" data_id="non-business-rab-count" data_count="0"
<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"
document_url="{{ route('web-spatial-plannings.index', ['menu_id' => $menus->where('url','web-spatial-plannings.index')->first()->id]) }}"
/>
</div>
<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;"
visible_data="true" data_id="non-business-krk-count" data_count="0"
<x-custom-circle title="KRK" size="medium" style="background-color: #1d8b1d;float:left;margin-left:250px;"
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]) }}"
/>
</div>
<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;"
visible_data="true" data_id="non-business-dlh-count" data_count="0"
<x-custom-circle title="DLH" size="medium" style="background-color: #351d02;float:left;margin-left:250px;"
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]) }}"
/>
</div>

View File

@@ -14,13 +14,13 @@ class="authentication-bg"
<div class="card-body p-0">
<div class="row align-items-center g-0">
<div class="col">
<div class="mx-auto mb-4 text-center">
<img src="/images/simbg-dputr.png" alt="auth" height="250" class="mt-5 mb-3" />
<div class="mx-auto mb-4 text-center">
<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>
<p class="text-muted mt-1 mb-4">Our site is currently undergoing scheduled maintenance.<br /> Please check back later.</p>
<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>
</div>
</div>
</div> <!-- end col -->
</div> <!-- end row -->
</div> <!-- end card-body -->

View File

@@ -4,19 +4,42 @@
@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 className="col-lg-8 col-md-10 col-sm-12">
<div className="card shadow-lg rounded-3 p-4">
<div className="card-body text-center">
<h1 className="card-title text-primary">Selamat Datang di SIBEDAS PBG!</h1>
<p className="card-text text-secondary mt-3">
Sistem Informasi Berbasis Data (SIBEDAS) adalah sebuah sistem yang dirancang untuk mengelola dan mengolah data pegawai secara efektif dan efisien.
Dengan teknologi modern, SIBEDAS memungkinkan pegawai untuk mendata, melihat, dan memanipulasi informasi pegawai dengan mudah.
</p>
<p className="card-text text-secondary">
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.
</p>
<div class="container-fluid bg-gradient-primary">
<div class="container">
<div class="row justify-content-center">
<div class="col-lg-10 col-xl-8">
<div class="card border-0 shadow-lg">
<div class="card-body">
<div class="text-center mb-4">
<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>
</div>
<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>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@@ -26,7 +26,7 @@ class="authentication-bg"
</a> -->
</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>
<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>

View File

@@ -80,10 +80,24 @@
<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}}">
</div>
<div>
<div class="mb-3">
<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>
</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 class="row">