id) ->whereIn('status', ['Dipinjam', 'Terlambat']) ->where('due_at', '<', now()) ->exists(); if (($hasOverdue || $user->is_banned) && $user->role === 'siswa') { return redirect()->route('dashboard')->with('error', 'AKSES DITOLAK: Akun Anda sedang dibekukan karena ada buku terlambat!'); } $filters = $request->only(['search', 'kategori', 'tahun', 'penulis']); $query = Book::with('category')->whereJsonContains('tipe_akses', 'offline'); if ($request->filled('search')) { $query->where('judul', 'like', '%' . $request->search . '%'); } if ($request->filled('kategori')) { $query->whereHas('category', function($q) use ($request) { $q->where('name', $request->kategori); }); } if ($request->filled('tahun')) { $query->where('tahun', $request->tahun); } if ($request->filled('penulis')) { $query->where('penulis', $request->penulis); } $semuaBuku = $query->latest()->get(); $filterOptions = [ 'kategori' => Category::pluck('name')->unique()->sort()->values(), 'tahun' => Book::pluck('tahun')->unique()->sortDesc()->values(), 'penulis' => Book::pluck('penulis')->unique()->sort()->values(), ]; return view('katalog.index', [ 'semuaBuku' => $semuaBuku, 'filterOptions' => $filterOptions, 'input' => $request->query(), 'pageTitle' => 'Peminjaman Buku Offline', 'mode' => 'offline', ]); } public function ringkasan($id) { $user = Auth::user(); $buku = Book::with('category')->findOrFail($id); return view('katalog.ringkasan', [ 'user' => $user, 'buku' => $buku, 'pageTitle' => 'Peminjaman Buku Offline', 'actionRoute' => 'peminjaman.form', 'previousRoute' => 'peminjaman.index', 'actionButtonText' => 'Lanjutkan ke Form Peminjaman', 'actionButtonIcon' => 'bi-file-earmark-text-fill', ]); } public function form($id) { $user = Auth::user(); $buku = Book::with('category')->findOrFail($id); $semuaBuku = Book::whereJsonContains('tipe_akses', 'offline') ->where('status', 'Tersedia') ->get(); return view('peminjaman.form', compact('user', 'buku', 'semuaBuku')); } public function store(Request $request) { $request->validate([ 'buku_ids' => 'required|array|min:1|max:3', 'buku_ids.*' => 'exists:books,id', 'tanggal_pinjam' => 'required', 'tanggal_kembali' => 'required', ]); $bukuIds = $request->input('buku_ids'); // Parse dates: always today for borrow, and 2 days from now for due date $borrowedAt = now(); $dueAt = now()->addDays(2); DB::transaction(function () use ($bukuIds, $borrowedAt, $dueAt) { foreach ($bukuIds as $bukuId) { $book = Book::lockForUpdate()->find($bukuId); if ($book->status !== 'Tersedia') { throw new \Exception("Buku '{$book->judul}' sudah tidak tersedia."); } Loan::create([ 'user_id' => Auth::id(), 'book_id' => $bukuId, 'loan_code' => 'PIN-' . date('Ym') . '-' . strtoupper(Str::random(4)) . '-' . $bukuId, 'borrowed_at' => $borrowedAt, 'due_at' => $dueAt, 'status' => 'Dipinjam', ]); $book->update(['status' => 'Dipinjam']); } }); return redirect()->route('dashboard') ->with('success', 'Berhasil meminjam ' . count($bukuIds) . ' buku!'); } }