141 lines
4.5 KiB
PHP
141 lines
4.5 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\Book;
|
|
use App\Models\Category;
|
|
use App\Models\Loan;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Str;
|
|
|
|
class PeminjamanController extends Controller
|
|
{
|
|
public function index(Request $request)
|
|
{
|
|
$user = Auth::user();
|
|
|
|
// Check for overdue loans
|
|
$hasOverdue = Loan::where('user_id', $user->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('stok', '>', 0)
|
|
->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->stok <= 0) {
|
|
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',
|
|
]);
|
|
|
|
$newStok = $book->stok - 1;
|
|
$book->update([
|
|
'stok' => $newStok,
|
|
'status' => $newStok <= 0 ? 'Dipinjam' : 'Tersedia'
|
|
]);
|
|
}
|
|
});
|
|
|
|
return redirect()->route('dashboard')
|
|
->with('success', 'Berhasil meminjam ' . count($bukuIds) . ' buku!');
|
|
}
|
|
}
|