TKK_E32230908/app/Http/Controllers/Admin/PeminjamanController.php

319 lines
11 KiB
PHP

<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\BorrowTransaction;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log; // Tambahkan ini
use App\Mail\BukuSiapDiambilMail;
use App\Mail\PeminjamanDitolakMail;
use App\Mail\BukuDikembalikanMail;
use App\Mail\PerpanjanganDisetujuiMail;
use App\Mail\PerpanjanganDitolakMail;
use Carbon\Carbon;
use App\Models\IotMode;
class PeminjamanController extends Controller
{
public function index()
{
// Gunakan eager loading 'anggota.user' untuk mendapatkan email dari tabel users
$transactions = BorrowTransaction::with(['anggota.user', 'koleksi'])
->orderBy('created_at', 'desc')
->get();
return view('admin.peminjaman', compact('transactions'));
}
public function cetakNota($id)
{
$transaction = BorrowTransaction::with(['anggota', 'koleksi'])->findOrFail($id);
return view('admin.peminjaman.nota', compact('transaction'));
}
public function downloadSuratPengantar($id)
{
$transaction = BorrowTransaction::findOrFail($id);
if (!$transaction->surat_pengantar) {
return back()->with('error', 'File surat pengantar tidak tersedia.');
}
$filePath = 'public/surat_pengantar/' . $transaction->surat_pengantar;
if (!Storage::exists($filePath)) {
return back()->with('error', 'File surat pengantar tidak ditemukan.');
}
return Storage::download($filePath, $transaction->surat_pengantar);
}
public function setujui(Request $request, $id)
{
$transaction = BorrowTransaction::with('anggota.user')->findOrFail($id);
if (!in_array($transaction->status, ['menunggu', 'pending'])) {
return redirect()->back()->with('error', 'Transaksi ini sudah diproses.');
}
// 🔥 CEK LIMIT PINJAMAN
$jumlahPinjaman = BorrowTransaction::where('anggota_id', $transaction->anggota_id)
->whereIn('status', ['dipinjam', 'disetujui', 'pengembalian_menunggu'])
->count();
if ($jumlahPinjaman >= 2) {
return redirect()->back()->with('error', 'Anggota sudah mencapai batas maksimal peminjaman (2 buku).');
}
$request->validate([
'pickup_date' => 'required|date',
'pickup_time' => 'required',
'tanggal_kembali' => 'nullable|date|after_or_equal:pickup_date',
]);
$tanggalKembali = $request->tanggal_kembali
? Carbon::parse($request->tanggal_kembali)
: Carbon::parse($request->pickup_date)->addDays(7);
// Update Data
$transaction->update([
'pickup_date' => $request->pickup_date,
'pickup_time' => $request->pickup_time,
'tanggal_kembali' => $tanggalKembali,
'status' => 'disetujui'
]);
IotMode::query()->update([
'mode' => 'user',
'updated_at' => now()
]);
// 📧 PROSES KIRIM EMAIL
// Pastikan relasi ke user benar untuk mengambil email
$recipientEmail = $transaction->anggota->user->email ?? $transaction->anggota->email;
if ($recipientEmail) {
try {
Mail::to($recipientEmail)->send(new BukuSiapDiambilMail($transaction));
} catch (\Exception $e) {
Log::error('Gagal kirim email BukuSiapDiambil: ' . $e->getMessage());
// Tetap lanjut meskipun email gagal agar status di DB tersimpan
}
}
return redirect()->route('admin.peminjaman')->with('success', 'Peminjaman disetujui dan email notifikasi dikirim.');
}
public function ambilBuku($id)
{
$transaction = BorrowTransaction::findOrFail($id);
if ($transaction->status !== 'disetujui') {
return redirect()->route('admin.peminjaman')->with('error', 'Buku belum disetujui atau sudah diambil.');
}
$transaction->markAsDipinjam();
IotMode::query()->update([
'mode' => 'standby',
'updated_at' => now()
]);
return redirect()->route('admin.peminjaman')->with('success', 'Buku berhasil diambil.');
}
public function tolak($id)
{
$transaction = BorrowTransaction::with('anggota.user')->findOrFail($id);
if (!in_array($transaction->status, ['menunggu', 'pending'])) {
return redirect()->back()->with('error', 'Transaksi ini sudah diproses.');
}
$transaction->markAsDitolak();
$recipientEmail = $transaction->anggota->user->email ?? $transaction->anggota->email;
if ($recipientEmail) {
try {
Mail::to($recipientEmail)->send(new PeminjamanDitolakMail($transaction));
} catch (\Exception $e) {
Log::error('Gagal kirim email PeminjamanDitolak: ' . $e->getMessage());
}
}
return redirect()->route('admin.peminjaman')->with('success', 'Peminjaman ditolak.');
}
public function setujuiPerpanjangan(Request $request, $id)
{
$transaction = BorrowTransaction::with('anggota.user')->findOrFail($id);
if ($transaction->status !== 'perpanjangan_menunggu') {
return back()->with('error', 'Permohonan perpanjangan tidak ditemukan.');
}
// Jika Admin input tanggal di modal, gunakan itu. Jika tidak, tambah 7 hari dari tanggal kembali lama.
$newTanggalKembali = $request->tanggal_kembali
? Carbon::parse($request->tanggal_kembali)
: Carbon::parse($transaction->tanggal_kembali)->addDays(7);
$transaction->update([
'tanggal_kembali' => $newTanggalKembali,
'status' => 'dipinjam'
]);
$recipientEmail = $transaction->anggota->user->email ?? $transaction->anggota->email;
if ($recipientEmail) {
try {
Mail::to($recipientEmail)->send(new PerpanjanganDisetujuiMail($transaction));
} catch (\Exception $e) {
Log::error('Gagal kirim email PerpanjanganDisetujui: ' . $e->getMessage());
}
}
return back()->with('success', 'Perpanjangan disetujui.');
}
public function tolakPerpanjangan($id)
{
$transaction = BorrowTransaction::with('anggota.user')->findOrFail($id);
if ($transaction->status !== 'perpanjangan_menunggu') {
return back()->with('error', 'Permohonan tidak valid.');
}
$transaction->update(['status' => 'dipinjam']);
$recipientEmail = $transaction->anggota->user->email ?? $transaction->anggota->email;
if ($recipientEmail) {
try {
Mail::to($recipientEmail)->send(new PerpanjanganDitolakMail($transaction));
} catch (\Exception $e) {
Log::error('Gagal kirim email PerpanjanganDitolak: ' . $e->getMessage());
}
}
return back()->with('success', 'Perpanjangan ditolak.');
}
public function kembalikan($id)
{
$transaction = BorrowTransaction::with('anggota.user')->findOrFail($id);
if (!in_array($transaction->status, ['dipinjam', 'pengembalian_menunggu'])) {
return redirect()->route('admin.peminjaman')->with('error', 'Status tidak valid untuk dikembalikan.');
}
$transaction->markAsDikembalikan();
$recipientEmail = $transaction->anggota->user->email ?? $transaction->anggota->email;
if ($recipientEmail) {
try {
Mail::to($recipientEmail)->send(new BukuDikembalikanMail($transaction));
} catch (\Exception $e) {
Log::error('Gagal kirim email BukuDikembalikan: ' . $e->getMessage());
}
}
return redirect()->route('admin.peminjaman')->with('success', 'Buku berhasil dikembalikan.');
}
public function espScan(Request $request)
{
$uid = strtoupper($request->query('uid') ?? '');
$mode = $request->query('mode') ?? '';
if (!$uid) return response()->json(['status' => 'uid_kosong']);
if ($mode !== 'user') return response()->json(['status' => 'mode_salah']);
$anggota = DB::table('anggota')->where('uid', $uid)->first();
if (!$anggota) return response()->json(['status' => 'tidak_valid']);
$jumlahPinjaman = BorrowTransaction::where('anggota_id', $anggota->id)
->whereIn('status', ['dipinjam', 'pengembalian_menunggu'])
->count();
if ($jumlahPinjaman >= 2) return response()->json(['status' => 'limit_tercapai']);
$transaction = BorrowTransaction::where('anggota_id', $anggota->id)
->where('status', 'disetujui')
->first();
if (!$transaction) return response()->json(['status' => 'tidak_valid']);
$transaction->markAsDipinjam();
IotMode::query()->update([
'mode' => 'standby',
'updated_at' => now()
]);
return response()->json(['status' => 'valid']);
}
// Tambahkan ini di PeminjamanController.php
public function konfirmasiKembali()
{
try {
// 1. Ambil data terakhir dari IotMode untuk tahu buku apa yang baru di-scan
$iot = IotMode::first();
if (!$iot || !$iot->book_id) {
return response()->json([
'status' => 'error',
'message' => 'Data buku tidak ditemukan di sistem IoT'
], 404);
}
// 2. Cari transaksi yang statusnya 'dipinjam' atau 'pengembalian_menunggu' berdasarkan buku tersebut
$transaction = BorrowTransaction::with('anggota.user')
->where('koleksi_id', $iot->book_id) // Pastikan kolom ini sesuai dengan di DB Anda
->whereIn('status', ['dipinjam', 'pengembalian_menunggu'])
->first();
if (!$transaction) {
return response()->json([
'status' => 'error',
'message' => 'Transaksi aktif untuk buku ini tidak ditemukan'
], 404);
}
// 3. Proses Pengembalian (Memakai fungsi yang sudah Anda punya di model)
$transaction->markAsDikembalikan();
// 4. Reset IotMode ke standby
IotMode::query()->update([
'mode' => 'standby',
'book_id' => null, // Bersihkan ID buku agar tidak terbaca lagi
'updated_at' => now()
]);
// 5. Kirim Email (Opsional, memakai logika yang sama dengan fungsi kembalikan manual)
$recipientEmail = $transaction->anggota->user->email ?? $transaction->anggota->email;
if ($recipientEmail) {
try {
Mail::to($recipientEmail)->send(new BukuDikembalikanMail($transaction));
} catch (\Exception $e) {
Log::error('Gagal kirim email: ' . $e->getMessage());
}
}
// 6. WAJIB: Kirim balasan JSON agar JS tidak error
return response()->json([
'status' => 'berhasil_kembali',
'message' => 'Buku ' . $transaction->koleksi->judul . ' berhasil dikembalikan'
]);
} catch (\Exception $e) {
Log::error('Error Konfirmasi Kembali: ' . $e->getMessage());
return response()->json([
'status' => 'error',
'message' => 'Terjadi kesalahan internal: ' . $e->getMessage()
], 500);
}
}
}