filled('search')) { $search = $request->search; $query->where(function($q) use ($search) { $q->where('no_resep', 'like', "%{$search}%") ->orWhere('nama_pasien', 'like', "%{$search}%") ->orWhere('no_rm', 'like', "%{$search}%"); }); } // Filter by status if ($request->filled('status')) { $query->where('status', $request->status); } $reseps = $query->orderBy('tanggal_resep', 'desc')->paginate(10); return view('resep.index', compact('reseps')); } /** * Show the form for creating a new prescription. */ public function create() { // Get medicines with available stock $obats = ObatMasuk::where('stok', '>', 0) ->where('tanggal_kadaluarsa', '>=', now()) ->with('kategori', 'satuan') ->orderBy('nama_obat') ->get(); return view('resep.create', compact('obats')); } /** * Store a newly created prescription in storage. */ public function store(Request $request) { $validated = $request->validate([ // Data Resep 'nama_dokter' => 'required|string|max:100', 'no_sip' => 'nullable|string|max:50', 'tanggal_resep' => 'required|date', 'jenis_penjamin' => 'required|in:umum,BPJS Kes,BPJS Naker,Jamkesmas/KIS,R. Inap', 'jenis_layanan' => 'required|in:BP,KIA,Gigi,UGD,Lainnya', // Data Pasien 'no_rm' => 'nullable|string|max:50', 'nama_pasien' => 'required|string|max:100', 'alamat_pasien' => 'nullable|string|max:255', 'jenis_kelamin' => 'required|in:L,P', 'umur_pasien' => 'required|integer|min:0|max:150', 'berat_badan' => 'required|numeric|min:0|max:500', 'diagnosa' => 'required|string', 'catatan' => 'nullable|string', // Daftar Obat 'items' => 'required|array|min:1', 'items.*.obat_masuk_id' => 'required|exists:obat_masuks,id', 'items.*.jumlah' => 'required|integer|min:1', 'items.*.aturan_pakai' => 'nullable|string|max:255', ]); // Validate stock availability foreach ($validated['items'] as $item) { $obatMasuk = ObatMasuk::find($item['obat_masuk_id']); if ($obatMasuk->stok < $item['jumlah']) { return back()->withErrors([ 'items' => "Stok obat {$obatMasuk->nama_obat} tidak mencukupi. Tersedia: {$obatMasuk->stok}" ])->withInput(); } } DB::transaction(function () use ($validated, $request) { // Create resep with status 'proses' (not 'selesai') $resep = Resep::create([ 'no_resep' => Resep::generateNoResep(), 'user_id' => auth()->id(), 'nama_dokter' => $validated['nama_dokter'], 'no_sip' => $validated['no_sip'] ?? null, 'jenis_penjamin' => $validated['jenis_penjamin'], 'jenis_layanan' => $validated['jenis_layanan'], 'no_rm' => $validated['no_rm'] ?? null, 'nama_pasien' => $validated['nama_pasien'], 'alamat_pasien' => $validated['alamat_pasien'] ?? null, 'jenis_kelamin' => $validated['jenis_kelamin'], 'umur_pasien' => $validated['umur_pasien'], 'berat_badan' => $validated['berat_badan'], 'tanggal_resep' => $validated['tanggal_resep'], 'diagnosa' => $validated['diagnosa'], 'catatan' => $validated['catatan'] ?? null, 'status' => 'proses', // Changed from 'selesai' to 'proses' 'is_read' => false, ]); // Create resep items and reduce stock foreach ($validated['items'] as $item) { $obatMasuk = ObatMasuk::find($item['obat_masuk_id']); // Create resep item ResepItem::create([ 'resep_id' => $resep->id, 'obat_masuk_id' => $item['obat_masuk_id'], 'nama_obat' => $obatMasuk->nama_obat, 'jumlah' => $item['jumlah'], 'aturan_pakai' => $item['aturan_pakai'] ?? null, ]); // Create obat keluar record with status 'proses' ObatKeluar::create([ 'obat_masuk_id' => $item['obat_masuk_id'], 'nama_obat' => $obatMasuk->nama_obat, 'sumber_dana' => $obatMasuk->sumber_dana, 'user_id' => auth()->id(), 'kode_batch' => $obatMasuk->kode_batch, 'barcode' => $obatMasuk->barcode, 'jumlah' => $item['jumlah'], 'tujuan_pemakaian' => 'Resep: ' . $resep->no_resep . ' - ' . $validated['nama_pasien'], 'tanggal_pengeluaran' => $validated['tanggal_resep'], 'tanggal_kadaluarsa' => $obatMasuk->tanggal_kadaluarsa, 'no_pengeluaran' => $resep->no_resep, 'nama_petugas' => auth()->user()->name, 'nama_penerima' => $validated['nama_pasien'], 'catatan' => 'Otomatis dari resep ' . $resep->no_resep, 'status' => 'proses', // Changed from 'terkirim' to 'proses' ]); // Do NOT reduce stock here because status is 'proses' } }); return redirect()->route('resep.index')->with('success', 'Resep berhasil dibuat.'); } /** * Display the specified prescription. */ public function show(Resep $resep) { $resep->load(['user', 'items.obatMasuk.satuan']); // Mark as read if apoteker is viewing if (auth()->user()->isApoteker()) { $resep->markAsRead(); } return view('resep.show', compact('resep')); } /** * Show the form for editing the specified prescription. */ public function edit(Resep $resep) { // Resep yang sudah selesai tidak bisa diedit if ($resep->status === 'selesai') { return redirect()->route('resep.show', $resep) ->with('error', 'Resep dengan status selesai tidak dapat diedit.'); } $resep->load(['items']); $obats = ObatMasuk::where(function ($q) { $q->where('stok', '>', 0) ->where('tanggal_kadaluarsa', '>=', now()); }) ->orWhereIn('id', $resep->items->pluck('obat_masuk_id')) ->with('kategori', 'satuan') ->orderBy('nama_obat') ->get(); return view('resep.edit', compact('resep', 'obats')); } /** * Update the specified prescription in storage. */ public function update(Request $request, Resep $resep) { // Resep yang sudah selesai tidak bisa diubah if ($resep->status === 'selesai') { return redirect()->route('resep.show', $resep) ->with('error', 'Resep dengan status selesai tidak dapat diedit.'); } $validated = $request->validate([ // Data Resep 'nama_dokter' => 'required|string|max:100', 'no_sip' => 'nullable|string|max:50', 'tanggal_resep' => 'required|date', 'jenis_penjamin' => 'required|in:umum,BPJS Kes,BPJS Naker,Jamkesmas/KIS,R. Inap', 'jenis_layanan' => 'required|in:BP,KIA,Gigi,UGD,Lainnya', // Data Pasien 'no_rm' => 'nullable|string|max:50', 'nama_pasien' => 'required|string|max:100', 'alamat_pasien' => 'nullable|string|max:255', 'jenis_kelamin' => 'required|in:L,P', 'umur_pasien' => 'required|integer|min:0|max:150', 'berat_badan' => 'required|numeric|min:0|max:500', 'diagnosa' => 'required|string', 'catatan' => 'nullable|string', 'status' => 'required|in:proses,selesai,dibatalkan', // Daftar Obat 'items' => 'required|array|min:1', 'items.*.obat_masuk_id' => 'required|exists:obat_masuks,id', 'items.*.jumlah' => 'required|integer|min:1', 'items.*.aturan_pakai' => 'nullable|string|max:255', ]); DB::transaction(function () use ($validated, $resep) { // Restore old stock first (only if status was selesai, but update is not allowed for selesai) foreach ($resep->items as $oldItem) { // Delete related obat keluar ObatKeluar::where('no_pengeluaran', $resep->no_resep) ->where('obat_masuk_id', $oldItem->obat_masuk_id) ->delete(); } // Delete old items $resep->items()->delete(); // Validate new stock foreach ($validated['items'] as $item) { $obatMasuk = ObatMasuk::find($item['obat_masuk_id']); if ($obatMasuk->stok < $item['jumlah']) { throw new \Exception("Stok obat {$obatMasuk->nama_obat} tidak mencukupi. Tersedia: {$obatMasuk->stok}"); } } // Update resep $resep->update([ 'nama_dokter' => $validated['nama_dokter'], 'no_sip' => $validated['no_sip'] ?? null, 'jenis_penjamin' => $validated['jenis_penjamin'], 'jenis_layanan' => $validated['jenis_layanan'], 'no_rm' => $validated['no_rm'] ?? null, 'nama_pasien' => $validated['nama_pasien'], 'alamat_pasien' => $validated['alamat_pasien'] ?? null, 'jenis_kelamin' => $validated['jenis_kelamin'], 'umur_pasien' => $validated['umur_pasien'], 'berat_badan' => $validated['berat_badan'], 'tanggal_resep' => $validated['tanggal_resep'], 'diagnosa' => $validated['diagnosa'], 'catatan' => $validated['catatan'] ?? null, 'status' => $validated['status'], ]); // Create new items and reduce stock foreach ($validated['items'] as $item) { $obatMasuk = ObatMasuk::find($item['obat_masuk_id']); // Create resep item ResepItem::create([ 'resep_id' => $resep->id, 'obat_masuk_id' => $item['obat_masuk_id'], 'nama_obat' => $obatMasuk->nama_obat, 'jumlah' => $item['jumlah'], 'aturan_pakai' => $item['aturan_pakai'] ?? null, ]); // Create obat keluar record ObatKeluar::create([ 'obat_masuk_id' => $item['obat_masuk_id'], 'nama_obat' => $obatMasuk->nama_obat, 'sumber_dana' => $obatMasuk->sumber_dana, 'user_id' => auth()->id(), 'kode_batch' => $obatMasuk->kode_batch, 'barcode' => $obatMasuk->barcode, 'jumlah' => $item['jumlah'], 'tujuan_pemakaian' => 'Resep: ' . $resep->no_resep . ' - ' . $validated['nama_pasien'], 'tanggal_pengeluaran' => $validated['tanggal_resep'], 'tanggal_kadaluarsa' => $obatMasuk->tanggal_kadaluarsa, 'no_pengeluaran' => $resep->no_resep, 'nama_petugas' => auth()->user()->name, 'nama_penerima' => $validated['nama_pasien'], 'catatan' => 'Otomatis dari resep ' . $resep->no_resep, 'status' => $validated['status'] === 'selesai' ? 'selesai' : ($validated['status'] === 'dibatalkan' ? 'dibatalkan' : 'proses'), ]); // Reduce stock only if status is selesai if ($validated['status'] === 'selesai') { $obatMasuk->decrement('stok', $item['jumlah']); } } }); return redirect()->route('resep.index')->with('success', 'Resep berhasil diperbarui.'); } /** * Update the status of the specified prescription (by apoteker). */ public function updateStatus(Request $request, Resep $resep) { // Resep yang sudah selesai tidak bisa diubah statusnya if ($resep->status === 'selesai') { return redirect()->route('resep.index') ->with('error', 'Status resep yang sudah selesai tidak dapat diubah.'); } $validated = $request->validate([ 'status' => 'required|in:proses,selesai,dibatalkan', ]); DB::transaction(function () use ($validated, $resep) { $oldStatus = $resep->status; $resep->update(['status' => $validated['status']]); // Also update related obat keluar records ObatKeluar::where('no_pengeluaran', $resep->no_resep) ->update(['status' => $validated['status']]); // If changing to 'selesai', reduce stock if ($oldStatus !== 'selesai' && $validated['status'] === 'selesai') { foreach ($resep->items as $item) { if ($item->obatMasuk) { $item->obatMasuk->decrement('stok', $item->jumlah); } } } }); return redirect()->route('resep.index')->with('success', 'Status resep berhasil diperbarui.'); } /** * Remove the specified prescription from storage. */ public function destroy(Resep $resep) { DB::transaction(function () use ($resep) { // Restore stock for each item ONLY IF status was selesai if ($resep->status === 'selesai') { foreach ($resep->items as $item) { if ($item->obatMasuk) { $item->obatMasuk->increment('stok', $item->jumlah); } } } // Delete related obat keluar ObatKeluar::where('no_pengeluaran', $resep->no_resep)->delete(); // Delete resep (items will cascade) $resep->delete(); }); return redirect()->route('resep.index')->with('success', 'Resep berhasil dihapus dan stok dikembalikan.'); } /** * Print the prescription. */ public function print(Resep $resep) { $resep->load(['user', 'items.obatMasuk.satuan']); return view('resep.print', compact('resep')); } }