319 lines
11 KiB
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);
|
|
}
|
|
}
|
|
}
|
|
|