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 = $this->validateFormPayload($request, $tabelId); 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 = $this->validateFormPayload($request, $tabelId, $form); $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); } private function validateFormPayload(Request $request, string $tabelId, ?FormBasisData $form = null): array { $tipe = $request->input('tipe'); $needsParent = in_array($tipe, [LayoutForm::COLUMN->value, LayoutForm::VALUE->value], true); $mustBeRoot = in_array($tipe, [LayoutForm::ROW->value, LayoutForm::SECTION->value, LayoutForm::HR_LINE->value], true); $validator = Validator::make($request->all(), [ 'parent_id' => [ Rule::requiredIf($needsParent), Rule::prohibitedIf($mustBeRoot), 'nullable', Rule::exists('ekosistem_basis_data_form', 'id') ->where(fn ($query) => $query ->where('tabel_id', $tabelId) ->whereNull('deleted_at')), ], 'tipe' => ['required', Rule::enum(LayoutForm::class)], 'column_width' => [ Rule::requiredIf($tipe === LayoutForm::COLUMN->value), 'nullable', 'integer', 'min:1', 'max:12' ], 'kolom_id' => [ Rule::requiredIf($tipe === LayoutForm::VALUE->value), 'nullable', Rule::exists('ekosistem_basis_data_kolom', 'id') ->where(fn ($query) => $query ->where('tabel_id', $tabelId) ->whereNull('deleted_at')), ], 'section_label' => [ Rule::requiredIf($tipe === LayoutForm::SECTION->value), 'nullable', 'string' ], ]); $validator->after(function ($validator) use ($request, $tabelId, $form) { if ($validator->errors()->isNotEmpty() || !$request->filled('parent_id')) { return; } if ($form && (int) $request->input('parent_id') === (int) $form->id) { $validator->errors()->add('parent_id', 'Induk formulir tidak boleh menunjuk ke dirinya sendiri.'); return; } $layout = LayoutForm::from($request->input('tipe')); $expectedParent = match ($layout) { LayoutForm::COLUMN => LayoutForm::ROW, LayoutForm::VALUE => LayoutForm::COLUMN, default => null, }; if (!$expectedParent) { return; } $parent = FormBasisData::where('tabel_id', $tabelId)->find($request->input('parent_id')); if (!$parent || $parent->tipe !== $expectedParent) { $validator->errors()->add('parent_id', 'Induk formulir tidak sesuai dengan tipe formulir.'); } }); $validated = $validator->validate(); $layout = LayoutForm::from($validated['tipe']); if (in_array($layout, [LayoutForm::ROW, LayoutForm::SECTION, LayoutForm::HR_LINE], true)) { $validated['parent_id'] = null; } if ($layout !== LayoutForm::COLUMN) { $validated['column_width'] = null; } if ($layout !== LayoutForm::VALUE) { $validated['kolom_id'] = null; } if ($layout !== LayoutForm::SECTION) { $validated['section_label'] = null; } return $validated; } }