From e7950e22f2566847f82a570607fd257d53456c99 Mon Sep 17 00:00:00 2001 From: arifal Date: Mon, 24 Mar 2025 21:16:05 +0700 Subject: [PATCH] add flatpicker for edit pbg task data --- app/Enums/PbgTaskApplicationTypes.php | 25 ++ app/Enums/PbgTaskStatus.php | 59 ++++ .../Controllers/Api/PbgTaskController.php | 312 ++++-------------- .../RequestAssignment/PbgTaskController.php | 6 +- resources/js/pbg-task/show.js | 71 ++++ resources/views/pbg_task/show.blade.php | 132 +++++--- routes/api.php | 4 +- 7 files changed, 300 insertions(+), 309 deletions(-) create mode 100644 app/Enums/PbgTaskApplicationTypes.php create mode 100644 app/Enums/PbgTaskStatus.php diff --git a/app/Enums/PbgTaskApplicationTypes.php b/app/Enums/PbgTaskApplicationTypes.php new file mode 100644 index 0000000..74c301a --- /dev/null +++ b/app/Enums/PbgTaskApplicationTypes.php @@ -0,0 +1,25 @@ + "Pilih Application Type", + self::PERSETUJUAN_BG->value => 'Persetujuan Bangunan Gedung', + self::PERUBAHAN_BG->value => 'Perubahan Bangunan Gedung', + self::SLF_BB->value => 'Sertifikat Laik Fungsi - Bangunan Baru', + self::SLF->value => 'Sertifikat Laik Fungsi', + ]; + } + public static function getLabel(?string $status): ?string + { + return self::labels()[$status] ?? null; + } +} \ No newline at end of file diff --git a/app/Enums/PbgTaskStatus.php b/app/Enums/PbgTaskStatus.php new file mode 100644 index 0000000..cdf7b3d --- /dev/null +++ b/app/Enums/PbgTaskStatus.php @@ -0,0 +1,59 @@ + "Pilih Status", + self::VERIFIKASI_KELENGKAPAN->value => "Verifikasi Kelengkapan Dokumen", + self::PERBAIKAN_DOKUMEN->value => "Perbaikan Dokumen", + self::PERMOHONAN_DIBATALKAN->value => "Permohonan Dibatalkan", + self::MENUNGGU_PENUGASAN_TPT_TPA->value => "Menunggu Penugasan TPT/TPA", + self::MENUNGGU_JADWAL_KONSULTASI->value => "Menunggu Jadwal Konsultasi", + self::PELAKSANAAN_KONSULTASI->value => "Pelaksanaan Konsultasi", + self::PERBAIKAN_DOKUMEN_KONSULTASI->value => "Perbaikan Dokumen Konsultasi", + self::PERMOHONAN_DITOLAK->value => "Permohonan Ditolak", + self::PERHITUNGAN_RETRIBUSI->value => "Perhitungan Retribusi", + self::MENUNGGU_PEMBAYARAN_RETRIBUSI->value => "Menunggu Pembayaran Retribusi", + self::VERIFIKASI_PEMBAYARAN_RETRIBUSI->value => "Verifikasi Pembayaran Retribusi", + self::RETRIBUSI_TIDAK_SESUAI->value => "Retribusi Tidak Sesuai", + self::VERIFIKASI_SK_PBG->value => "Verifikasi SK PBG", + self::PENERBITAN_SK_PBG->value => "Penerbitan SK PBG", + self::SK_PBG_TERBIT->value => "SK PBG Terbit", + self::PENERBITAN_SPPST->value => "Penerbitan SPPST", + self::PROSES_PENERBITAN_SKRD->value => "Proses Penerbitan SKRD", + self::MENUNGGU_PENUGASAN_TPT->value => "Menunggu Penugasan TPT", + self::VERIFIKASI_DATA_TPT->value => "Verifikasi Data TPT", + self::SERTIFIKAT_SLF_TERBIT->value => "Sertifikat SLF Terbit", + ]; + } + + public static function getLabel(?int $status): ?string + { + return self::getStatuses()[$status] ?? null; + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Api/PbgTaskController.php b/app/Http/Controllers/Api/PbgTaskController.php index 9c34a1b..2ac3132 100644 --- a/app/Http/Controllers/Api/PbgTaskController.php +++ b/app/Http/Controllers/Api/PbgTaskController.php @@ -3,6 +3,8 @@ namespace App\Http\Controllers\Api; use App\Enums\ImportDatasourceStatus; +use App\Enums\PbgTaskApplicationTypes; +use App\Enums\PbgTaskStatus; use App\Http\Controllers\Controller; use App\Http\Requests\PbgTaskMultiStepRequest; use App\Http\Resources\PbgTaskResource; @@ -14,6 +16,7 @@ use App\Services\GoogleSheetService; use Carbon\Carbon; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; +use Illuminate\Validation\Rules\Enum; class PbgTaskController extends Controller { @@ -116,9 +119,63 @@ class PbgTaskController extends Controller /** * Update the specified resource in storage. */ - public function update(Request $request, string $id) + public function update(Request $request, string $task_uuid) { - // + try{ + $pbg_task = PbgTask::where('uuid',$task_uuid)->first(); + + if(!$pbg_task){ + return response()->json([ + "success"=> false, + "message"=> "Data PBG Task tidak ditemukan", + ], 404); + } + + $validated = $request->validate([ + 'name' => 'required|string|max:255', + 'owner_name' => 'required|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', + 'status' => ['nullable', new Enum(PbgTaskStatus::class)], + 'address' => 'required|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', + ]); + + $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'], + ]); + return response()->json([ + "success"=> true, + "message"=> "Data berhasil diubah", + "data"=> $pbg_task + ]); + }catch(\Exception $e){ + return response()->json([ + "success"=> false, + "message"=> $e->getMessage(), + ]); + } } /** @@ -135,255 +192,4 @@ class PbgTaskController extends Controller ]); } - public function syncPbgFromGoogleSheet(){ - $import_datasource = ImportDatasource::create([ - "message" => "initialization", - "response_body" => null, - "status" => ImportDatasourceStatus::Processing->value, - ]); - try{ - $totalRowCount = $this->googleSheetService->getLastRowByColumn("C"); - $sheetData = $this->googleSheetService->getSheetDataCollection($totalRowCount); - $sheet_big_data = $this->googleSheetService->get_data_by_sheet(); - $data_setting_result = []; // Initialize result storage - - $found_section = null; // Track which section is found - - foreach ($sheet_big_data as $row) { - // Check for section headers - if (in_array("•PROSES PENERBITAN:", $row)) { - $found_section = "MENUNGGU_KLIK_DPMPTSP"; - } elseif (in_array("•BERKAS AKTUAL TERVERIFIKASI DINAS TEKNIS 2024:", $row)) { - $found_section = "REALISASI_TERBIT_PBG"; - } elseif (in_array("•TERPROSES DI DPUTR: belum selesai rekomtek'", $row)) { - $found_section = "PROSES_DINAS_TEKNIS"; - } - - // If a section is found and we reach "Grand Total", save the corresponding values - if ($found_section && isset($row[0]) && trim($row[0]) === "Grand Total") { - if ($found_section === "MENUNGGU_KLIK_DPMPTSP") { - $data_setting_result["MENUNGGU_KLIK_DPMPTSP_COUNT"] = $row[2] ?? null; - $data_setting_result["MENUNGGU_KLIK_DPMPTSP_SUM"] = $row[3] ?? null; - } elseif ($found_section === "REALISASI_TERBIT_PBG") { - $data_setting_result["REALISASI_TERBIT_PBG_COUNT"] = $row[2] ?? null; - $data_setting_result["REALISASI_TERBIT_PBG_SUM"] = $row[4] ?? null; - } elseif ($found_section === "PROSES_DINAS_TEKNIS") { - $data_setting_result["PROSES_DINAS_TEKNIS_COUNT"] = $row[2] ?? null; - $data_setting_result["PROSES_DINAS_TEKNIS_SUM"] = $row[3] ?? null; - } - - // Reset section tracking after capturing "Grand Total" - $found_section = null; - } - } - foreach ($data_setting_result as $key => $value) { - DataSetting::updateOrInsert( - ["key" => $key], // Find by key - ["value" => $value] // Update or insert value - ); - } - $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', - ]); - } - - $total_data = count($mapToUpsert); - - $import_datasource->update([ - "message" => "Successfully processed: {$total_data}", - "status" => ImportDatasourceStatus::Success->value, - ]); - - DB::commit(); - - return response()->json([ - "success" => true, - "message" => "Data berhasil disimpan ke database" - ], 200); - }catch(\Exception $ex){ - DB::rollBack(); - $import_datasource->update([ - "message" => "Failed to importing", - "response_body" => $ex->getMessage(), - "status" => ImportDatasourceStatus::Failed->value, - ]); - 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/RequestAssignment/PbgTaskController.php b/app/Http/Controllers/RequestAssignment/PbgTaskController.php index 830fa64..91922fe 100644 --- a/app/Http/Controllers/RequestAssignment/PbgTaskController.php +++ b/app/Http/Controllers/RequestAssignment/PbgTaskController.php @@ -2,11 +2,13 @@ namespace App\Http\Controllers\RequestAssignment; +use App\Enums\PbgTaskApplicationTypes; use App\Http\Controllers\Controller; use App\Models\PbgTask; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Auth; +use App\Enums\PbgTaskStatus; class PbgTaskController extends Controller { @@ -60,7 +62,9 @@ class PbgTaskController extends Controller public function show(string $id) { $data = PbgTask::with(['pbg_task_retributions','pbg_task_index_integrations', 'pbg_task_retributions.pbg_task_prasarana'])->findOrFail($id); - return view("pbg_task.show", compact("data")); + $statusOptions = PbgTaskStatus::getStatuses(); + $applicationTypes = PbgTaskApplicationTypes::labels(); + return view("pbg_task.show", compact("data", 'statusOptions', 'applicationTypes')); } /** diff --git a/resources/js/pbg-task/show.js b/resources/js/pbg-task/show.js index a583a5a..686570c 100644 --- a/resources/js/pbg-task/show.js +++ b/resources/js/pbg-task/show.js @@ -2,10 +2,22 @@ import { Grid } from "gridjs/dist/gridjs.umd.js"; import "gridjs/dist/gridjs.umd.js"; import gridjs from "gridjs/dist/gridjs.umd.js"; import GlobalConfig from "../global-config"; +import flatpickr from "flatpickr"; +import "flatpickr/dist/flatpickr.min.css"; class PbgTaskAssignments { init() { this.initTablePbgTaskAssignments(); + this.handleUpdateData(); + this.initDatePicker(); + } + + initDatePicker() { + let element = document.getElementById("datepicker_due_date"); + flatpickr(element, { + dateFormat: "Y-m-d", + minDate: new Date(), + }); } initTablePbgTaskAssignments() { @@ -62,6 +74,65 @@ class PbgTaskAssignments { }, }).render(tableContainer); } + + handleUpdateData() { + const button = document.getElementById("btnUpdatePbgTask"); + const form = document.getElementById("formUpdatePbgTask"); + const toastNotification = document.getElementById("toastNotification"); + const toast = new bootstrap.Toast(toastNotification); + button.addEventListener("click", function (event) { + event.preventDefault(); + let submitButton = this; + let spinner = document.getElementById("spinner"); + submitButton.disabled = true; + spinner.classList.remove("d-none"); + + const formData = new FormData(form); + const formObject = {}; + formData.forEach((value, key) => { + formObject[key] = value; + }); + fetch(form.action, { + method: "PUT", // Ensure your Laravel route is set to accept PUT requests + body: JSON.stringify(formObject), // Convert form data to JSON + credentials: "include", + headers: { + Authorization: `Bearer ${document + .querySelector('meta[name="api-token"]') + .getAttribute("content")}`, + "Content-Type": "application/json", + "X-CSRF-TOKEN": document.querySelector( + 'meta[name="csrf-token"]' + ).content, // For Laravel security + }, + }) + .then((response) => { + if (!response.ok) { + return response.json().then((err) => { + throw new Error( + err.message || "Something went wrong" + ); + }); + } + return response.json(); + }) + .then((data) => { + document.getElementById("toast-message").innerText = + data.message; + toast.show(); + submitButton.disabled = false; + spinner.classList.add("d-none"); + }) + .catch((error) => { + console.error("Error updating task:", error); + document.getElementById("toast-message").innerText = + error.message; + toast.show(); + submitButton.disabled = false; + spinner.classList.add("d-none"); + }); + }); + } } document.addEventListener("DOMContentLoaded", function (e) { diff --git a/resources/views/pbg_task/show.blade.php b/resources/views/pbg_task/show.blade.php index fec50c9..5a5d573 100644 --- a/resources/views/pbg_task/show.blade.php +++ b/resources/views/pbg_task/show.blade.php @@ -7,69 +7,93 @@ @section('content') @include('layouts.partials/page-title', ['title' => 'Data', 'subtitle' => 'PBG']) - +
-
-
-
-
Name
-
{{$data->name}}
+
+ @csrf +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
-
-
Owner Name
-
{{$data->owner_name}}
-
-
-
Aplication Type Name
-
{{$data->application_type_name}}
-
-
-
Condition
-
{{$data->condition}}
-
-
-
Registration Number
-
{{$data->registration_number}}
-
-
-
Document Number
-
{{$data->document_number}}
-
-
-
Status Name
-
{{$data->status_name}}
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
-
-
-
Address
-
{{$data->address}}
-
-
-
SLF Status Name
-
{{$data->slf_status_name}}
-
-
-
Function Type
-
{{$data->function_type}}
-
-
-
Consultation Type
-
{{$data->consultation_type}}
-
-
-
Due Date
-
{{$data->due_date}}
-
-
-
Task Created At
-
{{$data->task_created_at}}
+
+
+
-
+
diff --git a/routes/api.php b/routes/api.php index 9e602cd..196f419 100644 --- a/routes/api.php +++ b/routes/api.php @@ -105,9 +105,11 @@ Route::group(['middleware' => 'auth:sanctum'], function (){ }); Route::apiResource('/api-pbg-task', PbgTaskController::class); + Route::controller(PbgTaskController::class)->group( function (){ + Route::put('/pbg-task/{task_uuid}/update', 'update')->name('api.pbg-task.update'); + }); // sync pbg google sheet - Route::get('/sync-pbg-task-google-sheet', [PbgTaskController::class, 'syncPbgFromGoogleSheet'])->name('pbg-task.sync-google-sheet'); Route::apiResource('/api-google-sheet', GoogleSheetController::class); Route::get('/sync-task', [SyncronizeController::class, 'syncPbgTask'])->name('api.task'); Route::get('/get-user-token', [SyncronizeController::class, 'getUserToken'])->name('api.task.token');