Files
lis/htdocs/app/Http/Controllers/BiorepositoryController.php
T
2026-02-21 05:39:38 +07:00

212 lines
7.6 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\BioCabinet;
use App\BioRack;
use App\BioSpecimen;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Session;
use Validator;
class BiorepositoryController extends Controller
{
public function index()
{
if (Session::get('previlage') == '') {
return redirect('/login');
}
$data = [];
$data['cabinetOptions'] = BioCabinet::orderBy('name', 'ASC')->get();
$data['totalCabinets'] = BioCabinet::count();
$data['totalRacks'] = BioRack::count();
$data['totalSpecimens'] = BioSpecimen::count();
$data['specimenRows'] = BioSpecimen::with(['cabinet', 'rack'])
->orderBy('stored_at', 'DESC')
->orderBy('id', 'DESC')
->get();
$data['cabinets'] = BioCabinet::with([
'racks' => function ($query) {
$query->orderBy('level', 'ASC')->orderBy('rack_number', 'ASC');
},
'racks.specimens' => function ($query) {
$query->orderBy('stored_at', 'ASC');
},
])->orderBy('name', 'ASC')->get();
$data['oldestSpecimen'] = BioSpecimen::with(['cabinet', 'rack'])
->whereNotNull('stored_at')
->orderBy('stored_at', 'ASC')
->first();
$data['oldestStorageDays'] = 0;
if ($data['oldestSpecimen']) {
$data['oldestStorageDays'] = Carbon::parse($data['oldestSpecimen']->stored_at)->diffInDays(Carbon::now());
}
return view('admin.biorepository', $data);
}
public function storeCabinet(Request $request)
{
$validator = Validator::make($request->all(), [
'code' => 'required|max:50|unique:bio_cabinets,code',
'name' => 'required|max:150',
'location' => 'nullable|max:200',
'notes' => 'nullable',
]);
if ($validator->fails()) {
return back()->withErrors($validator)->withInput();
}
BioCabinet::create([
'code' => $request->input('code'),
'name' => $request->input('name'),
'location' => $request->input('location'),
'notes' => $request->input('notes'),
]);
return redirect('/biorepository')->with('success', 'Lemari biorepository berhasil ditambahkan.');
}
public function storeRack(Request $request)
{
$validator = Validator::make($request->all(), [
'cabinet_id' => 'required|exists:bio_cabinets,id',
'code' => 'required|max:50',
'name' => 'required|max:150',
'level' => 'required|integer|min:1',
'rack_number' => 'required|integer|min:1',
'box_number' => 'required|integer|min:1',
'capacity' => 'required|integer|min:1',
'notes' => 'nullable',
]);
if ($validator->fails()) {
return back()->withErrors($validator)->withInput();
}
$exists = BioRack::where('cabinet_id', $request->input('cabinet_id'))
->where('code', $request->input('code'))
->exists();
if ($exists) {
return back()->withErrors(['code' => 'Kode rack sudah dipakai pada lemari ini.'])->withInput();
}
BioRack::create([
'cabinet_id' => $request->input('cabinet_id'),
'code' => $request->input('code'),
'name' => $request->input('name'),
'level' => $request->input('level'),
'rack_number' => $request->input('rack_number'),
'box_number' => $request->input('box_number'),
'capacity' => $request->input('capacity'),
'notes' => $request->input('notes'),
]);
return redirect('/biorepository')->with('success', 'Rack berhasil ditambahkan.');
}
public function storeSpecimen(Request $request)
{
$validator = Validator::make($request->all(), [
'rack_id' => 'required|exists:bio_racks,id',
'kategorisimpan' => 'required|in:A,B,C,D',
'shelfnomor' => 'required|integer|min:1',
'raknomor' => 'required|integer|min:1',
'slotnomor' => 'required|integer|min:1',
'boxnomor' => 'required|integer|min:1',
'tubenomor' => 'required|integer|min:1',
'nmbakteri' => 'required|max:200',
'strain' => 'required|in:Gram Negatif,Gram Positif',
'stored_at' => 'required|date',
]);
if ($validator->fails()) {
return back()->withErrors($validator)->withInput();
}
$rack = BioRack::find($request->input('rack_id'));
$expectedRackNo = $rack->rack_number ?: $rack->id;
$expectedBoxNo = $rack->box_number ?: 1;
if ((int) $request->input('shelfnomor') !== (int) $rack->level ||
(int) $request->input('raknomor') !== (int) $expectedRackNo ||
(int) $request->input('boxnomor') !== (int) $expectedBoxNo) {
return back()->withErrors(['slotnomor' => 'Posisi slot tidak sesuai dengan konfigurasi rack.'])->withInput();
}
if ((int) $request->input('slotnomor') > (int) $rack->capacity) {
return back()->withErrors(['slotnomor' => 'Slot melebihi kapasitas rack.'])->withInput();
}
$slotTaken = BioSpecimen::where('rack_id', $rack->id)
->where('slot_number', $request->input('slotnomor'))
->exists();
if ($slotTaken) {
return back()->withErrors(['slotnomor' => 'Slot ini sudah terisi spesimen.'])->withInput();
}
$atccByUser = strtoupper(preg_replace('/[^A-Za-z0-9]/', '', Session::get('nama', 'UNKNOWN')));
if ($atccByUser === '') {
$atccByUser = 'UNKNOWN';
}
$generatedCode = implode('-', [
$request->input('kategorisimpan'),
$request->input('shelfnomor'),
$request->input('raknomor'),
$request->input('slotnomor'),
$request->input('boxnomor'),
$request->input('tubenomor'),
]);
$baseCode = $generatedCode;
$counter = 1;
while (BioSpecimen::where('specimen_code', $generatedCode)->exists()) {
$counter++;
$generatedCode = $baseCode.'-'.$counter;
}
BioSpecimen::create([
'cabinet_id' => $rack->cabinet_id,
'rack_id' => $rack->id,
'specimen_code' => $generatedCode,
'specimen_name' => $request->input('nmbakteri'),
'category_storage' => $request->input('kategorisimpan'),
'shelf_number' => $request->input('shelfnomor'),
'rack_number' => $request->input('raknomor'),
'slot_number' => $request->input('slotnomor'),
'box_number' => $request->input('boxnomor'),
'tube_number' => $request->input('tubenomor'),
'bacteria_name' => $request->input('nmbakteri'),
'strain' => $request->input('strain'),
'atcc' => $atccByUser,
'input_by' => Session::get('nama'),
'stored_at' => $request->input('stored_at'),
'storage_condition' => $this->mapStorageCondition($request->input('kategorisimpan')),
'notes' => $request->input('notes'),
]);
return redirect('/biorepository')->with('success', 'Spesimen berhasil disimpan ke slot terpilih.');
}
private function mapStorageCondition($category)
{
$mapping = [
'A' => 'Suhu Ruang',
'B' => '4 Derajat',
'C' => '20 Derajat',
'D' => '80 Derajat',
];
return $mapping[$category] ?? 'Tidak Diketahui';
}
}