From 037c48264917091ac011edf5133d36f16d59e007 Mon Sep 17 00:00:00 2001 From: Irwan Cahyono Date: Tue, 26 May 2026 00:09:55 +0700 Subject: [PATCH] ekosistem dan framework --- .../Api/Ekosistem/FormBasisDataController.php | 140 +++++++ .../Ekosistem/TabelBasisDataController.php | 79 ++++ .../Ekosistem/ValueBasisDataController.php | 367 ++++++++++++++++++ .../Ekosistem/ValueBasisDataController.php | 35 +- .../Web/Program/AktivitasController.php | 6 + .../Web/Program/FrameworkController.php | 3 +- .../Web/Program/RealisasiController.php | 125 ++++++ .../Web/Program/TargetController.php | 108 +++++- .../Web/Program/VerifikasiController.php | 90 +++++ .../Ekosistem/KolomBasisDataResource.php | 32 ++ .../Ekosistem/TabelBasisDataResource.php | 34 ++ .../Ekosistem/ValueBasisDataResource.php | 34 ++ app/Models/Ekosistem/FormBasisData.php | 267 ++++++++++--- app/Models/Program/Aktivitas.php | 19 +- app/Models/Program/Framework.php | 6 +- app/Models/Program/Realisasi.php | 37 ++ app/Models/Program/Target.php | 17 + app/Models/Program/Transformasi.php | 8 +- app/Models/Program/Verifikasi.php | 30 ++ app/Providers/AppServiceProvider.php | 4 +- ...6_05_15_161421_update_frameworks_table.php | 36 ++ .../ekosistem/value-basis-data/add.blade.php | 2 +- ...{add.blade.php => add-aktivitas.blade.php} | 19 +- .../program/aktivitas/add-tujuan.blade.php | 106 +++++ ...dit.blade.php => edit-aktivitas.blade.php} | 10 +- .../program/aktivitas/edit-tujuan.blade.php | 112 ++++++ .../framework/view-aktivitas.blade.php | 74 ++++ .../program/framework/view-tujuan.blade.php | 109 ++++++ .../program/framework/view.blade copy.php | 296 ++++++++++++++ .../views/program/framework/view.blade.php | 108 +----- .../views/program/realisasi/add.blade.php | 175 +++++++++ .../views/program/realisasi/edit.blade.php | 168 ++++++++ .../realisasi/index-aktivitas.blade.php | 118 ++++++ .../program/realisasi/index-tujuan.blade.php | 126 ++++++ .../views/program/realisasi/index.blade.php | 101 +++++ .../views/program/realisasi/list.blade.php | 83 ++++ resources/views/program/target/add.blade.php | 20 +- resources/views/program/target/edit.blade.php | 196 ++++++++++ .../views/program/verifikasi/add.blade.php | 176 +++++++++ routes/api.php | 13 +- routes/web.php | 4 +- 41 files changed, 3281 insertions(+), 212 deletions(-) create mode 100644 app/Http/Controllers/Api/Ekosistem/FormBasisDataController.php create mode 100644 app/Http/Controllers/Api/Ekosistem/TabelBasisDataController.php create mode 100644 app/Http/Controllers/Api/Ekosistem/ValueBasisDataController.php create mode 100644 app/Http/Controllers/Web/Program/RealisasiController.php create mode 100644 app/Http/Controllers/Web/Program/VerifikasiController.php create mode 100644 app/Http/Resources/Ekosistem/KolomBasisDataResource.php create mode 100644 app/Http/Resources/Ekosistem/TabelBasisDataResource.php create mode 100644 app/Http/Resources/Ekosistem/ValueBasisDataResource.php create mode 100644 app/Models/Program/Realisasi.php create mode 100644 app/Models/Program/Verifikasi.php create mode 100644 database/migrations/2026_05_15_161421_update_frameworks_table.php rename resources/views/program/aktivitas/{add.blade.php => add-aktivitas.blade.php} (85%) create mode 100644 resources/views/program/aktivitas/add-tujuan.blade.php rename resources/views/program/aktivitas/{edit.blade.php => edit-aktivitas.blade.php} (92%) create mode 100644 resources/views/program/aktivitas/edit-tujuan.blade.php create mode 100644 resources/views/program/framework/view-aktivitas.blade.php create mode 100644 resources/views/program/framework/view-tujuan.blade.php create mode 100644 resources/views/program/framework/view.blade copy.php create mode 100644 resources/views/program/realisasi/add.blade.php create mode 100644 resources/views/program/realisasi/edit.blade.php create mode 100644 resources/views/program/realisasi/index-aktivitas.blade.php create mode 100644 resources/views/program/realisasi/index-tujuan.blade.php create mode 100644 resources/views/program/realisasi/index.blade.php create mode 100644 resources/views/program/realisasi/list.blade.php create mode 100644 resources/views/program/target/edit.blade.php create mode 100644 resources/views/program/verifikasi/add.blade.php diff --git a/app/Http/Controllers/Api/Ekosistem/FormBasisDataController.php b/app/Http/Controllers/Api/Ekosistem/FormBasisDataController.php new file mode 100644 index 0000000..2aca1c6 --- /dev/null +++ b/app/Http/Controllers/Api/Ekosistem/FormBasisDataController.php @@ -0,0 +1,140 @@ +whereHas('kolom', function ($query) { + $query->where('is_active', true); + })->find($tabelId); + if (!$tabel) { + abort(404, 'Data tabel tidak ditemukan.'); + } + $kolom = KolomBasisData::where('tabel_id', $tabelId) + ->where('is_active', true)->get(); + if ($kolom->isEmpty()) { + abort(404, 'Data kolom tidak ditemukan untuk tabel ini.'); + } + + $program = null; + if (app()->has('SystemProgram')) { + $program = app('SystemProgram'); + } else { + if ($request->has('program_id') && $request->query('program_id')) { + $programId = $request->query('program_id'); + $program = Program::find($programId); + } + } + if (!$program) { + abort(400, 'Program tidak ditemukan.'); + } + + $method = $request->query('method', 'add'); + + $list_relasi = null; + if ($method == 'add' || $method == 'edit') { + $list_relasi = []; + foreach ($kolom as $k) { + if ($k->tipe == 'foreign_key') { + $relasi['kolom_id'] = $k->id; + try { + $options_kolom = DB::table($k->relasi_tabel)->selectRaw($k->relasi_kolom_label . ' as label, ' . $k->relasi_kolom_id . ' as value')->whereNull('deleted_at'); + $relasi['options'] = $options_kolom->get(); + $relasi['sql'] = $options_kolom->toSql(); + } catch (\Throwable $th) { + $relasi['options'] = []; + } + $list_relasi[] = $relasi; + } + } + $list_relasi = collect($list_relasi); + } elseif ($method == 'view') { + $id = $request->query('value_id'); + if (!$id) { + abort(400, 'value_id query parameter diperlukan untuk view method.'); + } + + $values = ValueBasisData::query() + ->where('tabel_id', $tabelId) + ->where('value_id', $id) + ->where('program_id', $program->id) + ->get(); + if ($values->isEmpty()) { + abort(404, 'Data tidak ditemukan.'); + } + + foreach ($values as $v) { + $k = $kolom->where('id', $v->kolom_id)->first(); + if ($k->tipe == 'foreign_key') { + $v->value_relasi_label = DB::table($k->relasi_tabel)->where($k->relasi_kolom_id, $v->value_relasi)->value($k->relasi_kolom_label); + } else if ($k->tipe == 'enum') { + $opsi = collect($k->enum_opsi); + $found = $opsi->first(function ($item) use ($v) { + return (string) $item['value'] === (string) $v->value_enum; + }); + $v->value_enum_label = $found['label'] ?? null; + } + } + + $value_id = $id; + } + + + $errors = $request->query('errors', null); + + return response()->json($tabel->renderHtml($method, $errors, $list_relasi)); + } + + /** + * 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/Ekosistem/TabelBasisDataController.php b/app/Http/Controllers/Api/Ekosistem/TabelBasisDataController.php new file mode 100644 index 0000000..4f6512d --- /dev/null +++ b/app/Http/Controllers/Api/Ekosistem/TabelBasisDataController.php @@ -0,0 +1,79 @@ +query('per_page', 10); + $search = strtolower($request->query('search', '')); + + $tabel = TabelBasisData::with('kolom') + ->whereHas('kolom', function ($query) { + $query->where('is_active', true); + }) + ->whereRaw('lower(tabel) LIKE ?', ["%$search%"]) + ->paginate($perPage); + + return TabelBasisDataResource::collection($tabel); + } + + /** + * Store a newly created resource in storage. + */ + public function store(Request $request) + { + // + } + + /** + * Display the specified resource. + */ + public function show(Request $request, string $id): JsonResponse + { + if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) { + abort(403); + } + + $tabel = TabelBasisData::with('kolom')->findOrFail($id); + + return (new TabelBasisDataResource($tabel)) + ->response() + ->setStatusCode(201); + } + + /** + * 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/Ekosistem/ValueBasisDataController.php b/app/Http/Controllers/Api/Ekosistem/ValueBasisDataController.php new file mode 100644 index 0000000..d2134cc --- /dev/null +++ b/app/Http/Controllers/Api/Ekosistem/ValueBasisDataController.php @@ -0,0 +1,367 @@ +query('per_page', 10); + $search = strtolower($request->query('search', '')); + + $program = null; + $programList = Program::get(); + if (app()->has('SystemProgram')) { + $program = app('SystemProgram'); + } else { + if ($request->has('program_id') && $request->query('program_id')) { + $programId = $request->query('program_id'); + $program = Program::find($programId); + if (!$program) { + abort(400, 'Program tidak ditemukan.'); + } + } + } + + $tabel = TabelBasisData::with('kolom') + ->whereHas('kolom', function ($query) { + $query->where('is_active', true); + }) + ->find($tabelId); + if (!$tabel) { + abort(404, 'Data tabel tidak ditemukan.'); + } + $kolom = KolomBasisData::where('tabel_id', $tabelId) + ->where('is_active', true) + ->when('is_browse', function ($q) { + $q->where('is_browse', true); + }) + ->orderBy('urutan', 'asc') + ->get(); + if ($kolom->isEmpty()) { + abort(404, 'Data kolom tidak ditemukan untuk tabel ini.'); + } + + $selects = []; + foreach ($kolom as $k) { + if ($k->tipe == 'boolean') { + $selects[] = " + MAX( + CASE + WHEN kolom_id = {$k->id} + THEN CASE + WHEN value_boolean = true THEN 'Ya' + WHEN value_boolean = false THEN 'Tidak' + ELSE NULL + END + ELSE NULL + END + ) AS \"{$k->kolom}\" + "; + } elseif ($k->tipe == 'foreign_key') { + $selects[] = " + MAX( + CASE + WHEN kolom_id = {$k->id} + THEN (select {$k->relasi_kolom_label} from {$k->relasi_tabel} where {$k->relasi_kolom_id} = value_relasi) + ELSE NULL + END + ) AS \"{$k->kolom}\" + "; + } elseif ($k->tipe == 'enum') { + $selects[] = " + MAX( + CASE + WHEN kolom_id = {$k->id} + THEN ( + SELECT elem->>'label' + FROM ekosistem_basis_data_kolom k, + jsonb_array_elements(k.enum_opsi::jsonb) AS elem + WHERE k.id = kolom_id + AND elem->>'value' = value_enum + LIMIT 1 + ) + ELSE NULL + END + ) AS \"{$k->kolom}\" + "; + } else { + $selects[] = " + MAX( + CASE + WHEN kolom_id = {$k->id} + THEN value_{$k->tipe} + ELSE NULL + END + ) AS \"{$k->kolom}\" + "; + } + } + + $base = ValueBasisData::query() + ->join('core_program', 'core_program.id', '=', 'ekosistem_basis_data_value.program_id') + ->where('tabel_id', $tabelId) + ->when($program, function ($query) use ($program) { + $query->where('program_id', $program->id); + }) + ->selectRaw(" + core_program.id AS program_id, + core_program.nama AS program_nama, + tabel_id, + value_id, + " . implode(",\n", $selects) . " + ") + ->groupBy('core_program.id', 'core_program.nama', 'tabel_id', 'value_id') + ->orderBy('value_id', 'asc'); + + $values = DB::query()->fromSub($base, 'pivot') + ->when($search, function ($query) use ($search, $kolom) { + $query->where(function ($q) use ($search, $kolom) { + foreach ($kolom as $k) { + if ($k->tipe == 'text' || $k->tipe == 'varchar') { + $q->orWhereRaw("lower({$k->kolom}) LIKE ?", ["%$search%"]); + } + } + }); + }) + ->paginate($perPage); + + return response()->json($values); + } + + /** + * Store a newly created resource in storage. + */ + public function store(Request $request, string $tabelId): JsonResponse + { + if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) { + abort(403); + } + + $tabel = TabelBasisData::whereHas('kolom', function ($query) { + $query->where('is_active', true); + })->find($tabelId); + if (!$tabel) { + abort(404, 'Data tabel tidak ditemukan.'); + } + $kolom = KolomBasisData::where('tabel_id', $tabelId) + ->where('is_active', true)->get(); + if ($kolom->isEmpty()) { + abort(404, 'Data kolom tidak ditemukan untuk tabel ini.'); + } + if (app()->has('SystemProgram')) { + $program = app('SystemProgram'); + } else { + if ($request->has('program_id') && $request->query('program_id')) { + $programId = $request->query('program_id'); + $program = Program::find($programId); + if (!$program) { + abort(400, 'Program tidak ditemukan.'); + } + } else { + abort(400, 'Program tidak ditemukan.'); + } + } + + $validationRules = []; + foreach ($kolom as $k) { + if ($k->validasi && is_array($k->validasi)) { + $validationRules[$k->kolom] = $k->validasi; + } else { + $validationRules[$k->kolom] = ['nullable']; + } + } + $validated = $request->validate($validationRules); + + DB::transaction(function () use ($program, $tabelId, $validated, $kolom) { + $maxId = ValueBasisData::where('tabel_id', $tabelId) + ->where('program_id', $program->id) + ->whereNotNull('value_id') + ->max('value_id'); + foreach ($kolom as $k) { + $values = [ + 'program_id' => $program->id, + 'tabel_id' => (int)$tabelId, + 'kolom_id' => $k->id, + 'value_id' => ($maxId ?? 0) + 1, + 'created_by' => auth()->id(), + 'updated_by' => auth()->id(), + ]; + if ($k->tipe == 'foreign_key') { + $values['value_relasi'] = $validated[$k->kolom] ?? null; + } else { + $values['value_' . $k->tipe] = $validated[$k->kolom] ?? null; + } + + ValueBasisData::create($values); + } + }); + + return response()->json(['message' => 'Data berhasil disimpan.']); + } + + /** + * Display the specified resource. + */ + public function show(string $id) + { + // + } + + /** + * Update the specified resource in storage. + */ + public function update(Request $request, string $id): JsonResponse + { + if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) { + abort(403); + } + + $tabel = TabelBasisData::whereHas('kolom', function ($query) { + $query->where('is_active', true); + })->find($tabelId); + if (!$tabel) { + abort(404, 'Data tabel tidak ditemukan.'); + } + $kolom = KolomBasisData::where('tabel_id', $tabelId) + ->where('is_active', true)->get(); + if ($kolom->isEmpty()) { + abort(404, 'Data kolom tidak ditemukan untuk tabel ini.'); + } + if (app()->has('SystemProgram')) { + $program = app('SystemProgram'); + } else { + if ($request->has('program_id') && $request->query('program_id')) { + $programId = $request->query('program_id'); + $program = Program::find($programId); + if (!$program) { + abort(400, 'Program tidak ditemukan.'); + } + } else { + abort(400, 'Program tidak ditemukan.'); + } + } + + $values = ValueBasisData::query() + ->where('tabel_id', $tabelId) + ->where('value_id', $id) + ->where('program_id', $program->id) + ->get(); + if ($values->isEmpty()) { + abort(404, 'Data tidak ditemukan.'); + } + + $validationRules = []; + foreach ($kolom as $k) { + if ($k->validasi && is_array($k->validasi)) { + $validationRules[$k->kolom] = $k->validasi; + } else { + $validationRules[$k->kolom] = ['nullable']; + } + } + $validated = $request->validate($validationRules); + + DB::transaction(function () use ($program, $tabelId, $validated, $kolom, $id, $values) { + foreach ($validated as $kol => $val) { + $k = $kolom->where('kolom', $kol)->first(); + if (!$k) { + continue; + } + $v = $values->where('kolom_id', $k->id)->first(); + if (!$v) { + $vals = [ + 'program_id' => $program->id, + 'tabel_id' => (int)$tabelId, + 'kolom_id' => $k->id, + 'value_id' => $id, + 'created_by' => auth()->id(), + 'updated_by' => auth()->id(), + ]; + if ($k->tipe == 'foreign_key') { + $vals['value_relasi'] = $validated[$k->kolom] ?? null; + } else { + $vals['value_' . $k->tipe] = $validated[$k->kolom] ?? null; + } + ValueBasisData::create($vals); + } else { + $v->update([ + 'value_' . ($k->tipe == 'foreign_key' ? 'relasi' : $k->tipe) => $val, + 'updated_by' => auth()->id(), + ]); + } + } + }); + + return response()->json(['message' => 'Data berhasil diperbarui.']); + } + + /** + * Remove the specified resource from storage. + */ + public function destroy(string $tabelId, string $id): JsonResponse + { + if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) { + abort(403); + } + + $tabel = TabelBasisData::whereHas('kolom', function ($query) { + $query->where('is_active', true); + })->find($tabelId); + if (!$tabel) { + abort(404, 'Data tabel tidak ditemukan.'); + } + $kolom = KolomBasisData::where('tabel_id', $tabelId)->get(); + if ($kolom->isEmpty()) { + abort(404, 'Data kolom tidak ditemukan untuk tabel ini.'); + } + if (app()->has('SystemProgram')) { + $program = app('SystemProgram'); + } else { + if ($request->has('program_id') && $request->query('program_id')) { + $programId = $request->query('program_id'); + $program = Program::find($programId); + if (!$program) { + abort(400, 'Program tidak ditemukan.'); + } + } else { + abort(400, 'Program tidak ditemukan.'); + } + } + + $values = ValueBasisData::query() + ->where('tabel_id', $tabelId) + ->where('value_id', $id) + ->where('program_id', $program->id) + ->get(); + if ($values->isEmpty()) { + abort(404, 'Data tidak ditemukan.'); + } + + ValueBasisData::query() + ->where('tabel_id', $tabelId) + ->where('value_id', $id) + ->where('program_id', $program->id) + ->delete(); + + return response()->json(['message' => 'Data berhasil dihapus.']); + } +} diff --git a/app/Http/Controllers/Web/Ekosistem/ValueBasisDataController.php b/app/Http/Controllers/Web/Ekosistem/ValueBasisDataController.php index 2c5234c..8279d3b 100644 --- a/app/Http/Controllers/Web/Ekosistem/ValueBasisDataController.php +++ b/app/Http/Controllers/Web/Ekosistem/ValueBasisDataController.php @@ -23,7 +23,7 @@ class ValueBasisDataController extends Controller { public function index(Request $request, string $tabelId): View { - if (!Gate::any(['super_admin', 'admin'])) { + if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) { abort(403); } @@ -44,13 +44,15 @@ class ValueBasisDataController extends Controller } } - $tabel = TabelBasisData::find($tabelId); + $tabel = TabelBasisData::with('kolom') + ->whereHas('kolom', function ($query) { + $query->where('is_active', true); + })->find($tabelId); if (!$tabel) { abort(404, 'Data tabel tidak ditemukan.'); } - $kolom = KolomBasisData::where('tabel_id', $tabelId) + $kolom = KolomBasisData::where('tabel_id', $tabel->id) ->where('is_active', true) - ->where('is_browse', true) ->get(); if ($kolom->isEmpty()) { abort(404, 'Data kolom tidak ditemukan untuk tabel ini.'); @@ -165,7 +167,10 @@ class ValueBasisDataController extends Controller abort(403); } - $tabel = TabelBasisData::find($tabelId); + $tabel = TabelBasisData::with('kolom') + ->whereHas('kolom', function ($query) { + $query->where('is_active', true); + })->find($tabelId); if (!$tabel) { abort(404, 'Data tabel tidak ditemukan.'); } @@ -213,7 +218,10 @@ class ValueBasisDataController extends Controller abort(403); } - $tabel = TabelBasisData::find($tabelId); + $tabel = TabelBasisData::with('kolom') + ->whereHas('kolom', function ($query) { + $query->where('is_active', true); + })->find($tabelId); if (!$tabel) { abort(404, 'Data tabel tidak ditemukan.'); } @@ -282,7 +290,10 @@ class ValueBasisDataController extends Controller abort(403); } - $tabel = TabelBasisData::find($tabelId); + $tabel = TabelBasisData::with('kolom') + ->whereHas('kolom', function ($query) { + $query->where('is_active', true); + })->find($tabelId); if (!$tabel) { abort(404, 'Data tabel tidak ditemukan.'); } @@ -339,7 +350,10 @@ class ValueBasisDataController extends Controller abort(403); } - $tabel = TabelBasisData::find($tabelId); + $tabel = TabelBasisData::with('kolom') + ->whereHas('kolom', function ($query) { + $query->where('is_active', true); + })->find($tabelId); if (!$tabel) { abort(404, 'Data tabel tidak ditemukan.'); } @@ -402,7 +416,10 @@ class ValueBasisDataController extends Controller abort(403); } - $tabel = TabelBasisData::find($tabelId); + $tabel = TabelBasisData::with('kolom') + ->whereHas('kolom', function ($query) { + $query->where('is_active', true); + })->find($tabelId); if (!$tabel) { abort(404, 'Data tabel tidak ditemukan.'); } diff --git a/app/Http/Controllers/Web/Program/AktivitasController.php b/app/Http/Controllers/Web/Program/AktivitasController.php index 9c34155..1f88669 100644 --- a/app/Http/Controllers/Web/Program/AktivitasController.php +++ b/app/Http/Controllers/Web/Program/AktivitasController.php @@ -54,6 +54,9 @@ class AktivitasController extends Controller 'jenis_aktivitas' => ['required','string','max:255', Rule::in(['tujuan', 'aktivitas']),], 'indikator' => ['required','string'], 'deskripsi' => ['required','string'], + 'parent_id' => [ + Rule::requiredIf($request->jenis_aktivitas === 'aktivitas'), + 'nullable','exists:program_aktivitas,id',], ]); Aktivitas::create([...$validated, @@ -125,6 +128,9 @@ class AktivitasController extends Controller 'jenis_aktivitas' => ['required','string','max:255', Rule::in(['tujuan', 'aktivitas']),], 'indikator' => ['required','string'], 'deskripsi' => ['required','string'], + 'parent_id' => [ + Rule::requiredIf($request->jenis_aktivitas === 'aktivitas'), + 'nullable','exists:program_aktivitas,id'], ]); $aktivitas->update([...$validated, diff --git a/app/Http/Controllers/Web/Program/FrameworkController.php b/app/Http/Controllers/Web/Program/FrameworkController.php index 365d6fe..10df7cc 100644 --- a/app/Http/Controllers/Web/Program/FrameworkController.php +++ b/app/Http/Controllers/Web/Program/FrameworkController.php @@ -102,7 +102,8 @@ class FrameworkController extends Controller abort(403); } - $framework = Framework::findOrFail($id); + $framework = Framework::with('transformasi')->with('transformasi.tujuan') + ->findOrFail($id); $program = Program::all(); return view('program.framework.edit', compact('framework', 'program')); diff --git a/app/Http/Controllers/Web/Program/RealisasiController.php b/app/Http/Controllers/Web/Program/RealisasiController.php new file mode 100644 index 0000000..25eed7d --- /dev/null +++ b/app/Http/Controllers/Web/Program/RealisasiController.php @@ -0,0 +1,125 @@ +has('frameworkid'), function ($query) use ($request) { + $query->where('id', $request->frameworkid); + })->latest()->first(); + if ($framework == null) { + abort(404); + } + + return view('program.realisasi.index', compact('framework')); + } + + public function create() + { + // + } + + public function store(Request $request): JsonResponse + { + if (!Gate::any(['super_admin', 'admin'])) { + abort(403); + } + + $validated = $request->validate([ + 'target_id' => ['required', 'integer', 'exists:program_target,id'], + 'realisasi_integer' => ['nullable', 'integer'], + 'realisasi_float' => ['nullable', 'numeric'], + 'realisasi_boolean' => ['nullable', 'boolean'], + ]); + + $realisasi = Realisasi::create([...$validated, + 'created_by' => auth()->id(), + 'updated_by' => auth()->id() + ]); + + return response()->json([ + 'status' => 'success', + 'message' => 'Target berhasil ditambahkan.' + ], 201); + } + + public function show(string $id) + { + if (!Gate::any(['super_admin', 'admin'])) { + abort(403); + } + + $realisasi = Realisasi::with('target', 'target.aktivitas', 'target.aktivitas.transformasi') + ->find($id); + if (!$realisasi) { + return response()->json([ + 'status' => 'error', + 'message' => 'Data realisasi tidak ditemukan.' + ], 404); + } + + return response()->json([ + 'status' => 'success', + 'data' => $realisasi + ]); + } + + public function edit(string $id) + { + // + } + + public function update(Request $request, string $id): JsonResponse + { + if (!Gate::any(['super_admin', 'admin'])) { + abort(403); + } + + $realisasi = Realisasi::find($id); + if (!$realisasi) { + return response()->json([ + 'status' => 'error', + 'message' => 'Data realisasi tidak ditemukan.' + ], 404); + } + + $validated = $request->validate([ + 'target_id' => ['required', 'integer', 'exists:program_target,id'], + 'realisasi_integer' => ['nullable', 'integer'], + 'realisasi_float' => ['nullable', 'numeric'], + 'realisasi_boolean' => ['nullable', 'boolean'], + ]); + + $realisasi->update([...$validated, + 'updated_by' => auth()->id(), + ]); + + return response()->json([ + 'status' => 'success', + 'message' => 'Target berhasil diperbarui.' + ], 200); + } + + /** + * Remove the specified resource from storage. + */ + public function destroy(string $id) + { + // + } +} diff --git a/app/Http/Controllers/Web/Program/TargetController.php b/app/Http/Controllers/Web/Program/TargetController.php index b47ee4f..ac4ab67 100644 --- a/app/Http/Controllers/Web/Program/TargetController.php +++ b/app/Http/Controllers/Web/Program/TargetController.php @@ -69,6 +69,16 @@ class TargetController extends Controller 'nullable', 'boolean' ], + 'tipe_realisasi' => [ + 'nullable', + 'string', + Rule::in(['manual', 'referensi']) + ], + 'value_query' => [ + Rule::requiredIf($request->tipe_realisasi === 'referensi'), + 'nullable', + 'string' + ] ]); } @@ -77,9 +87,6 @@ class TargetController extends Controller } - /** - * Store a newly created resource in storage. - */ public function store(Request $request, string $frameworkId, string $transformasiId, string $aktivitasId): JsonResponse { if (!Gate::any(['super_admin', 'admin'])) { @@ -109,12 +116,32 @@ class TargetController extends Controller ], 201); } - /** - * Display the specified resource. - */ - public function show(string $id) + public function show(string $frameworkId, string $transformasiId, string $aktivitasId, string $id) { - // + if (!Gate::any(['super_admin', 'admin'])) { + abort(403); + } + + $target = Target::with('realisasi', 'latestRealisasi') + ->whereHas('aktivitas.transformasi', function ($query) use ($frameworkId) { + $query->where('framework_id', $frameworkId); + }) + ->whereHas('aktivitas', function ($query) use ($transformasiId) { + $query->where('transformasi_id', $transformasiId); + }) + ->where('aktivitas_id', $aktivitasId)->find($id); + + if (!$target) { + return response()->json([ + 'status' => 'error', + 'message' => 'Data target tidak ditemukan.' + ], 404); + } + + return response()->json([ + 'status' => 'success', + 'data' => $target + ]); } /** @@ -128,16 +155,67 @@ class TargetController extends Controller /** * Update the specified resource in storage. */ - public function update(Request $request, string $id) + public function update(Request $request, string $frameworkId, string $transformasiId, string $aktivitasId, string $id) { - // + if (!Gate::any(['super_admin', 'admin'])) { + abort(403); + } + + $target = Target::whereHas('aktivitas.transformasi', function ($query) use ($frameworkId) { + $query->where('framework_id', $frameworkId); + }) + ->whereHas('aktivitas', function ($query) use ($transformasiId) { + $query->where('transformasi_id', $transformasiId); + }) + ->where('aktivitas_id', $aktivitasId)->find($id); + + if (!$target) { + return response()->json([ + 'status' => 'error', + 'message' => 'Data target tidak ditemukan.' + ], 404); + } + + $validated = $this->validated($request); + $target->update([...$validated, + 'updated_by' => auth()->id(), + ]); + + return response()->json([ + 'status' => 'success', + 'message' => 'Target berhasil diperbarui.' + ], 200); } - /** - * Remove the specified resource from storage. - */ - public function destroy(string $id) + public function destroy(string $frameworkId, string $transformasiId, string $aktivitasId, string $id) { - // + if (!Gate::any(['super_admin', 'admin'])) { + abort(403); + } + + $target = Target::whereHas('aktivitas.transformasi', function ($query) use ($frameworkId) { + $query->where('framework_id', $frameworkId); + }) + ->whereHas('aktivitas', function ($query) use ($transformasiId) { + $query->where('transformasi_id', $transformasiId); + }) + ->where('aktivitas_id', $aktivitasId)->find($id); + + if (!$target) { + return response()->json([ + 'status' => 'error', + 'message' => 'Data target tidak ditemukan.' + ], 404); + } + + $target->update([ + 'deleted_by' => auth()->id(), + ]); + $target->delete(); + + return response()->json([ + 'status' => 'success', + 'message' => 'Target berhasil dihapus.' + ], 200); } } diff --git a/app/Http/Controllers/Web/Program/VerifikasiController.php b/app/Http/Controllers/Web/Program/VerifikasiController.php new file mode 100644 index 0000000..0e52d7e --- /dev/null +++ b/app/Http/Controllers/Web/Program/VerifikasiController.php @@ -0,0 +1,90 @@ +validate([ + 'realisasi_id' => ['required', 'integer', 'exists:program_realisasi,id'], + 'dokumen' => ['required', 'string'], + 'link_dokumen' => ['required', 'url'], + ]); + + $verifikasi = Verifikasi::create([...$validated, + 'created_by' => auth()->id(), + 'updated_by' => auth()->id() + ]); + + return response()->json([ + 'status' => 'success', + 'message' => 'Dokumen bukti berhasil ditambahkan.' + ], 201); + } + + /** + * Display the specified resource. + */ + public function show(string $id): JsonResponse + { + // + } + + /** + * Show the form for editing the specified resource. + */ + public function edit(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/Resources/Ekosistem/KolomBasisDataResource.php b/app/Http/Resources/Ekosistem/KolomBasisDataResource.php new file mode 100644 index 0000000..f156a3d --- /dev/null +++ b/app/Http/Resources/Ekosistem/KolomBasisDataResource.php @@ -0,0 +1,32 @@ + + */ + public function toArray(Request $request): array + { + return [ + 'id' => $this->id, + 'label' => $this->label, + 'kolom' => $this->kolom, + 'tipe' => $this->tipe, + 'validasi' => $this->validasi, + 'urutan' => $this->urutan, + 'relasi_tabel' => $this->relasi_tabel, + 'relasi_kolom_id' => $this->relasi_kolom_id, + 'relasi_kolom_label' => $this->relasi_kolom_label, + 'enum_opsi' => $this->enum_opsi, + 'is_active' => $this->is_active, + 'is_browse' => $this->is_browse, + ]; + } +} diff --git a/app/Http/Resources/Ekosistem/TabelBasisDataResource.php b/app/Http/Resources/Ekosistem/TabelBasisDataResource.php new file mode 100644 index 0000000..2b2feb6 --- /dev/null +++ b/app/Http/Resources/Ekosistem/TabelBasisDataResource.php @@ -0,0 +1,34 @@ + + */ + public function toArray(Request $request): array + { + return [ + 'id' => $this->id, + 'tabel' => $this->tabel, + 'label' => $this->label, + 'menu' => $this->menu, + 'deskripsi' => $this->deskripsi, + // 'group_id' => $this->group_id, + 'urutan' => $this->urutan, + // 'group' => new GroupBasisDataResource($this->whenLoaded('group')), + 'kolom' => KolomBasisDataResource::collection($this->whenLoaded('kolom')), + //'ringkasan' => RingkasanBasisDataResource::collection($this->whenLoaded('ringkasan')), + ]; + } +} diff --git a/app/Http/Resources/Ekosistem/ValueBasisDataResource.php b/app/Http/Resources/Ekosistem/ValueBasisDataResource.php new file mode 100644 index 0000000..b377c8b --- /dev/null +++ b/app/Http/Resources/Ekosistem/ValueBasisDataResource.php @@ -0,0 +1,34 @@ + + */ + public function toArray(Request $request): array + { + return [ + 'id' => $this->id, + 'program_id' => $this->program_id, + 'tabel_id' => $this->tabel_id, + 'kolom_id' => $this->kolom_id, + 'value_id' => $this->value_id, + 'value_varchar' => $this->value_varchar, + 'value_integer' => $this->value_integer, + 'value_float' => $this->value_float, + 'value_boolean' => $this->value_boolean, + 'value_date' => $this->value_date, + 'value_datetime' => $this->value_datetime, + 'value_text' => $this->value_text, + 'value_relasi' => $this->value_relasi, + 'value_enum' => $this->value_enum, + ]; + } +} diff --git a/app/Models/Ekosistem/FormBasisData.php b/app/Models/Ekosistem/FormBasisData.php index d8f7ab4..75ecef6 100644 --- a/app/Models/Ekosistem/FormBasisData.php +++ b/app/Models/Ekosistem/FormBasisData.php @@ -65,30 +65,42 @@ class FormBasisData extends Model return $this->belongsTo(KolomBasisData::class, 'kolom_id'); } - public function renderHtml(string $state, $errors = null, $optionsFK = null, $values = null): string + public function renderHtml(string $state, $errors = null, $optionsFK = null, $values = null, $framework = 'bootstrap'): string { - return match ($this->tipe) { - LayoutForm::COLUMN => '
' - .$this->childHtml($state, $errors, $optionsFK, $values).'
', - LayoutForm::VALUE => $this->value($state, $errors, $optionsFK, $values), - LayoutForm::SECTION => '
'.$this->section_label.'
', - LayoutForm::ROW => '
'.$this->childHtml($state, $errors, $optionsFK, $values).'
', - LayoutForm::HR_LINE => '
', - default => '' - }; + if ($framework == 'tailwind') { + return match ($this->tipe) { + LayoutForm::COLUMN => '
' + .$this->childHtml($state, $errors, $optionsFK, $values, $framework).'
', + LayoutForm::VALUE => $this->value($state, $errors, $optionsFK, $values, $framework), + LayoutForm::SECTION => '

'.$this->section_label.'

', + LayoutForm::ROW => '
'.$this->childHtml($state, $errors, $optionsFK, $values, $framework).'
', + LayoutForm::HR_LINE => '
', + default => '' + }; + } else { + return match ($this->tipe) { + LayoutForm::COLUMN => '
' + .$this->childHtml($state, $errors, $optionsFK, $values, $framework).'
', + LayoutForm::VALUE => $this->value($state, $errors, $optionsFK, $values, $framework), + LayoutForm::SECTION => '
'.$this->section_label.'
', + LayoutForm::ROW => '
'.$this->childHtml($state, $errors, $optionsFK, $values, $framework).'
', + LayoutForm::HR_LINE => '
', + default => '' + }; + } } - private function childHtml(string $state, $errors = null, $optionsFK = null, $values = null): string + private function childHtml(string $state, $errors = null, $optionsFK = null, $values = null, $framework = 'bootstrap'): string { $html = ''; foreach ($this->form as $form) { - $html .= $form->renderHtml($state, $errors, $optionsFK, $values); + $html .= $form->renderHtml($state, $errors, $optionsFK, $values, $framework); } return $html; } - private function value(string $state, $errors = null, $optionsFK = null, $values = null): string + private function value(string $state, $errors = null, $optionsFK = null, $values = null, $framework = 'bootstrap'): string { $html = ''; if ($this->kolom) { @@ -97,92 +109,227 @@ class FormBasisData extends Model $value = $values ? $values->where('kolom_id', $k->id)->first() : null; $oldValue = old($k->kolom); - $html .= ''; + if ($framework == 'tailwind') { + $html .= ''; + } else { + $html .= ''; + } if($k->tipe == 'varchar') { - $html .= ''; + if ($framework == 'tailwind') { + $html .= ''; + } else { + $html .= ''; + } } elseif($k->tipe == 'text') { - $html .= ''; + if ($framework == 'tailwind') { + $html .= ''; + } else { + $html .= ''; + } } elseif($k->tipe == 'integer') { - $html .= ''; + if ($framework == 'tailwind') { + $html .= ''; + } else { + $html .= ''; + } } elseif($k->tipe == 'float') { - $html .= ''; + if ($framework == 'tailwind') { + $html .= ''; + } else { + $html .= ''; + } } elseif($k->tipe == 'date') { - $html .= ''; + if ($framework == 'tailwind') { + $html .= ''; + } else { + $html .= ''; + } } elseif($k->tipe == 'datetime'){ - $html .= ''; + if ($framework == 'tailwind') { + $html .= ''; + } else { + $html .= ''; + } } elseif($k->tipe == 'boolean') { if ($state == 'preview' || $state == 'view') { - $html .= 'kolom) == 1 ? 'selected' : '') .'>Ya - - '; + if ($framework == 'tailwind') { + $html .= ''; + } else { + $html .= ''; + } } elseif ($state == 'edit') { - $html .= ''; + if ($framework == 'tailwind') { + $html .= ''; + } else { + $html .= ''; + } } } elseif($k->tipe == 'foreign_key') { if ($state == 'preview' || $state == 'view') { - $html .= ''; + if ($framework == 'tailwind') { + $html .= ''; + } else { + $html .= ''; + } } elseif ($state == 'add') { - $html .= ' + + + '; + if ($optionsFK && $optionsFK->where('kolom_id', $k->id)->first() != null) { + foreach ($optionsFK->where('kolom_id', $k->id)->first()['options'] as $option) { + $html .= ' + '.$option->label.' + '; + } } + $html .= ''; + } else { + $html .= ''; } - $html .= ''; } elseif ($state == 'edit') { - $html .= ' + + + '; + if ($optionsFK && $optionsFK->where('kolom_id', $k->id)->first() != null) { + foreach ($optionsFK->where('kolom_id', $k->id)->first()['options'] as $option) { + $html .= ' + kolom) ?? ($value ? ($value['value_relasi'] == $option->value) : null) ? 'selected' : '') .'>'.$option->label.' + '; + } } + $html .= ''; + } else { + $html .= ''; } - $html .= ''; } } elseif($k->tipe == 'enum') { if ($state == 'preview' || $state == 'view') { - $html .= ''; + if ($framework == 'tailwind') { + $html .= ''; + } else { + $html .= ''; + } } elseif ($state == 'add') { - $html .= ' + + + '; + foreach($k->enum_opsi as $opsi) { + $html .= ' + '.$opsi['label'].' + '; + } + $html .= ''; + } else { + $html .= ''; } - $html .= ''; } elseif ($state == 'edit') { - $html .= ' + + + '; + foreach($k->enum_opsi as $opsi) { + $html .= ' + '.$opsi['label'].' + '; + } + $html .= ''; + } else { + $html .= ''; } - $html .= ''; } } else { - $html .= ''; + if ($framework == 'tailwind') { + $html .= ''; + } else { + $html .= ''; + } } $errorClass = $errors && $errors->has($k->kolom) diff --git a/app/Models/Program/Aktivitas.php b/app/Models/Program/Aktivitas.php index 4e471d0..47cd02d 100644 --- a/app/Models/Program/Aktivitas.php +++ b/app/Models/Program/Aktivitas.php @@ -23,6 +23,9 @@ class Aktivitas extends Model "indikator", "deskripsi", "transformasi_id", + "parent_id", + "created_by", + "updated_by" ]; public function transformasi(): BelongsTo @@ -32,6 +35,20 @@ class Aktivitas extends Model public function target(): HasMany { - return $this->hasMany(Target::class, 'aktivitas_id', 'id'); + return $this->hasMany(Target::class, 'aktivitas_id', 'id') + ->orderBy('id', 'asc'); + } + + public function parent(): BelongsTo + { + return $this->belongsTo(Aktivitas::class, 'parent_id', 'id'); + } + + public function aktivitas(): HasMany + { + return $this->hasMany(Aktivitas::class, 'parent_id', 'id') + ->where('jenis_aktivitas', 'aktivitas') + ->orderBy('kode', 'asc') + ->orderBy('id', 'asc'); } } diff --git a/app/Models/Program/Framework.php b/app/Models/Program/Framework.php index 5740a89..e7d1d2a 100644 --- a/app/Models/Program/Framework.php +++ b/app/Models/Program/Framework.php @@ -20,6 +20,8 @@ class Framework extends Model "nama", "tahun", "program_id", + "created_by", + "updated_by", ]; public function program(): BelongsTo @@ -29,6 +31,8 @@ class Framework extends Model public function transformasi(): HasMany { - return $this->hasMany(Transformasi::class, 'framework_id', 'id'); + return $this->hasMany(Transformasi::class, 'framework_id', 'id') + ->orderBy('kode', 'asc') + ->orderBy('id', 'asc'); } } diff --git a/app/Models/Program/Realisasi.php b/app/Models/Program/Realisasi.php new file mode 100644 index 0000000..ba56efa --- /dev/null +++ b/app/Models/Program/Realisasi.php @@ -0,0 +1,37 @@ +belongsTo(Target::class, 'target_id', 'id'); + } + + public function verifikasi(): HasMany + { + return $this->hasMany(Verifikasi::class, 'realisasi_id', 'id')->oldest(); + } +} diff --git a/app/Models/Program/Target.php b/app/Models/Program/Target.php index a1a791a..8bf0f80 100644 --- a/app/Models/Program/Target.php +++ b/app/Models/Program/Target.php @@ -5,6 +5,8 @@ namespace App\Models\Program; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\HasMany; +use Illuminate\Database\Eloquent\Relations\HasOne; use App\Models\Program\Aktivitas; @@ -27,10 +29,25 @@ class Target extends Model "realisasi_float", "realisasi_boolean", "aktivitas_id", + "tipe_realisasi", + "value_query", + "created_by", + "updated_by", + "deleted_by", ]; public function aktivitas(): BelongsTo { return $this->belongsTo(Aktivitas::class, 'aktivitas_id', 'id'); } + + public function realisasi(): HasMany + { + return $this->hasMany(Realisasi::class, 'target_id', 'id')->latest(); + } + + public function latestRealisasi(): HasOne + { + return $this->hasOne(Realisasi::class, 'target_id', 'id')->latest(); + } } diff --git a/app/Models/Program/Transformasi.php b/app/Models/Program/Transformasi.php index 9e2bd68..504c5f8 100644 --- a/app/Models/Program/Transformasi.php +++ b/app/Models/Program/Transformasi.php @@ -27,8 +27,12 @@ class Transformasi extends Model return $this->belongsTo(Framework::class, 'framework_id', 'id'); } - public function aktivitas(): HasMany + public function tujuan(): HasMany { - return $this->hasMany(Aktivitas::class, 'transformasi_id', 'id'); + return $this->hasMany(Aktivitas::class, 'transformasi_id', 'id') + ->whereNull('parent_id') + ->where('jenis_aktivitas', 'tujuan') + ->orderBy('kode', 'asc') + ->orderBy('id', 'asc'); } } diff --git a/app/Models/Program/Verifikasi.php b/app/Models/Program/Verifikasi.php new file mode 100644 index 0000000..837e48b --- /dev/null +++ b/app/Models/Program/Verifikasi.php @@ -0,0 +1,30 @@ +belongsTo(Realisasi::class, 'realisasi_id', 'id'); + } +} diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index d1ccde5..d8209f0 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -67,7 +67,9 @@ class AppServiceProvider extends ServiceProvider }); View::composer('*', function ($view) { - $tabel_menu = TabelBasisData::has('kolom')->get(); + $tabel_menu = TabelBasisData::whereHas('kolom', function ($query) { + $query->where('is_active', true); + })->get(); $view->with('tabel_menu', $tabel_menu); }); diff --git a/database/migrations/2026_05_15_161421_update_frameworks_table.php b/database/migrations/2026_05_15_161421_update_frameworks_table.php new file mode 100644 index 0000000..dc94b1b --- /dev/null +++ b/database/migrations/2026_05_15_161421_update_frameworks_table.php @@ -0,0 +1,36 @@ +foreignId('parent_id')->nullable()->constrained('program_aktivitas')->nullOnDelete(); + }); + + Schema::table('program_target', function (Blueprint $table) { + $table->enum('tipe_realisasi', ['manual', 'referensi'])->default('manual'); + $table->text('value_query')->nullable(); + }); + + Schema::table('program_verifikasi', function (Blueprint $table) { + $table->foreignId('realisasi_id')->nullable()->constrained('program_realisasi')->nullOnDelete(); + $table->dropColumn('aktivitas_id'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + + } +}; \ No newline at end of file diff --git a/resources/views/ekosistem/value-basis-data/add.blade.php b/resources/views/ekosistem/value-basis-data/add.blade.php index c75a269..d66c836 100644 --- a/resources/views/ekosistem/value-basis-data/add.blade.php +++ b/resources/views/ekosistem/value-basis-data/add.blade.php @@ -27,7 +27,7 @@ +@endpush \ No newline at end of file diff --git a/resources/views/program/aktivitas/edit.blade.php b/resources/views/program/aktivitas/edit-aktivitas.blade.php similarity index 92% rename from resources/views/program/aktivitas/edit.blade.php rename to resources/views/program/aktivitas/edit-aktivitas.blade.php index ac3e5ac..b8d7a44 100644 --- a/resources/views/program/aktivitas/edit.blade.php +++ b/resources/views/program/aktivitas/edit-aktivitas.blade.php @@ -18,6 +18,8 @@ + +
@@ -27,13 +29,6 @@
-
- - -
@@ -72,6 +67,7 @@ $('#update-aktivitas-jenis').val(res.data.jenis_aktivitas); $('#update-aktivitas-indikator').val(res.data.indikator); $('#update-aktivitas-deskripsi').val(res.data.deskripsi); + $('#update-aktivitas-parent_id').val(res.data.parent_id); offcanvasUpdateAktivitas.show(); } }); diff --git a/resources/views/program/aktivitas/edit-tujuan.blade.php b/resources/views/program/aktivitas/edit-tujuan.blade.php new file mode 100644 index 0000000..fe8449a --- /dev/null +++ b/resources/views/program/aktivitas/edit-tujuan.blade.php @@ -0,0 +1,112 @@ +
+
+
Update Tujuan
+ +
+
+
+ @csrf + @method('PUT') + + + + + +
+ + +
+
+ + +
+
+ + +
+
+ + +
+ + + +
+
+
+ +@push('scripts') + +@endpush \ No newline at end of file diff --git a/resources/views/program/framework/view-aktivitas.blade.php b/resources/views/program/framework/view-aktivitas.blade.php new file mode 100644 index 0000000..a8afbef --- /dev/null +++ b/resources/views/program/framework/view-aktivitas.blade.php @@ -0,0 +1,74 @@ + @forelse($tujuan->aktivitas as $aktivitas) + @forelse($aktivitas->target as $targetAktivitas) + + {{ $transformasi->kode }} {{ $transformasi->nama }} (ID: {{ $transformasi->id }}) + {{ $aktivitas->kode }} {{ $aktivitas->nama }} (ID: {{ $aktivitas->id }}) + {{ $aktivitas->deskripsi }} + {{ $aktivitas->indikator }} + {{ $targetAktivitas->variabel }} (ID: {{ $targetAktivitas->id }}, Tipe: {{ $targetAktivitas->tipe }}, Realiasasi: {{ $targetAktivitas->tipe_realisasi }}) + + @if($targetAktivitas->tipe === 'integer') + {{ $targetAktivitas->target_integer }} + @elseif($targetAktivitas->tipe === 'float') + {{ $targetAktivitas->target_float }} + @elseif($targetAktivitas->tipe === 'boolean') + {{ $targetAktivitas->target_boolean ? 'Ya' : 'Tidak' }} + @endif + + + @if($targetAktivitas->tipe === 'integer') + {{ $targetAktivitas->baseline_integer }} + @elseif($targetAktivitas->tipe === 'float') + {{ $targetAktivitas->baseline_float }} + @elseif($targetAktivitas->tipe === 'boolean') + {{ $targetAktivitas->baseline_boolean ? 'Ya' : 'Tidak' }} + @endif + + + + + + @empty + + {{ $transformasi->kode }} {{ $transformasi->nama }} (ID: {{ $transformasi->id }}) + {{ $aktivitas->kode }} {{ $aktivitas->nama }} (ID: {{ $aktivitas->id }}) + {{ $aktivitas->deskripsi }} + {{ $aktivitas->indikator }} + + + + + + + + @endforelse + + @empty + @endforelse + \ No newline at end of file diff --git a/resources/views/program/framework/view-tujuan.blade.php b/resources/views/program/framework/view-tujuan.blade.php new file mode 100644 index 0000000..4c0f0c5 --- /dev/null +++ b/resources/views/program/framework/view-tujuan.blade.php @@ -0,0 +1,109 @@ + @forelse($transformasi->tujuan as $tujuan) + @forelse($tujuan->target as $target) + + {{ $transformasi->kode }} {{ $transformasi->nama }} (ID: {{ $transformasi->id }}) + {{ $tujuan->kode }} {{ $tujuan->nama }} (ID: {{ $tujuan->id }}) + {{ $tujuan->deskripsi }} + {{ $tujuan->indikator }} + {{ $target->variabel }} (ID: {{ $target->id }}, Tipe: {{ $target->tipe }}, Realiasasi: {{ $target->tipe_realisasi }}) + + @if($target->tipe === 'integer') + {{ $target->target_integer }} + @elseif($target->tipe === 'float') + {{ $target->target_float }} + @elseif($target->tipe === 'boolean') + {{ $target->target_boolean ? 'Ya' : 'Tidak' }} + @endif + + + @if($target->tipe === 'integer') + {{ $target->baseline_integer }} + @elseif($target->tipe === 'float') + {{ $target->baseline_float }} + @elseif($target->tipe === 'boolean') + {{ $target->baseline_boolean ? 'Ya' : 'Tidak' }} + @endif + + + + + + @empty + + {{ $transformasi->kode }} {{ $transformasi->nama }} (ID: {{ $transformasi->id }}) + {{ $tujuan->kode }} {{ $tujuan->nama }} (ID: {{ $tujuan->id }}) + {{ $tujuan->deskripsi }} + {{ $tujuan->indikator }} + + + + + + + + @endforelse + + @include('program.framework.view-aktivitas') + @empty + + {{ $transformasi->kode }} {{ $transformasi->nama }} + + + + + + + + + + + @endforelse + \ No newline at end of file diff --git a/resources/views/program/framework/view.blade copy.php b/resources/views/program/framework/view.blade copy.php new file mode 100644 index 0000000..ee5ff29 --- /dev/null +++ b/resources/views/program/framework/view.blade copy.php @@ -0,0 +1,296 @@ +@extends('layout.main') + +@section('content') +
+
+
+
Lihat Kerangka Kerja
+
+ +
+
+ @csrf + +
Informasi Kerangka Kerja
+
+
+ + +
+
+ + +
+
+ + +
+
+ +
Informasi Rencana Kerja
+ +
+
+
+ +
+
+ +
+
+ +
+ + + + + + + + + + + + + + + @forelse($framework->transformasi as $transformasi) + @forelse($transformasi->tujuan as $tujuan) + @forelse($tujuan->target as $target) + + + + + + + + + + + @empty + + + + + + + + + + + @endforelse + + @empty + + + + + + + + + + + @endforelse + + @empty + + + + @endforelse + + +
TransformasiTujuan Jangka Pendek/AktivitasDeskripsiIndikatorVariabelTargetBaselineAksi
{{ $transformasi->kode }} {{ $transformasi->nama }}{{ $tujuan->nama }}{{ $tujuan->deskripsi }}{{ $tujuan->indikator }}{{ $target->variabel }} + @if($target->tipe === 'integer') + {{ $target->target_integer }} + @elseif($target->tipe === 'float') + {{ $target->target_float }} + @elseif($target->tipe === 'boolean') + {{ $target->target_boolean ? 'Ya' : 'Tidak' }} + @endif + + @if($target->tipe === 'integer') + {{ $target->baseline_integer }} + @elseif($target->tipe === 'float') + {{ $target->baseline_float }} + @elseif($target->tipe === 'boolean') + {{ $target->baseline_boolean ? 'Ya' : 'Tidak' }} + @endif + + +
{{ $transformasi->kode }} {{ $transformasi->nama }}{{ $tujuan->nama }}{{ $tujuan->deskripsi }}{{ $tujuan->indikator }} + +
{{ $transformasi->kode }} {{ $transformasi->nama }} + +
Tidak ada data ditemukan.
+
+ +
+
+ +
+ Kembali +
+
+
+
+ @include('program.transformasi.add') + @include('program.transformasi.edit') + @include('program.aktivitas.add-tujuan') + @include('program.aktivitas.edit') + @include('program.target.add') +
+@endsection + +@push('scripts') + +@endpush \ No newline at end of file diff --git a/resources/views/program/framework/view.blade.php b/resources/views/program/framework/view.blade.php index ab94244..b5445a1 100644 --- a/resources/views/program/framework/view.blade.php +++ b/resources/views/program/framework/view.blade.php @@ -57,106 +57,7 @@ @forelse($framework->transformasi as $transformasi) - @forelse($transformasi->aktivitas as $aktivitas) - @forelse($aktivitas->target as $target) - - {{ $transformasi->kode }} {{ $transformasi->nama }} - {{ $aktivitas->nama }} - {{ $aktivitas->deskripsi }} - {{ $aktivitas->indikator }} - {{ $target->variabel }} - - @if($target->tipe === 'integer') - {{ $target->target_integer }} - @elseif($target->tipe === 'float') - {{ $target->target_float }} - @elseif($target->tipe === 'boolean') - {{ $target->target_boolean ? 'Ya' : 'Tidak' }} - @endif - - - @if($target->tipe === 'integer') - {{ $target->baseline_integer }} - @elseif($target->tipe === 'float') - {{ $target->baseline_float }} - @elseif($target->tipe === 'boolean') - {{ $target->baseline_boolean ? 'Ya' : 'Tidak' }} - @endif - - - - - - @empty - - {{ $transformasi->kode }} {{ $transformasi->nama }} - {{ $aktivitas->nama }} - {{ $aktivitas->deskripsi }} - {{ $aktivitas->indikator }} - - - - - - - - @endforelse - - @empty - - {{ $transformasi->kode }} {{ $transformasi->nama }} - - - - - - - - - - - @endforelse - + @include('program.framework.view-tujuan') @empty Tidak ada data ditemukan. @@ -178,9 +79,12 @@
@include('program.transformasi.add') @include('program.transformasi.edit') - @include('program.aktivitas.add') - @include('program.aktivitas.edit') + @include('program.aktivitas.add-tujuan') + @include('program.aktivitas.add-aktivitas') + @include('program.aktivitas.edit-tujuan') + @include('program.aktivitas.edit-aktivitas') @include('program.target.add') + @include('program.target.edit') @endsection diff --git a/resources/views/program/realisasi/add.blade.php b/resources/views/program/realisasi/add.blade.php new file mode 100644 index 0000000..a1c2772 --- /dev/null +++ b/resources/views/program/realisasi/add.blade.php @@ -0,0 +1,175 @@ +
+
+
Perbarui Capaian Realisasi
+ +
+
+
+ @csrf + + + + + +
+ + +
+
+ + + + + +
+
+ + + + + +
+
+ + + + + +
+ + + +
+
+
+ +@push('scripts') + +@endpush \ No newline at end of file diff --git a/resources/views/program/realisasi/edit.blade.php b/resources/views/program/realisasi/edit.blade.php new file mode 100644 index 0000000..05f9203 --- /dev/null +++ b/resources/views/program/realisasi/edit.blade.php @@ -0,0 +1,168 @@ +
+
+
Ubah Capaian Realisasi
+ +
+
+
+ @csrf + @method('PUT') + + + + + + +
+ + +
+
+ + + + + +
+
+ + + + + +
+
+ + + + + +
+ + + +
+
+
+ +@push('scripts') + +@endpush \ No newline at end of file diff --git a/resources/views/program/realisasi/index-aktivitas.blade.php b/resources/views/program/realisasi/index-aktivitas.blade.php new file mode 100644 index 0000000..45d01b7 --- /dev/null +++ b/resources/views/program/realisasi/index-aktivitas.blade.php @@ -0,0 +1,118 @@ + @forelse($tujuan->aktivitas as $aktivitas) + @forelse($aktivitas->target as $targetAktivitas) + + {{ $transformasi->kode }} {{ $transformasi->nama }} (ID: {{ $transformasi->id }}) + {{ $aktivitas->kode }} {{ $aktivitas->nama }} (ID: {{ $aktivitas->id }}) + {{ $aktivitas->deskripsi }} + {{ $aktivitas->indikator }} + {{ $targetAktivitas->variabel }} (ID: {{ $targetAktivitas->id }}, Tipe: {{ $targetAktivitas->tipe }}, Realiasasi: {{ $targetAktivitas->tipe_realisasi }}) + + @if($targetAktivitas->tipe === 'integer') + {{ $targetAktivitas->target_integer }} + @elseif($targetAktivitas->tipe === 'float') + {{ $targetAktivitas->target_float }} + @elseif($targetAktivitas->tipe === 'boolean') + {{ $targetAktivitas->target_boolean ? 'Ya' : 'Tidak' }} + @endif + + + @if($targetAktivitas->tipe === 'integer') + {{ $targetAktivitas->baseline_integer }} + @elseif($targetAktivitas->tipe === 'float') + {{ $targetAktivitas->baseline_float }} + @elseif($targetAktivitas->tipe === 'boolean') + {{ $targetAktivitas->baseline_boolean ? 'Ya' : 'Tidak' }} + @endif + + + @if($targetAktivitas->latestRealisasi) + @if($targetAktivitas->tipe === 'integer') + {{ $targetAktivitas->latestRealisasi->realisasi_integer }} + + ({{ number_format(($targetAktivitas->latestRealisasi->realisasi_integer / $targetAktivitas->target_integer) * 100, 2) }}%) + + @elseif($targetAktivitas->tipe === 'float') + {{ $targetAktivitas->latestRealisasi->realisasi_float }} + + ({{ number_format(($targetAktivitas->latestRealisasi->realisasi_float / $targetAktivitas->target_float) * 100, 2) }}%) + + @elseif($targetAktivitas->tipe === 'boolean') + {{ $targetAktivitas->latestRealisasi->realisasi_boolean ? 'Ya' : 'Tidak' }} + @endif + @if($targetAktivitas->latestRealisasi && $targetAktivitas->latestRealisasi->verifikasi->count() > 0) + + + + @else + + + + @endif + @else + - + @endif + + + +
+ + + + @if($targetAktivitas->latestRealisasi) + + + + + + + + + + @if($targetAktivitas->latestRealisasi && $targetAktivitas->latestRealisasi->verifikasi->count() == 0) + @else + @endif + @endif +
+ + + @empty + + {{ $transformasi->kode }} {{ $transformasi->nama }} (ID: {{ $transformasi->id }}) + {{ $aktivitas->kode }} {{ $aktivitas->nama }} (ID: {{ $aktivitas->id }}) + {{ $aktivitas->deskripsi }} + {{ $aktivitas->indikator }} + + + + + + + @endforelse + + @empty + @endforelse + \ No newline at end of file diff --git a/resources/views/program/realisasi/index-tujuan.blade.php b/resources/views/program/realisasi/index-tujuan.blade.php new file mode 100644 index 0000000..0768930 --- /dev/null +++ b/resources/views/program/realisasi/index-tujuan.blade.php @@ -0,0 +1,126 @@ + @forelse($transformasi->tujuan as $tujuan) + @forelse($tujuan->target as $target) + + {{ $transformasi->kode }} {{ $transformasi->nama }} (ID: {{ $transformasi->id }}) + {{ $tujuan->kode }} {{ $tujuan->nama }} (ID: {{ $tujuan->id }}) + {{ $tujuan->deskripsi }} + {{ $tujuan->indikator }} + {{ $target->variabel }} (ID: {{ $target->id }}, Tipe: {{ $target->tipe }}, Realiasasi: {{ $target->tipe_realisasi }}) + + @if($target->tipe === 'integer') + {{ $target->target_integer }} + @elseif($target->tipe === 'float') + {{ $target->target_float }} + @elseif($target->tipe === 'boolean') + {{ $target->target_boolean ? 'Ya' : 'Tidak' }} + @endif + + + @if($target->tipe === 'integer') + {{ $target->baseline_integer }} + @elseif($target->tipe === 'float') + {{ $target->baseline_float }} + @elseif($target->tipe === 'boolean') + {{ $target->baseline_boolean ? 'Ya' : 'Tidak' }} + @endif + + + @if($target->latestRealisasi) + @if($target->tipe === 'integer') + {{ $target->latestRealisasi->realisasi_integer }} + + ({{ number_format(($target->latestRealisasi->realisasi_integer / $target->target_integer) * 100, 2) }}%) + + @elseif($target->tipe === 'float') + {{ $target->latestRealisasi->realisasi_float }} + + ({{ number_format(($target->latestRealisasi->realisasi_float / $target->target_float) * 100, 2) }}%) + + @elseif($target->tipe === 'boolean') + {{ $target->latestRealisasi->realisasi_boolean ? 'Ya' : 'Tidak' }} + @endif + @if($target->latestRealisasi && $target->latestRealisasi->verifikasi->count() > 0) + + + + @else + + + + @endif + @else + - + @endif + + +
+ + + + @if($target->latestRealisasi) + + + + + + + + + + @endif +
+ + + @empty + + {{ $transformasi->kode }} {{ $transformasi->nama }} (ID: {{ $transformasi->id }}) + {{ $tujuan->kode }} {{ $tujuan->nama }} (ID: {{ $tujuan->id }}) + {{ $tujuan->deskripsi }} + {{ $tujuan->indikator }} + + + + + + + @endforelse + + @include('program.realisasi.index-aktivitas') + @empty + + {{ $transformasi->kode }} {{ $transformasi->nama }} + + + + + + + + + + @endforelse + \ No newline at end of file diff --git a/resources/views/program/realisasi/index.blade.php b/resources/views/program/realisasi/index.blade.php new file mode 100644 index 0000000..0d4bdd0 --- /dev/null +++ b/resources/views/program/realisasi/index.blade.php @@ -0,0 +1,101 @@ +@extends('layout.main') + +@push('styles') + +@endpush + +@section('content') +
+
+
+
Lihat Realiasi
+
+ +
+
+ @csrf + +
Informasi Kerangka Kerja
+
+
+ + +
+
+ + +
+
+ + +
+
+ +
Informasi Rencana Kerja dan Realisasi
+ +
+ +
+
+ +
+ + + + + + + + + + + + + + + + @forelse($framework->transformasi as $transformasi) + @include('program.realisasi.index-tujuan') + @empty + + + + @endforelse + + +
TransformasiTujuan Jangka Pendek/AktivitasDeskripsiIndikatorVariabelTargetBaselineCapaian RealisasiAksi
Tidak ada data ditemukan.
+
+ +
+
+
+
+
+
+@include('program.realisasi.add') +@include('program.realisasi.list') +@include('program.realisasi.edit') +@include('program.verifikasi.add') +@endsection + +@push('scripts') + + + +@endpush \ No newline at end of file diff --git a/resources/views/program/realisasi/list.blade.php b/resources/views/program/realisasi/list.blade.php new file mode 100644 index 0000000..21c9532 --- /dev/null +++ b/resources/views/program/realisasi/list.blade.php @@ -0,0 +1,83 @@ +
+
+
Riwayat Capaian Realisasi
+ +
+
+
+ + + + + +
+ + +
+ + + + + + + + + + +
Nilai RealisasiUpdate
+ + +
+
+
+ +@push('scripts') + +@endpush \ No newline at end of file diff --git a/resources/views/program/target/add.blade.php b/resources/views/program/target/add.blade.php index dded5ec..cec2eaa 100644 --- a/resources/views/program/target/add.blade.php +++ b/resources/views/program/target/add.blade.php @@ -56,6 +56,17 @@ +
+ + +
+ @@ -68,7 +79,7 @@ $(document).ready(function() { const offcanvasAddTarget = new bootstrap.Offcanvas(document.getElementById('offcanvasAddTarget')); - $('#add-target-tipe').select2({ + $('#add-target-tipe, #add-target-tipe-realisasi').select2({ dropdownParent: $('#offcanvasAddTarget'), width: '100%', }); @@ -91,6 +102,13 @@ $('#add-target-baseline-boolean-true, #add-target-baseline-boolean-false').show().prop('disabled', false); } }); + $('#add-target-tipe-realisasi').change(function() { + const tipe = $(this).val(); + $('#add-target-value-query-container').hide().prop('disabled', true); + if (tipe === 'referensi') { + $('#add-target-value-query-container').show().prop('disabled', false); + } + }); $(".add-target").click(function () { const id = $(this).data('id'); diff --git a/resources/views/program/target/edit.blade.php b/resources/views/program/target/edit.blade.php new file mode 100644 index 0000000..4e5e935 --- /dev/null +++ b/resources/views/program/target/edit.blade.php @@ -0,0 +1,196 @@ +
+
+
Edit Target
+ +
+
+
+ @csrf + @method('PUT') + + + + + +
+ + +
+
+ + +
+
+ + + + + +
+
+ + + + + +
+
+ + +
+ + + + +
+
+
+ +@push('scripts') + +@endpush \ No newline at end of file diff --git a/resources/views/program/verifikasi/add.blade.php b/resources/views/program/verifikasi/add.blade.php new file mode 100644 index 0000000..69d9bdc --- /dev/null +++ b/resources/views/program/verifikasi/add.blade.php @@ -0,0 +1,176 @@ +
+
+
Tambah Verifikasi
+ +
+
+
+ @csrf + + + + + + +
+ + +
+
+ + + + + +
+
+ + + + + +
+
+ + + + + +
+
+ + +
+
+ + +
+ + + +
+
+
+ +@push('scripts') + +@endpush \ No newline at end of file diff --git a/routes/api.php b/routes/api.php index 957199f..679fa03 100644 --- a/routes/api.php +++ b/routes/api.php @@ -65,4 +65,15 @@ Route::middleware('auth:sanctum') ->group(function () { Route::apiResource('fasilitator', \App\Http\Controllers\Api\FacilitatorController::class); -}); \ No newline at end of file +}); + +Route::middleware('auth:sanctum') + ->name('ekosistem.') + ->prefix('ekosistem') + ->group(function () { + + Route::resource('tabel', App\Http\Controllers\Api\Ekosistem\TabelBasisDataController::class)->only(['index', 'show']); + Route::resource('tabel.formulir', App\Http\Controllers\Api\Ekosistem\FormBasisDataController::class)->only(['index']); + Route::resource('tabel.data', App\Http\Controllers\Api\Ekosistem\ValueBasisDataController::class); + +}); \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index 1675e25..1a68e89 100644 --- a/routes/web.php +++ b/routes/web.php @@ -134,6 +134,6 @@ Route::middleware('auth') Route::resource('framework.transformasi', App\Http\Controllers\Web\Program\TransformasiController::class)->only(['show', 'store', 'update', 'destroy']); Route::resource('framework.transformasi.aktivitas', App\Http\Controllers\Web\Program\AktivitasController::class)->only(['show', 'store', 'update', 'destroy']); Route::resource('framework.transformasi.aktivitas.target', App\Http\Controllers\Web\Program\TargetController::class)->only(['show', 'store', 'update', 'destroy']); - - + Route::resource('realisasi', App\Http\Controllers\Web\Program\RealisasiController::class)->only('index', 'store', 'show', 'update', 'destroy'); + Route::resource('verifikasi', App\Http\Controllers\Web\Program\VerifikasiController::class)->only('store', 'update', 'destroy'); }); \ No newline at end of file