206 lines
7.3 KiB
PHP
206 lines
7.3 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace App\Http\Controllers;
|
||
|
|
|
||
|
|
use App\Models\Cat;
|
||
|
|
use App\Models\Medicine;
|
||
|
|
use App\Models\MedicalRecord;
|
||
|
|
use Illuminate\Http\Request;
|
||
|
|
use Illuminate\Support\Facades\Gate;
|
||
|
|
use Illuminate\Support\Facades\DB;
|
||
|
|
use Exception;
|
||
|
|
|
||
|
|
class MedicalRecordController extends Controller
|
||
|
|
{
|
||
|
|
/**
|
||
|
|
* Simpan rekam medis individu (dari halaman show cat)
|
||
|
|
*/
|
||
|
|
public function store(Request $request)
|
||
|
|
{
|
||
|
|
Gate::authorize('check-access', ['cats', 'update']);
|
||
|
|
|
||
|
|
// Tambahan Validasi
|
||
|
|
$request->validate([
|
||
|
|
'cat_id' => 'required|exists:cats,id',
|
||
|
|
'type' => 'required|string',
|
||
|
|
'date_given' => 'required|date',
|
||
|
|
'next_schedule' => 'nullable|date|after_or_equal:date_given',
|
||
|
|
'medicines' => 'nullable|array',
|
||
|
|
]);
|
||
|
|
|
||
|
|
try {
|
||
|
|
return DB::transaction(function () use ($request) {
|
||
|
|
$type = $request->type;
|
||
|
|
$medicines = $request->input('medicines', []);
|
||
|
|
|
||
|
|
if ($type === 'Grooming') {
|
||
|
|
$this->createRecord($request->cat_id, $type, 'Routine Grooming', null, 'SESSION', $request);
|
||
|
|
} else {
|
||
|
|
foreach ($medicines as $med) {
|
||
|
|
if (empty($med['name'])) continue;
|
||
|
|
|
||
|
|
$doseValue = $this->parseFraction($med['dosage']);
|
||
|
|
|
||
|
|
// Pengecekan Stok Sebelum Potong
|
||
|
|
$item = Medicine::where('nama_obat', $med['name'])->first();
|
||
|
|
if ($item) {
|
||
|
|
if ($item->qty < $doseValue) {
|
||
|
|
throw new Exception("Stok obat '{$med['name']}' tidak mencukupi. Sisa: {$item->qty}");
|
||
|
|
}
|
||
|
|
$item->decrement('qty', $doseValue);
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->createRecord($request->cat_id, $type, $med['name'], $med['dosage'], $med['unit'], $request);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Update pengingat di tabel cats
|
||
|
|
$this->updateCatReminder($request->cat_id, $type, $request->next_schedule);
|
||
|
|
|
||
|
|
return back()->with('success', 'Medical Ledger berhasil dicatat dan jadwal otomatis diperbarui.');
|
||
|
|
});
|
||
|
|
} catch (Exception $e) {
|
||
|
|
return back()->with('error', 'Gagal mencatat rekam medis: ' . $e->getMessage())->withInput();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Tampilkan form Bulk Treatment
|
||
|
|
*/
|
||
|
|
/**
|
||
|
|
* Tampilkan form Bulk Treatment
|
||
|
|
*/
|
||
|
|
public function bulkCreate()
|
||
|
|
{
|
||
|
|
Gate::authorize('check-access', ['cats', 'update']);
|
||
|
|
|
||
|
|
// Mengambil kucing yang Sehat (2) maupun yang sedang Treatment (1)
|
||
|
|
$cats = Cat::whereIn('treatment_status', [1, 2])
|
||
|
|
->orderBy('nama_kucing', 'asc')
|
||
|
|
->get();
|
||
|
|
|
||
|
|
// Mengambil obat dengan stok yang valid (qty > 0)
|
||
|
|
$availableMedicines = Medicine::where('qty', '>', 0)->orderBy('nama_obat')->get();
|
||
|
|
|
||
|
|
return view('pages.cats.medical-bulk', compact('cats', 'availableMedicines'));
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Simpan Bulk Treatment (Massal)
|
||
|
|
*/
|
||
|
|
public function bulkStore(Request $request)
|
||
|
|
{
|
||
|
|
Gate::authorize('check-access', ['cats', 'update']);
|
||
|
|
|
||
|
|
$request->validate([
|
||
|
|
'cat_ids' => 'required|array|min:1',
|
||
|
|
'type' => 'required',
|
||
|
|
'date_given' => 'required|date',
|
||
|
|
'next_schedule' => 'nullable|date|after_or_equal:date_given',
|
||
|
|
]);
|
||
|
|
|
||
|
|
try {
|
||
|
|
return DB::transaction(function () use ($request) {
|
||
|
|
$catIds = $request->cat_ids;
|
||
|
|
$medicines = $request->input('medicines', []);
|
||
|
|
$totalCats = count($catIds);
|
||
|
|
|
||
|
|
foreach ($catIds as $catId) {
|
||
|
|
if ($request->type === 'Grooming') {
|
||
|
|
$this->createRecord($catId, $request->type, 'Routine Grooming', null, 'SESSION', $request);
|
||
|
|
} else {
|
||
|
|
foreach ($medicines as $med) {
|
||
|
|
if (empty($med['name'])) continue;
|
||
|
|
|
||
|
|
$doseValue = $this->parseFraction($med['dosage']);
|
||
|
|
|
||
|
|
// Validasi stok untuk bulk (kebutuhan = dosis * jumlah kucing)
|
||
|
|
$item = Medicine::where('nama_obat', $med['name'])->first();
|
||
|
|
if ($item) {
|
||
|
|
if ($item->qty < $doseValue) {
|
||
|
|
throw new Exception("Stok '{$med['name']}' tidak cukup untuk pemrosesan massal.");
|
||
|
|
}
|
||
|
|
$item->decrement('qty', $doseValue);
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->createRecord($catId, $request->type, $med['name'], $med['dosage'], $med['unit'], $request);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->updateCatReminder($catId, $request->type, $request->next_schedule);
|
||
|
|
}
|
||
|
|
|
||
|
|
return redirect()->route('cats.index')->with('success', "Bulk Treatment berhasil diterapkan pada $totalCats kucing.");
|
||
|
|
});
|
||
|
|
} catch (Exception $e) {
|
||
|
|
return back()->with('error', 'Gagal memproses bulk treatment: ' . $e->getMessage())->withInput();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Helper: Simpan data ke tabel medical_records
|
||
|
|
*/
|
||
|
|
/**
|
||
|
|
* Helper: Simpan data ke tabel medical_records
|
||
|
|
*/
|
||
|
|
private function createRecord($catId, $type, $name, $dosage, $unit, $request)
|
||
|
|
{
|
||
|
|
return MedicalRecord::create([
|
||
|
|
'cat_id' => $catId,
|
||
|
|
'user_id' => auth()->id(), // Ini adalah kolom yang benar sesuai migration kita
|
||
|
|
'type' => $type,
|
||
|
|
'treatment_name' => $name,
|
||
|
|
'dosage' => $this->parseFraction($dosage),
|
||
|
|
'unit' => $unit,
|
||
|
|
'date_given' => $request->date_given,
|
||
|
|
'next_schedule' => $request->next_schedule,
|
||
|
|
'notes' => $request->notes
|
||
|
|
// HAPUS baris 'performed_by' di sini
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Helper: Update kolom jadwal di tabel cats
|
||
|
|
*/
|
||
|
|
private function updateCatReminder($catId, $type, $nextDate)
|
||
|
|
{
|
||
|
|
if (!$nextDate) return;
|
||
|
|
|
||
|
|
$mapping = [
|
||
|
|
'Vaccine' => 'jadwal_vaksin',
|
||
|
|
'Deworming' => 'jadwal_obat_cacing',
|
||
|
|
'Flea Treatment' => 'jadwal_obat_kutu',
|
||
|
|
'Grooming' => 'jadwal_grooming',
|
||
|
|
];
|
||
|
|
|
||
|
|
if (isset($mapping[$type])) {
|
||
|
|
Cat::where('id', $catId)->update([$mapping[$type] => $nextDate]);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Helper: Konversi pecahan (1/2) ke desimal (0.5)
|
||
|
|
*/
|
||
|
|
private function parseFraction($fraction)
|
||
|
|
{
|
||
|
|
if (is_null($fraction)) return 0;
|
||
|
|
|
||
|
|
$fraction = str_replace(' ', '', $fraction); // Hapus spasi jika ada
|
||
|
|
|
||
|
|
if (str_contains($fraction, '/')) {
|
||
|
|
list($numerator, $denominator) = explode('/', $fraction);
|
||
|
|
return $denominator > 0 ? (float)$numerator / (float)$denominator : 0;
|
||
|
|
}
|
||
|
|
return (float)$fraction;
|
||
|
|
}
|
||
|
|
|
||
|
|
public function create(Cat $cat)
|
||
|
|
{
|
||
|
|
Gate::authorize('check-access', ['cats', 'update']);
|
||
|
|
|
||
|
|
$availableMedicines = Medicine::where('qty', '>', 0)->orderBy('nama_obat')->get();
|
||
|
|
|
||
|
|
|
||
|
|
return view('pages.cats.medical-ledger-create', compact('cat', 'availableMedicines'));
|
||
|
|
}
|
||
|
|
}
|