From ed39f7544c431b115dcf8e7c2133f983ca96b313 Mon Sep 17 00:00:00 2001 From: "fauzgabriel@gmail.com" Date: Tue, 12 May 2026 10:12:51 +0700 Subject: [PATCH 01/46] user UID --- app/Http/Controllers/Api/AuthController.php | 2 ++ app/Models/User.php | 1 + database/migrations/0001_01_01_000000_create_users_table.php | 1 + 3 files changed, 4 insertions(+) diff --git a/app/Http/Controllers/Api/AuthController.php b/app/Http/Controllers/Api/AuthController.php index 787498a..c9b3929 100644 --- a/app/Http/Controllers/Api/AuthController.php +++ b/app/Http/Controllers/Api/AuthController.php @@ -46,6 +46,7 @@ class AuthController extends Controller 'email' => ['required', 'email', 'max:255', 'unique:users'], 'password' => ['required', 'string', 'min:8', 'confirmed'], 'role' => ['string'], + 'uid' => ['required','string', 'unique:users'], ]); $user = User::create([ @@ -53,6 +54,7 @@ class AuthController extends Controller 'email' => $credentials['email'], 'password' => Hash::make($credentials['password']), 'role' => $credentials['role'], + 'uid' => $credentials['uid'], ]); $profile = Profile::create([ diff --git a/app/Models/User.php b/app/Models/User.php index a35ec1f..b2e6cb6 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -21,6 +21,7 @@ class User extends Authenticatable 'password', 'email_verified_at', 'role', + 'uid' ]; protected $hidden = [ diff --git a/database/migrations/0001_01_01_000000_create_users_table.php b/database/migrations/0001_01_01_000000_create_users_table.php index 2872310..6a48c7e 100644 --- a/database/migrations/0001_01_01_000000_create_users_table.php +++ b/database/migrations/0001_01_01_000000_create_users_table.php @@ -16,6 +16,7 @@ return new class extends Migration $table->string('password'); $table->rememberToken(); $table->string('role')->nullable(); + $table->string('uid')->unique(); $table->foreignId('created_by')->nullable()->constrained('users')->onDelete('set null'); $table->foreignId('updated_by')->nullable()->constrained('users')->onDelete('set null'); $table->foreignId('deleted_by')->nullable()->constrained('users')->onDelete('set null'); From 23566681c1828e79ad0cba4509404aa60a161458 Mon Sep 17 00:00:00 2001 From: althaf Date: Wed, 13 May 2026 14:01:38 +0700 Subject: [PATCH 02/46] feat: add data completeness indicator badge to province table --- .../Web/Master/ProvinsiController.php | 9 ++++++--- .../views/master/provinsi/index.blade.php | 19 ++++++++++++++++++- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/app/Http/Controllers/Web/Master/ProvinsiController.php b/app/Http/Controllers/Web/Master/ProvinsiController.php index c962629..88097d7 100644 --- a/app/Http/Controllers/Web/Master/ProvinsiController.php +++ b/app/Http/Controllers/Web/Master/ProvinsiController.php @@ -17,9 +17,12 @@ class ProvinsiController extends Controller $perPage = $request->query('per_page', 10); $search = $request->query('search', ''); - $provinsi = Provinsi::where('nama', 'like', "%$search%") - ->orWhere('kode', 'like', "%$search%") - ->orWhere('iso', 'like', "%$search%") + $provinsi = Provinsi::withCount('kabupatenKota') + ->where(function($query) use ($search) { + $query->where('nama', 'like', "%$search%") + ->orWhere('kode', 'like', "%$search%") + ->orWhere('iso', 'like', "%$search%"); + }) ->paginate($perPage); return view('master.provinsi.index', compact('title', 'provinsi')); diff --git a/resources/views/master/provinsi/index.blade.php b/resources/views/master/provinsi/index.blade.php index 67407df..67d78b7 100644 --- a/resources/views/master/provinsi/index.blade.php +++ b/resources/views/master/provinsi/index.blade.php @@ -2,6 +2,9 @@ @section('content')
+
+ +
@@ -35,6 +38,7 @@ No Kode Provinsi Nama Provinsi + Status Kelengkapan Actions @@ -62,6 +66,19 @@
+ + + @if($prov->kabupaten_kota_count > 0) + + Aktif (Ada Kabupaten) + + @else + + Belum Ada Wilayah + + @endif + +
@@ -72,7 +89,7 @@ @empty - Tidak ada data ditemukan. + Tidak ada data ditemukan. @endforelse From 4333e16626f1a35eab74f7749404cb6f8fd9be83 Mon Sep 17 00:00:00 2001 From: althaf Date: Wed, 13 May 2026 14:18:48 +0700 Subject: [PATCH 03/46] hide sev card --- resources/views/master/provinsi/index.blade.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/resources/views/master/provinsi/index.blade.php b/resources/views/master/provinsi/index.blade.php index 67d78b7..f460df0 100644 --- a/resources/views/master/provinsi/index.blade.php +++ b/resources/views/master/provinsi/index.blade.php @@ -2,9 +2,6 @@ @section('content')
-
- -
From 066b50ab9cccfed01a471b1800d9374a192deb81 Mon Sep 17 00:00:00 2001 From: "fauzgabriel@gmail.com" Date: Wed, 13 May 2026 14:32:35 +0700 Subject: [PATCH 04/46] profile dan user uid --- app/Http/Controllers/Api/AuthController.php | 1 + app/Models/Profile.php | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/AuthController.php b/app/Http/Controllers/Api/AuthController.php index c9b3929..f876902 100644 --- a/app/Http/Controllers/Api/AuthController.php +++ b/app/Http/Controllers/Api/AuthController.php @@ -61,6 +61,7 @@ class AuthController extends Controller 'nama' => $credentials['name'], 'email' => $credentials['email'], 'role' => $credentials['role'], + 'user_uid' => $credentials['uid'], 'user_id' => $user->id, 'created_by' => $user->id, 'updated_by' => $user->id, diff --git a/app/Models/Profile.php b/app/Models/Profile.php index e961336..d41fed6 100644 --- a/app/Models/Profile.php +++ b/app/Models/Profile.php @@ -17,13 +17,14 @@ class Profile extends Model protected $fillable = [ 'user_id', 'role', + 'user_uid', 'nama', 'email', 'telepon', 'alamat', 'kk', 'ktp', - + 'uid', 'desa_kelurahan_id', 'path_kk', 'file_kk', From 36258344da35882ec108be23b21f3d961e1ed975 Mon Sep 17 00:00:00 2001 From: "fauzgabriel@gmail.com" Date: Fri, 15 May 2026 13:19:14 +0700 Subject: [PATCH 05/46] komoditas object --- app/Http/Controllers/Api/TanamanController.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/TanamanController.php b/app/Http/Controllers/Api/TanamanController.php index 9b23bee..97ee4fc 100644 --- a/app/Http/Controllers/Api/TanamanController.php +++ b/app/Http/Controllers/Api/TanamanController.php @@ -95,7 +95,9 @@ class TanamanController extends Controller abort(403); } $profile = Auth::user()->profile; - + if ($request->has('komoditas.id')) { + $request->merge(['komoditas_id' => $request->input('komoditas.id')]); + } $validated = $request->validate([ 'nama' => ['required', 'string', 'max:255'], 'komoditas_id' => ['required', 'exists:master_komoditas,id'], From 34d09d03bb450cb65650d2c58c5c05de6866e8f8 Mon Sep 17 00:00:00 2001 From: "fauzgabriel@gmail.com" Date: Fri, 15 May 2026 13:23:03 +0700 Subject: [PATCH 06/46] kl --- app/Http/Controllers/Api/TanamanController.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/Api/TanamanController.php b/app/Http/Controllers/Api/TanamanController.php index 97ee4fc..3f938cd 100644 --- a/app/Http/Controllers/Api/TanamanController.php +++ b/app/Http/Controllers/Api/TanamanController.php @@ -95,9 +95,12 @@ class TanamanController extends Controller abort(403); } $profile = Auth::user()->profile; - if ($request->has('komoditas.id')) { - $request->merge(['komoditas_id' => $request->input('komoditas.id')]); - } + + $request->merge([ + 'komoditas_id' => $request->input('komoditas.id') ?? $request->input('komoditas_id'), + 'lahan_id' => $request->input('lahan.id') ?? $request->input('lahan_id'), + 'profile_id' => $profile->id + ]); $validated = $request->validate([ 'nama' => ['required', 'string', 'max:255'], 'komoditas_id' => ['required', 'exists:master_komoditas,id'], From e0ab4bdace5b6b8bb1fb987c3d405412dda5d071 Mon Sep 17 00:00:00 2001 From: Irwan Cahyono Date: Fri, 15 May 2026 15:31:19 +0700 Subject: [PATCH 07/46] form tabel --- app/Enums/LayoutForm.php | 31 ++ .../Web/Ekosistem/FormBasisDataController.php | 295 ++++++++++++++++++ .../Ekosistem/KolomBasisDataController.php | 4 +- .../Ekosistem/ValueBasisDataController.php | 7 +- app/Models/Ekosistem/FormBasisData.php | 236 ++++++++++++++ app/Models/Ekosistem/TabelBasisData.php | 20 ++ ...08_161821_create_form_basis_data_table.php | 47 +++ .../form-basis-data/add-column.blade.php | 81 +++++ .../form-basis-data/add-hr-line.blade.php | 27 ++ .../form-basis-data/add-row.blade.php | 27 ++ .../form-basis-data/add-section.blade.php | 77 +++++ .../form-basis-data/add-value.blade.php | 85 +++++ .../form-basis-data/edit-column.blade.php | 94 ++++++ .../form-basis-data/edit-section.blade.php | 89 ++++++ .../form-basis-data/edit-value.blade.php | 97 ++++++ .../ekosistem/form-basis-data/index.blade.php | 283 +++++++++++++++++ .../form-basis-data/move-column.blade.php | 98 ++++++ .../ekosistem/tabel-basis-data/view.blade.php | 18 ++ .../value-basis-data/add-ref.blade.php | 107 +++++++ .../ekosistem/value-basis-data/add.blade.php | 54 +--- .../value-basis-data/edit-ref.blade.php | 124 ++++++++ .../ekosistem/value-basis-data/edit.blade.php | 70 +---- .../ekosistem/value-basis-data/view.blade.php | 58 +--- routes/web.php | 6 +- 24 files changed, 1853 insertions(+), 182 deletions(-) create mode 100644 app/Enums/LayoutForm.php create mode 100644 app/Http/Controllers/Web/Ekosistem/FormBasisDataController.php create mode 100644 app/Models/Ekosistem/FormBasisData.php create mode 100644 database/migrations/2026_05_08_161821_create_form_basis_data_table.php create mode 100644 resources/views/ekosistem/form-basis-data/add-column.blade.php create mode 100644 resources/views/ekosistem/form-basis-data/add-hr-line.blade.php create mode 100644 resources/views/ekosistem/form-basis-data/add-row.blade.php create mode 100644 resources/views/ekosistem/form-basis-data/add-section.blade.php create mode 100644 resources/views/ekosistem/form-basis-data/add-value.blade.php create mode 100644 resources/views/ekosistem/form-basis-data/edit-column.blade.php create mode 100644 resources/views/ekosistem/form-basis-data/edit-section.blade.php create mode 100644 resources/views/ekosistem/form-basis-data/edit-value.blade.php create mode 100644 resources/views/ekosistem/form-basis-data/index.blade.php create mode 100644 resources/views/ekosistem/form-basis-data/move-column.blade.php create mode 100644 resources/views/ekosistem/value-basis-data/add-ref.blade.php create mode 100644 resources/views/ekosistem/value-basis-data/edit-ref.blade.php diff --git a/app/Enums/LayoutForm.php b/app/Enums/LayoutForm.php new file mode 100644 index 0000000..434d90a --- /dev/null +++ b/app/Enums/LayoutForm.php @@ -0,0 +1,31 @@ + 'Row', + self::COLUMN => 'Column', + self::VALUE => 'Value', + self::SECTION => 'Section', + self::HR_LINE => 'HR Line', + }; + } + + public static function options(): array + { + return collect(self::cases())->map(fn ($case) => [ + 'value' => $case->value, + 'label' => $case->label(), + ])->toArray(); + } +} diff --git a/app/Http/Controllers/Web/Ekosistem/FormBasisDataController.php b/app/Http/Controllers/Web/Ekosistem/FormBasisDataController.php new file mode 100644 index 0000000..4d03593 --- /dev/null +++ b/app/Http/Controllers/Web/Ekosistem/FormBasisDataController.php @@ -0,0 +1,295 @@ +json([ + 'status' => 'error', + 'message' => 'Data tabel tidak ditemukan.' + ], 404); + } + + $listEnum = LayoutForm::options(); + + $tab = $request->tab ?? 'form'; + $tabel->state = 'preview'; + + return view('ekosistem.form-basis-data.index', compact('tabel', 'listEnum', 'tab')); + } + + public function create() + { + // + } + + public function store(Request $request, string $tabelId): JsonResponse + { + Gate::authorize('super_admin'); + + $tabel = TabelBasisData::find($tabelId); + if (!$tabel) { + return response()->json([ + 'status' => 'error', + 'message' => 'Data tabel tidak ditemukan.' + ], 404); + } + + $validated = $request->validate([ + 'parent_id' => ['nullable', 'exists:ekosistem_basis_data_form,id'], + 'tipe' => ['required', Rule::enum(LayoutForm::class)], + 'column_width' => [ + Rule::requiredIf($request->tipe === LayoutForm::COLUMN->value), + 'nullable', 'integer', 'min:1', 'max:12'], + 'kolom_id' => [ + Rule::requiredIf($request->tipe === LayoutForm::VALUE->value), + 'nullable', 'exists:ekosistem_basis_data_kolom,id'], + 'section_label' => [ + Rule::requiredIf($request->tipe === LayoutForm::SECTION->value), + 'nullable', 'string'], + ]); + + FormBasisData::create([...$validated, + 'tabel_id' => $tabelId, + 'created_by' => auth()->user()->id, + 'updated_by' => auth()->user()->id + ]); + + return response()->json([ + 'status' => 'success', + 'message' => 'Form basis data berhasil ditambahkan.' + ], 201); + } + + public function show(string $tabelId, string $id): JsonResponse + { + Gate::authorize('super_admin'); + + $form = FormBasisData::where('tabel_id', $tabelId)->find($id); + if (!$form) { + return response()->json([ + 'status' => 'error', + 'message' => 'Data formulir basis data tidak ditemukan.' + ], 404); + } + return response()->json([ + 'status' => 'success', + 'data' => $form + ], 200); + } + + public function edit(string $id) + { + // + } + + public function update(Request $request, string $tabelId, string $id) + { + Gate::authorize('super_admin'); + + $form = FormBasisData::where('tabel_id', $tabelId)->find($id); + if (!$form) { + return response()->json([ + 'status' => 'error', + 'message' => 'Data formulir basis data tidak ditemukan.' + ], 404); + } + + $validated = $request->validate([ + 'parent_id' => ['nullable', 'exists:ekosistem_basis_data_form,id'], + 'tipe' => ['required', Rule::enum(LayoutForm::class)], + 'column_width' => [ + Rule::requiredIf($request->tipe === LayoutForm::COLUMN->value), + 'nullable', 'integer', 'min:1', 'max:12'], + 'kolom_id' => [ + Rule::requiredIf($request->tipe === LayoutForm::VALUE->value), + 'nullable', 'exists:ekosistem_basis_data_kolom,id'], + 'section_label' => [ + Rule::requiredIf($request->tipe === LayoutForm::SECTION->value), + 'nullable', 'string'], + ]); + + $form->update([...$validated, + 'updated_by' => auth()->user()->id + ]); + + return response()->json([ + 'status' => 'success', + 'message' => 'Form basis data berhasil diubah.' + ]); + } + + public function destroy(string $tabelId, string $id): JsonResponse + { + Gate::authorize('super_admin'); + + $form = FormBasisData::where('tabel_id', $tabelId)->find($id); + if (!$form) { + return response()->json([ + 'status' => 'error', + 'message' => 'Data form basis data tidak ditemukan.' + ], 404); + } + if ($form->form->count() > 0) { + return response()->json([ + 'status' => 'error', + 'message' => 'Tidak dapat menghapus formulir basis data yang memiliki formulir.' + ], 400); + } + $form->update([ + 'deleted_by' => auth()->user()->id + ]); + $form->delete(); + + return response()->json([ + 'status' => 'success', + 'message' => 'Form basis data berhasil dihapus.' + ], 200); + } + + public function generate(Request $request, string $tabelId): RedirectResponse + { + Gate::authorize('super_admin'); + + $tabel = TabelBasisData::find($tabelId); + if (!$tabel) { + return redirect()->route('tabel.formulir.index', $tabelId)->with('error', 'Tabel basis data tidak ditemukan.'); + } + + DB::transaction(function () use ($tabel) { + + FormBasisData::where('tabel_id', $tabel->id)->delete(); + + FormBasisData::create([ + 'tabel_id' => $tabel->id, + 'tipe' => LayoutForm::SECTION, + 'section_label' => $tabel->label, + 'created_by' => auth()->user()->id, + 'updated_by' => auth()->user()->id + ]); + + FormBasisData::create([ + 'tabel_id' => $tabel->id, + 'tipe' => LayoutForm::HR_LINE, + 'created_by' => auth()->user()->id, + 'updated_by' => auth()->user()->id + ]); + + $chunks = $tabel->kolom->chunk(4); + + foreach ($chunks as $chunk) { + + $row = FormBasisData::create([ + 'tabel_id' => $tabel->id, + 'tipe' => LayoutForm::ROW, + 'created_by' => auth()->user()->id, + 'updated_by' => auth()->user()->id + ]); + + foreach ($chunk as $kolom) { + $column = FormBasisData::create([ + 'tabel_id' => $tabel->id, + 'tipe' => LayoutForm::COLUMN, + 'column_width' => 3, + 'parent_id' => $row->id, + 'created_by' => auth()->user()->id, + 'updated_by' => auth()->user()->id + ]); + + FormBasisData::create([ + 'tabel_id' => $tabel->id, + 'tipe' => LayoutForm::VALUE, + 'parent_id' => $column->id, + 'kolom_id' => $kolom->id, + 'created_by' => auth()->user()->id, + 'updated_by' => auth()->user()->id + ]); + } + } + + }); + + return redirect()->route('tabel.formulir.index', $tabelId)->with('success', 'Formulir berhasil dibuat.'); + } + + public function moveUp(Request $request, string $tabelId, string $id): JsonResponse + { + Gate::authorize('super_admin'); + + $current = FormBasisData::where('tabel_id', $tabelId)->find($id); + if (!$current) { + return response()->json([ + 'status' => 'error', + 'message' => 'Data formulir tidak ditemukan.' + ], 404); + } + + $prev = FormBasisData::where('tabel_id', $tabelId) + ->where('urutan', '<', $current->urutan) + ->where('parent_id', $current->parent_id) + ->orderBy('urutan', 'desc') + ->first(); + + if ($prev) { + // swap + [$current->urutan, $prev->urutan] = [$prev->urutan, $current->urutan]; + $current->save(); + $prev->save(); + } + + return response()->json([ + 'status' => 'success', + 'message' => 'Formulir basis data berhasil diperbarui.' + ], 200); + } + + public function moveDown(Request $request, string $tabelId, string $id): JsonResponse + { + Gate::authorize('super_admin'); + + $current = FormBasisData::where('tabel_id', $tabelId)->find($id); + if (!$current) { + return response()->json([ + 'status' => 'error', + 'message' => 'Data formulir tidak ditemukan.' + ], 404); + } + + $next = FormBasisData::where('tabel_id', $tabelId) + ->where('urutan', '>', $current->urutan) + ->where('parent_id', $current->parent_id) + ->orderBy('urutan', 'asc') + ->first(); + + if ($next) { + // swap + [$current->urutan, $next->urutan] = [$next->urutan, $current->urutan]; + $current->save(); + $next->save(); + } + + return response()->json([ + 'status' => 'success', + 'message' => 'Formulir basis data berhasil diperbarui.' + ], 200); + } +} diff --git a/app/Http/Controllers/Web/Ekosistem/KolomBasisDataController.php b/app/Http/Controllers/Web/Ekosistem/KolomBasisDataController.php index 3813976..d29fb2c 100644 --- a/app/Http/Controllers/Web/Ekosistem/KolomBasisDataController.php +++ b/app/Http/Controllers/Web/Ekosistem/KolomBasisDataController.php @@ -188,7 +188,7 @@ class KolomBasisDataController extends Controller ], 404); } - $prev = KolomBasisData::where('tabel_id', $current->tabel_id) + $prev = KolomBasisData::where('tabel_id', $tabelId) ->where('urutan', '<', $current->urutan) ->orderBy('urutan', 'desc') ->first(); @@ -218,7 +218,7 @@ class KolomBasisDataController extends Controller ], 404); } - $next = KolomBasisData::where('tabel_id', $current->tabel_id) + $next = KolomBasisData::where('tabel_id', $tabelId) ->where('urutan', '>', $current->urutan) ->orderBy('urutan', 'asc') ->first(); diff --git a/app/Http/Controllers/Web/Ekosistem/ValueBasisDataController.php b/app/Http/Controllers/Web/Ekosistem/ValueBasisDataController.php index 84828cb..2c5234c 100644 --- a/app/Http/Controllers/Web/Ekosistem/ValueBasisDataController.php +++ b/app/Http/Controllers/Web/Ekosistem/ValueBasisDataController.php @@ -8,6 +8,10 @@ use Illuminate\Support\Facades\Gate; use Illuminate\View\View; use Illuminate\Http\RedirectResponse; use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Validator; +use Illuminate\Http\JsonResponse; +use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Str; use App\Models\Ekosistem\TabelBasisData; use App\Models\Ekosistem\KolomBasisData; @@ -199,8 +203,7 @@ class ValueBasisDataController extends Controller } } $list_relasi = collect($list_relasi); - // dd($kolom->where('tipe', 'enum')->first()?->enum_opsi); - + return view('ekosistem.value-basis-data.add', compact('tabel', 'kolom', 'program', 'list_relasi')); } diff --git a/app/Models/Ekosistem/FormBasisData.php b/app/Models/Ekosistem/FormBasisData.php new file mode 100644 index 0000000..d8f7ab4 --- /dev/null +++ b/app/Models/Ekosistem/FormBasisData.php @@ -0,0 +1,236 @@ + LayoutForm::class + ]; + + protected static function booted() + { + static::creating(function ($model) { + $max = self::where('tabel_id', $model->tabel_id)->max('urutan'); + $model->urutan = ($max ?? 0) + 1; + }); + static::addGlobalScope('order', function (Builder $builder) { + $builder->orderBy('urutan'); + }); + } + + + public function tabel(): BelongsTo + { + return $this->belongsTo(TabelBasisData::class, 'tabel_id'); + } + + public function form(): HasMany + { + return $this->hasMany(FormBasisData::class, 'parent_id') + ->with('form') + ->orderBy('urutan'); + } + + public function kolom(): BelongsTo + { + return $this->belongsTo(KolomBasisData::class, 'kolom_id'); + } + + public function renderHtml(string $state, $errors = null, $optionsFK = null, $values = null): 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 => '' + }; + } + + + private function childHtml(string $state, $errors = null, $optionsFK = null, $values = null): string + { + $html = ''; + foreach ($this->form as $form) { + $html .= $form->renderHtml($state, $errors, $optionsFK, $values); + } + return $html; + } + + private function value(string $state, $errors = null, $optionsFK = null, $values = null): string + { + $html = ''; + if ($this->kolom) { + $k = $this->kolom; + + $value = $values ? $values->where('kolom_id', $k->id)->first() : null; + $oldValue = old($k->kolom); + + $html .= ''; + + if($k->tipe == 'varchar') { + $html .= ''; + } + elseif($k->tipe == 'text') { + $html .= ''; + } + elseif($k->tipe == 'integer') { + $html .= ''; + } + elseif($k->tipe == 'float') { + $html .= ''; + } + elseif($k->tipe == 'date') { + $html .= ''; + } + elseif($k->tipe == 'datetime'){ + $html .= ''; + } + elseif($k->tipe == 'boolean') { + if ($state == 'preview' || $state == 'view') { + $html .= ''; + } elseif ($state == 'add') { + $html .= ''; + } elseif ($state == 'edit') { + $html .= ''; + } + } + elseif($k->tipe == 'foreign_key') { + if ($state == 'preview' || $state == 'view') { + $html .= ''; + } elseif ($state == 'add') { + $html .= ''; + } elseif ($state == 'edit') { + $html .= ''; + } + } + elseif($k->tipe == 'enum') { + if ($state == 'preview' || $state == 'view') { + $html .= ''; + } elseif ($state == 'add') { + $html .= ''; + } elseif ($state == 'edit') { + $html .= ''; + } + } + else { + $html .= ''; + } + + $errorClass = $errors && $errors->has($k->kolom) + ? 'is-invalid' + : ''; + + if ($state == 'preview') { + $html = Str::of($html) + ->replace('kolom_value', '') + ->replace('kolom_name', $k->kolom) + ->replace('kolom_error', '') + ->replace('kolom_required', ''); + } elseif ($state == 'add') { + $html = Str::of($html) + ->replace('kolom_value', e($oldValue)) + ->replace('kolom_name', $k->kolom) + ->replace('kolom_error', $errorClass) + ->replace('kolom_required', '') + ->replace('readonly', ''); + } elseif ($state == 'edit') { + $html = Str::of($html) + ->replace('kolom_value', e($oldValue ?? ($value ? ($value['value_'.$k->tipe]) : null))) + ->replace('kolom_name', $k->kolom) + ->replace('kolom_error', $errorClass) + ->replace('kolom_required', '') + ->replace('readonly', ''); + } elseif ($state == 'view') { + $html = Str::of($html) + ->replace('kolom_name', $k->kolom) + ->replace('kolom_error', '') + ->replace('kolom_required', ''); + + if ($k->tipe == 'boolean') { + $html = Str::of($html) + ->replace('kolom_value', e($value ? ($value['value_'.$k->tipe] == 1 ? 'Ya' : 'Tidak') : null)); + } elseif($k->tipe == 'foreign_key') { + $html = Str::of($html) + ->replace('kolom_value', e($value ? $value['value_relasi_label'] : null)); + } elseif($k->tipe == 'enum') { + $html = Str::of($html) + ->replace('kolom_value', e($value ? $value['value_enum_label'] : null)); + } else { + $html = Str::of($html) + ->replace('kolom_value', e($value ? $value['value_'.$k->tipe] : null)); + } + } + } + + return $html; + } +} diff --git a/app/Models/Ekosistem/TabelBasisData.php b/app/Models/Ekosistem/TabelBasisData.php index b238269..5d04b2e 100644 --- a/app/Models/Ekosistem/TabelBasisData.php +++ b/app/Models/Ekosistem/TabelBasisData.php @@ -7,10 +7,14 @@ use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\HasOne; +use Illuminate\Database\Eloquent\Factories\HasFactory; +use Illuminate\Database\Eloquent\Casts\Attribute; use App\Models\Ekosistem\KolomBasisData; use App\Models\Ekosistem\GroupBasisData; use App\Models\Ekosistem\RingkasanBasisData; +use App\Models\Ekosistem\FormBasisData; class TabelBasisData extends Model { @@ -53,4 +57,20 @@ class TabelBasisData extends Model { return $this->hasMany(RingkasanBasisData::class, 'tabel_id')->orderBy('urutan'); } + + public function form(): HasMany + { + return $this->hasMany(FormBasisData::class, 'tabel_id') + ->whereNull('parent_id') + ->orderBy('urutan'); + } + + public function renderHtml(string $state, $errors = null, $optionsFK = null, $values = null): string + { + $html = ''; + foreach ($this->form as $form) { + $html .= $form->renderHtml($state, $errors, $optionsFK, $values); + } + return $html; + } } diff --git a/database/migrations/2026_05_08_161821_create_form_basis_data_table.php b/database/migrations/2026_05_08_161821_create_form_basis_data_table.php new file mode 100644 index 0000000..2502189 --- /dev/null +++ b/database/migrations/2026_05_08_161821_create_form_basis_data_table.php @@ -0,0 +1,47 @@ +id(); + + $table->foreignId('tabel_id')->constrained('ekosistem_basis_data_tabel')->restrictOnDelete(); + + $table->foreignId('parent_id')->nullable()->constrained('ekosistem_basis_data_form')->restrictOnDelete(); + + $table->enum('tipe', ['form-row', 'form-column', 'form-value', 'form-section', 'form-hr-line'])->default('form-value'); + + $table->integer('column_width')->nullable(); + + $table->foreignId('kolom_id')->nullable()->constrained('ekosistem_basis_data_kolom')->nullOnDelete(); + + $table->string('section_label')->nullable(); + + $table->integer('urutan')->default(1); + + $table->foreignId('created_by')->nullable()->constrained('users')->onDelete('set null'); + $table->foreignId('updated_by')->nullable()->constrained('users')->onDelete('set null'); + $table->foreignId('deleted_by')->nullable()->constrained('users')->onDelete('set null'); + + $table->timestamps(); + $table->softDeletes(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('ekosistem_basis_data_form'); + } +}; diff --git a/resources/views/ekosistem/form-basis-data/add-column.blade.php b/resources/views/ekosistem/form-basis-data/add-column.blade.php new file mode 100644 index 0000000..7ab57e1 --- /dev/null +++ b/resources/views/ekosistem/form-basis-data/add-column.blade.php @@ -0,0 +1,81 @@ +
+
+
Tambah Kolom
+ +
+
+ + @csrf + + + + +
+ + +
+ + + + +
+
+ +@push('scripts') + +@endpush \ No newline at end of file diff --git a/resources/views/ekosistem/form-basis-data/add-hr-line.blade.php b/resources/views/ekosistem/form-basis-data/add-hr-line.blade.php new file mode 100644 index 0000000..22475be --- /dev/null +++ b/resources/views/ekosistem/form-basis-data/add-hr-line.blade.php @@ -0,0 +1,27 @@ +@push('scripts') + +@endpush \ No newline at end of file diff --git a/resources/views/ekosistem/form-basis-data/add-row.blade.php b/resources/views/ekosistem/form-basis-data/add-row.blade.php new file mode 100644 index 0000000..8693842 --- /dev/null +++ b/resources/views/ekosistem/form-basis-data/add-row.blade.php @@ -0,0 +1,27 @@ +@push('scripts') + +@endpush \ No newline at end of file diff --git a/resources/views/ekosistem/form-basis-data/add-section.blade.php b/resources/views/ekosistem/form-basis-data/add-section.blade.php new file mode 100644 index 0000000..a9837ec --- /dev/null +++ b/resources/views/ekosistem/form-basis-data/add-section.blade.php @@ -0,0 +1,77 @@ +
+
+
Tambah Section
+ +
+
+
+ @csrf + + +
+ + +
+ + + +
+
+
+ +@push('scripts') + +@endpush \ No newline at end of file diff --git a/resources/views/ekosistem/form-basis-data/add-value.blade.php b/resources/views/ekosistem/form-basis-data/add-value.blade.php new file mode 100644 index 0000000..f80e27a --- /dev/null +++ b/resources/views/ekosistem/form-basis-data/add-value.blade.php @@ -0,0 +1,85 @@ +
+
+
Tambah Formulir Nilai
+ +
+
+
+ @csrf + + + + +
+ + +
+ + + +
+
+
+ +@push('scripts') + +@endpush \ No newline at end of file diff --git a/resources/views/ekosistem/form-basis-data/edit-column.blade.php b/resources/views/ekosistem/form-basis-data/edit-column.blade.php new file mode 100644 index 0000000..99d8e01 --- /dev/null +++ b/resources/views/ekosistem/form-basis-data/edit-column.blade.php @@ -0,0 +1,94 @@ +
+
+
Edit Kolom
+ +
+
+
+ @csrf + @method('PUT') + + + + + +
+ + +
+ + + +
+
+
+ +@push('scripts') + +@endpush \ No newline at end of file diff --git a/resources/views/ekosistem/form-basis-data/edit-section.blade.php b/resources/views/ekosistem/form-basis-data/edit-section.blade.php new file mode 100644 index 0000000..509079a --- /dev/null +++ b/resources/views/ekosistem/form-basis-data/edit-section.blade.php @@ -0,0 +1,89 @@ +
+
+
Edit Section
+ +
+
+
+ @csrf + @method('PUT') + + + +
+ + +
+ + + +
+
+
+ +@push('scripts') + +@endpush \ No newline at end of file diff --git a/resources/views/ekosistem/form-basis-data/edit-value.blade.php b/resources/views/ekosistem/form-basis-data/edit-value.blade.php new file mode 100644 index 0000000..14384e9 --- /dev/null +++ b/resources/views/ekosistem/form-basis-data/edit-value.blade.php @@ -0,0 +1,97 @@ +
+
+
Edit Formulir Nilai
+ +
+
+
+ @csrf + @method('PUT') + + + + + +
+ + +
+ + + +
+
+
+ +@push('scripts') + +@endpush \ No newline at end of file diff --git a/resources/views/ekosistem/form-basis-data/index.blade.php b/resources/views/ekosistem/form-basis-data/index.blade.php new file mode 100644 index 0000000..27fceeb --- /dev/null +++ b/resources/views/ekosistem/form-basis-data/index.blade.php @@ -0,0 +1,283 @@ +@extends('layout.main') + +@section('content') +
+
+
+
Formulir untuk Tabel Basis Data Ekosistem: {{ $tabel->label }}
+ +
+
+ @csrf + +
+ +
+
+ +
+ + +
+ + +
+ +
+ Kembali +
+
+
+
+@include('ekosistem.form-basis-data.add-row') +@include('ekosistem.form-basis-data.add-section') +@include('ekosistem.form-basis-data.edit-section') +@include('ekosistem.form-basis-data.add-hr-line') +@include('ekosistem.form-basis-data.add-column') +@include('ekosistem.form-basis-data.edit-column') +@include('ekosistem.form-basis-data.move-column') +@include('ekosistem.form-basis-data.add-value') +@include('ekosistem.form-basis-data.edit-value') +@endsection + +@push('scripts') + + + +@endpush \ No newline at end of file diff --git a/resources/views/ekosistem/form-basis-data/move-column.blade.php b/resources/views/ekosistem/form-basis-data/move-column.blade.php new file mode 100644 index 0000000..ad27ef6 --- /dev/null +++ b/resources/views/ekosistem/form-basis-data/move-column.blade.php @@ -0,0 +1,98 @@ +
+
+
Edit Kolom
+ +
+
+
+ @csrf + @method('PUT') + + + + + +
+ + +
+ + + +
+
+
+ +@push('scripts') + +@endpush \ No newline at end of file diff --git a/resources/views/ekosistem/tabel-basis-data/view.blade.php b/resources/views/ekosistem/tabel-basis-data/view.blade.php index 3eb64f1..3c90a9b 100644 --- a/resources/views/ekosistem/tabel-basis-data/view.blade.php +++ b/resources/views/ekosistem/tabel-basis-data/view.blade.php @@ -159,6 +159,24 @@
+
Informasi Formulir Tabel
+ +
+
+ +
+ +
+
+
Pratinjau Formulir
+ {!! $tabel->renderHtml('preview') !!} +
+
+ diff --git a/resources/views/ekosistem/value-basis-data/add-ref.blade.php b/resources/views/ekosistem/value-basis-data/add-ref.blade.php new file mode 100644 index 0000000..22bce66 --- /dev/null +++ b/resources/views/ekosistem/value-basis-data/add-ref.blade.php @@ -0,0 +1,107 @@ +@extends('layout.main') + +@section('content') +
+
+
+
Tambah Data {{ $tabel->label }}
+
+ +
+
+ @csrf + +
Informasi {{ $tabel->label }}
+
+ @foreach($kolom as $k) +
+ + @if($k->tipe == 'varchar') + + @elseif($k->tipe == 'text') + + @elseif($k->tipe == 'integer') + + @elseif($k->tipe == 'float') + + @elseif($k->tipe == 'date') + + @elseif($k->tipe == 'datetime') + + @elseif($k->tipe == 'boolean') + + @elseif($k->tipe == 'foreign_key') + + @elseif($k->tipe == 'enum') + + @else + + @endif + @error($k->kolom)
{{ $message }}
@enderror +
+ @endforeach +
+ + +
+ Kembali + +
+
+
+
+
+@endsection + +@push('scripts') + +@endpush \ 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 22bce66..c75a269 100644 --- a/resources/views/ekosistem/value-basis-data/add.blade.php +++ b/resources/views/ekosistem/value-basis-data/add.blade.php @@ -10,58 +10,8 @@
@csrf - -
Informasi {{ $tabel->label }}
-
- @foreach($kolom as $k) -
- - @if($k->tipe == 'varchar') - - @elseif($k->tipe == 'text') - - @elseif($k->tipe == 'integer') - - @elseif($k->tipe == 'float') - - @elseif($k->tipe == 'date') - - @elseif($k->tipe == 'datetime') - - @elseif($k->tipe == 'boolean') - - @elseif($k->tipe == 'foreign_key') - - @elseif($k->tipe == 'enum') - - @else - - @endif - @error($k->kolom)
{{ $message }}
@enderror -
- @endforeach -
- + + {!! $tabel->renderHtml('add', $errors, $list_relasi) !!}
Kembali diff --git a/resources/views/ekosistem/value-basis-data/edit-ref.blade.php b/resources/views/ekosistem/value-basis-data/edit-ref.blade.php new file mode 100644 index 0000000..6963d01 --- /dev/null +++ b/resources/views/ekosistem/value-basis-data/edit-ref.blade.php @@ -0,0 +1,124 @@ +@extends('layout.main') + +@section('content') +
+
+
+
Tambah Data {{ $tabel->label }}
+
+ +
+ + @csrf + @method('PUT') + +
Informasi {{ $tabel->label }}
+ @if (!$program) +
+
+ + +
+
+ @endif +
+ @foreach($kolom as $k) + where('kolom_id', $k->id)->first(); + ?> +
+ + @if($k->tipe == 'varchar') + + @elseif($k->tipe == 'text') + + @elseif($k->tipe == 'integer') + + @elseif($k->tipe == 'float') + + @elseif($k->tipe == 'date') + + @elseif($k->tipe == 'datetime') + + @elseif($k->tipe == 'boolean') + + @elseif($k->tipe == 'foreign_key') + + @elseif($k->tipe == 'enum') + + @else + + @endif + @error($k->kolom)
{{ $message }}
@enderror +
+ @endforeach +
+ + +
+ Kembali + +
+ +
+
+
+@endsection + +@push('scripts') + +@endpush \ No newline at end of file diff --git a/resources/views/ekosistem/value-basis-data/edit.blade.php b/resources/views/ekosistem/value-basis-data/edit.blade.php index 6963d01..ae3326f 100644 --- a/resources/views/ekosistem/value-basis-data/edit.blade.php +++ b/resources/views/ekosistem/value-basis-data/edit.blade.php @@ -10,76 +10,10 @@
@csrf - @method('PUT') + @method('PUT') -
Informasi {{ $tabel->label }}
- @if (!$program) -
-
- - -
-
- @endif -
- @foreach($kolom as $k) - where('kolom_id', $k->id)->first(); - ?> -
- - @if($k->tipe == 'varchar') - - @elseif($k->tipe == 'text') - - @elseif($k->tipe == 'integer') - - @elseif($k->tipe == 'float') - - @elseif($k->tipe == 'date') - - @elseif($k->tipe == 'datetime') - - @elseif($k->tipe == 'boolean') - - @elseif($k->tipe == 'foreign_key') - - @elseif($k->tipe == 'enum') - - @else - - @endif - @error($k->kolom)
{{ $message }}
@enderror -
- @endforeach -
+ {!! $tabel->renderHtml('edit', $errors, $list_relasi, $values) !!} -
Kembali diff --git a/resources/views/ekosistem/value-basis-data/view.blade.php b/resources/views/ekosistem/value-basis-data/view.blade.php index 6716131..bdc2da3 100644 --- a/resources/views/ekosistem/value-basis-data/view.blade.php +++ b/resources/views/ekosistem/value-basis-data/view.blade.php @@ -12,63 +12,7 @@ @csrf @method('PUT') -
Informasi {{ $tabel->label }}
- @if (!$program) -
-
- - -
-
- @endif -
- @foreach($kolom as $k) - where('kolom_id', $k->id)->first(); - ?> -
- - @if($k->tipe == 'varchar') - - @elseif($k->tipe == 'text') - - @elseif($k->tipe == 'integer') - - @elseif($k->tipe == 'float') - - @elseif($k->tipe == 'date') - - @elseif($k->tipe == 'datetime') - - @elseif($k->tipe == 'boolean') - - @elseif($k->tipe == 'foreign_key') - - @elseif($k->tipe == 'enum') - - @else - - @endif - @error($k->kolom)
{{ $message }}
@enderror -
- @endforeach -
- + {!! $tabel->renderHtml('view', $errors, null, $values) !!}
Kembali diff --git a/routes/web.php b/routes/web.php index 9ceb9fb..1675e25 100644 --- a/routes/web.php +++ b/routes/web.php @@ -118,9 +118,13 @@ Route::middleware('auth') Route::put('tabel/{tabelId}/kolom/{id}/move-down', [App\Http\Controllers\Web\Ekosistem\KolomBasisDataController::class, 'moveDown'])->name('tabel.kolom.move-down'); Route::resource('tabel.kolom', App\Http\Controllers\Web\Ekosistem\KolomBasisDataController::class)->only(['show', 'store', 'update', 'destroy']); Route::resource('tabel.data', App\Http\Controllers\Web\Ekosistem\ValueBasisDataController::class); - Route::resource('tabel.ringkasan', App\Http\Controllers\Web\Ekosistem\RingkasanBasisDataController::class); Route::put('tabel/{tabelId}/ringkasan/{id}/move-up', [App\Http\Controllers\Web\Ekosistem\RingkasanBasisDataController::class, 'moveUp'])->name('tabel.ringkasan.move-up'); Route::put('tabel/{tabelId}/ringkasan/{id}/move-down', [App\Http\Controllers\Web\Ekosistem\RingkasanBasisDataController::class, 'moveDown'])->name('tabel.ringkasan.move-down'); + Route::resource('tabel.ringkasan', App\Http\Controllers\Web\Ekosistem\RingkasanBasisDataController::class); + Route::post('tabel/{tabelId}/formulir/generate', [App\Http\Controllers\Web\Ekosistem\FormBasisDataController::class, 'generate'])->name('tabel.formulir.generate'); + Route::put('tabel/{tabelId}/formulir/{id}/move-up', [App\Http\Controllers\Web\Ekosistem\FormBasisDataController::class, 'moveUp'])->name('tabel.formulir.move-up'); + Route::put('tabel/{tabelId}/formulir/{id}/move-down', [App\Http\Controllers\Web\Ekosistem\FormBasisDataController::class, 'moveDown'])->name('tabel.formulir.move-down'); + Route::resource('tabel.formulir', App\Http\Controllers\Web\Ekosistem\FormBasisDataController::class); Route::resource('petani-cpm', App\Http\Controllers\Web\Ekosistem\PetaniCPMController::class); Route::get('petani-cpm/summary/{tipe}', [App\Http\Controllers\Web\Ekosistem\PetaniCPMController::class, 'summary'])->name('petani-cpm.summary'); From e9abd33d85a01c0e2aac2f24ada91233b5bb9378 Mon Sep 17 00:00:00 2001 From: Irwan Cahyono Date: Fri, 15 May 2026 15:47:10 +0700 Subject: [PATCH 08/46] rename tgl migrate --- ...ble.php => 2026_05_12_161821_create_form_basis_data_table.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename database/migrations/{2026_05_08_161821_create_form_basis_data_table.php => 2026_05_12_161821_create_form_basis_data_table.php} (100%) diff --git a/database/migrations/2026_05_08_161821_create_form_basis_data_table.php b/database/migrations/2026_05_12_161821_create_form_basis_data_table.php similarity index 100% rename from database/migrations/2026_05_08_161821_create_form_basis_data_table.php rename to database/migrations/2026_05_12_161821_create_form_basis_data_table.php From 75d679f4923f848bece570836a30cc95f8cc2125 Mon Sep 17 00:00:00 2001 From: "fauzgabriel@gmail.com" Date: Mon, 18 May 2026 12:17:23 +0700 Subject: [PATCH 09/46] update resources --- app/Http/Resources/ProfileResource.php | 2 ++ app/Http/Resources/UserResource.php | 1 + 2 files changed, 3 insertions(+) diff --git a/app/Http/Resources/ProfileResource.php b/app/Http/Resources/ProfileResource.php index e64348d..57ef1c7 100644 --- a/app/Http/Resources/ProfileResource.php +++ b/app/Http/Resources/ProfileResource.php @@ -7,6 +7,7 @@ use Illuminate\Http\Resources\Json\JsonResource; use App\Http\Resources\Wilayah\DesaKelurahanResource; use App\Http\Resources\UserResource; +use phpDocumentor\Reflection\Types\This; class ProfileResource extends JsonResource { @@ -31,6 +32,7 @@ class ProfileResource extends JsonResource 'desa_kelurahan_id' => $this->desa_kelurahan_id, 'desa_kelurahan' => $this->desaKelurahan ? new DesaKelurahanResource($this->desaKelurahan) : null, 'user' => $this->user ? new UserResource($this->user) : null, + 'user_uid' => $this->user_uid, ]; } } diff --git a/app/Http/Resources/UserResource.php b/app/Http/Resources/UserResource.php index 4af8ec0..da4db94 100644 --- a/app/Http/Resources/UserResource.php +++ b/app/Http/Resources/UserResource.php @@ -20,6 +20,7 @@ class UserResource extends JsonResource 'email' => $this->email, 'email_verified_at' => $this->email_verified_at, 'role' => $this->role, + 'uid' => $this->uid, ]; } } From 6c0c47751ce151312943074148fb9661646be863 Mon Sep 17 00:00:00 2001 From: "fauzgabriel@gmail.com" Date: Mon, 18 May 2026 14:41:31 +0700 Subject: [PATCH 10/46] add column uid lahan profile --- app/Models/Map/Lahan.php | 1 + ...026_02_19_172905_create_profiles_table.php | 2 + ...26_05_18_112159_add_uid_to_map_tanaman.php | 39 +++++++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 database/migrations/2026_05_18_112159_add_uid_to_map_tanaman.php diff --git a/app/Models/Map/Lahan.php b/app/Models/Map/Lahan.php index 78534c7..f0dcc6c 100644 --- a/app/Models/Map/Lahan.php +++ b/app/Models/Map/Lahan.php @@ -17,6 +17,7 @@ class Lahan extends Model 'status_kepemilikan', 'profile_id', 'desa_kelurahan_id', + 'uid', 'path', 'luas_lahan', 'created_by', diff --git a/database/migrations/2026_02_19_172905_create_profiles_table.php b/database/migrations/2026_02_19_172905_create_profiles_table.php index 1423340..9d605b5 100644 --- a/database/migrations/2026_02_19_172905_create_profiles_table.php +++ b/database/migrations/2026_02_19_172905_create_profiles_table.php @@ -51,6 +51,7 @@ return new class extends Migration Schema::create('profiles', function (Blueprint $table) { $table->id(); $table->foreignId('user_id')->constrained(); + $table->string('user_uid'); $table->string('role')->nullable(); $table->string('nama'); @@ -67,6 +68,7 @@ return new class extends Migration $table->string('file_kk')->nullable(); $table->string('path_ktp', 500)->nullable(); $table->string('file_ktp')->nullable(); + $table->string('user_uid'); $table->foreignId('keluarga_id')->nullable()->constrained('keluarga')->onDelete('set null'); diff --git a/database/migrations/2026_05_18_112159_add_uid_to_map_tanaman.php b/database/migrations/2026_05_18_112159_add_uid_to_map_tanaman.php new file mode 100644 index 0000000..4f41d03 --- /dev/null +++ b/database/migrations/2026_05_18_112159_add_uid_to_map_tanaman.php @@ -0,0 +1,39 @@ +string('uid')->unique(); // LH-1234567890&0987654321 (sepuluh digit user - 10 digit lahan) + }); + + Schema::table('map_tanaman', function(Blueprint $table){ + $table->string('uid')->unique(); //// LH-1234567890&0987654321&5432167890 + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('map_lahan', function (Blueprint $table) { + $table->dropUnique(['uid']); + $table->dropColumn(['uid']); + }); + + Schema::table('map_tanaman', function (Blueprint $table) { + $table->dropUnique(['uid']); + $table->dropColumn(['uid']); + }); + } +}; From 9e748fc8cd5956c5a75f77be7b9f0da6d1399be6 Mon Sep 17 00:00:00 2001 From: ahmadafriadi Date: Tue, 19 May 2026 13:24:38 +0700 Subject: [PATCH 11/46] Update master Varietas --- .../2026_02_20_110207_create_komoditas_table.php | 15 +++++++++++++++ .../2026_02_20_131504_create_lahans_table.php | 3 ++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/database/migrations/2026_02_20_110207_create_komoditas_table.php b/database/migrations/2026_02_20_110207_create_komoditas_table.php index 4238135..f495045 100644 --- a/database/migrations/2026_02_20_110207_create_komoditas_table.php +++ b/database/migrations/2026_02_20_110207_create_komoditas_table.php @@ -22,6 +22,20 @@ return new class extends Migration $table->timestamps(); $table->softDeletes(); }); + + Schema::create('master_varietas', function (Blueprint $table) { + $table->id(); + $table->foreignId('komoditas_id')->constrained('master_komoditas')->onDelete('cascade'); + $table->string('nama'); + $table->text('deskripsi')->unique(); + + $table->foreignId('created_by')->nullable()->constrained('users')->onDelete('set null'); + $table->foreignId('updated_by')->nullable()->constrained('users')->onDelete('set null'); + $table->foreignId('deleted_by')->nullable()->constrained('users')->onDelete('set null'); + + $table->timestamps(); + $table->softDeletes(); + }); } /** @@ -30,5 +44,6 @@ return new class extends Migration public function down(): void { Schema::dropIfExists('master_komoditas'); + Schema::dropIfExists('master_varietas'); } }; diff --git a/database/migrations/2026_02_20_131504_create_lahans_table.php b/database/migrations/2026_02_20_131504_create_lahans_table.php index 70f30e5..9469b3e 100644 --- a/database/migrations/2026_02_20_131504_create_lahans_table.php +++ b/database/migrations/2026_02_20_131504_create_lahans_table.php @@ -21,7 +21,7 @@ return new class extends Migration $table->foreignId('adat_pemilik_id')->nullable()->constrained('adat')->onDelete('set null'); $table->foreignId('desa_kelurahan_id')->nullable()->constrained('master_desa_kelurahan'); - $table->text('path')->nullable(); + $table->jsonb('path')->nullable(); $table->float('luas_lahan', 8)->nullable(); @@ -38,6 +38,7 @@ return new class extends Migration $table->string('nama'); $table->foreignId('komoditas_id')->constrained('master_komoditas')->onDelete('set null'); + $table->foreignId('varietas_id')->constrained('master_varietas')->onDelete('set null'); $table->foreignId('profile_id')->constrained('profiles')->onDelete('set null'); $table->foreignId('lahan_id')->constrained('map_lahan')->onDelete('set null'); From 5f6dbb4d1e09b7f96af8fc6771a9928e466dee8c Mon Sep 17 00:00:00 2001 From: althaf Date: Tue, 19 May 2026 16:38:47 +0700 Subject: [PATCH 12/46] feat(ui): update administrative summary widgets --- resources/views/master/provinsi/index.blade.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/resources/views/master/provinsi/index.blade.php b/resources/views/master/provinsi/index.blade.php index f460df0..67d78b7 100644 --- a/resources/views/master/provinsi/index.blade.php +++ b/resources/views/master/provinsi/index.blade.php @@ -2,6 +2,9 @@ @section('content')
+
+ +
From 7e8ad932a4dd5a08263261edb97e3377a868ac69 Mon Sep 17 00:00:00 2001 From: "fauzgabriel@gmail.com" Date: Mon, 25 May 2026 10:58:39 +0700 Subject: [PATCH 13/46] user id profile --- database/migrations/2026_02_19_172905_create_profiles_table.php | 1 - database/seeders/AdminUserSeeder.php | 2 ++ database/seeders/DatabaseSeeder.php | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/database/migrations/2026_02_19_172905_create_profiles_table.php b/database/migrations/2026_02_19_172905_create_profiles_table.php index 9d605b5..b2fae24 100644 --- a/database/migrations/2026_02_19_172905_create_profiles_table.php +++ b/database/migrations/2026_02_19_172905_create_profiles_table.php @@ -51,7 +51,6 @@ return new class extends Migration Schema::create('profiles', function (Blueprint $table) { $table->id(); $table->foreignId('user_id')->constrained(); - $table->string('user_uid'); $table->string('role')->nullable(); $table->string('nama'); diff --git a/database/seeders/AdminUserSeeder.php b/database/seeders/AdminUserSeeder.php index c99c647..39cfc85 100644 --- a/database/seeders/AdminUserSeeder.php +++ b/database/seeders/AdminUserSeeder.php @@ -20,6 +20,7 @@ class AdminUserSeeder extends Seeder 'email_verified_at' => now(), 'password' => Hash::make('Asalada123'), 'role' => 'super_admin', + 'uid' => 'AD-1234567891', 'created_at' => now(), 'updated_at' => now(), ]); @@ -44,6 +45,7 @@ class AdminUserSeeder extends Seeder 'created_at' => now(), 'updated_at' => now(), 'adat_id' => null, + 'user_uid' => 'AD-1234567891', ]); } } diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 6b901f8..f5f3a82 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -20,6 +20,7 @@ class DatabaseSeeder extends Seeder User::factory()->create([ 'name' => 'Test User', 'email' => 'test@example.com', + 'uid' => 'AD-1234567890', ]); } } From 60063b86ba92ba43a2551765997c1d8f1c8bccec Mon Sep 17 00:00:00 2001 From: "fauzgabriel@gmail.com" Date: Mon, 25 May 2026 15:01:25 +0700 Subject: [PATCH 14/46] username --- app/Http/Controllers/Api/AuthController.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/Http/Controllers/Api/AuthController.php b/app/Http/Controllers/Api/AuthController.php index f876902..a3d16b3 100644 --- a/app/Http/Controllers/Api/AuthController.php +++ b/app/Http/Controllers/Api/AuthController.php @@ -45,6 +45,7 @@ class AuthController extends Controller 'name' => ['required', 'string', 'max:255'], 'email' => ['required', 'email', 'max:255', 'unique:users'], 'password' => ['required', 'string', 'min:8', 'confirmed'], + 'username' => ['required', 'string', 'max:255'], 'role' => ['string'], 'uid' => ['required','string', 'unique:users'], ]); @@ -53,6 +54,7 @@ class AuthController extends Controller 'name' => $credentials['name'], 'email' => $credentials['email'], 'password' => Hash::make($credentials['password']), + 'username' => $credentials['username'], 'role' => $credentials['role'], 'uid' => $credentials['uid'], ]); From 6341199fd548b335d388a9adc6f36f34e1477b38 Mon Sep 17 00:00:00 2001 From: "fauzgabriel@gmail.com" Date: Mon, 25 May 2026 15:11:00 +0700 Subject: [PATCH 15/46] username on model --- app/Models/User.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Models/User.php b/app/Models/User.php index b2e6cb6..7dbb062 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -21,6 +21,7 @@ class User extends Authenticatable 'password', 'email_verified_at', 'role', + 'username', 'uid' ]; From b08df8f6fae2cd2383715408160354114a5bc18b Mon Sep 17 00:00:00 2001 From: "fauzgabriel@gmail.com" Date: Mon, 25 May 2026 15:34:47 +0700 Subject: [PATCH 16/46] convert profile id --- app/Http/Controllers/Api/LahanController.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/LahanController.php b/app/Http/Controllers/Api/LahanController.php index b312bd8..5b48ed3 100644 --- a/app/Http/Controllers/Api/LahanController.php +++ b/app/Http/Controllers/Api/LahanController.php @@ -87,7 +87,10 @@ class LahanController extends Controller if (!$profile) { abort(404, 'Profile tidak ditemukan'); } - + if ($request->has('profile_id')) { + $request->merge(['profile_id' => (int) $request->profile_id]); + } + $profileRule = $user->role === 'fasilitator' ? ['required', 'numeric', 'exists:profiles,id'] : ['nullable']; $validated = $request->validate([ @@ -97,6 +100,7 @@ class LahanController extends Controller 'path' => ['nullable', 'array'], 'path.*' => ['array'], 'luas_lahan' => ['nullable', 'numeric'], + 'uid' => ['required', 'string'], 'profile_id' => $profileRule, ]); From 3f37dcb51e262a230255ccea1a00fba1f11a4b95 Mon Sep 17 00:00:00 2001 From: "fauzgabriel@gmail.com" Date: Mon, 25 May 2026 15:49:10 +0700 Subject: [PATCH 17/46] catch map lahan --- app/Models/Pertanian/Lahan.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Models/Pertanian/Lahan.php b/app/Models/Pertanian/Lahan.php index 7bfc525..c22ac45 100644 --- a/app/Models/Pertanian/Lahan.php +++ b/app/Models/Pertanian/Lahan.php @@ -19,6 +19,7 @@ class Lahan extends Model protected $table = 'map_lahan'; protected $fillable = [ + 'uid', 'nama', 'status_kepemilikan', 'profile_id', From 037c48264917091ac011edf5133d36f16d59e007 Mon Sep 17 00:00:00 2001 From: Irwan Cahyono Date: Tue, 26 May 2026 00:09:55 +0700 Subject: [PATCH 18/46] 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 From 9231f25e5d08bfaa19ab45348869dd2dc7d63af7 Mon Sep 17 00:00:00 2001 From: Irwan Cahyono Date: Tue, 26 May 2026 00:55:51 +0700 Subject: [PATCH 19/46] Program api --- .../Api/Core/ProgramController.php | 59 +++++++++++++++++++ .../Core/ProgramKomoditasResource.php | 27 +++++++++ .../Resources/Core/ProgramLokasiResource.php | 36 +++++++++++ app/Http/Resources/Core/ProgramResource.php | 33 +++++++++++ routes/api.php | 11 +++- 5 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 app/Http/Controllers/Api/Core/ProgramController.php create mode 100644 app/Http/Resources/Core/ProgramKomoditasResource.php create mode 100644 app/Http/Resources/Core/ProgramLokasiResource.php create mode 100644 app/Http/Resources/Core/ProgramResource.php diff --git a/app/Http/Controllers/Api/Core/ProgramController.php b/app/Http/Controllers/Api/Core/ProgramController.php new file mode 100644 index 0000000..34f1cec --- /dev/null +++ b/app/Http/Controllers/Api/Core/ProgramController.php @@ -0,0 +1,59 @@ +query('per_page', 10); + $search = $request->query('search', ''); + + $program = Program::where('nama', 'like', "%$search%") + ->paginate($perPage); + + return ProgramResource::collection($program); + } + + /** + * Store a newly created resource in storage. + */ + public function store(Request $request) + { + // + } + + /** + * Display the specified resource. + */ + public function show(string $id): ProgramResource + { + $program = Program::findOrFail($id); + return new ProgramResource($program); + } + + /** + * 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/Core/ProgramKomoditasResource.php b/app/Http/Resources/Core/ProgramKomoditasResource.php new file mode 100644 index 0000000..313e256 --- /dev/null +++ b/app/Http/Resources/Core/ProgramKomoditasResource.php @@ -0,0 +1,27 @@ + + */ + public function toArray(Request $request): array + { + return [ + 'id' => $this->id, + 'program_id' => $this->program_id, + 'komoditas_id' => $this->komoditas_id, + 'default' => $this->default, + 'komoditas' => $this->komoditas ? new KomoditasResource($this->komoditas) : null, + ]; + } +} diff --git a/app/Http/Resources/Core/ProgramLokasiResource.php b/app/Http/Resources/Core/ProgramLokasiResource.php new file mode 100644 index 0000000..934c296 --- /dev/null +++ b/app/Http/Resources/Core/ProgramLokasiResource.php @@ -0,0 +1,36 @@ + + */ + public function toArray(Request $request): array + { + return [ + 'id' => $this->id, + 'program_id' => $this->program_id, + 'provinsi_id' => $this->provinsi_id, + 'kabupaten_kota_id' => $this->kabupaten_kota_id, + 'kecamatan_id' => $this->kecamatan_id, + 'desa_kelurahan_id' => $this->desa_kelurahan_id, + 'default' => $this->default, + 'provinsi' => $this->provinsi ? new ProvinsiResource($this->provinsi) : null, + 'kabupatenKota' => $this->kabupatenKota ? new KabupatenKotaResource($this->kabupatenKota) : null, + 'kecamatan' => $this->kecamatan ? new KecamatanResource($this->kecamatan) : null, + 'desaKelurahan' => $this->desaKelurahan ? new DesaKelurahanResource($this->desaKelurahan) : null, + ]; + } +} diff --git a/app/Http/Resources/Core/ProgramResource.php b/app/Http/Resources/Core/ProgramResource.php new file mode 100644 index 0000000..3b6503f --- /dev/null +++ b/app/Http/Resources/Core/ProgramResource.php @@ -0,0 +1,33 @@ + + */ + public function toArray(Request $request): array + { + return [ + 'id' => $this->id, + 'nama' => $this->nama, + 'sub_domain' => $this->sub_domain, + 'tahun' => $this->tahun, + 'instansi' => $this->instansi, + 'komoditas' => $this->komoditas()->with('komoditas')->get()->map(function ($item) { + return new ProgramKomoditasResource($item); + }), + 'lokasi' => $this->lokasi()->with(['provinsi', 'kabupatenKota', 'kecamatan', 'desaKelurahan'])->get()->map(function ($item) { + return new ProgramLokasiResource($item); + }), + ]; + } +} diff --git a/routes/api.php b/routes/api.php index 679fa03..98562db 100644 --- a/routes/api.php +++ b/routes/api.php @@ -76,4 +76,13 @@ Route::middleware('auth:sanctum') 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 +}); + +Route::middleware('auth:sanctum') + ->name('core.') + ->prefix('core') + ->group(function () { + + Route::resource('program', App\Http\Controllers\Api\Core\ProgramController::class)->only(['index', 'show']); + +}); \ No newline at end of file From e4f7d675a17b2e44ad1374580da1a7097a6ce06b Mon Sep 17 00:00:00 2001 From: ahmadafriadi Date: Tue, 26 May 2026 09:38:38 +0700 Subject: [PATCH 20/46] Update Migration & Seeder --- .../0001_01_01_000000_create_users_table.php | 17 +----- ...26_02_20_110207_create_komoditas_table.php | 21 +++++-- .../2026_02_20_131504_create_lahans_table.php | 30 ++++++++++ .../2026_04_10_131504_update_jsonb_path.php | 42 -------------- ...6_04_15_103739_create_basis_data_table.php | 10 +++- ...026_04_16_172905_update_profiles_table.php | 25 --------- .../2026_04_27_092222_create_petani_table.php | 13 +++-- ...6_05_05_103739_update_basis_data_table.php | 55 ------------------- ...3516_create_ekosistem_lahan_cpcl_table.php | 1 + ...05_07_103739_update_basis_data_table_2.php | 27 --------- ...26_05_18_112159_add_uid_to_map_tanaman.php | 39 ------------- database/seeders/AdminUserSeeder.php | 6 +- 12 files changed, 71 insertions(+), 215 deletions(-) delete mode 100644 database/migrations/2026_04_10_131504_update_jsonb_path.php delete mode 100644 database/migrations/2026_04_16_172905_update_profiles_table.php delete mode 100644 database/migrations/2026_05_05_103739_update_basis_data_table.php delete mode 100644 database/migrations/2026_05_07_103739_update_basis_data_table_2.php delete mode 100644 database/migrations/2026_05_18_112159_add_uid_to_map_tanaman.php diff --git a/database/migrations/0001_01_01_000000_create_users_table.php b/database/migrations/0001_01_01_000000_create_users_table.php index 6a48c7e..cf2f279 100644 --- a/database/migrations/0001_01_01_000000_create_users_table.php +++ b/database/migrations/0001_01_01_000000_create_users_table.php @@ -10,13 +10,14 @@ return new class extends Migration { Schema::create('users', function (Blueprint $table) { $table->id(); + $table->string('uid')->unique(); $table->string('name'); - $table->string('email')->unique(); + $table->string('username')->unique(); + $table->string('email')->unique()->nullable(); $table->timestamp('email_verified_at')->nullable(); $table->string('password'); $table->rememberToken(); $table->string('role')->nullable(); - $table->string('uid')->unique(); $table->foreignId('created_by')->nullable()->constrained('users')->onDelete('set null'); $table->foreignId('updated_by')->nullable()->constrained('users')->onDelete('set null'); $table->foreignId('deleted_by')->nullable()->constrained('users')->onDelete('set null'); @@ -24,17 +25,6 @@ return new class extends Migration $table->softDeletes(); }); - // Schema::create('user_roles', function (Blueprint $table) { - // $table->id(); - // $table->foreignId('user_id')->unique()->constrained('users')->onDelete('cascade'); - // $table->enum('role_name', ['Super Admin', 'Admin', 'Koordinator', 'Penyuluh', 'Pendamping', 'Petani'])->default('Petani'); - // $table->foreignId('created_by')->nullable()->constrained('users')->onDelete('set null'); - // $table->foreignId('updated_by')->nullable()->constrained('users')->onDelete('set null'); - // $table->foreignId('deleted_by')->nullable()->constrained('users')->onDelete('set null'); - // $table->timestamps(); - // $table->softDeletes(); - // }); - Schema::create('password_reset_tokens', function (Blueprint $table) { $table->string('email')->primary(); $table->string('token'); @@ -54,7 +44,6 @@ return new class extends Migration public function down(): void { Schema::dropIfExists('users'); - // Schema::dropIfExists('user_roles'); Schema::dropIfExists('password_reset_tokens'); Schema::dropIfExists('sessions'); } diff --git a/database/migrations/2026_02_20_110207_create_komoditas_table.php b/database/migrations/2026_02_20_110207_create_komoditas_table.php index f495045..1f7e0bb 100644 --- a/database/migrations/2026_02_20_110207_create_komoditas_table.php +++ b/database/migrations/2026_02_20_110207_create_komoditas_table.php @@ -23,9 +23,22 @@ return new class extends Migration $table->softDeletes(); }); + Schema::create('jenis_komoditas', function (Blueprint $table) { + $table->id(); + $table->foreignId('komoditas_id')->constrained('master_komoditas')->onDelete('cascade'); + $table->string('nama'); + $table->foreignId('created_by')->nullable()->constrained('users')->onDelete('set null'); + $table->foreignId('updated_by')->nullable()->constrained('users')->onDelete('set null'); + $table->foreignId('deleted_by')->nullable()->constrained('users')->onDelete('set null'); + + $table->timestamps(); + $table->softDeletes(); + }); + Schema::create('master_varietas', function (Blueprint $table) { $table->id(); $table->foreignId('komoditas_id')->constrained('master_komoditas')->onDelete('cascade'); + $table->foreignId('jenis_komoditas_id')->constrained('jenis_komoditas')->onDelete('cascade'); $table->string('nama'); $table->text('deskripsi')->unique(); @@ -37,13 +50,11 @@ return new class extends Migration $table->softDeletes(); }); } - - /** - * Reverse the migrations. - */ + public function down(): void { - Schema::dropIfExists('master_komoditas'); Schema::dropIfExists('master_varietas'); + Schema::dropIfExists('jenis_komoditas'); + Schema::dropIfExists('master_komoditas'); } }; diff --git a/database/migrations/2026_02_20_131504_create_lahans_table.php b/database/migrations/2026_02_20_131504_create_lahans_table.php index 9469b3e..13dc242 100644 --- a/database/migrations/2026_02_20_131504_create_lahans_table.php +++ b/database/migrations/2026_02_20_131504_create_lahans_table.php @@ -13,6 +13,7 @@ return new class extends Migration { Schema::create('map_lahan', function (Blueprint $table) { $table->id(); + $table->string('uid')->unique(); $table->string('nama'); $table->string('status_kepemilikan'); @@ -21,8 +22,14 @@ return new class extends Migration $table->foreignId('adat_pemilik_id')->nullable()->constrained('adat')->onDelete('set null'); $table->foreignId('desa_kelurahan_id')->nullable()->constrained('master_desa_kelurahan'); + $table->string('lat')->nullable(); + $table->string('long')->nullable(); $table->jsonb('path')->nullable(); + $table->boolean('sertifikat')->default(false); + $table->boolean('konflik')->default(false); + $table->text('deskripsi')->nullable(); + $table->float('luas_lahan', 8)->nullable(); $table->foreignId('created_by')->nullable()->constrained('users')->onDelete('set null'); @@ -33,11 +40,31 @@ return new class extends Migration $table->softDeletes(); }); + Schema::create('sertifikat_lahan', function (Blueprint $table) { + $table->id(); + $table->string('uid')->unique(); + $table->string('nomor_sertifikat'); + $table->date('tanggal_terbit'); + $table->date('tanggal_kadaluarsa')->nullable(); + $table->string('lembaga_penerbit')->nullable(); + + $table->foreignId('lahan_id')->constrained('map_lahan')->onDelete('cascade'); + + $table->foreignId('created_by')->nullable()->constrained('users')->onDelete('set null'); + $table->foreignId('updated_by')->nullable()->constrained('users')->onDelete('set null'); + $table->foreignId('deleted_by')->nullable()->constrained('users')->onDelete('set null'); + + $table->timestamps(); + $table->softDeletes(); + }); + Schema::create('map_tanaman', function (Blueprint $table) { $table->id(); + $table->string('uid')->unique(); $table->string('nama'); $table->foreignId('komoditas_id')->constrained('master_komoditas')->onDelete('set null'); + $table->foreignId('jenis_komoditas_id')->constrained('jenis_komoditas')->onDelete('set null'); $table->foreignId('varietas_id')->constrained('master_varietas')->onDelete('set null'); $table->foreignId('profile_id')->constrained('profiles')->onDelete('set null'); $table->foreignId('lahan_id')->constrained('map_lahan')->onDelete('set null'); @@ -46,6 +73,8 @@ return new class extends Migration $table->float('longitude')->nullable(); $table->string('kondisi_tanaman')->nullable(); + $table->string('metode_pengumpulan')->nullable(); + $table->text('deskripsi')->nullable(); $table->foreignId('created_by')->nullable()->constrained('users')->onDelete('set null'); $table->foreignId('updated_by')->nullable()->constrained('users')->onDelete('set null'); @@ -62,6 +91,7 @@ return new class extends Migration public function down(): void { Schema::dropIfExists('map_tanaman'); + Schema::dropIfExists('sertifikat_lahan'); Schema::dropIfExists('map_lahan'); } }; diff --git a/database/migrations/2026_04_10_131504_update_jsonb_path.php b/database/migrations/2026_04_10_131504_update_jsonb_path.php deleted file mode 100644 index d7534c8..0000000 --- a/database/migrations/2026_04_10_131504_update_jsonb_path.php +++ /dev/null @@ -1,42 +0,0 @@ -jsonb('path')->nullable()->change(); - }); - - Schema::table('master_provinsi', function (Blueprint $table) { - $table->jsonb('path')->nullable()->change(); - }); - - Schema::table('master_kabupaten_kota', function (Blueprint $table) { - $table->jsonb('path')->nullable()->change(); - }); - - Schema::table('master_kecamatan', function (Blueprint $table) { - $table->jsonb('path')->nullable()->change(); - }); - - Schema::table('master_desa_kelurahan', function (Blueprint $table) { - $table->jsonb('path')->nullable()->change(); - }); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - - } -}; diff --git a/database/migrations/2026_04_15_103739_create_basis_data_table.php b/database/migrations/2026_04_15_103739_create_basis_data_table.php index e8d3fa8..35aeedb 100644 --- a/database/migrations/2026_04_15_103739_create_basis_data_table.php +++ b/database/migrations/2026_04_15_103739_create_basis_data_table.php @@ -29,9 +29,15 @@ return new class extends Migration $table->foreignId('tabel_id')->constrained('ekosistem_basis_data_tabel')->restrictOnDelete(); $table->string('kolom'); $table->string('label'); - $table->enum('tipe', ['varchar', 'integer', 'float', 'boolean', 'date', 'datetime', 'text'])->default('varchar'); + $table->enum('tipe', ['varchar', 'integer', 'float', 'boolean', 'date', 'datetime', 'text', 'foreign_key', 'enum'])->default('varchar'); $table->jsonb('validasi')->nullable(); $table->integer('urutan')->default(1); + $table->string('relasi_tabel')->nullable(); + $table->string('relasi_kolom_id')->nullable(); + $table->string('relasi_kolom_label')->nullable(); + $table->boolean('is_active')->default('true'); + $table->boolean('is_browse')->default('false'); + $table->jsonb('enum_opsi')->nullable(); $table->timestamps(); $table->softDeletes(); @@ -60,6 +66,8 @@ return new class extends Migration $table->date('value_date')->nullable(); $table->datetime('value_datetime')->nullable(); $table->text('value_text')->nullable(); + $table->integer('value_relasi')->nullable(); + $table->string('value_enum')->nullable(); $table->foreignId('created_by')->nullable()->constrained('users')->onDelete('set null'); $table->foreignId('updated_by')->nullable()->constrained('users')->onDelete('set null'); diff --git a/database/migrations/2026_04_16_172905_update_profiles_table.php b/database/migrations/2026_04_16_172905_update_profiles_table.php deleted file mode 100644 index f2ee0fb..0000000 --- a/database/migrations/2026_04_16_172905_update_profiles_table.php +++ /dev/null @@ -1,25 +0,0 @@ -foreignId('adat_id')->nullable()->constrained('adat'); - }); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - } -}; diff --git a/database/migrations/2026_04_27_092222_create_petani_table.php b/database/migrations/2026_04_27_092222_create_petani_table.php index 13df24f..46a432c 100644 --- a/database/migrations/2026_04_27_092222_create_petani_table.php +++ b/database/migrations/2026_04_27_092222_create_petani_table.php @@ -13,9 +13,11 @@ return new class extends Migration { Schema::create('ekosistem_petani_cpm', function (Blueprint $table) { $table->id(); - + $table->string('uid')->unique(); + $table->foreignId('program_id')->nullable()->constrained('core_program')->nullOnDelete(); $table->string('nama'); $table->boolean('jenis_kelamin'); + $table->string('tempat_lahir')->nullable(); $table->date('tanggal_lahir'); $table->string('pendidikan_terakhir')->nullable(); @@ -28,11 +30,17 @@ return new class extends Migration $table->float('lama_bertani', 8)->nullable(); $table->float('luas_lahan', 8)->nullable(); + $table->string('dusun_rt_rw')->nullable(); + $table->string('nomor_telepon')->nullable(); + $table->string('foto')->nullable(); + $table->string('pekerjaan_sampingan')->nullable(); $table->foreignId('komoditas_sampingan_id')->nullable()->constrained('master_komoditas'); $table->float('lama_bertani_sampingan', 8)->nullable(); $table->float('luas_lahan_sampingan', 8)->nullable(); + + $table->string('status_perkawinan')->nullable(); $table->string('status_keluarga')->nullable(); $table->integer('jumlah_tanggungan')->nullable(); @@ -48,9 +56,6 @@ return new class extends Migration }); } - /** - * Reverse the migrations. - */ public function down(): void { Schema::dropIfExists('ekosistem_petani_cpm'); diff --git a/database/migrations/2026_05_05_103739_update_basis_data_table.php b/database/migrations/2026_05_05_103739_update_basis_data_table.php deleted file mode 100644 index cee687b..0000000 --- a/database/migrations/2026_05_05_103739_update_basis_data_table.php +++ /dev/null @@ -1,55 +0,0 @@ -string('relasi_tabel')->nullable(); - $table->string('relasi_kolom_id')->nullable(); - $table->string('relasi_kolom_label')->nullable(); - - $table->jsonb('enum_opsi')->nullable(); - }); - - DB::statement("alter table public.ekosistem_basis_data_kolom drop constraint ekosistem_basis_data_kolom_tipe_check;"); - DB::statement(" - alter table public.ekosistem_basis_data_kolom add constraint ekosistem_basis_data_kolom_tipe_check check (((tipe)::text = any - ((array[ - 'varchar'::character varying, - 'integer'::character varying, - 'float'::character varying, - 'boolean'::character varying, - 'date'::character varying, - 'datetime'::character varying, - 'text'::character varying, - 'foreign_key'::character varying, - 'enum'::character varying - ])::text[]))) - "); - - Schema::table('ekosistem_basis_data_value', function (Blueprint $table) { - $table->integer('value_relasi')->nullable(); - $table->string('value_enum')->nullable(); - }); - - Schema::table('ekosistem_petani_cpm', function (Blueprint $table) { - $table->foreignId('program_id')->nullable()->constrained('core_program')->nullOnDelete(); - }); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - } -}; diff --git a/database/migrations/2026_05_06_113516_create_ekosistem_lahan_cpcl_table.php b/database/migrations/2026_05_06_113516_create_ekosistem_lahan_cpcl_table.php index d2d866f..db86702 100644 --- a/database/migrations/2026_05_06_113516_create_ekosistem_lahan_cpcl_table.php +++ b/database/migrations/2026_05_06_113516_create_ekosistem_lahan_cpcl_table.php @@ -13,6 +13,7 @@ return new class extends Migration { Schema::create('ekosistem_lahan_cpcl', function (Blueprint $table) { $table->id(); + $table->string('uid')->unique(); $table->string('nama'); $table->string('status_kepemilikan'); diff --git a/database/migrations/2026_05_07_103739_update_basis_data_table_2.php b/database/migrations/2026_05_07_103739_update_basis_data_table_2.php deleted file mode 100644 index a187a6b..0000000 --- a/database/migrations/2026_05_07_103739_update_basis_data_table_2.php +++ /dev/null @@ -1,27 +0,0 @@ -boolean('is_active')->default('true'); - $table->boolean('is_browse')->default('false'); - }); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - } -}; diff --git a/database/migrations/2026_05_18_112159_add_uid_to_map_tanaman.php b/database/migrations/2026_05_18_112159_add_uid_to_map_tanaman.php deleted file mode 100644 index 4f41d03..0000000 --- a/database/migrations/2026_05_18_112159_add_uid_to_map_tanaman.php +++ /dev/null @@ -1,39 +0,0 @@ -string('uid')->unique(); // LH-1234567890&0987654321 (sepuluh digit user - 10 digit lahan) - }); - - Schema::table('map_tanaman', function(Blueprint $table){ - $table->string('uid')->unique(); //// LH-1234567890&0987654321&5432167890 - }); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - Schema::table('map_lahan', function (Blueprint $table) { - $table->dropUnique(['uid']); - $table->dropColumn(['uid']); - }); - - Schema::table('map_tanaman', function (Blueprint $table) { - $table->dropUnique(['uid']); - $table->dropColumn(['uid']); - }); - } -}; diff --git a/database/seeders/AdminUserSeeder.php b/database/seeders/AdminUserSeeder.php index 39cfc85..d1193be 100644 --- a/database/seeders/AdminUserSeeder.php +++ b/database/seeders/AdminUserSeeder.php @@ -15,17 +15,18 @@ class AdminUserSeeder extends Seeder public function run(): void { DB::table('users')->insert([ + 'uid' => 'AD-1234567891', 'name' => 'Admin', + 'username' => 'admin', 'email' => 'admin@example.com', 'email_verified_at' => now(), 'password' => Hash::make('Asalada123'), 'role' => 'super_admin', - 'uid' => 'AD-1234567891', 'created_at' => now(), 'updated_at' => now(), ]); - Db::table('profiles')->insert([ + DB::table('profiles')->insert([ 'user_id' => 1, 'role' => 'super_admin', 'nama' => 'Admin', @@ -44,7 +45,6 @@ class AdminUserSeeder extends Seeder 'updated_by' => 1, 'created_at' => now(), 'updated_at' => now(), - 'adat_id' => null, 'user_uid' => 'AD-1234567891', ]); } From 12f06869658da24fb192594fd4c4ad6dec1d8521 Mon Sep 17 00:00:00 2001 From: ahmadafriadi Date: Tue, 26 May 2026 11:30:24 +0700 Subject: [PATCH 21/46] Update Jenis Komoditas --- .../Web/Master/JenisKomoditasController.php | 216 ++++++++ app/Models/Master/JenisKomoditas.php | 28 + .../views/master/jeniskomoditas/add.blade.php | 42 ++ .../master/jeniskomoditas/edit.blade.php | 45 ++ .../master/jeniskomoditas/index.blade.php | 485 ++++++++++++++++++ .../master/jeniskomoditas/view.blade.php | 24 + routes/web.php | 2 + 7 files changed, 842 insertions(+) create mode 100644 app/Http/Controllers/Web/Master/JenisKomoditasController.php create mode 100644 app/Models/Master/JenisKomoditas.php create mode 100644 resources/views/master/jeniskomoditas/add.blade.php create mode 100644 resources/views/master/jeniskomoditas/edit.blade.php create mode 100644 resources/views/master/jeniskomoditas/index.blade.php create mode 100644 resources/views/master/jeniskomoditas/view.blade.php diff --git a/app/Http/Controllers/Web/Master/JenisKomoditasController.php b/app/Http/Controllers/Web/Master/JenisKomoditasController.php new file mode 100644 index 0000000..d4728b2 --- /dev/null +++ b/app/Http/Controllers/Web/Master/JenisKomoditasController.php @@ -0,0 +1,216 @@ +get('per_page', 10); + $search = $request->get('search'); + + $jenisKomoditas = JenisKomoditas::with('komoditas') + ->when($search, function ($query) use ($search) { + $query->where(function ($q) use ($search) { + $q->where('nama', 'ILIKE', "%{$search}%") + ->orWhere('path', 'ILIKE', "%{$search}%") + ->orWhereHas('komoditas', function ($komoditasQuery) use ($search) { + $komoditasQuery->where('nama', 'ILIKE', "%{$search}%"); + }); + }); + }) + ->latest() + ->paginate($perPage); + + $komoditas = Komoditas::orderBy('nama', 'asc')->get(); + + return view('master.jeniskomoditas.index', compact( + 'jenisKomoditas', + 'komoditas' + )); + } + + /** + * Store a newly created resource in storage. + */ + public function store(Request $request) + { + $validated = $request->validate([ + 'komoditas_id' => [ + 'required', + 'integer', + 'exists:master_komoditas,id', + ], + 'nama' => [ + 'required', + 'string', + 'max:255', + Rule::unique('jenis_komoditas', 'nama') + ->where('komoditas_id', $request->komoditas_id), + ], + ], [ + 'komoditas_id.required' => 'Komoditas wajib dipilih.', + 'komoditas_id.exists' => 'Komoditas yang dipilih tidak valid.', + 'nama.required' => 'Nama jenis komoditas wajib diisi.', + 'nama.unique' => 'Nama jenis komoditas sudah tersedia pada komoditas ini.', + ]); + + try { + DB::beginTransaction(); + + $jenisKomoditas = JenisKomoditas::create([ + 'komoditas_id' => $validated['komoditas_id'], + 'nama' => $validated['nama'], + 'created_by' => auth()->id(), + 'updated_by' => auth()->id(), + ]); + + DB::commit(); + + return response()->json([ + 'status' => 'success', + 'message' => 'Data jenis komoditas berhasil disimpan.', + 'data' => $jenisKomoditas, + ]); + } catch (\Throwable $e) { + DB::rollBack(); + + Log::error('Gagal menyimpan jenis komoditas', [ + 'error' => $e->getMessage(), + 'request' => $request->all(), + ]); + + return response()->json([ + 'status' => 'error', + 'message' => 'Gagal menyimpan data: ' . $e->getMessage(), + ], 500); + } + } + + /** + * Display the specified resource. + */ + public function show(string $id) + { + try { + $jenisKomoditas = JenisKomoditas::with('komoditas')->findOrFail($id); + + return response()->json([ + 'status' => 'success', + 'data' => $jenisKomoditas, + ]); + } catch (\Throwable $e) { + return response()->json([ + 'status' => 'error', + 'message' => 'Data jenis komoditas tidak ditemukan.', + ], 404); + } + } + + /** + * Update the specified resource in storage. + */ + public function update(Request $request, string $id) + { + $jenisKomoditas = JenisKomoditas::findOrFail($id); + + $validated = $request->validate([ + 'komoditas_id' => [ + 'required', + 'integer', + 'exists:master_komoditas,id', + ], + 'nama' => [ + 'required', + 'string', + 'max:255', + Rule::unique('jenis_komoditas', 'nama') + ->where('komoditas_id', $request->komoditas_id) + ->ignore($jenisKomoditas->id), + ], + 'path' => [ + 'nullable', + 'string', + ], + ], [ + 'komoditas_id.required' => 'Komoditas wajib dipilih.', + 'komoditas_id.exists' => 'Komoditas yang dipilih tidak valid.', + 'nama.required' => 'Nama jenis komoditas wajib diisi.', + 'nama.unique' => 'Nama jenis komoditas sudah tersedia pada komoditas ini.', + ]); + + try { + DB::beginTransaction(); + + $jenisKomoditas->update([ + 'komoditas_id' => $validated['komoditas_id'], + 'nama' => $validated['nama'], + 'updated_by' => auth()->id(), + ]); + + DB::commit(); + + return response()->json([ + 'status' => 'success', + 'message' => 'Data jenis komoditas berhasil diperbarui.', + 'data' => $jenisKomoditas->fresh('komoditas'), + ]); + } catch (\Throwable $e) { + DB::rollBack(); + + Log::error('Gagal update jenis komoditas', [ + 'error' => $e->getMessage(), + 'id' => $id, + 'request' => $request->all(), + ]); + + return response()->json([ + 'status' => 'error', + 'message' => 'Gagal mengupdate data: ' . $e->getMessage(), + ], 500); + } + } + + /** + * Remove the specified resource from storage. + */ + public function destroy(string $id) + { + try { + DB::beginTransaction(); + + $jenisKomoditas = JenisKomoditas::findOrFail($id); + $jenisKomoditas->update(['deleted_by' => auth()->id()]); + $jenisKomoditas->delete(); + + DB::commit(); + + return response()->json([ + 'status' => 'success', + 'message' => 'Data jenis komoditas berhasil dihapus.', + ]); + } catch (\Throwable $e) { + DB::rollBack(); + + Log::error('Gagal hapus jenis komoditas', [ + 'error' => $e->getMessage(), + 'id' => $id, + ]); + + return response()->json([ + 'status' => 'error', + 'message' => 'Gagal menghapus data: ' . $e->getMessage(), + ], 500); + } + } +} diff --git a/app/Models/Master/JenisKomoditas.php b/app/Models/Master/JenisKomoditas.php new file mode 100644 index 0000000..cce5c46 --- /dev/null +++ b/app/Models/Master/JenisKomoditas.php @@ -0,0 +1,28 @@ +belongsTo(Komoditas::class, 'komoditas_id'); + } +} diff --git a/resources/views/master/jeniskomoditas/add.blade.php b/resources/views/master/jeniskomoditas/add.blade.php new file mode 100644 index 0000000..543735d --- /dev/null +++ b/resources/views/master/jeniskomoditas/add.blade.php @@ -0,0 +1,42 @@ +
+
+
Tambah Jenis Komoditas
+ +
+ +
+
+ @csrf + +
+ + +
+ +
+ + +
+ +
+ + +
+
+
+
\ No newline at end of file diff --git a/resources/views/master/jeniskomoditas/edit.blade.php b/resources/views/master/jeniskomoditas/edit.blade.php new file mode 100644 index 0000000..fd9a5dd --- /dev/null +++ b/resources/views/master/jeniskomoditas/edit.blade.php @@ -0,0 +1,45 @@ +
+
+
Edit Jenis Komoditas
+ +
+ +
+
+ @csrf + @method('PUT') + + + +
+ + +
+ +
+ + +
+ +
+ + +
+
+
+
\ No newline at end of file diff --git a/resources/views/master/jeniskomoditas/index.blade.php b/resources/views/master/jeniskomoditas/index.blade.php new file mode 100644 index 0000000..936d389 --- /dev/null +++ b/resources/views/master/jeniskomoditas/index.blade.php @@ -0,0 +1,485 @@ +@extends('layout.main') + +@section('content') +
+ +
+
+
+
+
Jenis Komoditas
+ Kelola data jenis komoditas +
+ + +
+
+ +
+
+ +
+
+ + + +
+
+ +
+
+ + + @if(request('search')) + + + + @endif + + +
+
+
+
+ +
+ + + + + + + + + + + + @forelse($jenisKomoditas as $index => $jenis) + @php + $komoditasNama = $jenis->komoditas->nama ?? '-'; + $words = preg_split('/\s+/', trim($komoditasNama)); + $initials = collect($words) + ->filter() + ->map(fn($word) => strtoupper(substr($word, 0, 1))) + ->take(2) + ->implode(''); + + $states = ['success', 'danger', 'warning', 'info', 'primary', 'secondary']; + $state = $states[$jenis->id % count($states)]; + @endphp + + + + + + + + + + + @empty + + + + @endforelse + +
NoNama Jenis KomoditasKomoditasActions
{{ $jenisKomoditas->firstItem() + $index }} +
+
+
+ + {{ $initials ?: 'JK' }} + +
+
+ +
+ {{ $jenis->nama }} + ID: {{ $jenis->id }} +
+
+
+ + {{ $komoditasNama }} + + +
+ + + + + +
+
+
+ + Tidak ada data ditemukan. +
+
+
+ + @if($jenisKomoditas->hasPages()) + + @endif +
+
+ +@include('master.jeniskomoditas.add') +@include('master.jeniskomoditas.edit') +@include('master.jeniskomoditas.view') +@endsection + + +@push('scripts') + +@endpush \ No newline at end of file diff --git a/resources/views/master/jeniskomoditas/view.blade.php b/resources/views/master/jeniskomoditas/view.blade.php new file mode 100644 index 0000000..b4f71d6 --- /dev/null +++ b/resources/views/master/jeniskomoditas/view.blade.php @@ -0,0 +1,24 @@ +
+
+
Detail Jenis Komoditas
+ +
+ +
+
+ + +
+ +
+ + +
+ +
+ +
+
+
\ No newline at end of file diff --git a/routes/web.php b/routes/web.php index 1a68e89..64fb4e6 100644 --- a/routes/web.php +++ b/routes/web.php @@ -85,6 +85,8 @@ Route::middleware('auth') Route::put('/komoditas/{id}', [App\Http\Controllers\Web\Master\KomoditasController::class, 'update'])->name('komoditas.update'); Route::delete('/komoditas/{id}', [App\Http\Controllers\Web\Master\KomoditasController::class, 'destroy'])->name('komoditas.destroy'); + Route::resource('jenis-komoditas', App\Http\Controllers\Web\Master\JenisKomoditasController::class); + Route::get('/keluarga', [App\Http\Controllers\Web\Master\KeluargaController::class, 'index'])->name('keluarga.index'); Route::get('/keluarga/add', [App\Http\Controllers\Web\Master\KeluargaController::class, 'create'])->name('keluarga.create'); Route::post('/keluarga', [App\Http\Controllers\Web\Master\KeluargaController::class, 'store'])->name('keluarga.store'); From a274f84fe2c3591097cce845f128a92228ca54ca Mon Sep 17 00:00:00 2001 From: Irwan Cahyono Date: Tue, 26 May 2026 12:25:18 +0700 Subject: [PATCH 22/46] RedirectResponse --- app/Http/Controllers/Web/Ekosistem/FormBasisDataController.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Http/Controllers/Web/Ekosistem/FormBasisDataController.php b/app/Http/Controllers/Web/Ekosistem/FormBasisDataController.php index 4d03593..c2982ec 100644 --- a/app/Http/Controllers/Web/Ekosistem/FormBasisDataController.php +++ b/app/Http/Controllers/Web/Ekosistem/FormBasisDataController.php @@ -10,6 +10,7 @@ use Illuminate\Http\JsonResponse; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Validator; use Illuminate\Validation\Rule; +use Illuminate\Http\RedirectResponse; use App\Models\Ekosistem\TabelBasisData; use App\Models\Ekosistem\FormBasisData; From 05967cce752f78944991d6f183974d73759b67fa Mon Sep 17 00:00:00 2001 From: Irwan Cahyono Date: Tue, 26 May 2026 13:01:57 +0700 Subject: [PATCH 23/46] test value --- .../Ekosistem/ValueBasisDataController.php | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/app/Http/Controllers/Web/Ekosistem/ValueBasisDataController.php b/app/Http/Controllers/Web/Ekosistem/ValueBasisDataController.php index 8279d3b..16597ca 100644 --- a/app/Http/Controllers/Web/Ekosistem/ValueBasisDataController.php +++ b/app/Http/Controllers/Web/Ekosistem/ValueBasisDataController.php @@ -21,6 +21,13 @@ use App\Models\Core\Program; class ValueBasisDataController extends Controller { + private $tableModelClassMap = [ + 'master_provinsi' => \App\Models\Wilayah\Provinsi::class, + 'master_kabupaten_kota' => \App\Models\Wilayah\KabupatenKota::class, + 'master_kecamatan' => \App\Models\Wilayah\Kecamatan::class, + 'master_desa_kelurahan' => \App\Models\Wilayah\DesaKelurahan::class, + ]; + public function index(Request $request, string $tabelId): View { if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) { @@ -198,7 +205,12 @@ class ValueBasisDataController extends Controller 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'); + $modelClass = $this->tableModelClassMap[$k->relasi_tabel] ?? null; + if ($modelClass) { + $options_kolom = $modelClass::select($k->relasi_kolom_label . ' as label', $k->relasi_kolom_id . ' as value')->whereNull('deleted_at'); + } else { + $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) { @@ -281,9 +293,6 @@ class ValueBasisDataController extends Controller return redirect()->route('tabel.data.index', [$tabelId, 'program_id' => $program->id])->with('success', 'Data berhasil ditambahkan.'); } - /** - * Display the specified resource. - */ public function show(Request $request, string $tabelId, string $id): View { if (!Gate::any(['super_admin', 'admin'])) { @@ -329,7 +338,9 @@ class ValueBasisDataController extends Controller 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); + $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) { From 17c4c966937d33a2e8e2289d9fc8a505db022301 Mon Sep 17 00:00:00 2001 From: ahmadafriadi Date: Tue, 26 May 2026 14:30:43 +0700 Subject: [PATCH 24/46] Penambahan Form Varietas --- .../Web/Master/JenisKomoditasController.php | 12 + .../Web/Master/VarietasController.php | 226 ++++++++ app/Models/Master/Varietas.php | 33 ++ resources/views/master/varietas/add.blade.php | 61 ++ .../views/master/varietas/edit.blade.php | 64 ++ .../views/master/varietas/index.blade.php | 547 ++++++++++++++++++ .../views/master/varietas/view.blade.php | 34 ++ routes/web.php | 2 + 8 files changed, 979 insertions(+) create mode 100644 app/Http/Controllers/Web/Master/VarietasController.php create mode 100644 app/Models/Master/Varietas.php create mode 100644 resources/views/master/varietas/add.blade.php create mode 100644 resources/views/master/varietas/edit.blade.php create mode 100644 resources/views/master/varietas/index.blade.php create mode 100644 resources/views/master/varietas/view.blade.php diff --git a/app/Http/Controllers/Web/Master/JenisKomoditasController.php b/app/Http/Controllers/Web/Master/JenisKomoditasController.php index d4728b2..ea6ce41 100644 --- a/app/Http/Controllers/Web/Master/JenisKomoditasController.php +++ b/app/Http/Controllers/Web/Master/JenisKomoditasController.php @@ -40,6 +40,18 @@ class JenisKomoditasController extends Controller )); } + public function getByKomoditas($komoditas_id) + { + $jenisKomoditas = JenisKomoditas::where('komoditas_id', $komoditas_id) + ->orderBy('nama', 'asc') + ->get(['id', 'nama']); + + return response()->json([ + 'status' => 'success', + 'data' => $jenisKomoditas, + ]); + } + /** * Store a newly created resource in storage. */ diff --git a/app/Http/Controllers/Web/Master/VarietasController.php b/app/Http/Controllers/Web/Master/VarietasController.php new file mode 100644 index 0000000..420380c --- /dev/null +++ b/app/Http/Controllers/Web/Master/VarietasController.php @@ -0,0 +1,226 @@ +get('per_page', 10); + $search = $request->get('search'); + + $varietas = Varietas::with(['komoditas', 'jenisKomoditas']) + ->when($search, function ($query) use ($search) { + $query->where(function ($q) use ($search) { + $q->where('nama', 'ILIKE', "%{$search}%") + ->orWhere('path', 'ILIKE', "%{$search}%") + ->orWhereHas('komoditas', function ($komoditasQuery) use ($search) { + $komoditasQuery->where('nama', 'ILIKE', "%{$search}%"); + }) + ->orWhereHas('jenisKomoditas', function ($jenisQuery) use ($search) { + $jenisQuery->where('nama', 'ILIKE', "%{$search}%"); + }); + }); + }) + ->latest() + ->paginate($perPage); + + $komoditas = Komoditas::orderBy('nama', 'asc')->get(); + + return view('master.varietas.index', compact( + 'varietas', + 'komoditas' + )); + } + + public function store(Request $request) + { + $komoditasTable = (new Komoditas)->getTable(); + $jenisKomoditasTable = (new JenisKomoditas)->getTable(); + $varietasTable = (new Varietas)->getTable(); + + $validated = $request->validate([ + 'komoditas_id' => [ + 'required', + 'integer', + Rule::exists($komoditasTable, 'id'), + ], + 'jenis_komoditas_id' => [ + 'required', + 'integer', + Rule::exists($jenisKomoditasTable, 'id') + ->where('komoditas_id', $request->komoditas_id), + ], + 'nama' => [ + 'required', + 'string', + 'max:255', + Rule::unique($varietasTable, 'nama') + ->where('komoditas_id', $request->komoditas_id) + ->where('jenis_komoditas_id', $request->jenis_komoditas_id), + ], + 'deskripsi' => [ + 'nullable', + 'string', + ], + ]); + + try { + DB::beginTransaction(); + + $varietas = Varietas::create([ + 'komoditas_id' => $validated['komoditas_id'], + 'jenis_komoditas_id' => $validated['jenis_komoditas_id'], + 'nama' => $validated['nama'], + 'deskripsi' => $validated['deskripsi'] ?? null, + 'created_by' => auth()->id(), + 'updated_by' => auth()->id(), + ]); + + DB::commit(); + + return response()->json([ + 'status' => 'success', + 'message' => 'Data varietas berhasil disimpan.', + 'data' => $varietas, + ]); + } catch (\Throwable $e) { + DB::rollBack(); + + Log::error('Gagal menyimpan varietas', [ + 'error' => $e->getMessage(), + 'request' => $request->all(), + ]); + + return response()->json([ + 'status' => 'error', + 'message' => 'Gagal menyimpan data: ' . $e->getMessage(), + ], 500); + } + } + + public function show(string $id) + { + try { + $varietas = Varietas::with(['komoditas', 'jenisKomoditas'])->findOrFail($id); + + return response()->json([ + 'status' => 'success', + 'data' => $varietas, + ]); + } catch (\Throwable $e) { + return response()->json([ + 'status' => 'error', + 'message' => 'Data varietas tidak ditemukan.', + ], 404); + } + } + + public function update(Request $request, string $id) + { + $komoditasTable = (new Komoditas)->getTable(); + $jenisKomoditasTable = (new JenisKomoditas)->getTable(); + $varietasTable = (new Varietas)->getTable(); + + $validated = $request->validate([ + 'komoditas_id' => [ + 'required', + 'integer', + Rule::exists($komoditasTable, 'id'), + ], + 'jenis_komoditas_id' => [ + 'required', + 'integer', + Rule::exists($jenisKomoditasTable, 'id') + ->where('komoditas_id', $request->komoditas_id), + ], + 'nama' => [ + 'required', + 'string', + 'max:255', + Rule::unique($varietasTable, 'nama') + ->where('komoditas_id', $request->komoditas_id) + ->where('jenis_komoditas_id', $request->jenis_komoditas_id), + ], + 'deskripsi' => [ + 'nullable', + 'string', + ], + ]); + + try { + DB::beginTransaction(); + + $varietas = Varietas::findOrFail($id); + $varietas->update([ + 'komoditas_id' => $validated['komoditas_id'], + 'jenis_komoditas_id' => $validated['jenis_komoditas_id'], + 'nama' => $validated['nama'], + 'deskripsi' => $validated['deskripsi'] ?? null, + 'updated_by' => auth()->id(), + ]); + + DB::commit(); + + return response()->json([ + 'status' => 'success', + 'message' => 'Data varietas berhasil diperbarui.', + 'data' => $varietas->fresh(['komoditas', 'jenisKomoditas']), + ]); + } catch (\Throwable $e) { + DB::rollBack(); + + Log::error('Gagal update varietas', [ + 'error' => $e->getMessage(), + 'id' => $id, + 'request' => $request->all(), + ]); + + return response()->json([ + 'status' => 'error', + 'message' => 'Gagal mengupdate data: ' . $e->getMessage(), + ], 500); + } + } + + public function destroy(string $id) + { + try { + DB::beginTransaction(); + + $varietas = Varietas::findOrFail($id); + $varietas->update(['deleted_by' => auth()->id()]); + $varietas->delete(); + + DB::commit(); + + return response()->json([ + 'status' => 'success', + 'message' => 'Data varietas berhasil dihapus.', + ]); + } catch (\Throwable $e) { + DB::rollBack(); + + Log::error('Gagal hapus varietas', [ + 'error' => $e->getMessage(), + 'id' => $id, + ]); + + return response()->json([ + 'status' => 'error', + 'message' => 'Gagal menghapus data: ' . $e->getMessage(), + ], 500); + } + } +} diff --git a/app/Models/Master/Varietas.php b/app/Models/Master/Varietas.php new file mode 100644 index 0000000..b8d867f --- /dev/null +++ b/app/Models/Master/Varietas.php @@ -0,0 +1,33 @@ +belongsTo(JenisKomoditas::class, 'jenis_komoditas_id'); + } + + public function komoditas() + { + return $this->belongsTo(Komoditas::class, 'komoditas_id'); + } +} diff --git a/resources/views/master/varietas/add.blade.php b/resources/views/master/varietas/add.blade.php new file mode 100644 index 0000000..25717c2 --- /dev/null +++ b/resources/views/master/varietas/add.blade.php @@ -0,0 +1,61 @@ +
+
+
Tambah Varietas
+ +
+ +
+
+ @csrf + +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+
+
\ No newline at end of file diff --git a/resources/views/master/varietas/edit.blade.php b/resources/views/master/varietas/edit.blade.php new file mode 100644 index 0000000..42a5300 --- /dev/null +++ b/resources/views/master/varietas/edit.blade.php @@ -0,0 +1,64 @@ +
+
+
Edit Varietas
+ +
+ +
+
+ @csrf + @method('PUT') + + + +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+
+
\ No newline at end of file diff --git a/resources/views/master/varietas/index.blade.php b/resources/views/master/varietas/index.blade.php new file mode 100644 index 0000000..ffd26ca --- /dev/null +++ b/resources/views/master/varietas/index.blade.php @@ -0,0 +1,547 @@ +@extends('layout.main') + +@section('content') +
+
+
+
+
+
+ + + +
+
+ +
+
+ + + @if(request('search')) + + + + @endif + + +
+ + +
+
+
+ +
+ + + + + + + + + + + + + @forelse($varietas as $index => $item) + @php + $namaVarietas = $item->nama ?? '-'; + $words = preg_split('/\s+/', trim($namaVarietas)); + $initials = collect($words) + ->filter() + ->map(fn($word) => strtoupper(substr($word, 0, 1))) + ->take(2) + ->implode(''); + + $states = ['success', 'danger', 'warning', 'info', 'primary', 'secondary']; + $state = $states[$item->id % count($states)]; + @endphp + + + + + + + + + + + + + @empty + + + + @endforelse + +
NoNama VarietasKomoditasJenis KomoditasActions
{{ $varietas->firstItem() + $index }} +
+
+
+ + {{ $initials ?: 'VR' }} + +
+
+ +
+ {{ $item->nama }} + {{ $item->deskripsi }} +
+
+
+ + {{ $item->komoditas->nama ?? '-' }} + + + + {{ $item->jenisKomoditas->nama ?? '-' }} + + +
+ + + + + +
+
+ Tidak ada data ditemukan. +
+
+ + @if($varietas->hasPages()) + + @endif +
+
+ +@include('master.varietas.add') +@include('master.varietas.edit') +@include('master.varietas.view') +@endsection + +@push('scripts') + +@endpush \ No newline at end of file diff --git a/resources/views/master/varietas/view.blade.php b/resources/views/master/varietas/view.blade.php new file mode 100644 index 0000000..fabb816 --- /dev/null +++ b/resources/views/master/varietas/view.blade.php @@ -0,0 +1,34 @@ +
+
+
Detail Varietas
+ +
+ +
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ +
+
+
\ No newline at end of file diff --git a/routes/web.php b/routes/web.php index 64fb4e6..ea137e3 100644 --- a/routes/web.php +++ b/routes/web.php @@ -86,6 +86,8 @@ Route::middleware('auth') Route::delete('/komoditas/{id}', [App\Http\Controllers\Web\Master\KomoditasController::class, 'destroy'])->name('komoditas.destroy'); Route::resource('jenis-komoditas', App\Http\Controllers\Web\Master\JenisKomoditasController::class); + Route::get('/jenis-komoditas-by-komoditas/{komoditas_id}', [App\Http\Controllers\Web\Master\JenisKomoditasController::class, 'getByKomoditas'])->name('jenis-komoditas.by-komoditas'); + Route::resource('varietas', App\Http\Controllers\Web\Master\VarietasController::class); Route::get('/keluarga', [App\Http\Controllers\Web\Master\KeluargaController::class, 'index'])->name('keluarga.index'); Route::get('/keluarga/add', [App\Http\Controllers\Web\Master\KeluargaController::class, 'create'])->name('keluarga.create'); From 7681984d890445f62215e74802f307e3c6f3aa4e Mon Sep 17 00:00:00 2001 From: Irwan Cahyono Date: Tue, 26 May 2026 16:32:25 +0700 Subject: [PATCH 25/46] tabel ekosistem --- .../Ekosistem/TabelBasisDataController.php | 5 ++- .../Ekosistem/ValueBasisDataController.php | 16 +++++++--- .../Ekosistem/FormBasisDataResource.php | 32 +++++++++++++++++++ .../Ekosistem/TabelBasisDataResource.php | 1 + app/Models/Wilayah/DesaKelurahan.php | 2 +- 5 files changed, 47 insertions(+), 9 deletions(-) create mode 100644 app/Http/Resources/Ekosistem/FormBasisDataResource.php diff --git a/app/Http/Controllers/Api/Ekosistem/TabelBasisDataController.php b/app/Http/Controllers/Api/Ekosistem/TabelBasisDataController.php index 4f6512d..f02ee4f 100644 --- a/app/Http/Controllers/Api/Ekosistem/TabelBasisDataController.php +++ b/app/Http/Controllers/Api/Ekosistem/TabelBasisDataController.php @@ -54,11 +54,10 @@ class TabelBasisDataController extends Controller abort(403); } - $tabel = TabelBasisData::with('kolom')->findOrFail($id); + $tabel = TabelBasisData::with('kolom', 'form', 'form.form', 'form.form.form', 'form.form.form.kolom')->findOrFail($id); return (new TabelBasisDataResource($tabel)) - ->response() - ->setStatusCode(201); + ->response(); } /** diff --git a/app/Http/Controllers/Web/Ekosistem/ValueBasisDataController.php b/app/Http/Controllers/Web/Ekosistem/ValueBasisDataController.php index 16597ca..ce3e301 100644 --- a/app/Http/Controllers/Web/Ekosistem/ValueBasisDataController.php +++ b/app/Http/Controllers/Web/Ekosistem/ValueBasisDataController.php @@ -12,6 +12,7 @@ use Illuminate\Support\Facades\Validator; use Illuminate\Http\JsonResponse; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Str; +use Illuminate\Support\Arr; use App\Models\Ekosistem\TabelBasisData; use App\Models\Ekosistem\KolomBasisData; @@ -173,7 +174,7 @@ class ValueBasisDataController extends Controller if (!Gate::any(['super_admin', 'admin'])) { abort(403); } - + $tabel = TabelBasisData::with('kolom') ->whereHas('kolom', function ($query) { $query->where('is_active', true); @@ -205,11 +206,11 @@ class ValueBasisDataController extends Controller if ($k->tipe == 'foreign_key') { $relasi['kolom_id'] = $k->id; try { - $modelClass = $this->tableModelClassMap[$k->relasi_tabel] ?? null; + $modelClass = Arr::get($this->tableModelClassMap, 'master_desa_kelurahan'); if ($modelClass) { - $options_kolom = $modelClass::select($k->relasi_kolom_label . ' as label', $k->relasi_kolom_id . ' as value')->whereNull('deleted_at'); + $options_kolom = $modelClass::select($k->relasi_kolom_label . ' as label', $k->relasi_kolom_id . ' as value')->limit(10000); } else { - $options_kolom = DB::table($k->relasi_tabel)->selectRaw($k->relasi_kolom_label . ' as label, ' . $k->relasi_kolom_id . ' as value')->whereNull('deleted_at'); + $options_kolom = DB::table($k->relasi_tabel)->selectRaw($k->relasi_kolom_label . ' as label, ' . $k->relasi_kolom_id . ' as value')->whereNull('deleted_at')->limit(10000); } $relasi['options'] = $options_kolom->get(); $relasi['sql'] = $options_kolom->toSql(); @@ -404,7 +405,12 @@ class ValueBasisDataController extends Controller 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'); + $modelClass = Arr::get($this->tableModelClassMap, 'master_desa_kelurahan'); + if ($modelClass) { + $options_kolom = $modelClass::select($k->relasi_kolom_label . ' as label', $k->relasi_kolom_id . ' as value')->limit(10000); + } else { + $options_kolom = DB::table($k->relasi_tabel)->selectRaw($k->relasi_kolom_label . ' as label, ' . $k->relasi_kolom_id . ' as value')->whereNull('deleted_at')->limit(10000); + } $relasi['options'] = $options_kolom->get(); $relasi['sql'] = $options_kolom->toSql(); } catch (\Throwable $th) { diff --git a/app/Http/Resources/Ekosistem/FormBasisDataResource.php b/app/Http/Resources/Ekosistem/FormBasisDataResource.php new file mode 100644 index 0000000..9b64112 --- /dev/null +++ b/app/Http/Resources/Ekosistem/FormBasisDataResource.php @@ -0,0 +1,32 @@ + + */ + public function toArray(Request $request): array + { + return [ + 'id' => $this->id, + 'tabel_id' => $this->tabel_id, + 'parent_id' => $this->parent_id, + 'tipe' => $this->tipe, + 'column_width' => $this->column_width, + 'kolom_id' => $this->kolom_id, + 'section_label' => $this->section_label, + 'urutan' => $this->urutan, + 'kolom' => new KolomBasisDataResource($this->whenLoaded('kolom')), + 'form' => FormBasisDataResource::collection($this->whenLoaded('form')), + ]; + } +} diff --git a/app/Http/Resources/Ekosistem/TabelBasisDataResource.php b/app/Http/Resources/Ekosistem/TabelBasisDataResource.php index 2b2feb6..5b4de9e 100644 --- a/app/Http/Resources/Ekosistem/TabelBasisDataResource.php +++ b/app/Http/Resources/Ekosistem/TabelBasisDataResource.php @@ -29,6 +29,7 @@ class TabelBasisDataResource extends JsonResource // 'group' => new GroupBasisDataResource($this->whenLoaded('group')), 'kolom' => KolomBasisDataResource::collection($this->whenLoaded('kolom')), //'ringkasan' => RingkasanBasisDataResource::collection($this->whenLoaded('ringkasan')), + 'form' => FormBasisDataResource::collection($this->whenLoaded('form')), ]; } } diff --git a/app/Models/Wilayah/DesaKelurahan.php b/app/Models/Wilayah/DesaKelurahan.php index ac8beef..123a402 100644 --- a/app/Models/Wilayah/DesaKelurahan.php +++ b/app/Models/Wilayah/DesaKelurahan.php @@ -1,6 +1,6 @@ Date: Thu, 28 May 2026 09:59:36 +0700 Subject: [PATCH 26/46] realisasi verifikasi --- .../Web/Program/RealisasiController.php | 2 +- .../Web/Program/VerifikasiController.php | 25 +++- resources/views/layout/sidebar.blade.php | 55 ++++---- .../realisasi/index-aktivitas.blade.php | 12 +- .../program/realisasi/index-tujuan.blade.php | 11 ++ .../views/program/realisasi/index.blade.php | 1 + .../views/program/verifikasi/list.blade.php | 117 ++++++++++++++++++ routes/web.php | 2 +- 8 files changed, 193 insertions(+), 32 deletions(-) create mode 100644 resources/views/program/verifikasi/list.blade.php diff --git a/app/Http/Controllers/Web/Program/RealisasiController.php b/app/Http/Controllers/Web/Program/RealisasiController.php index 25eed7d..697ccde 100644 --- a/app/Http/Controllers/Web/Program/RealisasiController.php +++ b/app/Http/Controllers/Web/Program/RealisasiController.php @@ -64,7 +64,7 @@ class RealisasiController extends Controller abort(403); } - $realisasi = Realisasi::with('target', 'target.aktivitas', 'target.aktivitas.transformasi') + $realisasi = Realisasi::with('target', 'target.aktivitas', 'target.aktivitas.transformasi', 'verifikasi') ->find($id); if (!$realisasi) { return response()->json([ diff --git a/app/Http/Controllers/Web/Program/VerifikasiController.php b/app/Http/Controllers/Web/Program/VerifikasiController.php index 0e52d7e..932da21 100644 --- a/app/Http/Controllers/Web/Program/VerifikasiController.php +++ b/app/Http/Controllers/Web/Program/VerifikasiController.php @@ -17,9 +17,9 @@ class VerifikasiController extends Controller /** * Display a listing of the resource. */ - public function index() + public function index(Request $request): JsonResponse { - // + } /** @@ -83,8 +83,25 @@ class VerifikasiController extends Controller /** * Remove the specified resource from storage. */ - public function destroy(string $id) + public function destroy(string $id): JsonResponse { - // + if (!Gate::any(['super_admin', 'admin'])) { + abort(403); + } + + $verifikasi = Verifikasi::find($id); + if (!$verifikasi) { + return response()->json([ + 'status' => 'error', + 'message' => 'Data verifikasi tidak ditemukan.' + ], 404); + } + + $verifikasi->update(['updated_by' => auth()->id()]); + $verifikasi->delete(); + return response()->json([ + 'status' => 'success', + 'message' => 'Dokumen bukti berhasil dihapus.' + ]); } } diff --git a/resources/views/layout/sidebar.blade.php b/resources/views/layout/sidebar.blade.php index 1e8bf4b..4ec5d33 100644 --- a/resources/views/layout/sidebar.blade.php +++ b/resources/views/layout/sidebar.blade.php @@ -144,11 +144,18 @@ --> -
diff --git a/resources/views/program/realisasi/index-tujuan.blade.php b/resources/views/program/realisasi/index-tujuan.blade.php index 0768930..343639d 100644 --- a/resources/views/program/realisasi/index-tujuan.blade.php +++ b/resources/views/program/realisasi/index-tujuan.blade.php @@ -91,6 +91,17 @@ data-bs-toggle="tooltip" data-bs-placement="top" data-bs-original-title="Tambah Dokumen Verifikasi"> + @if($target->latestRealisasi && $target->latestRealisasi->verifikasi->count() > 0) + + + + @endif @endif
diff --git a/resources/views/program/realisasi/index.blade.php b/resources/views/program/realisasi/index.blade.php index 0d4bdd0..697bf43 100644 --- a/resources/views/program/realisasi/index.blade.php +++ b/resources/views/program/realisasi/index.blade.php @@ -77,6 +77,7 @@ @include('program.realisasi.list') @include('program.realisasi.edit') @include('program.verifikasi.add') +@include('program.verifikasi.list') @endsection @push('scripts') diff --git a/resources/views/program/verifikasi/list.blade.php b/resources/views/program/verifikasi/list.blade.php new file mode 100644 index 0000000..b8ef1cf --- /dev/null +++ b/resources/views/program/verifikasi/list.blade.php @@ -0,0 +1,117 @@ +
+
+
Daftar Dokumen Verifikasi
+ +
+
+
+ + + + + + +
+ + +
+ + + + + + + + + + +
DokumenAksi
+ + +
+
+
+ +@push('scripts') + +@endpush \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index ea137e3..743d332 100644 --- a/routes/web.php +++ b/routes/web.php @@ -139,5 +139,5 @@ Route::middleware('auth') 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'); + Route::resource('verifikasi', App\Http\Controllers\Web\Program\VerifikasiController::class)->only('store', 'destroy'); }); \ No newline at end of file From fd42bf37fe7ce9c8644b7e5b112beb08136b259e Mon Sep 17 00:00:00 2001 From: Irwan Cahyono Date: Thu, 28 May 2026 10:50:29 +0700 Subject: [PATCH 27/46] realisasi float dan boolean --- .../Controllers/Web/ProgramController.php | 6 +- .../framework/view-aktivitas.blade.php | 2 +- .../program/framework/view.blade copy.php | 296 ------------------ .../views/program/realisasi/add.blade.php | 43 +-- 4 files changed, 21 insertions(+), 326 deletions(-) delete mode 100644 resources/views/program/framework/view.blade copy.php diff --git a/app/Http/Controllers/Web/ProgramController.php b/app/Http/Controllers/Web/ProgramController.php index e429e4e..a6239d6 100644 --- a/app/Http/Controllers/Web/ProgramController.php +++ b/app/Http/Controllers/Web/ProgramController.php @@ -94,6 +94,8 @@ class ProgramController extends Controller $validator = Validator::make($request->all(), [ 'nama' => ['required'], 'sub_domain' => ['required', Rule::unique(Program::class, 'sub_domain')->ignore($id)], + 'tahun' => ['required', 'integer'], + 'instansi' => ['nullable', 'string'], ]); if ($validator->fails()) { @@ -106,9 +108,7 @@ class ProgramController extends Controller return redirect()->route('program.index')->with('error', 'Data program tidak ditemukan!'); } - $program->update([ - 'nama' => $request->nama, - 'sub_domain' => $request->sub_domain, + $program->update([...$validator->validated(), 'updated_by' => auth()->id(), ]); diff --git a/resources/views/program/framework/view-aktivitas.blade.php b/resources/views/program/framework/view-aktivitas.blade.php index a8afbef..b8a952d 100644 --- a/resources/views/program/framework/view-aktivitas.blade.php +++ b/resources/views/program/framework/view-aktivitas.blade.php @@ -35,7 +35,7 @@ Edit Aktivitas Hapus Aktivitas
- Tambah Target + Tambah Target Edit Target Hapus Target
diff --git a/resources/views/program/framework/view.blade copy.php b/resources/views/program/framework/view.blade copy.php deleted file mode 100644 index ee5ff29..0000000 --- a/resources/views/program/framework/view.blade copy.php +++ /dev/null @@ -1,296 +0,0 @@ -@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/realisasi/add.blade.php b/resources/views/program/realisasi/add.blade.php index a1c2772..eb64800 100644 --- a/resources/views/program/realisasi/add.blade.php +++ b/resources/views/program/realisasi/add.blade.php @@ -25,33 +25,20 @@
- + - - + +
- + - - +
- +