383 lines
15 KiB
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'));
|
|
}
|
|
}
|
|
|