217 lines
7.8 KiB
PHP
217 lines
7.8 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\ObatMasuk;
|
|
use App\Models\ObatKeluar;
|
|
use App\Models\Kategori;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Carbon\Carbon;
|
|
|
|
class ObatKeluarController extends Controller
|
|
{
|
|
public function index(Request $request)
|
|
{
|
|
$query = ObatKeluar::with(['obatMasuk.kategori']);
|
|
|
|
// Search
|
|
if ($request->filled('search')) {
|
|
$search = $request->search;
|
|
$query->where(function($q) use ($search) {
|
|
$q->where('nama_obat', 'like', "%{$search}%")
|
|
->orWhere('kode_batch', 'like', "%{$search}%");
|
|
});
|
|
}
|
|
|
|
// Filter by status
|
|
if ($request->filled('status')) {
|
|
$query->where('status', $request->status);
|
|
}
|
|
|
|
$obatKeluars = $query->orderBy('tanggal_pengeluaran', 'desc')->paginate(10);
|
|
$kategoris = Kategori::all();
|
|
|
|
// Get filter month and year (default to current month)
|
|
$filterMonth = $request->get('chart_month', now()->month);
|
|
$filterYear = $request->get('chart_year', now()->year);
|
|
|
|
// Create date object for the selected month
|
|
$selectedDate = Carbon::createFromDate($filterYear, $filterMonth, 1);
|
|
|
|
// Pie chart data - Medicine trend (top 5 medicines by usage) for selected month
|
|
$medicineTrend = ObatKeluar::selectRaw('nama_obat, SUM(jumlah) as total_jumlah')
|
|
->whereMonth('tanggal_pengeluaran', $filterMonth)
|
|
->whereYear('tanggal_pengeluaran', $filterYear)
|
|
->groupBy('nama_obat')
|
|
->orderByDesc('total_jumlah')
|
|
->limit(5)
|
|
->get();
|
|
|
|
$pieLabels = $medicineTrend->pluck('nama_obat')->toArray();
|
|
$pieData = $medicineTrend->pluck('total_jumlah')->toArray();
|
|
$totalUsage = array_sum($pieData);
|
|
|
|
// Generate month options for filter (last 12 months)
|
|
$monthOptions = [];
|
|
for ($i = 0; $i < 12; $i++) {
|
|
$date = now()->subMonths($i);
|
|
$monthOptions[] = [
|
|
'value' => $date->format('Y-m'),
|
|
'label' => $date->translatedFormat('F Y'),
|
|
'month' => $date->month,
|
|
'year' => $date->year,
|
|
];
|
|
}
|
|
|
|
return view('obat-keluar.index', compact(
|
|
'obatKeluars',
|
|
'kategoris',
|
|
'pieLabels',
|
|
'pieData',
|
|
'totalUsage',
|
|
'monthOptions',
|
|
'filterMonth',
|
|
'filterYear',
|
|
'selectedDate'
|
|
));
|
|
}
|
|
|
|
public function create()
|
|
{
|
|
$kategoris = Kategori::all();
|
|
// Ambil obat dari tabel obat_masuks yang masih ada stoknya
|
|
$obats = ObatMasuk::where('stok', '>', 0)
|
|
->where('tanggal_kadaluarsa', '>=', now())
|
|
->with('kategori')
|
|
->orderBy('nama_obat')
|
|
->get();
|
|
|
|
return view('obat-keluar.create', compact('kategoris', 'obats'));
|
|
}
|
|
|
|
public function store(Request $request)
|
|
{
|
|
$validated = $request->validate([
|
|
'obat_masuk_id' => 'required|exists:obat_masuks,id',
|
|
'kode_batch' => 'required|string|max:50',
|
|
'barcode' => 'nullable|string|max:100',
|
|
'sumber_dana' => 'nullable|string|max:200',
|
|
'jumlah' => 'required|integer|min:1',
|
|
'harga' => 'nullable|numeric|min:0',
|
|
'harga_total' => 'nullable|numeric|min:0',
|
|
'tujuan_pemakaian' => 'required|string|max:200',
|
|
'tanggal_kadaluarsa' => 'required|date',
|
|
'tanggal_pengeluaran' => 'required|date',
|
|
'no_pengeluaran' => 'nullable|string|max:50',
|
|
'nama_petugas' => 'required|string|max:100',
|
|
'nama_penerima' => 'required|string|max:100',
|
|
'catatan' => 'nullable|string',
|
|
'status' => 'nullable|in:proses,selesai,dibatalkan',
|
|
]);
|
|
|
|
// Cek stok tersedia
|
|
$obatMasuk = ObatMasuk::findOrFail($validated['obat_masuk_id']);
|
|
|
|
if ($obatMasuk->stok < $validated['jumlah']) {
|
|
return back()->withErrors(['jumlah' => 'Jumlah melebihi stok yang tersedia (' . $obatMasuk->stok . ')'])->withInput();
|
|
}
|
|
|
|
DB::transaction(function () use ($validated, $obatMasuk) {
|
|
// Simpan nama obat dari obat masuk
|
|
$validated['nama_obat'] = $obatMasuk->nama_obat;
|
|
$validated['user_id'] = auth()->id();
|
|
$validated['status'] = $validated['status'] ?? 'proses';
|
|
|
|
// Buat obat keluar
|
|
ObatKeluar::create($validated);
|
|
|
|
// Kurangi stok obat masuk
|
|
$obatMasuk->decrement('stok', $validated['jumlah']);
|
|
});
|
|
|
|
return redirect()->route('obat-keluar.index')->with('success', 'Data obat keluar berhasil ditambahkan dan stok obat masuk telah dikurangi');
|
|
}
|
|
|
|
public function show(ObatKeluar $obatKeluar)
|
|
{
|
|
$obatKeluar->load(['obatMasuk.kategori', 'user']);
|
|
return view('obat-keluar.show', compact('obatKeluar'));
|
|
}
|
|
|
|
public function edit(ObatKeluar $obatKeluar)
|
|
{
|
|
$kategoris = Kategori::all();
|
|
$obats = ObatMasuk::where(function ($q) {
|
|
$q->where('stok', '>', 0)
|
|
->where('tanggal_kadaluarsa', '>=', now());
|
|
})
|
|
->orWhere('id', $obatKeluar->obat_masuk_id)
|
|
->with('kategori')
|
|
->orderBy('nama_obat')
|
|
->get();
|
|
|
|
return view('obat-keluar.edit', compact('obatKeluar', 'kategoris', 'obats'));
|
|
}
|
|
|
|
public function update(Request $request, ObatKeluar $obatKeluar)
|
|
{
|
|
$validated = $request->validate([
|
|
'obat_masuk_id' => 'required|exists:obat_masuks,id',
|
|
'kode_batch' => 'required|string|max:50',
|
|
'barcode' => 'nullable|string|max:100',
|
|
'sumber_dana' => 'nullable|string|max:200',
|
|
'jumlah' => 'required|integer|min:1',
|
|
'harga' => 'nullable|numeric|min:0',
|
|
'harga_total' => 'nullable|numeric|min:0',
|
|
'tujuan_pemakaian' => 'required|string|max:200',
|
|
'tanggal_kadaluarsa' => 'required|date',
|
|
'tanggal_pengeluaran' => 'required|date',
|
|
'no_pengeluaran' => 'nullable|string|max:50',
|
|
'nama_petugas' => 'required|string|max:100',
|
|
'nama_penerima' => 'required|string|max:100',
|
|
'catatan' => 'nullable|string',
|
|
'status' => 'nullable|in:proses,selesai,dibatalkan',
|
|
]);
|
|
|
|
$obatMasuk = ObatMasuk::findOrFail($validated['obat_masuk_id']);
|
|
|
|
// Hitung selisih jumlah
|
|
$selisih = $validated['jumlah'] - $obatKeluar->jumlah;
|
|
|
|
if ($selisih > 0 && $obatMasuk->stok < $selisih) {
|
|
return back()->withErrors(['jumlah' => 'Jumlah melebihi stok yang tersedia'])->withInput();
|
|
}
|
|
|
|
DB::transaction(function () use ($validated, $obatKeluar, $obatMasuk, $selisih) {
|
|
// Update nama obat
|
|
$validated['nama_obat'] = $obatMasuk->nama_obat;
|
|
|
|
// Update stok
|
|
if ($selisih > 0) {
|
|
$obatMasuk->decrement('stok', $selisih);
|
|
} elseif ($selisih < 0) {
|
|
$obatMasuk->increment('stok', abs($selisih));
|
|
}
|
|
|
|
$obatKeluar->update($validated);
|
|
});
|
|
|
|
return redirect()->route('obat-keluar.index')->with('success', 'Data obat keluar berhasil diperbarui');
|
|
}
|
|
|
|
public function destroy(ObatKeluar $obatKeluar)
|
|
{
|
|
DB::transaction(function () use ($obatKeluar) {
|
|
// Kembalikan stok ke obat masuk
|
|
if ($obatKeluar->obatMasuk) {
|
|
$obatKeluar->obatMasuk->increment('stok', $obatKeluar->jumlah);
|
|
}
|
|
|
|
$obatKeluar->delete();
|
|
});
|
|
|
|
return redirect()->route('obat-keluar.index')->with('success', 'Data obat keluar berhasil dihapus dan stok dikembalikan');
|
|
}
|
|
}
|