diff --git a/.env.example b/.env.example index b4fad41..3ef4203 100755 --- a/.env.example +++ b/.env.example @@ -65,6 +65,5 @@ AWS_USE_PATH_STYLE_ENDPOINT=false VITE_APP_NAME="${APP_NAME}" -SIMBG_HOST="xxxxxx" -SIMBG_EMAIL="xxxxxx" -SIMBG_PASSWORD="xxxxx" \ No newline at end of file +API_KEY_GOOGLE="xxxxx" +SPREAD_SHEET_ID="xxxxx" \ No newline at end of file diff --git a/app/Http/Controllers/Api/DashboardController.php b/app/Http/Controllers/Api/DashboardController.php index 2abb2ad..394aded 100644 --- a/app/Http/Controllers/Api/DashboardController.php +++ b/app/Http/Controllers/Api/DashboardController.php @@ -12,42 +12,47 @@ class DashboardController extends Controller use GlobalApiResponse; public function businnessDocument(Request $request){ - $businessData = DB::table('pbg_task') - ->leftJoin('pbg_task_retributions', 'pbg_task.uuid', '=', 'pbg_task_retributions.pbg_task_uid') - ->select( - DB::raw('COUNT(DISTINCT pbg_task.id) as task_count'), - DB::raw('SUM(pbg_task_retributions.nilai_retribusi_bangunan) as total_retribution') - ) + $query = DB::table('pbg_task AS pt') + ->leftJoin('pbg_task_google_sheet AS ptgs', 'pt.registration_number', '=', 'ptgs.no_registrasi') + ->leftJoin('pbg_task_retributions AS ptr', 'pt.uuid', '=', 'ptr.pbg_task_uid') // Join ke pbg_task_retributions ->where(function ($query) { - $query->where("pbg_task.function_type", "LIKE", "sebagai tempat usaha%"); + $query->whereRaw('LOWER(TRIM(ptgs.status_verifikasi)) != ?', [strtolower(trim('Selesai Verifikasi'))]) + ->orWhereNull('ptgs.status_verifikasi'); }) + ->where(function ($query) { + $query->whereRaw('LOWER(TRIM(pt.function_type)) = ?', [strtolower(trim('Sebagai Tempat Usaha'))]); + }) + ->selectRaw('COUNT(pt.id) AS total_data, + SUM(ptr.nilai_retribusi_bangunan) AS total_retribution') // Menambahkan SUM dari pbg_task_retributions ->first(); - $taskCount = $businessData->task_count; - $taskTotal = $businessData->total_retribution; + $taskCount = $query->total_data; + $taskTotal = $query->total_retribution ?? 0; $result = [ "count" => $taskCount, - "series" => [$taskCount], "total" => $taskTotal ]; return $this->resSuccess($result); } public function nonBusinnessDocument(Request $request){ - $businessData = DB::table('pbg_task') - ->leftJoin('pbg_task_retributions', 'pbg_task.uuid', '=', 'pbg_task_retributions.pbg_task_uid') - ->select( - DB::raw('COUNT(DISTINCT pbg_task.id) as task_count'), - DB::raw('SUM(pbg_task_retributions.nilai_retribusi_bangunan) as total_retribution') - ) + + $query = DB::table('pbg_task AS pt') + ->leftJoin('pbg_task_google_sheet AS ptgs', 'pt.registration_number', '=', 'ptgs.no_registrasi') + ->leftJoin('pbg_task_retributions AS ptr', 'pt.uuid', '=', 'ptr.pbg_task_uid') // Join ke pbg_task_retributions ->where(function ($query) { - $query->where("pbg_task.function_type", "NOT LIKE", "sebagai tempat usaha%") - ->orWhereNull("pbg_task.function_type"); + $query->whereRaw('LOWER(TRIM(ptgs.status_verifikasi)) != ?', [strtolower(trim('Selesai Verifikasi'))]) + ->orWhereNull('ptgs.status_verifikasi'); // Include NULL values }) + ->where(function ($query) { + $query->whereRaw('LOWER(TRIM(pt.function_type)) != ?', [strtolower(trim('Sebagai Tempat Usaha'))]) + ->orWhereNull('pt.function_type'); // Include NULL values + }) + ->selectRaw('COUNT(pt.id) AS total_data, + SUM(ptr.nilai_retribusi_bangunan) AS total_retribution') // Menambahkan SUM dari pbg_task_retributions ->first(); - $taskCount = $businessData->task_count; - $taskTotal = $businessData->total_retribution; + $taskCount = $query->total_data; + $taskTotal = $query->total_retribution ?? 0; $result = [ "count" => $taskCount, - "series" => [$taskCount], "total" => $taskTotal ]; return $this->resSuccess($result); @@ -64,12 +69,54 @@ class DashboardController extends Controller $taskTotal = $query->total_retribution; $result = [ "count" => $taskCount, - "series" => [$taskCount], "total" => $taskTotal ]; return $this->resSuccess($result); } + public function verificationDocuments(){ + $query = DB::table('pbg_task AS pt') + ->leftJoin('pbg_task_google_sheet AS ptgs', 'pt.registration_number', '=', 'ptgs.no_registrasi') + ->leftJoin('pbg_task_retributions AS ptr', 'pt.uuid', '=', 'ptr.pbg_task_uid') // Menambahkan join ke pbg_task_retributions + ->whereRaw('LOWER(TRIM(ptgs.status_verifikasi)) = ?', [strtolower(trim('Selesai Verifikasi'))]) + ->selectRaw('COUNT(pt.id) AS total_data, + SUM(ptr.nilai_retribusi_bangunan) AS total_retribution') + ->first(); + + $taskCount = $query->total_data; + $taskTotal = $query->total_retribution; + + $result = [ + "count"=> $taskCount, + "total"=> $taskTotal + ]; + + return $this->resSuccess($result); + } + + public function nonVerificationDocuments(){ + $query = DB::table('pbg_task AS pt') + ->leftJoin('pbg_task_google_sheet AS ptgs', 'pt.registration_number', '=', 'ptgs.no_registrasi') + ->leftJoin('pbg_task_retributions AS ptr', 'pt.uuid', '=', 'ptr.pbg_task_uid') // Join tabel pbg_task_retributions + ->where(function ($query) { + $query->whereRaw('LOWER(TRIM(ptgs.status_verifikasi)) != ?', [strtolower(trim('Selesai Verifikasi'))]) + ->orWhereNull('ptgs.status_verifikasi'); // Include NULL values + }) + ->selectRaw('COUNT(pt.id) AS total_data, + SUM(ptr.nilai_retribusi_bangunan) AS total_retribution') // Menambahkan SUM dari pbg_task_retributions + ->first(); + + $taskCount = $query->total_data; + $taskTotal = $query->total_retribution ?? 0; + + $result = [ + "count"=> $taskCount, + "total"=> $taskTotal + ]; + + return $this->resSuccess($result); + } + public function pbgTaskDocuments(Request $request){ $request->validate([ 'status' => 'required|string' diff --git a/app/Http/Controllers/Api/DataSettingController.php b/app/Http/Controllers/Api/DataSettingController.php new file mode 100644 index 0000000..ac5d1d4 --- /dev/null +++ b/app/Http/Controllers/Api/DataSettingController.php @@ -0,0 +1,104 @@ +orderBy('id', 'desc'); + if ($request->has("search") && !empty($request->get("search"))) { + $query = $query->where("key", $request->get("search")); + } + + return DataSettingResource::collection($query->paginate()); + } catch (Exception $e) { + return $this->resError($e->getMessage(), $e->getTrace()); + } + } + + /** + * Store a newly created resource in storage. + */ + public function store(DataSettingRequest $request) + { + try { + $data = DataSetting::create($request->validated()); + $result = [ + "success" => true, + "message" => "Data Setting created successfully", + "data" => new DataSettingResource($data) + ]; + return $this->resSuccess($result); + } catch (Exception $e) { + return $this->resError($e->getMessage(), $e); + } + } + + /** + * Display the specified resource. + */ + public function show(string $id) + { + try { + $setting = DataSetting::findOrFail($id); + $result = [ + "setting" => true, + "message" => "Data setting successfully", + "data" => new DataSettingResource($setting) + ]; + return $this->resSuccess($result); + } catch (Exception $e) { + return $this->resError($e->getMessage()); + } + } + + /** + * Update the specified resource in storage. + */ + public function update(DataSettingRequest $request, string $id) + { + try { + $data = DataSetting::findOrFail($id); + $data->update($request->validated()); + $result = [ + "success" => true, + "message" => "Data Setting updated successfully" + ]; + return $this->resSuccess($result); + } catch (Exception $e) { + return $this->resError($e->getMessage()); + } + } + + /** + * Remove the specified resource from storage. + */ + public function destroy(string $id) + { + try { + $setting = DataSetting::findOrFail($id); + $setting->delete(); + $result = [ + "success" => true, + "message" => "Data Setting deleted successfully" + ]; + return $this->resSuccess($result); + } catch (Exception $e) { + return $this->resError($e->getMessage()); + } + } +} diff --git a/app/Http/Controllers/Api/GoogleSheetController.php b/app/Http/Controllers/Api/GoogleSheetController.php new file mode 100644 index 0000000..7cad121 --- /dev/null +++ b/app/Http/Controllers/Api/GoogleSheetController.php @@ -0,0 +1,61 @@ +googleSheetService = $googleSheetService; + } + /** + * Display a listing of the resource. + */ + public function index() + { + $dataCollection = $this->googleSheetService->getSheetDataCollection(); + $result = [ + "last_row" => $this->googleSheetService->getLastRowByColumn("C"), + "last_column" => $this->googleSheetService->getLastColumn(), + "header" => $this->googleSheetService->getHeader(), + "data_collection" => $dataCollection + ]; + return response()->json($result); + } + + /** + * Store a newly created resource in storage. + */ + public function store(Request $request) + { + // + } + + /** + * Display the specified resource. + */ + public function show(string $id) + { + // + } + + /** + * Update the specified resource in storage. + */ + public function update(Request $request, string $id) + { + // + } + + /** + * Remove the specified resource from storage. + */ + public function destroy(string $id) + { + // + } +} diff --git a/app/Http/Controllers/Api/PbgTaskController.php b/app/Http/Controllers/Api/PbgTaskController.php new file mode 100644 index 0000000..0f7eb68 --- /dev/null +++ b/app/Http/Controllers/Api/PbgTaskController.php @@ -0,0 +1,291 @@ +googleSheetService = $googleSheetService; + } + public function index() + { + // + } + + /** + * Store a newly created resource in storage. + */ + public function store(PbgTaskMultiStepRequest $request) + { + try { + $data = PbgTask::create([ + "uuid" => $request->input("step1Form.uuid"), + "name" => $request->input("step1Form.name"), + "owner_name" => $request->input("step1Form.owner_name"), + "application_type" => $request->input("step1Form.application_type"), + "application_type_name" => $request->input("step1Form.application_type_name"), + "condition" => $request->input("step1Form.condition"), + "registration_number" => $request->input("step1Form.registration_number"), + "document_number" => $request->input("step1Form.document_number"), + "address" => $request->input("step1Form.address"), + "status" => $request->input("step1Form.status"), + "status_name" => $request->input("step1Form.status_name"), + "slf_status" => $request->input("step1Form.slf_status"), + "slf_status_name" => $request->input("step1Form.slf_status_name"), + "function_type" => $request->input("step1Form.function_type"), + "consultation_type" => $request->input("step1Form.consultation_type"), + "due_date" => $request->input("step1Form.due_date"), + "land_certificate_phase" => $request->input("step1Form.land_certificate_phase"), + "task_created_at" => $request->input("step1Form.task_created_at"), + ]); + + return response()->json([ + "success" => true, + "message" => "Step 1 berhasil disimpan!", + "data" => $data + ], 201); + } catch (\Exception $e) { + return response()->json([ + "success" => false, + "message" => "Gagal menyimpan data", + "error" => $e->getMessage() + ], 500); + } + } + + /** + * Display the specified resource. + */ + public function show(string $id) + { + // + } + + /** + * Update the specified resource in storage. + */ + public function update(Request $request, string $id) + { + // + } + + /** + * Remove the specified resource from storage. + */ + public function destroy(string $id) + { + // + } + + protected function validatePbgTask(Request $request){ + return $request->validate([ + "uuid" => $request->input("step1Form.uuid"), + ]); + } + + public function syncPbgFromGoogleSheet(){ + try{ + $totalRowCount = $this->googleSheetService->getLastRowByColumn("C"); + $sheetData = $this->googleSheetService->getSheetDataCollection($totalRowCount); + $mapToUpsert = []; + $count = 0; + foreach($sheetData as $data){ + $mapToUpsert[] = + [ + 'no_registrasi' => $data['no__registrasi'] ?? null, + 'jenis_konsultasi' => $data['jenis_konsultasi'] ?? null, + 'fungsi_bg' => $data['fungsi_bg'] ?? null, + 'tgl_permohonan' => $this->convertToDate($data['tgl_permohonan']), + 'status_verifikasi' => $data['status_verifikasi'] ?? null, + 'status_permohonan' => $this->convertToDate($data['status_permohonan']), + 'alamat_pemilik' => $data['alamat_pemilik'] ?? null, + 'no_hp' => $data['no__hp'] ?? null, + 'email' => $data['e_mail'] ?? null, + 'tanggal_catatan' => $this->convertToDate($data['tanggal_catatan']), + 'catatan_kekurangan_dokumen' => $data['catatan_kekurangan_dokumen'] ?? null, + 'gambar' => $data['gambar'] ?? null, + 'krk_kkpr' => $data['krk_kkpr'] ?? null, + 'no_krk' => $data['no__krk'] ?? null, + 'lh' => $data['lh'] ?? null, + 'ska' => $data['ska'] ?? null, + 'keterangan' => $data['keterangan'] ?? null, + 'helpdesk' => $data['helpdesk'] ?? null, + 'pj' => $data['pj'] ?? null, + 'kepemilikan' => $data['kepemilikan'] ?? null, + 'potensi_taru' => $data['potensi_taru'] ?? null, + 'validasi_dinas' => $data['validasi_dinas'] ?? null, + 'kategori_retribusi' => $data['kategori_retribusi'] ?? null, + 'no_urut_ba_tpt' => $data['no__urut_ba_tpt__2024_0001_'] ?? null, + 'tanggal_ba_tpt' => $this->convertToDate($data['tanggal_ba_tpt']), + 'no_urut_ba_tpa' => $data['no__urut_ba_tpa'] ?? null, + 'tanggal_ba_tpa' => $this->convertToDate($data['tanggal_ba_tpa']), + 'no_urut_skrd' => $data['no__urut_skrd__2024_0001_'] ?? null, + 'tanggal_skrd' => $this->convertToDate($data['tanggal_skrd']), + 'ptsp' => $data['ptsp'] ?? null, + 'selesai_terbit' => $data['selesai_terbit'] ?? null, + 'tanggal_pembayaran' => $this->convertToDate($data['tanggal_pembayaran__yyyy_mm_dd_']), + 'format_sts' => $data['format_sts'] ?? null, + 'tahun_terbit' => (int) $data['tahun_terbit'] ?? null, + 'tahun_berjalan' => (int) $data['tahun_berjalan'] ?? null, + 'kelurahan' => $data['kelurahan'] ?? null, + 'kecamatan' => $data['kecamatan'] ?? null, + 'lb' => $this->convertToDecimal($data['lb']) ?? null, + 'tb' => $this->convertToDecimal($data['tb']) ?? null, + 'jlb' => (int) $data['jlb'] ?? null, + 'unit' => (int) $data['unit'] ?? null, + 'usulan_retribusi' => (int) $data['usulan_retribusi'] ?? null, + 'nilai_retribusi_keseluruhan_simbg' => $this->convertToDecimal($data['nilai_retribusi_keseluruhan__simbg_']) ?? null, + 'nilai_retribusi_keseluruhan_pad' => $this->convertToDecimal($data['nilai_retribusi_keseluruhan__pad_']) ?? null, + 'denda' => $this->convertToDecimal($data['denda']) ?? null, + 'latitude' => $data['latitude'] ?? null, + 'longitude' => $data['longitude'] ?? null, + 'nik_nib' => $data['nik_nib'] ?? null, + 'dok_tanah' => $data['dok__tanah'] ?? null, + 'temuan' => $data['temuan'] ?? null, + ]; + } + + DB::beginTransaction(); + + $batchSize = 1000; + $chunks = array_chunk($mapToUpsert, $batchSize); + + foreach($chunks as $chunk){ + PbgTaskGoogleSheet::upsert($chunk, ["no_registrasi"],[ + 'jenis_konsultasi', + 'nama_pemilik', + 'lokasi_bg', + 'fungsi_bg', + 'nama_bangunan', + 'tgl_permohonan', + 'status_verifikasi', + 'status_permohonan', + 'alamat_pemilik', + 'no_hp', + 'email', + 'tanggal_catatan', + 'catatan_kekurangan_dokumen', + 'gambar', + 'krk_kkpr', + 'no_krk', + 'lh', + 'ska', + 'keterangan', + 'helpdesk', + 'pj', + 'kepemilikan', + 'potensi_taru', + 'validasi_dinas', + 'kategori_retribusi', + 'no_urut_ba_tpt', + 'tanggal_ba_tpt', + 'no_urut_ba_tpa', + 'tanggal_ba_tpa', + 'no_urut_skrd', + 'tanggal_skrd', + 'ptsp', + 'selesai_terbit', + 'tanggal_pembayaran', + 'format_sts', + 'tahun_terbit', + 'tahun_berjalan', + 'kelurahan', + 'kecamatan', + 'lb', + 'tb', + 'jlb', + 'unit', + 'usulan_retribusi', + 'nilai_retribusi_keseluruhan_simbg', + 'nilai_retribusi_keseluruhan_pad', + 'denda', + 'latitude', + 'longitude', + 'nik_nib', + 'dok_tanah', + 'temuan', + ]); + } + + DB::commit(); + + return response()->json([ + "success" => true, + "message" => "Data berhasil disimpan ke database" + ], 200); + }catch(\Exception $ex){ + DB::rollBack(); + return response()->json([ + "success" => false, + "message" => "Gagal menyimpan data", + "error" => $ex->getMessage() + ], 500); + } + } + + protected function convertToDecimal(?string $value): ?float + { + if (empty($value)) { + return null; // Return null if the input is empty + } + + // Remove all non-numeric characters except comma and dot + $value = preg_replace('/[^0-9,\.]/', '', $value); + + // If the number contains both dot (.) and comma (,) + if (strpos($value, '.') !== false && strpos($value, ',') !== false) { + $value = str_replace('.', '', $value); // Remove thousands separator + $value = str_replace(',', '.', $value); // Convert decimal separator to dot + } + // If only a dot is present (assumed as thousands separator) + elseif (strpos($value, '.') !== false) { + $value = str_replace('.', '', $value); // Remove all dots (treat as thousands separators) + } + // If only a comma is present (assumed as decimal separator) + elseif (strpos($value, ',') !== false) { + $value = str_replace(',', '.', $value); // Convert comma to dot (decimal separator) + } + + // Ensure the value is numeric before returning + return is_numeric($value) ? (float) number_format((float) $value, 2, '.', '') : null; + } + + protected function convertToInteger($value) { + // Check if the value is an empty string, and return null if true + if (trim($value) === "") { + return null; + } + + // Otherwise, cast to integer + return (int) $value; + } + + protected function convertToDate($dateString) + { + try { + // Check if the string is empty + if (empty($dateString)) { + return null; + } + + // Try to parse the date string + $date = Carbon::parse($dateString); + + // Return the Carbon instance + return $date->format('Y-m-d'); + } catch (\Exception $e) { + // Return null if an error occurs during parsing + return null; + } + } +} diff --git a/app/Http/Controllers/Api/RequestAssignmentController.php b/app/Http/Controllers/Api/RequestAssignmentController.php index 10d4319..56605f5 100644 --- a/app/Http/Controllers/Api/RequestAssignmentController.php +++ b/app/Http/Controllers/Api/RequestAssignmentController.php @@ -14,9 +14,10 @@ class RequestAssignmentController extends Controller */ public function index(Request $request) { - $query = PbgTask::query(); + $query = PbgTask::query()->orderBy('id', 'desc'); if($request->has('search') && !empty($request->get("search"))){ - $query->where('name', 'LIKE', '%'.$request->get('search').'%'); + $query->where('name', 'LIKE', '%'.$request->get('search').'%') + ->orWhere('registration_number', 'LIKE', '%'.$request->get('search').'%'); } return RequestAssignmentResouce::collection($query->paginate()); } diff --git a/app/Http/Controllers/DataSettingController.php b/app/Http/Controllers/DataSettingController.php new file mode 100644 index 0000000..872f87d --- /dev/null +++ b/app/Http/Controllers/DataSettingController.php @@ -0,0 +1,120 @@ +validated()); + DB::commit(); + return redirect()->route("data-settings.index")->with("success","Successfully created"); + }catch(Exception $ex){ + DB::rollBack(); + return redirect()->back() + ->withInput() + ->with('error', 'Something went wrong while saving data. ' . $ex->getMessage()); + } + } + + /** + * Display the specified resource. + */ + public function show(DataSetting $dataSetting) + { + // + } + + /** + * Show the form for editing the specified resource. + */ + public function edit(string $id) + { + try{ + $data = DataSetting::findOrFail($id); + if(empty($data)){ + return redirect()->route('data-settings.index')->with('error', 'Invalid id'); + } + return view("data-settings.edit", compact("data")); + }catch(Exception $ex){ + return redirect()->route("data-settings.index")->with("error", "Invalid id"); + } + } + + /** + * Update the specified resource in storage. + */ + public function update(DataSettingRequest $request,string $id) + { + try{ + DB::beginTransaction(); + $data = DataSetting::findOrFail($id); + $data->update($request->validated()); + DB::commit(); + return redirect()->route("data-settings.index")->with("success","Successfully updated"); + }catch(Exception $ex){ + DB::rollBack(); + return redirect()->back() + ->withInput() + ->with('error', 'Something went wrong while saving data. ' . $ex->getMessage()); + } + } + + /** + * Remove the specified resource from storage. + */ + public function destroy(string $id) + { + try{ + DB::beginTransaction(); + DataSetting::findOrFail($id)->delete(); + DB::commit(); + return response()->json(['success' => true, 'message' => 'Item deleted successfully.']); + }catch(Exception $e){ + DB::rollBack(); + Log::error($e->getMessage()); + return response()->json(['success' => false, 'message' => 'Failed to delete item.'], 500); + } + } + + public function getValueSetting(Request $request){ + try{ + $data = DataSetting::where('key', $request->key_name)->first(); + return response()->json([ + 'success' => true, + 'message' => "Successfully retrieved data", + "data"=> $data + ]); + }catch(Exception $e){ + return response()->json(['success' => false, 'message' => $e->getMessage()], 500); + } + } +} diff --git a/app/Http/Controllers/RequestAssignment/PbgTaskController.php b/app/Http/Controllers/RequestAssignment/PbgTaskController.php index 395ca33..d2e0cdf 100644 --- a/app/Http/Controllers/RequestAssignment/PbgTaskController.php +++ b/app/Http/Controllers/RequestAssignment/PbgTaskController.php @@ -12,7 +12,7 @@ class PbgTaskController extends Controller */ public function index() { - return view('request-assignment.index'); + return view('pbg_task.index'); } /** @@ -20,7 +20,7 @@ class PbgTaskController extends Controller */ public function create() { - // + return view("pbg_task.create"); } /** @@ -28,7 +28,7 @@ class PbgTaskController extends Controller */ public function store(Request $request) { - // + } /** @@ -36,7 +36,7 @@ class PbgTaskController extends Controller */ public function show(string $id) { - // + return view("pbg_task.show"); } /** @@ -44,7 +44,7 @@ class PbgTaskController extends Controller */ public function edit(string $id) { - // + return view("pbg_task.edit"); } /** diff --git a/app/Http/Controllers/RoutingController.php b/app/Http/Controllers/RoutingController.php index 6392e29..2bb3b5f 100755 --- a/app/Http/Controllers/RoutingController.php +++ b/app/Http/Controllers/RoutingController.php @@ -15,30 +15,4 @@ class RoutingController extends Controller return redirect('auth.signin'); } } - - /** - * Display a view based on first route param - * - * @return \Illuminate\Http\Response - */ - public function root(Request $request, $first) - { - return view($first); - } - - /** - * second level route - */ - public function secondLevel(Request $request, $first, $second) - { - return view($first . '.' . $second); - } - - /** - * third level route - */ - public function thirdLevel(Request $request, $first, $second, $third) - { - return view($first . '.' . $second . '.' . $third); - } } diff --git a/app/Http/Requests/DataSettingRequest.php b/app/Http/Requests/DataSettingRequest.php new file mode 100644 index 0000000..2305e39 --- /dev/null +++ b/app/Http/Requests/DataSettingRequest.php @@ -0,0 +1,31 @@ +|string> + */ + public function rules(): array + { + $id = $this->route('data_setting'); + return [ + "key" => "required|unique:data_settings,key," . $id, + "value" => "required", + "type" => "nullable", + ]; + } +} diff --git a/app/Http/Requests/PbgTaskMultiStepRequest.php b/app/Http/Requests/PbgTaskMultiStepRequest.php new file mode 100644 index 0000000..e76af85 --- /dev/null +++ b/app/Http/Requests/PbgTaskMultiStepRequest.php @@ -0,0 +1,62 @@ +|string> + */ + public function rules() + { + return [ + // rules step 1 + "step1Form.uuid" => "required", + "step1Form.name" => "nullable|string|max:255", + "step1Form.owner_name" => "nullable|string|max:255", + "step1Form.application_type" => "nullable|string|max:255", + "step1Form.application_type_name" => "nullable|string|max:255", + "step1Form.condition" => "nullable|string|max:255", + "step1Form.registration_number" => "nullable|string|max:255", + "step1Form.document_number" => "nullable|string|max:255", + "step1Form.address" => "nullable|string|max:255", + "step1Form.status" => "nullable|integer", + "step1Form.status_name" => "nullable|string|max:255", + "step1Form.slf_status" => "nullable|string|max:255", + "step1Form.slf_status_name" => "nullable|string|max:255", + "step1Form.function_type" => "nullable|string|max:255", + "step1Form.consultation_type" => "nullable|string|max:255", + "step1Form.due_date" => "nullable|date", + "step1Form.land_certificate_phase" => "nullable|boolean", + "step1Form.task_created_at" => "nullable|date", + ]; + } + + public function messages() + { + return [ + // message step 1 + "step1Form.uuid.required" => "UUID wajib diisi.", + "step1Form.uuid.uuid" => "Format UUID tidak valid.", + "step1Form.name.max" => "Nama tidak boleh lebih dari 255 karakter.", + "step1Form.owner_name.max" => "Nama pemilik tidak boleh lebih dari 255 karakter.", + "step1Form.registration_number.max" => "Nomor registrasi tidak boleh lebih dari 255 karakter.", + "step1Form.document_number.max" => "Nomor dokumen tidak boleh lebih dari 255 karakter.", + "step1Form.status.integer" => "Status harus berupa angka.", + "step1Form.due_date.date" => "Tanggal jatuh tempo tidak valid.", + "step1Form.land_certificate_phase.boolean" => "Fase sertifikat tanah harus berupa true/false.", + ]; + } +} diff --git a/app/Http/Resources/DataSettingResource.php b/app/Http/Resources/DataSettingResource.php new file mode 100644 index 0000000..3cc1d14 --- /dev/null +++ b/app/Http/Resources/DataSettingResource.php @@ -0,0 +1,26 @@ + + */ + public function toArray(Request $request): array + { + return [ + 'id' => $this->id, + 'key' => $this->key, + 'value' => $this->value, + 'type' => $this->type, + 'created_at' => $this->created_at->toDateTimeString(), + 'updated_at' => $this->updated_at->toDateTimeString(), + ]; + } +} diff --git a/app/Models/DataSetting.php b/app/Models/DataSetting.php new file mode 100644 index 0000000..8ac2f87 --- /dev/null +++ b/app/Models/DataSetting.php @@ -0,0 +1,15 @@ +get($url, $headers); + + Log::info("response index integration", ['res' => $res]); if (empty($res->original['success']) || !$res->original['success']) { // Log error @@ -128,9 +130,10 @@ class ServiceSIMBG $savedCount = $failedCount = 0; - for ($currentPage = 1; $currentPage <= $totalPage; $currentPage++) { + for ($currentPage = 50; $currentPage <= $totalPage; $currentPage++) { $pageUrl = "/api/pbg/v1/list/?page={$currentPage}&size={$this->fetch_per_page}&sort=ASC"; $getToken = $this->getToken(); + Log::info("response index integration", ['currentPage' => $currentPage]); if (empty($getToken->original['data']['token']['access'])) { $importDatasource->update([ 'status' => ImportDatasourceStatus::Failed->value, @@ -227,6 +230,8 @@ class ServiceSIMBG $res = $clientHelper->get($url, $headers); + Log::info("response task detail submit", ['res' => $res]); + if (empty($res->original['success']) || !$res->original['success']) { // Log error Log::error("API response indicates failure", ['url' => $url, 'uuid' => $uuid]); diff --git a/app/Services/GoogleSheetService.php b/app/Services/GoogleSheetService.php new file mode 100644 index 0000000..8118347 --- /dev/null +++ b/app/Services/GoogleSheetService.php @@ -0,0 +1,131 @@ +client = new Google_Client(); + $this->client->setApplicationName("Sibedas Google Sheets API"); + $this->client->setScopes([Google_Service_Sheets::SPREADSHEETS_READONLY]); + $this->client->setAuthConfig(storage_path("app/teak-banner-450003-s8-ea05661d9db0.json")); + $this->client->setAccessType("offline"); + + $this->service = new Google_Service_Sheets($this->client); + $this->spreadsheetID = env("SPREAD_SHEET_ID"); + + $this->service_sheets = new Google_Service_Sheets($this->client); + } + + public function getSheetData($range){ + $response = $this->service->spreadsheets_values->get($this->spreadsheetID, $range); + return $response->getValues(); + } + + public function getLastRowByColumn($column = "A") + { + // Ambil spreadsheet + $spreadsheet = $this->service->spreadsheets->get($this->spreadsheetID); + $sheets = $spreadsheet->getSheets(); + + if (!empty($sheets)) { + // Ambil nama sheet pertama dengan benar + $firstSheetTitle = $sheets[0]->getProperties()->getTitle(); + + // ✅ Format range harus benar! + $range = "{$firstSheetTitle}!{$column}:{$column}"; + + // Ambil data dari kolom yang diminta + $response = $this->service->spreadsheets_values->get($this->spreadsheetID, $range); + $values = $response->getValues(); + + // Cek nilai terakhir yang tidak kosong + $lastRow = 0; + if (!empty($values)) { + foreach ($values as $index => $row) { + if (!empty($row[0])) { // Jika ada data, update lastRow + $lastRow = $index + 1; + } + } + } + + return $lastRow; + } + + return 0; + } + public function getHeader() + { + $spreadsheet = $this->service->spreadsheets->get($this->spreadsheetID); + $sheets = $spreadsheet->getSheets(); + + // Ambil nama sheet pertama + $firstSheetTitle = $sheets[0]->getProperties()->getTitle(); + + // Ambil data dari baris pertama (header) + $range = "{$firstSheetTitle}!1:1"; + $response = $this->service->spreadsheets_values->get($this->spreadsheetID, $range); + $values = $response->getValues(); + + // Kembalikan header (baris pertama) + return !empty($values) ? $values[0] : []; + } + + public function getLastColumn() + { + $spreadsheet = $this->service->spreadsheets->get($this->spreadsheetID); + $sheets = $spreadsheet->getSheets(); + + // Ambil nama sheet pertama + $firstSheetTitle = $sheets[0]->getProperties()->getTitle(); + + // Ambil baris pertama untuk mendapatkan jumlah kolom yang terisi + $range = "{$firstSheetTitle}!1:1"; + $response = $this->service->spreadsheets_values->get($this->spreadsheetID, $range); + $values = $response->getValues(); + + // Hitung jumlah kolom yang memiliki nilai + return !empty($values) ? count(array_filter($values[0], fn($value) => $value !== "")) : 0; + } + + public function getSheetDataCollection($totalRow = 10){ + $spreadsheet = $this->service->spreadsheets->get($this->spreadsheetID); + $sheets = $spreadsheet->getSheets(); + $firstSheetTitle = $sheets[0]->getProperties()->getTitle(); + + $header = $this->getHeader(); + $header = array_map(function($columnHeader) { + // Trim spaces first, then replace non-alphanumeric characters with underscores + $columnHeader = trim($columnHeader); + return strtolower(preg_replace('/[^A-Za-z0-9_]/', '_', $columnHeader)); + }, $header); + $range = "{$firstSheetTitle}!2:{$totalRow}"; + + $response = $this->service->spreadsheets_values->get($this->spreadsheetID, $range); + $values = $response->getValues(); + + $mappedData = []; + if (!empty($values)) { + foreach ($values as $row) { + $rowData = []; + foreach ($header as $index => $columnHeader) { + // Map header to the corresponding value from the row + $rowData[$columnHeader] = isset($row[$index]) ? $row[$index] : null; + } + $mappedData[] = $rowData; + } + } + + return $mappedData; + } +} diff --git a/composer.json b/composer.json index e2276de..1c44a58 100755 --- a/composer.json +++ b/composer.json @@ -7,6 +7,7 @@ "license": "MIT", "require": { "php": "^8.2", + "google/apiclient": "^2.12", "guzzlehttp/guzzle": "^7.9", "laravel/framework": "^11.31", "laravel/sanctum": "^4.0", diff --git a/composer.lock b/composer.lock index 3dd62c7..f1e8843 100755 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "7bb7c3b4b4eb50972252c4683f797104", + "content-hash": "3fea2988b5efebfd50ec7c29aeae3830", "packages": [ { "name": "brick/math", @@ -510,6 +510,69 @@ ], "time": "2024-12-27T00:36:43+00:00" }, + { + "name": "firebase/php-jwt", + "version": "v6.11.0", + "source": { + "type": "git", + "url": "https://github.com/firebase/php-jwt.git", + "reference": "8f718f4dfc9c5d5f0c994cdfd103921b43592712" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/8f718f4dfc9c5d5f0c994cdfd103921b43592712", + "reference": "8f718f4dfc9c5d5f0c994cdfd103921b43592712", + "shasum": "" + }, + "require": { + "php": "^8.0" + }, + "require-dev": { + "guzzlehttp/guzzle": "^7.4", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.5", + "psr/cache": "^2.0||^3.0", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0" + }, + "suggest": { + "ext-sodium": "Support EdDSA (Ed25519) signatures", + "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present" + }, + "type": "library", + "autoload": { + "psr-4": { + "Firebase\\JWT\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Neuman Vong", + "email": "neuman+pear@twilio.com", + "role": "Developer" + }, + { + "name": "Anant Narayanan", + "email": "anant@php.net", + "role": "Developer" + } + ], + "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", + "homepage": "https://github.com/firebase/php-jwt", + "keywords": [ + "jwt", + "php" + ], + "support": { + "issues": "https://github.com/firebase/php-jwt/issues", + "source": "https://github.com/firebase/php-jwt/tree/v6.11.0" + }, + "time": "2025-01-23T05:11:06+00:00" + }, { "name": "fruitcake/php-cors", "version": "v1.3.0", @@ -581,6 +644,180 @@ ], "time": "2023-10-12T05:21:21+00:00" }, + { + "name": "google/apiclient", + "version": "v2.18.2", + "source": { + "type": "git", + "url": "https://github.com/googleapis/google-api-php-client.git", + "reference": "d8d201ba8a189a3cd7fb34e4da569f2ed440eee7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/googleapis/google-api-php-client/zipball/d8d201ba8a189a3cd7fb34e4da569f2ed440eee7", + "reference": "d8d201ba8a189a3cd7fb34e4da569f2ed440eee7", + "shasum": "" + }, + "require": { + "firebase/php-jwt": "^6.0", + "google/apiclient-services": "~0.350", + "google/auth": "^1.37", + "guzzlehttp/guzzle": "^7.4.5", + "guzzlehttp/psr7": "^2.6", + "monolog/monolog": "^2.9||^3.0", + "php": "^8.0", + "phpseclib/phpseclib": "^3.0.36" + }, + "require-dev": { + "cache/filesystem-adapter": "^1.1", + "composer/composer": "^1.10.23", + "phpcompatibility/php-compatibility": "^9.2", + "phpspec/prophecy-phpunit": "^2.1", + "phpunit/phpunit": "^9.6", + "squizlabs/php_codesniffer": "^3.8", + "symfony/css-selector": "~2.1", + "symfony/dom-crawler": "~2.1" + }, + "suggest": { + "cache/filesystem-adapter": "For caching certs and tokens (using Google\\Client::setCache)" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.x-dev" + } + }, + "autoload": { + "files": [ + "src/aliases.php" + ], + "psr-4": { + "Google\\": "src/" + }, + "classmap": [ + "src/aliases.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "description": "Client library for Google APIs", + "homepage": "http://developers.google.com/api-client-library/php", + "keywords": [ + "google" + ], + "support": { + "issues": "https://github.com/googleapis/google-api-php-client/issues", + "source": "https://github.com/googleapis/google-api-php-client/tree/v2.18.2" + }, + "time": "2024-12-16T22:52:40+00:00" + }, + { + "name": "google/apiclient-services", + "version": "v0.393.0", + "source": { + "type": "git", + "url": "https://github.com/googleapis/google-api-php-client-services.git", + "reference": "ed24c09584df8ef0cdcfb9d4305abf66fc17e609" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/ed24c09584df8ef0cdcfb9d4305abf66fc17e609", + "reference": "ed24c09584df8ef0cdcfb9d4305abf66fc17e609", + "shasum": "" + }, + "require": { + "php": "^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.6" + }, + "type": "library", + "autoload": { + "files": [ + "autoload.php" + ], + "psr-4": { + "Google\\Service\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "description": "Client library for Google APIs", + "homepage": "http://developers.google.com/api-client-library/php", + "keywords": [ + "google" + ], + "support": { + "issues": "https://github.com/googleapis/google-api-php-client-services/issues", + "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.393.0" + }, + "time": "2025-02-03T00:54:21+00:00" + }, + { + "name": "google/auth", + "version": "v1.45.3", + "source": { + "type": "git", + "url": "https://github.com/googleapis/google-auth-library-php.git", + "reference": "000d9439f430c6e56cba105c5ab750f5f7d69ea8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/googleapis/google-auth-library-php/zipball/000d9439f430c6e56cba105c5ab750f5f7d69ea8", + "reference": "000d9439f430c6e56cba105c5ab750f5f7d69ea8", + "shasum": "" + }, + "require": { + "firebase/php-jwt": "^6.0", + "guzzlehttp/guzzle": "^7.4.5", + "guzzlehttp/psr7": "^2.4.5", + "php": "^8.0", + "psr/cache": "^2.0||^3.0", + "psr/http-message": "^1.1||^2.0", + "psr/log": "^3.0" + }, + "require-dev": { + "guzzlehttp/promises": "^2.0", + "kelvinmo/simplejwt": "0.7.1", + "phpseclib/phpseclib": "^3.0.35", + "phpspec/prophecy-phpunit": "^2.1", + "phpunit/phpunit": "^9.6", + "sebastian/comparator": ">=1.2.3", + "squizlabs/php_codesniffer": "^3.5", + "symfony/process": "^6.0||^7.0", + "webmozart/assert": "^1.11" + }, + "suggest": { + "phpseclib/phpseclib": "May be used in place of OpenSSL for signing strings or for token management. Please require version ^2." + }, + "type": "library", + "autoload": { + "psr-4": { + "Google\\Auth\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "description": "Google Auth Library for PHP", + "homepage": "https://github.com/google/google-auth-library-php", + "keywords": [ + "Authentication", + "google", + "oauth2" + ], + "support": { + "docs": "https://googleapis.github.io/google-auth-library-php/main/", + "issues": "https://github.com/googleapis/google-auth-library-php/issues", + "source": "https://github.com/googleapis/google-auth-library-php/tree/v1.45.3" + }, + "time": "2025-01-29T18:17:08+00:00" + }, { "name": "graham-campbell/result-type", "version": "v1.1.3", @@ -2572,6 +2809,123 @@ ], "time": "2024-11-21T10:39:51+00:00" }, + { + "name": "paragonie/constant_time_encoding", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/paragonie/constant_time_encoding.git", + "reference": "df1e7fde177501eee2037dd159cf04f5f301a512" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/df1e7fde177501eee2037dd159cf04f5f301a512", + "reference": "df1e7fde177501eee2037dd159cf04f5f301a512", + "shasum": "" + }, + "require": { + "php": "^8" + }, + "require-dev": { + "phpunit/phpunit": "^9", + "vimeo/psalm": "^4|^5" + }, + "type": "library", + "autoload": { + "psr-4": { + "ParagonIE\\ConstantTime\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com", + "role": "Maintainer" + }, + { + "name": "Steve 'Sc00bz' Thomas", + "email": "steve@tobtu.com", + "homepage": "https://www.tobtu.com", + "role": "Original Developer" + } + ], + "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", + "keywords": [ + "base16", + "base32", + "base32_decode", + "base32_encode", + "base64", + "base64_decode", + "base64_encode", + "bin2hex", + "encoding", + "hex", + "hex2bin", + "rfc4648" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/constant_time_encoding/issues", + "source": "https://github.com/paragonie/constant_time_encoding" + }, + "time": "2024-05-08T12:36:18+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v9.99.100", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", + "shasum": "" + }, + "require": { + "php": ">= 7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/random_compat/issues", + "source": "https://github.com/paragonie/random_compat" + }, + "time": "2020-10-15T08:29:30+00:00" + }, { "name": "phpoption/phpoption", "version": "1.9.3", @@ -2647,6 +3001,165 @@ ], "time": "2024-07-20T21:41:07+00:00" }, + { + "name": "phpseclib/phpseclib", + "version": "3.0.43", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/phpseclib.git", + "reference": "709ec107af3cb2f385b9617be72af8cf62441d02" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/709ec107af3cb2f385b9617be72af8cf62441d02", + "reference": "709ec107af3cb2f385b9617be72af8cf62441d02", + "shasum": "" + }, + "require": { + "paragonie/constant_time_encoding": "^1|^2|^3", + "paragonie/random_compat": "^1.4|^2.0|^9.99.99", + "php": ">=5.6.1" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "suggest": { + "ext-dom": "Install the DOM extension to load XML formatted public keys.", + "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", + "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", + "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", + "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." + }, + "type": "library", + "autoload": { + "files": [ + "phpseclib/bootstrap.php" + ], + "psr-4": { + "phpseclib3\\": "phpseclib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" + }, + { + "name": "Patrick Monnerat", + "email": "pm@datasphere.ch", + "role": "Developer" + }, + { + "name": "Andreas Fischer", + "email": "bantu@phpbb.com", + "role": "Developer" + }, + { + "name": "Hans-Jürgen Petrich", + "email": "petrich@tronic-media.com", + "role": "Developer" + }, + { + "name": "Graham Campbell", + "email": "graham@alt-three.com", + "role": "Developer" + } + ], + "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", + "homepage": "http://phpseclib.sourceforge.net", + "keywords": [ + "BigInteger", + "aes", + "asn.1", + "asn1", + "blowfish", + "crypto", + "cryptography", + "encryption", + "rsa", + "security", + "sftp", + "signature", + "signing", + "ssh", + "twofish", + "x.509", + "x509" + ], + "support": { + "issues": "https://github.com/phpseclib/phpseclib/issues", + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.43" + }, + "funding": [ + { + "url": "https://github.com/terrafrost", + "type": "github" + }, + { + "url": "https://www.patreon.com/phpseclib", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", + "type": "tidelift" + } + ], + "time": "2024-12-14T21:12:59+00:00" + }, + { + "name": "psr/cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "support": { + "source": "https://github.com/php-fig/cache/tree/3.0.0" + }, + "time": "2021-02-03T23:26:27+00:00" + }, { "name": "psr/clock", "version": "1.0.0", diff --git a/database/migrations/2025_02_04_133926_create_data_settings_table.php b/database/migrations/2025_02_04_133926_create_data_settings_table.php new file mode 100644 index 0000000..b4ee77e --- /dev/null +++ b/database/migrations/2025_02_04_133926_create_data_settings_table.php @@ -0,0 +1,30 @@ +id(); + $table->string('key')->unique(); + $table->string('value'); + $table->string('type')->nullable()->default('integer'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('data_settings'); + } +}; diff --git a/database/migrations/2025_02_05_162953_create_pbg_task_google_sheet.php b/database/migrations/2025_02_05_162953_create_pbg_task_google_sheet.php new file mode 100644 index 0000000..07fb562 --- /dev/null +++ b/database/migrations/2025_02_05_162953_create_pbg_task_google_sheet.php @@ -0,0 +1,80 @@ +id(); + $table->string('jenis_konsultasi')->nullable(); + $table->string('no_registrasi')->nullable()->unique(); + $table->string('nama_pemilik')->nullable(); + $table->text('lokasi_bg')->nullable(); + $table->string('fungsi_bg')->nullable(); + $table->string('nama_bangunan')->nullable(); + $table->date('tgl_permohonan')->nullable(); + $table->string('status_verifikasi')->nullable(); + $table->string('status_permohonan')->nullable(); + $table->text('alamat_pemilik')->nullable(); + $table->string('no_hp')->nullable(); + $table->string('email')->nullable(); + $table->date('tanggal_catatan')->nullable(); + $table->text('catatan_kekurangan_dokumen')->nullable(); + $table->string('gambar')->nullable(); + $table->string('krk_kkpr')->nullable(); + $table->string('no_krk')->nullable(); + $table->string('lh')->nullable(); + $table->string('ska')->nullable(); + $table->text('keterangan')->nullable(); + $table->string('helpdesk')->nullable(); + $table->string('pj')->nullable(); + $table->string('kepemilikan')->nullable(); + $table->string('potensi_taru')->nullable(); + $table->string('validasi_dinas')->nullable(); + $table->string('kategori_retribusi')->nullable(); + $table->string('no_urut_ba_tpt')->nullable(); + $table->date('tanggal_ba_tpt')->nullable(); + $table->string('no_urut_ba_tpa')->nullable(); + $table->date('tanggal_ba_tpa')->nullable(); + $table->string('no_urut_skrd')->nullable(); + $table->date('tanggal_skrd')->nullable(); + $table->string('ptsp')->nullable(); + $table->string('selesai_terbit')->nullable(); + $table->date('tanggal_pembayaran')->nullable(); + $table->string('format_sts')->nullable(); + $table->integer('tahun_terbit')->nullable(); + $table->integer('tahun_berjalan')->nullable(); + $table->string('kelurahan')->nullable(); + $table->string('kecamatan')->nullable(); + $table->decimal('lb', 20,2)->nullable(); + $table->decimal('tb', 20, 2)->nullable(); + $table->integer('jlb')->nullable(); + $table->integer('unit')->nullable(); + $table->integer('usulan_retribusi')->nullable(); + $table->decimal('nilai_retribusi_keseluruhan_simbg', 20, 2)->nullable(); + $table->decimal('nilai_retribusi_keseluruhan_pad', 20, 2)->nullable(); + $table->decimal('denda', 20, 2)->nullable(); + $table->string('latitude')->nullable(); + $table->string('longitude')->nullable(); + $table->string('nik_nib')->nullable(); + $table->string('dok_tanah')->nullable(); + $table->text('temuan')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('pbg_task_google_sheet'); + } +}; diff --git a/database/migrations/2025_02_05_164238_modify_uuid_in_pbg_task.php b/database/migrations/2025_02_05_164238_modify_uuid_in_pbg_task.php new file mode 100644 index 0000000..7af5337 --- /dev/null +++ b/database/migrations/2025_02_05_164238_modify_uuid_in_pbg_task.php @@ -0,0 +1,28 @@ +string('uuid')->nullable()->unique()->change(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('pbg_task', function (Blueprint $table) { + $table->string('uuid')->nullable()->change(); + }); + } +}; diff --git a/database/migrations/2025_02_05_184032_modify_pbg_task_uid_in_pbg_task_index_integrations.php b/database/migrations/2025_02_05_184032_modify_pbg_task_uid_in_pbg_task_index_integrations.php new file mode 100644 index 0000000..296fef9 --- /dev/null +++ b/database/migrations/2025_02_05_184032_modify_pbg_task_uid_in_pbg_task_index_integrations.php @@ -0,0 +1,28 @@ +string('pbg_task_uid')->unique()->change(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('pbg_task_index_integrations', function (Blueprint $table) { + $table->string('pbg_task_uid')->unique()->change(); + }); + } +}; diff --git a/database/migrations/2025_02_05_185048_modify_detail_id_in_pbg_task_retributions.php b/database/migrations/2025_02_05_185048_modify_detail_id_in_pbg_task_retributions.php new file mode 100644 index 0000000..8d9c311 --- /dev/null +++ b/database/migrations/2025_02_05_185048_modify_detail_id_in_pbg_task_retributions.php @@ -0,0 +1,28 @@ +string('detail_id')->unique()->change(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('pbg_task_retributions', function (Blueprint $table) { + $table->string('detail_id')->unique()->change(); + }); + } +}; diff --git a/database/seeders/DataSettingSeeder.php b/database/seeders/DataSettingSeeder.php new file mode 100644 index 0000000..2303d5b --- /dev/null +++ b/database/seeders/DataSettingSeeder.php @@ -0,0 +1,35 @@ + "TARGET_PAD", + "value" => "33.200.000.000", + "type" => "integer" + ] + ]; + + foreach ($data_settings as $setting) { + DataSetting::updateOrCreate([ + "key" => $setting["key"], + ],[ + "value" => $setting["value"], + "type" => $setting["type"], + "created_at" => now(), + "updated_at" => now(), + ]); + } + } +} diff --git a/package-lock.json b/package-lock.json index 6861a22..96e09d5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,6 +6,7 @@ "": { "dependencies": { "apexcharts": "^3.44.2", + "big.js": "^6.2.2", "bootstrap": "^5.3.3", "countup.js": "^2.3.2", "dropzone": "^5.9.0", @@ -477,6 +478,19 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/big.js": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-6.2.2.tgz", + "integrity": "sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==", + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/bigjs" + } + }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", diff --git a/package.json b/package.json index 69ca869..23afe1f 100755 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ }, "dependencies": { "apexcharts": "^3.44.2", + "big.js": "^6.2.2", "bootstrap": "^5.3.3", "countup.js": "^2.3.2", "dropzone": "^5.9.0", diff --git a/public/index.php b/public/index.php index 947d989..ee72fab 100755 --- a/public/index.php +++ b/public/index.php @@ -4,6 +4,8 @@ use Illuminate\Http\Request; define('LARAVEL_START', microtime(true)); +ini_set('max_execution_time',14400); + // Determine if the application is in maintenance mode... if (file_exists($maintenance = __DIR__.'/../storage/framework/maintenance.php')) { require $maintenance; diff --git a/resources/js/dashboards/bigdata.js b/resources/js/dashboards/bigdata.js index 8bb04c5..c50eacf 100644 --- a/resources/js/dashboards/bigdata.js +++ b/resources/js/dashboards/bigdata.js @@ -1,13 +1,83 @@ -import ApexCharts from "apexcharts"; - +import Big from "big.js"; import GlobalConfig, { addThousandSeparators } from "../global-config.js"; class BigData { async init() { - try{ - this.resultDataTotal = await this.getTotalAllTask(); + try { + this.totalTargetPAD = await this.getTargetPAD(); + this.resultDataTotal = await this.getDataTotalPotensi(); + this.dataVerification = await this.getDataVerfication(); + this.dataNonVerification = await this.getDataNonVerfication(); + this.dataBusiness = await this.getDataBusiness(); + this.dataNonBusiness = await this.getDataNonBusiness(); - if (!this.resultDataTotal) { + // total potensi + this.bigTargetPAD = new Big(this.totalTargetPAD ?? 0); + this.bigTotalPotensi = new Big(this.resultDataTotal.totalData ?? 0); + + this.resultPercentage = 0; + if (this.bigTotalPotensi > 0 && this.bigTargetPAD > 0) { + this.resultPercentage = this.bigTotalPotensi + .div(this.bigTargetPAD) + .times(100) + .toFixed(2); + if (this.resultPercentage > 100) { + this.resultPercentage = 100; + } + } + + // kekurangan potensi + this.totalKekuranganPotensi = new Big( + this.totalTargetPAD - this.bigTotalPotensi + ); + this.percentageKekuranganPotensi = + this.totalKekuranganPotensi <= 0 || this.totalTargetPAD <= 0 + ? 0 + : this.totalKekuranganPotensi + .div(this.bigTargetPAD) + .times(100) + .toFixed(2); + + // non-verification documents + this.bigTotalNonVerification = new Big( + this.dataNonVerification.total + ); + this.percentageResultNonVerification = this.bigTotalNonVerification + .div(this.bigTotalPotensi) + .times(100) + .toFixed(2); + + // verification documents + this.bigTotalVerification = new Big(this.dataVerification.total); + this.percetageResultVerification = + this.bigTotalVerification <= 0 || this.bigTotalPotensi <= 0 + ? 0 + : this.bigTotalVerification + .div(this.bigTargetPAD) + .times(100) + .toFixed(2); + + // business documents + this.bigTotalBusiness = new Big(this.dataBusiness.total); + this.percentageResultBusiness = + this.bigTotalNonVerification <= 0 + ? 0 + : this.bigTotalBusiness + .div(this.bigTotalNonVerification) + .times(100) + .toFixed(2); + + // non-business documents + this.bigTotalNonBusiness = new Big(this.dataNonBusiness.total); + this.percentageResultNonBusiness = + this.bigTotalNonBusiness <= 0 + ? 0 + : this.bigTotalNonBusiness + .div(this.bigTotalNonVerification) + .times(100) + .toFixed(2); + + if (!this.totalTargetPAD) { console.error("Failed to load chart data"); return; } @@ -15,455 +85,469 @@ class BigData { this.initChartTargetPAD(); this.initChartUsaha(); this.initChartNonUsaha(); - this.initChartStatus1(); - this.initChartStatus2(); - this.initChartStatus3(); - this.initChartStatus4(); - this.initChartStatus5(); - this.initChartStatus6(); - this.initChartStatus7(); - this.initChartStatus20(); - this.initChartStatus24(); - }catch(e){ + this.initChartTotalPotensi(); + this.initChartVerificationDocuments(); + this.initChartNonVerificationDocuments(); + this.initChartKekuranganPotensi(); + this.initChartRealisasiTerbitPBG(); + this.initChartMenungguKlikDPMPTSP(); + this.initChartProsesDinasTeknis(); + this.initChartPotensiTataRuang(); + } catch (e) { console.error(e); } } - async getTotalAllTask() { + async getDataTotalPotensi() { try { - const response = await fetch(`${GlobalConfig.apiHost}/api/all-task-documents`, { - credentials: "include", - headers: { - Authorization: `Bearer ${document.querySelector("meta[name='api-token']").content}`, - "Content-Type": "application/json", - }, - }); - + const response = await fetch( + `${GlobalConfig.apiHost}/api/all-task-documents`, + { + credentials: "include", + headers: { + Authorization: `Bearer ${ + document.querySelector("meta[name='api-token']") + .content + }`, + "Content-Type": "application/json", + }, + } + ); + if (!response.ok) { console.error("Network response was not ok", response); } - + const data = await response.json(); return { seriesData: data.data.series, countData: data.data.count, - totalData: data.data.total + totalData: data.data.total, }; - } catch (error) { console.error("Error fetching chart data:", error); - return null; // Mengembalikan null jika terjadi error + return null; + } + } + + async getTargetPAD() { + try { + const response = await fetch( + `${GlobalConfig.apiHost}/api/api-data-settings?search=target_pad`, + { + credentials: "include", + headers: { + Authorization: `Bearer ${ + document.querySelector("meta[name='api-token']") + .content + }`, + "Content-Type": "application/json", + }, + } + ); + + if (!response.ok) { + console.error("Network response was not ok", response); + } + + const data = await response.json(); + return data.data[0].value; + } catch (error) { + console.error("Error fetching chart data:", error); + return null; + } + } + + async getDataVerfication() { + try { + const response = await fetch( + `${GlobalConfig.apiHost}/api/verification-documents`, + { + credentials: "include", + headers: { + Authorization: `Bearer ${ + document.querySelector("meta[name='api-token']") + .content + }`, + "Content-Type": "application/json", + }, + } + ); + + if (!response.ok) { + console.error("Network response was not ok", response); + } + + const data = await response.json(); + return { + count: data.data.count, + total: data.data.total, + }; + } catch (error) { + console.error("Error fetching chart data:", error); + return null; + } + } + + async getDataNonVerfication() { + try { + const response = await fetch( + `${GlobalConfig.apiHost}/api/non-verification-documents`, + { + credentials: "include", + headers: { + Authorization: `Bearer ${ + document.querySelector("meta[name='api-token']") + .content + }`, + "Content-Type": "application/json", + }, + } + ); + + if (!response.ok) { + console.error("Network response was not ok", response); + } + + const data = await response.json(); + return { + count: data.data.count, + total: data.data.total, + }; + } catch (error) { + console.error("Error fetching chart data:", error); + return null; + } + } + + async getDataBusiness() { + try { + const response = await fetch( + `${GlobalConfig.apiHost}/api/business-documents`, + { + credentials: "include", + headers: { + Authorization: `Bearer ${ + document.querySelector("meta[name='api-token']") + .content + }`, + "Content-Type": "application/json", + }, + } + ); + + if (!response.ok) { + console.error("Network response was not ok", response); + } + + const data = await response.json(); + return { + count: data.data.count, + total: data.data.total, + }; + } catch (error) { + console.error("Error fetching chart data:", error); + return null; + } + } + + async getDataNonBusiness() { + try { + const response = await fetch( + `${GlobalConfig.apiHost}/api/non-business-documents`, + { + credentials: "include", + headers: { + Authorization: `Bearer ${ + document.querySelector("meta[name='api-token']") + .content + }`, + "Content-Type": "application/json", + }, + } + ); + + if (!response.ok) { + console.error("Network response was not ok", response); + } + + const data = await response.json(); + return { + count: data.data.count, + total: data.data.total, + }; + } catch (error) { + console.error("Error fetching chart data:", error); + return null; } } initChartTargetPAD() { - const total = this.resultDataTotal.totalData; - const count = this.resultDataTotal.countData; - document.querySelectorAll('.document-count.chart-all-task').forEach((element) => { - element.innerText = `${count}`; - }); - document.querySelectorAll('.document-total.chart-all-task').forEach((element) => { - element.innerText = `Rp.${addThousandSeparators(total)}`; - }); - document.querySelectorAll('.small-percentage.chart-all-task').forEach((element) => { - element.innerText = `${100}%`; - }); + let totalPad = 0; + fetch( + `${GlobalConfig.apiHost}/api/api-data-settings?search=target_pad`, + { + credentials: "include", + headers: { + Authorization: `Bearer ${ + document.querySelector("meta[name='api-token']").content + }`, + "Content-Type": "application/json", + }, + } + ) + .then((response) => { + if (!response.ok) { + throw new Error("Network response was not ok"); + } + return response.json(); + }) + .then((data) => { + totalPad = data.data[0].value; + document + .querySelectorAll(".document-count.chart-target-pad") + .forEach((element) => { + element.innerText = ``; + }); + document + .querySelectorAll(".document-total.chart-target-pad") + .forEach((element) => { + element.innerText = `Rp.${addThousandSeparators( + totalPad + )}`; + }); + document + .querySelectorAll(".small-percentage.chart-target-pad") + .forEach((element) => { + element.innerText = `${100}%`; + }); + }) + .catch((error) => { + console.error("Error fetching target_pad:", error); + }); + } + initChartTotalPotensi() { + const countAll = this.resultDataTotal.countData ?? 0; + + document + .querySelectorAll(".document-count.chart-total-potensi") + .forEach((element) => { + element.innerText = `${countAll}`; + }); + document + .querySelectorAll(".document-total.chart-total-potensi") + .forEach((element) => { + element.innerText = `Rp.${addThousandSeparators( + this.bigTotalPotensi.toString() + )}`; + }); + document + .querySelectorAll(".small-percentage.chart-total-potensi") + .forEach((element) => { + element.innerText = `${this.resultPercentage}%`; + }); + } + initChartVerificationDocuments() { + document + .querySelectorAll(".document-count.chart-berkas-terverifikasi") + .forEach((element) => { + element.innerText = `${this.dataVerification.count}`; + }); + document + .querySelectorAll(".document-total.chart-berkas-terverifikasi") + .forEach((element) => { + element.innerText = `Rp.${addThousandSeparators( + this.bigTotalVerification.toString() + )}`; + }); + document + .querySelectorAll(".small-percentage.chart-berkas-terverifikasi") + .forEach((element) => { + element.innerText = `${this.percetageResultVerification}%`; + }); + } + initChartNonVerificationDocuments() { + document + .querySelectorAll( + ".document-count.chart-berkas-belum-terverifikasi" + ) + .forEach((element) => { + element.innerText = `${this.dataNonVerification.count}`; + }); + document + .querySelectorAll( + ".document-total.chart-berkas-belum-terverifikasi" + ) + .forEach((element) => { + element.innerText = `Rp.${addThousandSeparators( + this.bigTotalNonVerification.toString() + )}`; + }); + document + .querySelectorAll( + ".small-percentage.chart-berkas-belum-terverifikasi" + ) + .forEach((element) => { + element.innerText = `${this.percentageResultNonVerification}%`; + }); } initChartUsaha() { - fetch(`${GlobalConfig.apiHost}/api/business-documents`,{ - credentials: "include", - headers: { - Authorization: `Bearer ${document.querySelector("meta[name='api-token']").content}`, - "Content-Type": "application/json", - }, - }) - .then((response) => { - if (!response.ok) { - throw new Error("Network response was not ok"); - } - return response.json(); - }) - .then((data) => { - // Pastikan this.resultDataTotal sudah ada - if (!this.resultDataTotal) { - console.error("Error: resultDataTotal is undefined"); - return; - } - - const totalAll = this.resultDataTotal.totalData ?? 0; - const countAll = this.resultDataTotal.countData ?? 0; - const countUsaha = data?.data?.count ?? 0; - const totalUsaha = data?.data?.total ?? 0; - - // Perbaikan perhitungan persentase - let resultPercentage = 0; - if (countUsaha > 0) { - resultPercentage = (countUsaha / countAll) * 100; - if (resultPercentage > 100) { - resultPercentage = 100; // Batasi maksimum 100% - } - } - document.querySelectorAll('.document-count.chart-business').forEach((element) => { - element.innerText = `${countUsaha}`; + document + .querySelectorAll(".document-count.chart-business") + .forEach((element) => { + element.innerText = `${this.dataBusiness.count}`; }); - document.querySelectorAll('.document-total.chart-business').forEach((element) => { - element.innerText = `Rp.${addThousandSeparators(totalUsaha)}`; + document + .querySelectorAll(".document-total.chart-business") + .forEach((element) => { + element.innerText = `Rp.${addThousandSeparators( + this.bigTotalBusiness.toString() + )}`; }); - document.querySelectorAll('.small-percentage.chart-business').forEach((element) => { - element.innerText = `${resultPercentage.toFixed(2)}%`; + document + .querySelectorAll(".small-percentage.chart-business") + .forEach((element) => { + element.innerText = `${this.percentageResultBusiness}%`; }); - }) - .catch((error) => { - console.error("error fetching chart dara : ", error); - }); } initChartNonUsaha() { - fetch(`${GlobalConfig.apiHost}/api/non-business-documents`, { - credentials: "include", - headers: { - Authorization: `Bearer ${document.querySelector("meta[name='api-token']").content}`, - "Content-Type": "application/json", - }, - }) - .then((response) => { - if (!response.ok) { - throw new Error("Network response was not ok"); - } - return response.json(); - }) - .then((data) => { - // Pastikan this.resultDataTotal sudah ada - if (!this.resultDataTotal) { - console.error("Error: resultDataTotal is undefined"); - return; - } - - const totalAll = this.resultDataTotal.totalData ?? 0; - const countAll = this.resultDataTotal.countData ?? 0; - const countUsaha = data?.data?.count ?? 0; - const totalUsaha = data?.data?.total ?? 0; - - // Perbaikan perhitungan persentase - let resultPercentage = 0; - if (countUsaha > 0) { - resultPercentage = (countUsaha / countAll) * 100; - if (resultPercentage > 100) { - resultPercentage = 100; // Batasi maksimum 100% - } - } - document.querySelectorAll('.document-count.chart-non-business').forEach((element) => { - element.innerText = `${data.data.count}`; + document + .querySelectorAll(".document-count.chart-non-business") + .forEach((element) => { + element.innerText = `${this.dataNonBusiness.count}`; }); - document.querySelectorAll('.document-total.chart-non-business').forEach((element) => { - element.innerText = `Rp.${addThousandSeparators(data.data.total)}`; + document + .querySelectorAll(".document-total.chart-non-business") + .forEach((element) => { + element.innerText = `Rp.${addThousandSeparators( + this.bigTotalNonBusiness.toString() + )}`; }); - document.querySelectorAll('.small-percentage.chart-non-business').forEach((element) => { - element.innerText = `${resultPercentage.toFixed(2)}%`; + document + .querySelectorAll(".small-percentage.chart-non-business") + .forEach((element) => { + element.innerText = `${this.percentageResultNonBusiness}%`; }); - }) - .catch((error) => { - console.error("error fetching chart dara : ", error); - }); } - initChartStatus1(){ - fetch(`${GlobalConfig.apiHost}/api/pbg-task-documents?status=1`, { - credentials: "include", - headers: { - Authorization: `Bearer ${document.querySelector("meta[name='api-token']").content}`, - "Content-Type": "application/json", - } - }) - .then((response) => { - if (!response.ok) { - throw new Error("Network response was not ok"); - } - return response.json(); - }) - .then((data) => { - const seriesData = data.data.series; - // document.getElementById( - // "countStatus1" - // ).innerText = `${data.data.count} Berkas`; - // document.getElementById( - // "totalStatus1" - // ).innerText = `Rp.${addThousandSeparators(data.data.total)}`; - }) - .catch((error) => { - console.error("error fetching chart dara : ", error); - }); + initChartKekuranganPotensi() { + document + .querySelectorAll(".document-count.chart-kekurangan-potensi") + .forEach((element) => { + element.innerText = ``; + }); + document + .querySelectorAll(".document-total.chart-kekurangan-potensi") + .forEach((element) => { + element.innerText = `Rp.${addThousandSeparators( + this.totalKekuranganPotensi.toString() + )}`; + }); + document + .querySelectorAll(".small-percentage.chart-kekurangan-potensi") + .forEach((element) => { + element.innerText = `${this.percentageKekuranganPotensi}%`; + }); } - initChartStatus2(){ - fetch(`${GlobalConfig.apiHost}/api/pbg-task-documents?status=2`, { - credentials: "include", - headers: { - Authorization: `Bearer ${document.querySelector("meta[name='api-token']").content}`, - "Content-Type": "application/json", - } - }) - .then((response) => { - if (!response.ok) { - throw new Error("Network response was not ok"); - } - return response.json(); - }) - .then((data) => { - const seriesData = data.data.series; - // document.getElementById( - // "countStatus2" - // ).innerText = `${data.data.count} Berkas`; - // document.getElementById( - // "totalStatus2" - // ).innerText = `Rp.${addThousandSeparators(data.data.total)}`; - }) - .catch((error) => { - console.error("error fetching chart dara : ", error); - }); + initChartRealisasiTerbitPBG() { + document + .querySelectorAll(".document-count.chart-realisasi-tebit-pbg") + .forEach((element) => { + element.innerText = `0`; + }); + document + .querySelectorAll(".document-total.chart-realisasi-tebit-pbg") + .forEach((element) => { + element.innerText = `Rp.${addThousandSeparators("0.00")}`; + }); + document + .querySelectorAll(".small-percentage.chart-realisasi-tebit-pbg") + .forEach((element) => { + element.innerText = `0.00%`; + }); } - initChartStatus3(){ - fetch(`${GlobalConfig.apiHost}/api/pbg-task-documents?status=3`, { - credentials: "include", - headers: { - Authorization: `Bearer ${document.querySelector("meta[name='api-token']").content}`, - "Content-Type": "application/json", - } - }) - .then((response) => { - if (!response.ok) { - throw new Error("Network response was not ok"); - } - return response.json(); - }) - .then((data) => { - const seriesData = data.data.series; - // document.getElementById( - // "countStatus3" - // ).innerText = `${data.data.count} Berkas`; - // document.getElementById( - // "totalStatus3" - // ).innerText = `Rp.${addThousandSeparators(data.data.total)}`; - }) - .catch((error) => { - console.error("error fetching chart dara : ", error); - }); + initChartMenungguKlikDPMPTSP() { + document + .querySelectorAll(".document-count.chart-menunggu-klik-dpmptsp") + .forEach((element) => { + element.innerText = `${0}`; + }); + document + .querySelectorAll(".document-total.chart-menunggu-klik-dpmptsp") + .forEach((element) => { + element.innerText = `Rp.${addThousandSeparators("0.00")}`; + }); + document + .querySelectorAll(".small-percentage.chart-menunggu-klik-dpmptsp") + .forEach((element) => { + element.innerText = `0.00%`; + }); } - initChartStatus4(){ - fetch(`${GlobalConfig.apiHost}/api/pbg-task-documents?status=4`, { - credentials: "include", - headers: { - Authorization: `Bearer ${document.querySelector("meta[name='api-token']").content}`, - "Content-Type": "application/json", - } - }) - .then((response) => { - if (!response.ok) { - throw new Error("Network response was not ok"); - } - return response.json(); - }) - .then((data) => { - const seriesData = data.data.series; - // document.getElementById( - // "countStatus4" - // ).innerText = `${data.data.count} Berkas`; - // document.getElementById( - // "totalStatus4" - // ).innerText = `Rp.${addThousandSeparators(data.data.total)}`; - }) - .catch((error) => { - console.error("error fetching chart dara : ", error); - }); + initChartProsesDinasTeknis() { + document + .querySelectorAll(".document-count.chart-proses-dinas-teknis") + .forEach((element) => { + element.innerText = `${0}`; + }); + document + .querySelectorAll(".document-total.chart-proses-dinas-teknis") + .forEach((element) => { + element.innerText = `Rp.${addThousandSeparators("0.00")}`; + }); + document + .querySelectorAll(".small-percentage.chart-proses-dinas-teknis") + .forEach((element) => { + element.innerText = `0.00%`; + }); } - initChartStatus5(){ - fetch(`${GlobalConfig.apiHost}/api/pbg-task-documents?status=5`, { - credentials: "include", - headers: { - Authorization: `Bearer ${document.querySelector("meta[name='api-token']").content}`, - "Content-Type": "application/json", - } - }) - .then((response) => { - if (!response.ok) { - throw new Error("Network response was not ok"); - } - return response.json(); - }) - .then((data) => { - const seriesData = data.data.series; - // document.getElementById( - // "countStatus5" - // ).innerText = `${data.data.count} Berkas`; - // document.getElementById( - // "totalStatus5" - // ).innerText = `Rp.${addThousandSeparators(data.data.total)}`; - }) - .catch((error) => { - console.error("error fetching chart dara : ", error); - }); - } - initChartStatus6(){ - fetch(`${GlobalConfig.apiHost}/api/pbg-task-documents?status=6`, { - credentials: "include", - headers: { - Authorization: `Bearer ${document.querySelector("meta[name='api-token']").content}`, - "Content-Type": "application/json", - } - }) - .then((response) => { - if (!response.ok) { - throw new Error("Network response was not ok"); - } - return response.json(); - }) - .then((data) => { - const seriesData = data.data.series; - // document.getElementById( - // "countStatus6" - // ).innerText = `${data.data.count} Berkas`; - // document.getElementById( - // "totalStatus6" - // ).innerText = `Rp.${addThousandSeparators(data.data.total)}`; - }) - .catch((error) => { - console.error("error fetching chart dara : ", error); - }); - } - initChartStatus7(){ - fetch(`${GlobalConfig.apiHost}/api/pbg-task-documents?status=7`, { - credentials: "include", - headers: { - Authorization: `Bearer ${document.querySelector("meta[name='api-token']").content}`, - "Content-Type": "application/json", - } - }) - .then((response) => { - if (!response.ok) { - throw new Error("Network response was not ok"); - } - return response.json(); - }) - .then((data) => { - const seriesData = data.data.series; - // document.getElementById( - // "countStatus7" - // ).innerText = `${data.data.count} Berkas`; - // document.getElementById( - // "totalStatus7" - // ).innerText = `Rp.${addThousandSeparators(data.data.total)}`; - }) - .catch((error) => { - console.error("error fetching chart dara : ", error); - }); - } - initChartStatus20(){ - fetch(`${GlobalConfig.apiHost}/api/pbg-task-documents?status=20`, { - credentials: "include", - headers: { - Authorization: `Bearer ${document.querySelector("meta[name='api-token']").content}`, - "Content-Type": "application/json", - } - }) - .then((response) => { - if (!response.ok) { - throw new Error("Network response was not ok"); - } - return response.json(); - }) - .then((data) => { - const seriesData = data.data.series; - // document.getElementById( - // "countStatus20" - // ).innerText = `${data.data.count} Berkas`; - // document.getElementById( - // "totalStatus20" - // ).innerText = `Rp.${addThousandSeparators(data.data.total)}`; - }) - .catch((error) => { - console.error("error fetching chart dara : ", error); - }); - } - initChartStatus24(){ - fetch(`${GlobalConfig.apiHost}/api/pbg-task-documents?status=24`, { - credentials: "include", - headers: { - Authorization: `Bearer ${document.querySelector("meta[name='api-token']").content}`, - "Content-Type": "application/json", - } - }) - .then((response) => { - if (!response.ok) { - throw new Error("Network response was not ok"); - } - return response.json(); - }) - .then((data) => { - const seriesData = data.data.series; - // document.getElementById( - // "countStatus24" - // ).innerText = `${data.data.count} Berkas`; - // document.getElementById( - // "totalStatus24" - // ).innerText = `Rp.${addThousandSeparators(data.data.total)}`; - }) - .catch((error) => { - console.error("error fetching chart dara : ", error); - }); - } - -} - -class ArrowConnectorCircles { - init(){ - // Memanggil fungsi saat halaman dimuat dan ketika layar diubah ukurannya - document.addEventListener("resize", this.updateLine()); - document.addEventListener("load", this.updateLine()); - } - - updateLine() { - const circle1 = document.getElementById("chart-all-task-1").getBoundingClientRect(); - const circle2 = document.getElementById("chart-all-task-2").getBoundingClientRect(); - const line = document.getElementById("connector-line"); - - console.log(circle1); - console.log(circle2); - - line.setAttribute("x1", circle1.left + circle1.width / 2); - line.setAttribute("y1", circle1.top + circle1.height / 2); - line.setAttribute("x2", circle2.left + circle2.width / 2); - line.setAttribute("y2", circle2.top + circle2.height / 2); + initChartPotensiTataRuang() { + document + .querySelectorAll(".document-count.chart-potensi-tata-ruang") + .forEach((element) => { + element.innerText = `${0}`; + }); + document + .querySelectorAll(".document-total.chart-potensi-tata-ruang") + .forEach((element) => { + element.innerText = `Rp.${addThousandSeparators("0.00")}`; + }); + document + .querySelectorAll(".small-percentage.chart-potensi-tata-ruang") + .forEach((element) => { + element.innerText = `0.00%`; + }); } } document.addEventListener("DOMContentLoaded", async function (e) { await new BigData().init(); - // new ArrowConnectorCircles().init(); }); -function resizeDashboard(){ - //Target Width - let targetElement = document.getElementById("dashboard-fixed-wrapper"); - let targetWidth = targetElement.offsetWidth; - //console.log("TARGET ",targetWidth); +function resizeDashboard() { + //Target Width + let targetElement = document.getElementById("dashboard-fixed-wrapper"); + let targetWidth = targetElement.offsetWidth; + //console.log("TARGET ",targetWidth); - //Real Object Width - let dashboardElement = document.getElementById("dashboard-fixed-container"); - let dashboardWidth = 1110; //dashboardElement.offsetWidth; - //console.log("CURRENT ",dashboardWidth); + //Real Object Width + let dashboardElement = document.getElementById("dashboard-fixed-container"); + let dashboardWidth = 1110; //dashboardElement.offsetWidth; + //console.log("CURRENT ",dashboardWidth); - if(targetWidth> dashboardWidth){ - targetWidth = dashboardWidth; - } - - dashboardElement.style.transformOrigin = "left top"; - dashboardElement.style.transition = "transform 0.2s ease-in-out"; - dashboardElement.style.transform = "scale(" + (targetWidth/dashboardWidth).toFixed(2) + ")"; - //console.log("SCALE ", (targetWidth/dashboardWidth).toFixed(2)); + if (targetWidth > dashboardWidth) { + targetWidth = dashboardWidth; } + dashboardElement.style.transformOrigin = "left top"; + dashboardElement.style.transition = "transform 0.2s ease-in-out"; + dashboardElement.style.transform = + "scale(" + (targetWidth / dashboardWidth).toFixed(2) + ")"; + //console.log("SCALE ", (targetWidth/dashboardWidth).toFixed(2)); +} + window.addEventListener("load", function () { resizeDashboard(); }); window.addEventListener("resize", function () { resizeDashboard(); - -}); \ No newline at end of file +}); diff --git a/resources/js/data-settings/index.js b/resources/js/data-settings/index.js new file mode 100644 index 0000000..2e9f2a4 --- /dev/null +++ b/resources/js/data-settings/index.js @@ -0,0 +1,107 @@ +import { Grid } from "gridjs/dist/gridjs.umd.js"; +import gridjs from "gridjs/dist/gridjs.umd.js"; +import "gridjs/dist/gridjs.umd.js"; +import GlobalConfig from "../global-config.js"; + +class DataSettings { + init() { + this.getFetchApiData(); + } + + getFetchApiData() { + const table = new Grid({ + columns: [ + "ID", + "Key", + "Value", + "Created", + { + name: "Actions", + width: "120px", + formatter: function (cell) { + console.log("cell data", cell); + return gridjs.html(` +