diff --git a/app/Http/Controllers/Web/Ekosistem/KolomBasisDataController.php b/app/Http/Controllers/Web/Ekosistem/KolomBasisDataController.php index 0a55575..9c76681 100644 --- a/app/Http/Controllers/Web/Ekosistem/KolomBasisDataController.php +++ b/app/Http/Controllers/Web/Ekosistem/KolomBasisDataController.php @@ -125,7 +125,6 @@ class KolomBasisDataController extends Controller ]); $kolom->update([...$validated, - 'created_by' => auth()->id(), 'updated_by' => auth()->id(), ]); diff --git a/app/Http/Controllers/Web/Ekosistem/RingkasanBasisDataController.php b/app/Http/Controllers/Web/Ekosistem/RingkasanBasisDataController.php new file mode 100644 index 0000000..16f5001 --- /dev/null +++ b/app/Http/Controllers/Web/Ekosistem/RingkasanBasisDataController.php @@ -0,0 +1,191 @@ +json([ + 'status' => 'error', + 'message' => 'Data tabel tidak ditemukan.' + ], 404); + } + + $validated = $request->validate([ + 'heading' => ['required', 'string'], + 'subheading' => ['required', 'string'], + 'query_ringkasan' => ['required', 'string', new ValidSql()], + ]); + + RingkasanBasisData::create([ + 'tabel_id' => $tabelId, + 'heading' => $validated['heading'], + 'subheading' => $validated['subheading'], + 'query_ringkasan' => $validated['query_ringkasan'], + ]); + + return response()->json([ + 'status' => 'success', + 'message' => 'Ringkasan basis data berhasil ditambahkan.' + ], 201); + } + + public function show(string $tabelId, string $id): JsonResponse + { + Gate::authorize('super_admin'); + + $ringkasan = RingkasanBasisData::where('tabel_id', $tabelId)->find($id); + if (!$ringkasan) { + return response()->json([ + 'status' => 'error', + 'message' => 'Data ringkasan tidak ditemukan.' + ], 404); + } + + return response()->json(['data' => $ringkasan, 'status' => 'success']); + } + + public function edit(string $id) + { + // + } + + public function update(Request $request, string $id) + { + Gate::authorize('super_admin'); + + $ringkasan = RingkasanBasisData::find($id); + if (!$ringkasan) { + return response()->json([ + 'status' => 'error', + 'message' => 'Data ringkasan tidak ditemukan.' + ], 404); + } + + $validated = $request->validate([ + 'heading' => ['required', 'string'], + 'subheading' => ['required', 'string'], + 'query_ringkasan' => ['required', 'string', new ValidSql()], + ]); + + $ringkasan->update([...$validated, + 'updated_by' => auth()->id(), + ]); + + return response()->json([ + 'status' => 'success', + 'message' => 'Ringkasan basis data berhasil diperbarui.' + ], 200); + } + + public function destroy(string $id) + { + Gate::authorize('super_admin'); + + $ringkasan = RingkasanBasisData::find($id); + if (!$ringkasan) { + return response()->json([ + 'status' => 'error', + 'message' => 'Data ringkasan tidak ditemukan.' + ], 404); + } + + $ringkasan->update([ + 'deleted_by' => auth()->id(), + ]); + $ringkasan->delete(); + + return response()->json([ + 'status' => 'success', + 'message' => 'Ringkasan basis data berhasil dihapus.' + ], 200); + } + + public function moveUp(Request $request, string $tabelId, string $id): JsonResponse + { + Gate::authorize('super_admin'); + + $current = RingkasanBasisData::where('tabel_id', $tabelId)->find($id); + if (!$current) { + return response()->json([ + 'status' => 'error', + 'message' => 'Data ringkasan tidak ditemukan.' + ], 404); + } + + $prev = RingkasanBasisData::where('tabel_id', $current->tabel_id) + ->where('urutan', '<', $current->urutan) + ->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' => 'Ringkasan basis data berhasil diperbarui.' + ], 200); + } + + public function moveDown(Request $request, string $tabelId, string $id): JsonResponse + { + Gate::authorize('super_admin'); + + $current = RingkasanBasisData::where('tabel_id', $tabelId)->find($id); + if (!$current) { + return response()->json([ + 'status' => 'error', + 'message' => 'Data ringkasan tidak ditemukan.' + ], 404); + } + + $next = RingkasanBasisData::where('tabel_id', $current->tabel_id) + ->where('urutan', '>', $current->urutan) + ->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' => 'Ringkasan basis data berhasil diperbarui.' + ], 200); + } +} diff --git a/app/Http/Controllers/Web/Ekosistem/ValueBasisDataController.php b/app/Http/Controllers/Web/Ekosistem/ValueBasisDataController.php index a1f832a..07510f2 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\DB; use App\Models\Ekosistem\TabelBasisData; use App\Models\Ekosistem\KolomBasisData; use App\Models\Ekosistem\ValueBasisData; +use App\Models\Ekosistem\RingkasanBasisData; use App\Models\Core\Program; class ValueBasisDataController extends Controller @@ -53,29 +54,47 @@ class ValueBasisDataController extends Controller $selects = []; foreach ($kolom as $k) { - $selects[] = " - MAX( - CASE - WHEN kolom_id = {$k->id} - THEN value_{$k->tipe} - ELSE NULL - END - ) AS \"{$k->kolom}\" - "; + 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}\" + "; + } 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(" - program_id, + core_program.id AS program_id, + core_program.nama AS program_nama, tabel_id, value_id, " . implode(",\n", $selects) . " ") - ->groupBy('program_id', 'tabel_id', 'value_id') + ->groupBy('core_program.id', 'core_program.nama', 'tabel_id', 'value_id') ->orderBy('value_id', 'asc'); $values = DB::query()->fromSub($base, 'pivot') @@ -90,7 +109,23 @@ class ValueBasisDataController extends Controller }) ->paginate($perPage); - return view('ekosistem.value-basis-data.index', compact('programList', 'program', 'tabel', 'kolom', 'values')); + $ringkasan = RingkasanBasisData::where('tabel_id', $tabelId)->get(); + $baseSql = $base->toSql(); + if ($ringkasan->isNotEmpty()) { + foreach ($ringkasan as $r) { + $q = str_replace($tabel->tabel, "(" . $baseSql . ") as " . $tabel->tabel, $r->query_ringkasan); + $result_q = DB::select($q, $base->getBindings()); + if (!empty($result_q)) { + $row = (array) $result_q[0]; // object → array + $r->nilai = array_values($row)[0] ?? 0; // ambil value pertama + } else { + $r->nilai = 0; + } + $r->hasil_ringkasan = $result_q; + } + } + + return view('ekosistem.value-basis-data.index', compact('programList', 'program', 'tabel', 'kolom', 'values', 'ringkasan')); } /** @@ -117,13 +152,11 @@ class ValueBasisDataController extends Controller 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.'); } } + if (!$program) { + abort(400, 'Program tidak ditemukan.'); + } return view('ekosistem.value-basis-data.add', compact('tabel', 'kolom', 'program')); } @@ -188,7 +221,7 @@ class ValueBasisDataController extends Controller } }); - return redirect()->route('tabel.data.index', [$tabelId, 'program' => $program->id])->with('success', 'Data berhasil ditambahkan.'); + return redirect()->route('tabel.data.index', [$tabelId, 'program_id' => $program->id])->with('success', 'Data berhasil ditambahkan.'); } /** @@ -296,16 +329,40 @@ class ValueBasisDataController extends Controller $validated = $request->validate($validationRules); DB::transaction(function () use ($program, $tabelId, $validated, $kolom, $id, $values) { - foreach ($values as $v) { - $k = $kolom->where('id', $v->kolom_id)->first(); - $v->update([ - 'value_' . $k->tipe => $validated[$k->kolom] ?? null, - 'updated_by' => auth()->id(), - ]); + 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(), + ]; + $vals['value_' . $k->tipe] = $validated[$k->kolom] ?? null; + ValueBasisData::create($vals); + } else { + $v->update([ + 'value_' . $k->tipe => $val, + 'updated_by' => auth()->id(), + ]); + } } + // foreach ($values as $v) { + // $k = $kolom->where('id', $v->kolom_id)->first(); + // $v->update([ + // 'value_' . $k->tipe => $validated[$k->kolom] ?? null, + // 'updated_by' => auth()->id(), + // ]); + // } }); - return redirect()->route('tabel.data.index', [$tabelId, 'program' => $program->id])->with('success', 'Data berhasil diperbarui.'); + return redirect()->route('tabel.data.index', [$tabelId, 'program_id' => $program->id])->with('success', 'Data berhasil diperbarui.'); } /** @@ -354,6 +411,6 @@ class ValueBasisDataController extends Controller ->where('program_id', $program->id) ->delete(); - return redirect()->route('tabel.data.index', [$tabelId, 'program' => $program->id])->with('success', 'Data berhasil dihapus.'); + return redirect()->route('tabel.data.index', [$tabelId, 'program_id' => $program->id])->with('success', 'Data berhasil dihapus.'); } } diff --git a/app/Http/Controllers/Web/SummaryDashboardController copy.php b/app/Http/Controllers/Web/SummaryDashboardController copy.php new file mode 100644 index 0000000..e5e20b2 --- /dev/null +++ b/app/Http/Controllers/Web/SummaryDashboardController copy.php @@ -0,0 +1,19 @@ +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'); + } +} diff --git a/app/Models/Ekosistem/TabelBasisData.php b/app/Models/Ekosistem/TabelBasisData.php index 9eb67b1..b238269 100644 --- a/app/Models/Ekosistem/TabelBasisData.php +++ b/app/Models/Ekosistem/TabelBasisData.php @@ -9,6 +9,8 @@ use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Relations\BelongsTo; use App\Models\Ekosistem\KolomBasisData; +use App\Models\Ekosistem\GroupBasisData; +use App\Models\Ekosistem\RingkasanBasisData; class TabelBasisData extends Model { @@ -46,4 +48,9 @@ class TabelBasisData extends Model { return $this->belongsTo(GroupBasisData::class, 'group_id'); } + + public function ringkasan(): HasMany + { + return $this->hasMany(RingkasanBasisData::class, 'tabel_id')->orderBy('urutan'); + } } diff --git a/app/Models/Ekosistem/ValueBasisData.php b/app/Models/Ekosistem/ValueBasisData.php index feee72c..33075c1 100644 --- a/app/Models/Ekosistem/ValueBasisData.php +++ b/app/Models/Ekosistem/ValueBasisData.php @@ -27,6 +27,9 @@ class ValueBasisData extends Model 'value_date', 'value_datetime', 'value_text', + 'created_by', + 'updated_by', + 'deleted_by', ]; public function tabel(): BelongsTo diff --git a/app/Rules/ValidSql.php b/app/Rules/ValidSql.php new file mode 100644 index 0000000..bf01db8 --- /dev/null +++ b/app/Rules/ValidSql.php @@ -0,0 +1,62 @@ +getMessage()); + // } + } +} diff --git a/database/migrations/2026_05_04_092152_create_ringkasan_basis_data_table.php b/database/migrations/2026_05_04_092152_create_ringkasan_basis_data_table.php new file mode 100644 index 0000000..f52ff1f --- /dev/null +++ b/database/migrations/2026_05_04_092152_create_ringkasan_basis_data_table.php @@ -0,0 +1,40 @@ +id(); + + $table->foreignId('tabel_id')->constrained('ekosistem_basis_data_tabel')->restrictOnDelete(); + + $table->string('heading'); + $table->string('subheading'); + $table->text('query_ringkasan'); + $table->integer('urutan')->default(0); + + $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_ringkasan'); + } +}; diff --git a/resources/views/ekosistem/petani-cpm/index.blade.php b/resources/views/ekosistem/petani-cpm/index.blade.php index 56238f2..d7e6005 100644 --- a/resources/views/ekosistem/petani-cpm/index.blade.php +++ b/resources/views/ekosistem/petani-cpm/index.blade.php @@ -2,8 +2,75 @@ @section('content')