getClientOriginalExtension(); $file->move(public_path('storage/' . $folder), $filename); return $folder . '/' . $filename; } private function deletePhoto($path) { $fullPath = public_path('storage/' . $path); if (file_exists($fullPath)) { unlink($fullPath); } } public function index() { $diseases = Disease::with(['symptoms','treatments'])->get(); return view('diseases.index', compact('diseases')); } public function create() { $nextDiseaseCode = 'P' . str_pad(Disease::count() + 1, 2, '0', STR_PAD_LEFT); $nextSymptomCode = 'G' . str_pad(Symptom::count() + 1, 2, '0', STR_PAD_LEFT); $nextTreatmentCode = 'S' . str_pad(Treatment::count() + 1, 2, '0', STR_PAD_LEFT); return view('diseases.create', compact( 'nextDiseaseCode', 'nextSymptomCode', 'nextTreatmentCode' )); } public function edit(Disease $disease) { $disease->load(['symptoms','treatments']); return view('diseases.create', [ 'disease' => $disease, 'isEdit' => true, 'nextDiseaseCode' => $disease->code, ]); } public function update(Request $request, Disease $disease) { $request->validate([ 'name' => 'required|string|max:255', 'latin_name' => 'nullable|string|max:255', 'description' => 'nullable|string', ]); DB::transaction(function () use ($request, $disease) { $disease->update([ 'name' => $request->name, 'latin_name' => $request->latin_name, 'description' => $request->description, ]); // Handle foto penyakit if ($request->hasFile('photo')) { if ($disease->photo) { $this->deletePhoto($disease->photo); } $disease->update(['photo' => $this->savePhoto($request->file('photo'), 'diseases')]); } // RESET RELASI $disease->symptoms()->detach(); $disease->treatments()->delete(); // SYMPTOMS foreach ($request->symptoms as $i => $s) { if (empty($s['name'])) continue; $symptomPhoto = null; if (isset($s['photo']) && $s['photo'] instanceof \Illuminate\Http\UploadedFile) { $symptomPhoto = $this->savePhoto($s['photo'], 'symptoms'); } $symptom = Symptom::where('name', $s['name'])->first(); if (!$symptom) { $symptom = Symptom::create([ 'code' => 'G' . str_pad(Symptom::count() + 1, 2, '0', STR_PAD_LEFT), 'name' => $s['name'], 'photo' => $symptomPhoto, ]); } $disease->symptoms()->attach($symptom->id, ['cf_value' => $s['cf'] ?? 0.7]); } // TREATMENTS $maxRow = DB::select('SELECT MAX(CAST(SUBSTRING(code, 2) AS UNSIGNED)) as maxnum FROM treatments')[0]; $lastNum = $maxRow->maxnum ?? 0; foreach ($request->treatments as $i => $t) { if (!isset($t['description']) || trim($t['description']) === '') continue; $lastNum++; DB::table('treatments')->insert([ 'code' => 'S' . str_pad($lastNum, 2, '0', STR_PAD_LEFT), 'disease_id' => $disease->id, 'description' => trim($t['description']), 'order' => $i + 1, 'created_at' => now(), 'updated_at' => now(), ]); } }); return redirect()->route('diseases.show', $disease->id) ->with('status', 'Penyakit berhasil diupdate!'); } public function store(Request $request) { $request->validate([ 'name' => 'required|string|max:255', 'latin_name' => 'nullable|string|max:255', 'description' => 'nullable|string', 'photo' => 'nullable|image|mimes:jpg,jpeg,png|max:3072', 'symptoms' => 'required|array|min:3', 'symptoms.*.name' => 'required|string', 'treatments' => 'required|array|min:3', 'treatments.*.description' => 'nullable|string', ]); $disease = DB::transaction(function () use ($request) { $photoPath = null; if ($request->hasFile('photo')) { $photoPath = $this->savePhoto($request->file('photo'), 'diseases'); } $disease = Disease::create([ 'code' => 'P' . str_pad(Disease::count() + 1, 2, '0', STR_PAD_LEFT), 'name' => $request->name, 'latin_name' => $request->latin_name, 'description' => $request->description, 'photo' => $photoPath, ]); // SYMPTOMS foreach ($request->symptoms as $s) { if (empty($s['name'])) continue; $symptomPhoto = null; if (isset($s['photo']) && $s['photo'] instanceof \Illuminate\Http\UploadedFile) { $symptomPhoto = $this->savePhoto($s['photo'], 'symptoms'); } $symptom = Symptom::where('name', $s['name'])->first(); if (!$symptom) { $symptom = Symptom::create([ 'code' => 'G' . str_pad(Symptom::count() + 1, 2, '0', STR_PAD_LEFT), 'name' => $s['name'], 'photo' => $symptomPhoto, ]); } $disease->symptoms()->attach( $symptom->id, ['cf_value' => $s['cf'] ?? 0.7] ); } // TREATMENTS if ($request->has('treatments')) { $maxRow = DB::select('SELECT MAX(CAST(SUBSTRING(code, 2) AS UNSIGNED)) as maxnum FROM treatments')[0]; $lastNum = $maxRow->maxnum ?? 0; foreach ($request->treatments as $i => $t) { if (!isset($t['description']) || trim($t['description']) === '') continue; $lastNum++; DB::table('treatments')->insert([ 'code' => 'S' . str_pad($lastNum, 2, '0', STR_PAD_LEFT), 'disease_id' => $disease->id, 'description' => trim($t['description']), 'order' => $i + 1, 'created_at' => now(), 'updated_at' => now(), ]); } } return $disease; }); Notification::create([ 'user_id' => auth()->id(), 'type' => 'system', 'title' => 'Penyakit Baru Ditambahkan', 'message' => "Penyakit \"{$disease->name}\" ({$disease->code}) berhasil ditambahkan dengan " . $disease->symptoms()->count() . " gejala.", 'is_read' => false, ]); return redirect()->route('diseases.index') ->with('status', 'Penyakit berhasil ditambahkan!'); } public function show(Disease $disease) { $disease->load(['symptoms','treatments']); return view('diseases.show', compact('disease')); } public function destroy(Disease $disease) { $diseaseName = $disease->name; $diseaseCode = $disease->code; DB::transaction(function () use ($disease) { if ($disease->photo) { $this->deletePhoto($disease->photo); } foreach ($disease->symptoms as $symptom) { $usedByOthers = $symptom->diseases() ->where('diseases.id', '!=', $disease->id) ->exists(); if (!$usedByOthers) { if ($symptom->photo) { $this->deletePhoto($symptom->photo); } $symptom->delete(); } } $disease->symptoms()->detach(); $disease->treatments()->delete(); $disease->delete(); }); Notification::create([ 'user_id' => auth()->id(), 'type' => 'system', 'title' => 'Penyakit Dihapus', 'message' => "Penyakit \"{$diseaseName}\" ({$diseaseCode}) telah dihapus.", 'is_read' => false, ]); return redirect()->route('diseases.index') ->with('status', 'Penyakit berhasil dihapus!'); } }