diff --git a/app/Http/Controllers/masterPersetujuanController.php b/app/Http/Controllers/masterPersetujuanController.php new file mode 100644 index 0000000..8d40d6c --- /dev/null +++ b/app/Http/Controllers/masterPersetujuanController.php @@ -0,0 +1,196 @@ + 'Master Persetujuan' + ]; + return view('masterPersetujuan.index', $data); + } + + public function datatable(){ + return masterPersetujuan::where('statusenabled', true)->with([ + 'pegawai:id,namalengkap', + 'details.unitPegawai:id,name' + ])->get(); + } + + public function store(Request $request) + { + $payloads = $request->input('data', []); + if (!is_array($payloads) || empty($payloads)) { + return response()->json([ + 'status' => false, + 'message' => 'Data tidak boleh kosong' + ], 422); + } + DB::connection('dbDirectory')->beginTransaction(); + try { + foreach ($payloads as $payload) { + $pegawaiId = $payload['pegawai_id'] ?? null; // field name tetap, isi pegawai + if (!$pegawaiId) { + throw new \InvalidArgumentException('Pegawai wajib diisi.'); + } + + $master = masterPersetujuan::create([ + 'pegawai_id' => $pegawaiId, + 'statusenabled' => true, + 'entry_at' => Carbon::now(), + ]); + + $detailUnits = collect($payload['unit_akses'] ?? []) + ->filter() + ->unique() + ->values(); + foreach ($detailUnits as $unitId) { + masterPersetujuanDetail::create([ + 'master_persetujuan_file_directory_id' => $master->id, + 'unit_pegawai_id' => $unitId, + 'statusenabled' => true, + 'entry_at' => Carbon::now() + ]); + } + } + + DB::connection('dbDirectory')->commit(); + return response()->json([ + 'status' => true, + 'message' => 'Data berhasil disimpan' + ], 200); + } catch (\Throwable $th) { + DB::connection('dbDirectory')->rollBack(); + return response()->json([ + 'status' => false, + 'message' => $th->getMessage(), + ], 500); + } + } + + public function show(string $id) + { + $data = masterPersetujuan::with(['pegawai:id,nama', 'unitPegawai:id,name', 'details.unitPegawai:id,name']) + ->find($id); + + if (!$data) { + return response()->json([ + 'status' => false, + 'message' => 'Data tidak ditemukan' + ], 404); + } + + return response()->json([ + 'status' => true, + 'data' => [ + 'id' => $data->id, + 'unit_pegawai_id' => $data->unit_pegawai_id, + 'unit_pegawai_nama' => $data->pegawai?->nama, + 'detail_units' => $data->details->map(function ($detail) { + return [ + 'id' => $detail->unit_pegawai_id, + 'text' => $detail->unitPegawai?->name, + ]; + })->values(), + ], + ], 200); + } + + public function update(Request $request, string $id) + { + $data = masterPersetujuan::find($id); + if (!$data) { + return response()->json([ + 'status' => false, + 'message' => 'Data tidak ditemukan' + ], 404); + } + + $unitPegawaiId = $request->input('pegawai_id'); + if (!$unitPegawaiId) { + return response()->json([ + 'status' => false, + 'message' => 'Pegawai wajib diisi.' + ], 422); + } + + $detailUnits = collect($request->input('unit_akses', [])) + ->filter() + ->unique() + ->values(); + DB::connection('dbDirectory')->beginTransaction(); + try { + $data->update([ + 'pegawai_id' => $unitPegawaiId, + 'modified_at' => Carbon::now() + ]); + + masterPersetujuanDetail::where('master_persetujuan_file_directory_id', $data->id)->delete(); + + foreach ($detailUnits as $unitId) { + masterPersetujuanDetail::create([ + 'master_persetujuan_file_directory_id' => $data->id, + 'unit_pegawai_id' => $unitId, + 'entry_at' => Carbon::now(), + 'modified_at' => Carbon::now(), + 'statusenabled' => true + ]); + } + + DB::connection('dbDirectory')->commit(); + return response()->json([ + 'status' => true, + 'message' => 'Data berhasil diperbarui' + ], 200); + } catch (\Throwable $th) { + DB::connection('dbDirectory')->rollBack(); + return response()->json([ + 'status' => false, + 'message' => $th->getMessage(), + ], 500); + } + } + + public function destroy(string $id) + { + $data = masterPersetujuan::find($id); + if (!$data) { + return response()->json([ + 'status' => false, + 'message' => 'Data tidak ditemukan' + ], 404); + } + + DB::connection('dbDirectory')->beginTransaction(); + try { + masterPersetujuanDetail::where('master_persetujuan_file_directory_id', $data->id)->update([ + 'statusenabled' => false, + 'modified_at' => Carbon::now(), + ]); + $data->update([ + 'statusenabled' => false, + 'modified_at' => Carbon::now(), + ]); + + DB::connection('dbDirectory')->commit(); + return response()->json([ + 'status' => true, + 'message' => 'Data berhasil dihapus' + ], 200); + } catch (\Throwable $th) { + DB::connection('dbDirectory')->rollBack(); + return response()->json([ + 'status' => false, + 'message' => $th->getMessage(), + ], 500); + } + } +} diff --git a/app/Models/masterPersetujuan.php b/app/Models/masterPersetujuan.php new file mode 100644 index 0000000..59b94b9 --- /dev/null +++ b/app/Models/masterPersetujuan.php @@ -0,0 +1,32 @@ +belongsTo(UnitKerja::class, 'unit_pegawai_id', 'id'); + } + + public function pegawai() + { + return $this->belongsTo(DataUser::class, 'pegawai_id', 'id'); + } + + public function details() + { + return $this->hasMany(masterPersetujuanDetail::class, 'master_persetujuan_file_directory_id', 'id')->where('statusenabled', true); + } +} diff --git a/app/Models/masterPersetujuanDetail.php b/app/Models/masterPersetujuanDetail.php new file mode 100644 index 0000000..d61dbd4 --- /dev/null +++ b/app/Models/masterPersetujuanDetail.php @@ -0,0 +1,26 @@ +belongsTo(masterPersetujuan::class, 'master_persetujuan_file_directory_id', 'id'); + } + + public function unitPegawai() + { + return $this->belongsTo(UnitKerja::class, 'unit_pegawai_id', 'id'); + } +} diff --git a/public/js/masterPersetujuan/_init.js b/public/js/masterPersetujuan/_init.js new file mode 100644 index 0000000..88aedfa --- /dev/null +++ b/public/js/masterPersetujuan/_init.js @@ -0,0 +1,7 @@ +const datatableMasterPersetujuan = $("#table_master_persetujuan") + +const formCreateMasterPersetujuan = $("#formCreateMasterPersetujuan") +const modalCreate = document.getElementById('modalMasterPersetujuan') + +const modalEdit = document.getElementById('modalEditMasterPersetujuan') +const formEditMasterPersetujuan = $("#formEditMasterPersetujuan") diff --git a/public/js/masterPersetujuan/action.js b/public/js/masterPersetujuan/action.js new file mode 100644 index 0000000..f97573d --- /dev/null +++ b/public/js/masterPersetujuan/action.js @@ -0,0 +1,253 @@ +formCreateMasterPersetujuan.on('submit', function(e){ + e.preventDefault(); + + const form = this; + const formData = new FormData(form); + + fetch(`/master-persetujuan`, { + method: 'POST', + headers: { + 'X-CSRF-TOKEN': document.querySelector('input[name="_token"]').value, + }, + body: formData + }).then(async(res) => { + const responseData = await res.json(); + if (responseData.status) { + const handler = function () { + Swal.fire({ + icon: 'success', + title: 'Berhasil', + text: responseData.message || 'Berhasil melakukan aksi!', + timer: 2000, + showConfirmButton: false, + backdrop: true, + }); + $("#col_add_master_persetujuan").html(''); + colCount = 1; // reset counter + formCreateMasterPersetujuan.find('select').val(null).trigger('change'); + datatableMasterPersetujuan.bootstrapTable('refresh'); + modalCreate.removeEventListener('hidden.bs.modal', handler); + }; + modalCreate.addEventListener('hidden.bs.modal', handler); + bootstrap.Modal.getInstance(modalCreate).hide(); + } else { + throw new Error(responseData.message || 'Terjadi kesalahan saat menyimpan data.'); + } + + }).catch(err => { + if (err.message) { + Swal.fire({ + icon: 'error', + title: 'Gagal', + text: err.message + }); + } + }); +}); + + +function deleteAkses(e){ + let id =$(e).data('id') + Swal.fire({ + title: "Apakah kamu yakin ingin menghapus data master persetujuan?", + text : $(e).data('name'), + icon: "warning", + showCancelButton: true, + backdrop: true, + }).then((result) => { + if(result.isConfirmed){ + fetch(`/master-persetujuan/${id}`, { + method:'DELETE', + headers: { + "X-CSRF-TOKEN": document.querySelector('input[name="_token"]').value, + "Content-Type": "application/json" + } + }).then((response) => { + if(!response.ok){ + throw new Error("Network response was not ok"); + } + return response.json(); + }) + .then((data) => { + if(data.status){ + Swal.fire({ + title: "Success", + text: "Data berhasil dihapus", + icon:"success", + showConfirmButton: false, + timer: 1000 + }).then(() => { + datatableMasterPersetujuan.bootstrapTable("refresh") + }) + }else{ + Swal.fire({ + title: "Error!", + text: data.message || "Failed to delete Item.", + icon: "error" + }); + } + }) + .catch(error => { + Swal.fire({ + title: "Error!", + text: "Something went wrong. Please try again later.", + icon: "error" + }); + }); + } + }) +} + + +function editAkses(e){ + const data = $(e).data(); + new bootstrap.Modal(modalEdit).show(); + formEditMasterPersetujuan.attr('action', `/master-persetujuan/${data.id}`) + + selectOptionPegawaiEdit() + selectOptionUnitKerjaEdit() + if (data.pegawai_id) { + setOldSelect2Value('#pegawai_id_edit', data.pegawai_id, data.pegawai_nama); + } + + fetch(`/master-persetujuan/${data.id}`) + .then(async(res) => { + const responseData = await res.json(); + if (!responseData.status) { + throw new Error(responseData.message || 'Gagal memuat data akses.'); + } + const detail = responseData.data; + if (Array.isArray(detail.detail_units)) { + setOldSelect2Values('#unit_akses_edit', detail.detail_units); + } + }) + .catch((err) => { + console.log(err); + }); +} + + + +function selectOptionPegawaiEdit() { + let selectPegawai = $(`#pegawai_id_edit`); + // inisialisasi select2 untuk Unit Kerja + selectPegawai.select2({ + placeholder: '-- Pilih Pegawai --', + allowClear:true, + width: '100%', + dropdownParent: selectPegawai.parent(), + ajax:{ + url : '/select-pegawai', + dataType: 'json', + delay: 250, + data: function(params){ + return { q: params.term } + }, + processResults: function(data){ + return { + results : data?.data.map(item => ({ + id: item.id, + text: item.nama, + })) + } + }, + cache: true, + }, + minimumInputLength: 1, + }); +} + +function selectOptionUnitKerjaEdit() { + let selectUnit = $(`#unit_akses_edit`); + if (selectUnit.data('select2')) return; + selectUnit.select2({ + placeholder: '-- Pilih Unit Kerja --', + allowClear:true, + width: '100%', + dropdownParent: selectUnit.parent(), + ajax:{ + url : '/select-unit-kerja', + dataType: 'json', + delay: 250, + data: function(params){ + return { q: params.term } + }, + processResults: function(data){ + return { + results : data?.data.map(item => ({ + id: item.id, + text: item.name, + })) + } + }, + cache: true, + }, + minimumInputLength: 1, + }); +} + + + +function setOldSelect2Value(selector, id, text) { + if (!id || !text) return; + let option = new Option(text, id, true, true); + $(selector).append(option).trigger('change') +} + +function setOldSelect2Values(selector, items) { + if (!Array.isArray(items) || items.length === 0) return; + items.forEach(item => { + if (!item?.id || !item?.text) return; + let option = new Option(item.text, item.id, true, true); + $(selector).append(option); + }); + $(selector).trigger('change') +} + + +formEditMasterPersetujuan.on('submit', function(e){ + e.preventDefault(); + + const form = this; + const actionUrl = formEditMasterPersetujuan.attr('action'); + const formData = new FormData(form); + formData.append('_method', 'PUT') + fetch(actionUrl, { + method: 'POST', + headers: { + 'X-CSRF-TOKEN': document.querySelector('input[name="_token"]').value, + }, + body: formData + }).then(async(res) => { + const responseData = await res.json(); + + if (responseData.status) { + const handler = function () { + Swal.fire({ + icon: 'success', + title: 'Berhasil', + text: responseData.message || 'Berhasil melakukan aksi!', + timer: 2000, + showConfirmButton: false, + backdrop: true, + }); + formCreateMasterPersetujuan.find('select').val(null).trigger('change'); + datatableMasterPersetujuan.bootstrapTable('refresh'); + modalEdit.removeEventListener('hidden.bs.modal', handler); + }; + modalEdit.addEventListener('hidden.bs.modal', handler); + bootstrap.Modal.getInstance(modalEdit).hide(); + } else { + throw new Error(responseData.message || 'Terjadi kesalahan saat menyimpan data.'); + } + + }).catch(err => { + if (err.message) { + Swal.fire({ + icon: 'error', + title: 'Gagal', + text: err.message + }); + } + }); +}); diff --git a/public/js/masterPersetujuan/dt.js b/public/js/masterPersetujuan/dt.js new file mode 100644 index 0000000..3c1907e --- /dev/null +++ b/public/js/masterPersetujuan/dt.js @@ -0,0 +1,63 @@ + datatableMasterPersetujuan.bootstrapTable({ + url: "/datatable/master-persetujuan", + showRefresh: true, + sortable: true, + search: true, + searchOnEnterKey: false, + searchHighlight: true, + pagination: true, + serverSide:true, + pageSize: 10, + pageList: [10, 20, 30], + cookie: true, + cookieIdTable: "table_master_kategori", + icons: { + refresh: "fas fa-sync-alt", + }, + columns: [ + { + title:"Action", + formatter: function(value, row){ + console.log(row); + + let buttons = ''; + buttons += ` + + ` + buttons += ` + ` + return ` +
+ ${buttons} +
+ `; + } + }, + { + title:"Nama", + field:'pegawai.namalengkap' + }, + { + title:"Persetujuan", + formatter:function(value, row){ + const units = (row?.details ?? []) + .map(detail => detail?.unit_pegawai?.name) + .filter(Boolean); + + return units.length + ? units.join(', ') + : '-'; + } + } + ], + }); diff --git a/public/js/masterPersetujuan/functions.js b/public/js/masterPersetujuan/functions.js new file mode 100644 index 0000000..b6143c2 --- /dev/null +++ b/public/js/masterPersetujuan/functions.js @@ -0,0 +1,102 @@ +$(document).ready(function() { + selectOptionPegawai(0) + selectOptionUnitKerja(0) +}); + +function selectOptionPegawai(colCount) { + let selectPegawai = $(`#pegawai_id_${colCount}`); + // inisialisasi select2 untuk Unit Kerja + selectPegawai.select2({ + placeholder: '-- Pilih Pegawai --', + allowClear:true, + width: '100%', + dropdownParent: selectPegawai.parent(), + ajax:{ + url : '/select-pegawai', + dataType: 'json', + delay: 250, + data: function(params){ + return { q: params.term } + }, + processResults: function(data){ + return { + results : data?.data.map(item => ({ + id: item.id, + text: item.nama, + })) + } + }, + cache: true, + }, + minimumInputLength: 1, + }); +} + +function selectOptionUnitKerja(colCount) { + let selectUnit = $(`#unit_akses_${colCount}`); + selectUnit.select2({ + placeholder: '-- Pilih Unit Kerja --', + allowClear: true, + width: '100%', + dropdownParent: selectUnit.parent(), + ajax:{ + url : '/select-unit-kerja', + dataType: 'json', + delay: 250, + data: function(params){ + return { q: params.term } + }, + processResults: function(data){ + return { + results : data?.data.map(item => ({ + id: item.id, + text: item.name, + })) + } + }, + cache: true, + }, + minimumInputLength: 1, + }); +} + + + +let colCount = 1; +function addForm(){ + let col = $("#col_add_master_persetujuan") + + let html = ''; + + html += ` +
+
+
+ + + Cari nama pegawai. +
+
+ + + Bisa pilih lebih dari satu. +
+
+ +
+ +
+ ` + col.append(html) + selectOptionPegawai(colCount) + selectOptionUnitKerja(colCount) + colCount++; + +} + + +function removeCol(count){ + $(`#col-${count}`).remove() +} diff --git a/resources/views/layout/partials/sidenav.blade.php b/resources/views/layout/partials/sidenav.blade.php index 239a182..d1e7e42 100644 --- a/resources/views/layout/partials/sidenav.blade.php +++ b/resources/views/layout/partials/sidenav.blade.php @@ -105,6 +105,17 @@ + diff --git a/resources/views/masterPersetujuan/index.blade.php b/resources/views/masterPersetujuan/index.blade.php new file mode 100644 index 0000000..048718a --- /dev/null +++ b/resources/views/masterPersetujuan/index.blade.php @@ -0,0 +1,30 @@ +@extends('layout.main') + +@section('body_main') +
+
+
+
+

Master Persetujuan

+ +
+
+
+
+
+
+
+
+
+ +@include('masterPersetujuan.modal.add') +@include('masterPersetujuan.modal.edit') + + + + + +@endsection diff --git a/resources/views/masterPersetujuan/modal/add.blade.php b/resources/views/masterPersetujuan/modal/add.blade.php new file mode 100644 index 0000000..ea48ef5 --- /dev/null +++ b/resources/views/masterPersetujuan/modal/add.blade.php @@ -0,0 +1,48 @@ + diff --git a/resources/views/masterPersetujuan/modal/edit.blade.php b/resources/views/masterPersetujuan/modal/edit.blade.php new file mode 100644 index 0000000..ed16269 --- /dev/null +++ b/resources/views/masterPersetujuan/modal/edit.blade.php @@ -0,0 +1,45 @@ + diff --git a/routes/web.php b/routes/web.php index 373f254..94fd3ef 100644 --- a/routes/web.php +++ b/routes/web.php @@ -6,6 +6,7 @@ use App\Http\Controllers\DashboardController; use App\Http\Controllers\MasterKategoriController; use App\Http\Controllers\MasterKlasifikasiController; use App\Http\Controllers\LogActivityController; +use App\Http\Controllers\masterPersetujuanController; use Illuminate\Support\Facades\Route; Route::middleware(['auth'])->group(function(){ @@ -46,6 +47,9 @@ Route::middleware(['auth'])->group(function(){ Route::post('/pending-file/{id}/approve', [DashboardController::class, 'approvePendingFile']); Route::post('/pending-file/{id}/reject', [DashboardController::class, 'rejectPendingFile']); Route::get('/data/count-pending', [DashboardController::class, 'countDataPending']); + + Route::resource('/master-persetujuan', masterPersetujuanController::class)->only(['index','store','show','update','destroy']); + Route::get('datatable/master-persetujuan', [masterPersetujuanController::class, 'datatable']); }); Route::get('/login', [AuthController::class, 'index'])->name('login');