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

317 lines
11 KiB
PHP

<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Koleksi;
use App\Models\Publisher;
use App\Models\PublishPlace;
use App\Models\Setting;
use Illuminate\Support\Facades\Storage;
use Barryvdh\DomPDF\Facade\Pdf;
use Milon\Barcode\DNS1D;
class KoleksiController extends Controller
{
public function __construct()
{
}
public function index(Request $request)
{
$query = Koleksi::query();
if ($request->filled('search')) {
$search = $request->search;
$query->where(function ($q) use ($search) {
$q->where('title', 'like', "%{$search}%")
->orWhere('sor', 'like', "%{$search}%")
->orWhere('classification', 'like', "%{$search}%")
->orWhere('kode_eksemplar', 'like', "%{$search}%");
});
}
$results = $query->orderBy('input_date', 'desc')
->paginate(20)
->withQueryString();
return view('admin.koleksi.index', compact('results'));
}
public function create()
{
$publishers = Publisher::all();
$publishPlaces = PublishPlace::all();
return view('admin.koleksi.create', compact('publishers', 'publishPlaces'));
}
public function store(Request $request)
{
$request->validate([
'title' => 'required|string|max:255',
'sor' => 'nullable|string|max:255',
'jumlah_eksemplar' => 'required|integer|min:1',
'publisher_name' => 'nullable|string|max:255',
'publish_place_name' => 'nullable|string|max:255',
'publish_year' => 'nullable|integer',
'isbn_issn' => 'nullable|string|max:50',
'edition' => 'nullable|string|max:100',
'classification' => 'nullable|string|max:100',
'labels' => 'nullable|string|max:255',
'image' => 'nullable|file|mimes:jpg,jpeg,png,gif',
'opac_hide' => 'nullable|boolean',
'promoted' => 'nullable|boolean',
]);
$jumlah = $request->jumlah_eksemplar;
$imagePath = $request->hasFile('image') ? $request->file('image')->store('images', 'public') : null;
for ($i = 1; $i <= $jumlah; $i++) {
$kodeEksemplar = $this->generateKodeEksemplar();
$barcodePath = $this->generateBarcode($kodeEksemplar);
Koleksi::create([
'title' => $request->title,
'sor' => $request->sor,
'publisher_name' => $request->publisher_name,
'publish_place_name' => $request->publish_place_name,
'publish_year' => $request->publish_year,
// 🔥 FIX WAJIB
'tahun_terbit' => $request->publish_year,
'isbn_issn' => $request->isbn_issn,
'edition' => $request->edition,
'classification' => $request->classification,
'labels' => $request->labels,
'image' => $imagePath,
'barcode' => $barcodePath,
'kode_eksemplar' => $kodeEksemplar,
'input_date' => now(),
'last_update' => now(),
'uid' => auth()->id(),
'opac_hide' => $request->opac_hide ?? 0,
'promoted' => $request->promoted ?? 0,
]);
}
return redirect()->route('admin.koleksi.index')
->with('success', '✅ Koleksi berhasil ditambahkan dengan Barcode.');
}
protected function generateKodeEksemplar()
{
do {
$random = str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);
$kode = 'P' . $random . 'S';
} while (Koleksi::where('kode_eksemplar', $kode)->exists());
return $kode;
}
protected function generateBarcode($kodeEksemplar)
{
$barcode = new DNS1D();
$barcode->setStorPath(storage_path('app/public/barcodes'));
if (!Storage::disk('public')->exists('barcodes')) {
Storage::disk('public')->makeDirectory('barcodes');
}
$barcodePng = $barcode->getBarcodePNG($kodeEksemplar, 'C39+', 3, 100);
$barcodePath = "barcodes/{$kodeEksemplar}.png";
Storage::disk('public')->put($barcodePath, base64_decode($barcodePng));
return $barcodePath;
}
public function printBarcodeSingle($kode_eksemplar)
{
$koleksi = Koleksi::where('kode_eksemplar', $kode_eksemplar)->firstOrFail();
$setting = Setting::first();
$pdf = Pdf::loadView('admin.koleksi.label_barcode_single', compact('koleksi', 'setting'))
->setPaper([0, 0, 200, 120], 'portrait');
return $pdf->stream("barcode_{$koleksi->kode_eksemplar}.pdf");
}
public function printBarcodeMultiple(Request $request)
{
$selected = $request->input('selected', []);
if (!is_array($selected)) {
$selected = explode(',', $selected);
}
if (empty($selected)) {
return redirect()->back()->with('error', 'Pilih minimal satu koleksi untuk dicetak.');
}
$koleksiList = Koleksi::whereIn('kode_eksemplar', $selected)->get();
$setting = Setting::first();
$pdf = Pdf::loadView('admin.koleksi.label_barcode_multiple', compact('koleksiList', 'setting'))
->setPaper('a4', 'portrait');
return $pdf->stream("barcode_massal.pdf");
}
public function edit($kode_eksemplar)
{
$koleksi = Koleksi::where('kode_eksemplar', $kode_eksemplar)->firstOrFail();
$publishers = Publisher::all();
$publishPlaces = PublishPlace::all();
return view('admin.koleksi.edit', compact('koleksi', 'publishers', 'publishPlaces'));
}
public function update(Request $request, $kode_eksemplar)
{
$koleksi = Koleksi::where('kode_eksemplar', $kode_eksemplar)->firstOrFail();
$request->validate([
'title' => 'required|string|max:255',
'sor' => 'nullable|string|max:255',
'publisher_name' => 'nullable|string|max:255',
'publish_place_name' => 'nullable|string|max:255',
'publish_year' => 'nullable|integer',
'isbn_issn' => 'nullable|string|max:50',
'edition' => 'nullable|string|max:100',
'classification' => 'nullable|string|max:100',
'labels' => 'nullable|string|max:255',
'image' => 'nullable|file|mimes:jpg,jpeg,png,gif',
'opac_hide' => 'nullable|boolean',
'promoted' => 'nullable|boolean',
]);
if ($request->hasFile('image')) {
if ($koleksi->image) {
Storage::disk('public')->delete($koleksi->image);
}
$koleksi->image = $request->file('image')->store('images', 'public');
}
$koleksi->update([
'title' => $request->title,
'sor' => $request->sor,
'publisher_name' => $request->publisher_name,
'publish_place_name' => $request->publish_place_name,
'publish_year' => $request->publish_year,
// 🔥 FIX WAJIB
'tahun_terbit' => $request->publish_year,
'isbn_issn' => $request->isbn_issn,
'edition' => $request->edition,
'classification' => $request->classification,
'labels' => $request->labels,
'image' => $koleksi->image,
'opac_hide' => $request->opac_hide ?? 0,
'promoted' => $request->promoted ?? 0,
'last_update' => now(),
]);
return redirect()->route('admin.koleksi.index')
->with('success', '✅ Data koleksi berhasil diperbarui.');
}
public function destroy($kode_eksemplar)
{
$koleksi = Koleksi::where('kode_eksemplar', $kode_eksemplar)->firstOrFail();
if ($koleksi->image) {
// Cek apakah ada eksemplar LAIN yang masih menggunakan gambar ini
$fotoMasihDipakai = Koleksi::where('image', $koleksi->image)
->where('kode_eksemplar', '!=', $kode_eksemplar)
->exists();
// Jika tidak ada eksemplar lain yang pakai, baru hapus file fisiknya
if (!$fotoMasihDipakai) {
Storage::disk('public')->delete($koleksi->image);
}
}
// Barcode tetap langsung dihapus karena setiap eksemplar punya barcode unik
if ($koleksi->barcode) {
Storage::disk('public')->delete($koleksi->barcode);
}
$koleksi->delete();
return redirect()->route('admin.koleksi.index')
->with('success', '✅ Koleksi berhasil dihapus.');
}
// ... (di dalam KoleksiController)
public function printMultipleBarcode(Request $request)
{
// 1. Validasi input
if (!$request->has('kode_eksemplar') || !is_array($request->kode_eksemplar)) {
return redirect()->back()->with('error', 'Silakan centang minimal satu koleksi terlebih dahulu.');
}
$kodeEksemplarArray = $request->kode_eksemplar;
// --- BAGIAN INI DIPERBAIKI ---
// Mengurutkan data agar sama persis dengan urutan centang (array input)
$orderList = "'" . implode("','", $kodeEksemplarArray) . "'";
$items = Koleksi::whereIn('kode_eksemplar', $kodeEksemplarArray)
->orderByRaw("FIELD(kode_eksemplar, $orderList)")
->get();
// -----------------------------
if ($items->isEmpty()) {
return redirect()->back()->with('error', 'Data koleksi yang Anda pilih tidak ditemukan.');
}
$setting = Setting::first();
// 2. Render PDF
$pdf = Pdf::loadView('admin.koleksi.barcode_multiple', compact('items', 'setting'));
// 3. Atur kertas
$pdf->setPaper('a4', 'portrait');
// 4. Stream PDF
return $pdf->stream('Label_Barcode_Massal.pdf');
}
public function destroyMultiple(Request $request)
{
$kodese = $request->input('kode_eksemplar', []);
if (empty($kodese)) {
return redirect()->back()->with('error', 'Tidak ada item yang dipilih.');
}
// Ambil semua data koleksi yang kodenya sesuai array
$koleksis = Koleksi::whereIn('kode_eksemplar', $kodese)->get();
foreach ($koleksis as $koleksi) {
// Contoh logika hapus file cover jika tidak dipakai eksemplar lain
if ($koleksi->image) {
$fotoMasihDipakai = Koleksi::where('image', $koleksi->image)
->whereNotIn('kode_eksemplar', $kodese)
->exists();
if (!$fotoMasihDipakai) {
Storage::disk('public')->delete($koleksi->image);
}
}
// Hapus file barcode asli jika disimpan fisik
if ($koleksi->barcode) {
Storage::disk('public')->delete($koleksi->barcode);
}
$koleksi->delete();
}
return redirect()->route('admin.koleksi.index')->with('success', count($kodese) . ' data koleksi berhasil dihapus sekaligus.');
}
}