TIF_Nganjuk_E41220879/app/Http/Controllers/ResepController.php

383 lines
15 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Models\Resep;
use App\Models\ResepItem;
use App\Models\ObatMasuk;
use App\Models\ObatKeluar;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class ResepController extends Controller
{
/**
* Display a listing of the prescriptions.
*/
public function index(Request $request)
{
$query = Resep::with(['user', 'items']);
// Search
if ($request->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'));
}
}