TIF_NGANJUK_E41220820/app/Http/Controllers/PakanController.php

325 lines
11 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Models\InventoriKandang;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Models\User;
use Illuminate\Support\Facades\DB;
class PakanController extends Controller
{
public function index(Request $request)
{
$query = InventoriKandang::query();
/** @var User $user */
$user = Auth::user();
// FILTER ROLE
if ($user->isKaryawan()) {
$query->where('user_id', $user->id);
}
/* SEARCH */
if ($request->search) {
$s = $request->search;
$query->where(function ($q) use ($s) {
$q->where('nama_barang', 'like', "%$s%")
->orWhere('jenis_transaksi', 'like', "%$s%")
->orWhereRaw("CAST(jumlah AS CHAR) LIKE ?", ["%$s%"]);
});
}
/* FILTER */
if ($request->jenis) {
$query->where('jenis_transaksi', $request->jenis);
}
if ($request->bulan) {
$query->whereMonth('tanggal', $request->bulan);
}
if ($request->tahun) {
$query->whereYear('tanggal', $request->tahun);
}
$perPage = $request->perPage ?? 10;
// DATA TABEL
$data = $query
->orderBy('tanggal', 'desc')
->orderBy('id', 'desc')
->paginate($perPage)
->withQueryString();
// HITUNG STOK (GLOBAL)
$stok = InventoriKandang::selectRaw("
nama_barang,
SUM(CASE WHEN jenis_transaksi = 'masuk' THEN jumlah ELSE 0 END)
-
SUM(CASE WHEN jenis_transaksi = 'keluar' THEN jumlah ELSE 0 END)
AS stok
")
->groupBy('nama_barang')
->get();
// BATAS MINIMUM
$batasMinimum = [
'Jagung' => 5,
'Katul' => 5,
'Konsentrat' => 5,
'Pakan Layer' => 5,
'Pakan Starter' => 5,
];
$stokMenipis = $stok->filter(function ($item) use ($batasMinimum) {
$min = $batasMinimum[$item->nama_barang] ?? 5;
return $item->stok <= $min;
});
return view('inventori-pakan', compact('data', 'stokMenipis'));
}
public function store(Request $request)
{
/** @var User $user */
$user = Auth::user();
$request->merge([
'harga_satuan' => $request->harga_satuan
? str_replace('.', '', $request->harga_satuan)
: null
]);
// karyawan TIDAK BOLEH input barang masuk
if ($user->isKaryawan() && $request->jenis_transaksi === 'masuk') {
abort(403, 'Karyawan tidak diizinkan mencatat barang masuk.');
}
$namaBarang = ucfirst(strtolower(trim($request->nama_barang)));
$request->validate([
'tanggal' => 'required|date|before_or_equal:today',
'nama_barang' => 'required|string|max:100',
'jenis_transaksi' => 'required|in:masuk,keluar',
'jumlah' => 'required|numeric|min:1|max:999999',
// 'satuan' => 'required|string|max:50|in:karung',
'harga_satuan' => $request->jenis_transaksi === 'masuk'
? 'required|numeric|min:1|max:999999999'
: 'nullable',
], [
'tanggal.required' => 'Tanggal wajib diisi.',
'tanggal.date' => 'Format tanggal tidak valid.',
'nama_barang.required' => 'Nama barang wajib diisi.',
'nama_barang.string' => 'Nama barang harus berupa teks.',
'nama_barang.max' => 'Nama barang maksimal 100 karakter.',
'jenis_transaksi.required' => 'Jenis transaksi wajib dipilih.',
'jenis_transaksi.in' => 'Jenis transaksi tidak valid.',
'jumlah.required' => 'Jumlah wajib diisi.',
'jumlah.numeric' => 'Jumlah harus berupa angka.',
'jumlah.min' => 'Jumlah minimal 1.',
'jumlah.max' => 'Jumlah terlalu besar.',
// 'satuan.required' => 'Satuan wajib diisi.',
// 'satuan.string' => 'Satuan harus berupa teks.',
// 'satuan.max' => 'Satuan maksimal 50 karakter.',
'harga_satuan.required' => 'Harga satuan wajib diisi untuk transaksi masuk.',
'harga_satuan.numeric' => 'Harga satuan harus berupa angka.',
'harga_satuan.min' => 'Harga satuan minimal 1.',
'harga_satuan.max' => 'Harga satuan terlalu besar.',
]);
$total = null;
if ($request->jenis_transaksi === 'masuk') {
$total = $request->jumlah * $request->harga_satuan;
}
// CEK STOK JIKA BARANG KELUAR
if ($request->jenis_transaksi === 'keluar') {
$stokSekarang = InventoriKandang::where('nama_barang', $namaBarang)
->selectRaw("
SUM(CASE WHEN jenis_transaksi = 'masuk' THEN jumlah ELSE 0 END)
-
SUM(CASE WHEN jenis_transaksi = 'keluar' THEN jumlah ELSE 0 END)
AS stok
")
->value('stok') ?? 0;
if ($request->jumlah > $stokSekarang) {
return back()->withErrors([
'jumlah' => 'Stok ' . $namaBarang . ' tidak mencukupi. Sisa stok: ' . $stokSekarang
])->withInput();
}
}
InventoriKandang::create([
'user_id' => $user->id,
'tanggal' => $request->tanggal,
'nama_barang' => $namaBarang,
'jenis_transaksi' => $request->jenis_transaksi,
'jumlah' => $request->jumlah,
'satuan' => 'karung',
'harga_satuan' => $request->jenis_transaksi === 'masuk' ? $request->harga_satuan : null,
'total_harga' => $total,
]);
return redirect()->route('pakan')->with('success', 'Transaksi berhasil disimpan');
}
public function update(Request $request, $id)
{
/** @var User $user */
$user = Auth::user();
$request->merge([
'harga_satuan' => $request->harga_satuan
? str_replace('.', '', $request->harga_satuan)
: null
]);
if ($user->isKaryawan()) {
abort(403, 'Anda tidak memiliki izin mengedit data.');
}
$namaBarang = ucfirst(strtolower(trim($request->nama_barang)));
$request->validate([
'tanggal' => 'required|date|before_or_equal:today',
'nama_barang' => 'required|string|max:100',
'jenis_transaksi' => 'required|in:masuk,keluar',
'jumlah' => 'required|numeric|min:1|max:999999',
// 'satuan' => 'required|string|max:50|in:karung',
'harga_satuan' => $request->jenis_transaksi === 'masuk'
? 'required|numeric|min:1|max:999999999'
: 'nullable',
], [
'tanggal.required' => 'Tanggal wajib diisi.',
'tanggal.date' => 'Format tanggal tidak valid.',
'nama_barang.required' => 'Nama barang wajib diisi.',
'nama_barang.string' => 'Nama barang harus berupa teks.',
'nama_barang.max' => 'Nama barang maksimal 100 karakter.',
'jenis_transaksi.required' => 'Jenis transaksi wajib dipilih.',
'jenis_transaksi.in' => 'Jenis transaksi tidak valid.',
'jumlah.required' => 'Jumlah wajib diisi.',
'jumlah.numeric' => 'Jumlah harus berupa angka.',
'jumlah.min' => 'Jumlah minimal 1.',
'jumlah.max' => 'Jumlah terlalu besar.',
// 'satuan.required' => 'Satuan wajib diisi.',
// 'satuan.string' => 'Satuan harus berupa teks.',
// 'satuan.max' => 'Satuan maksimal 50 karakter.',
'harga_satuan.required' => 'Harga satuan wajib diisi untuk transaksi masuk.',
'harga_satuan.numeric' => 'Harga satuan harus berupa angka.',
'harga_satuan.min' => 'Harga satuan minimal 1.',
'harga_satuan.max' => 'Harga satuan terlalu besar.',
]);
try {
DB::transaction(function () use ($request, $id, $namaBarang) {
$item = InventoriKandang::findOrFail($id);
$total = null;
if ($request->jenis_transaksi === 'masuk') {
$total = $request->jumlah * $request->harga_satuan;
}
// CEK STOK JIKA KELUAR
if ($request->jenis_transaksi === 'keluar') {
$stokSekarang = InventoriKandang::where('nama_barang', $namaBarang)
->where('id', '!=', $id)
->selectRaw("
SUM(CASE WHEN jenis_transaksi = 'masuk' THEN jumlah ELSE 0 END)
-
SUM(CASE WHEN jenis_transaksi = 'keluar' THEN jumlah ELSE 0 END)
AS stok
")
->value('stok') ?? 0;
if ($request->jumlah > $stokSekarang) {
throw new \Exception('Stok tidak mencukupi. Sisa stok: ' . $stokSekarang);
}
}
$item->update([
'tanggal' => $request->tanggal,
'nama_barang' => $namaBarang,
'jenis_transaksi' => $request->jenis_transaksi,
'jumlah' => $request->jumlah,
'satuan' => 'karung',
'harga_satuan' => $request->jenis_transaksi === 'masuk'
? $request->harga_satuan
: null,
'total_harga' => $total,
]);
});
} catch (\Exception $e) {
return back()
->withErrors([
'jumlah' => $e->getMessage()
])
->withInput();
}
return redirect()->route('pakan')->with('success', 'Transaksi berhasil diupdate');
}
public function destroy($id)
{
/** @var \App\Models\User $user */
$user = Auth::user();
// hanya admin boleh hapus
if ($user->isKaryawan()) {
abort(403, 'Anda tidak memiliki izin menghapus data.');
}
$item = InventoriKandang::findOrFail($id);
// Cek jika yang dihapus adalah transaksi masuk
if ($item->jenis_transaksi === 'masuk') {
$stokSekarang = InventoriKandang::where('nama_barang', $item->nama_barang)
->selectRaw("
SUM(CASE WHEN jenis_transaksi = 'masuk' THEN jumlah ELSE 0 END)
-
SUM(CASE WHEN jenis_transaksi = 'keluar' THEN jumlah ELSE 0 END)
AS stok
")
->value('stok') ?? 0;
// jika setelah dihapus stok jadi minus
if (($stokSekarang - $item->jumlah) < 0) {
return redirect()
->route('pakan')
->withErrors([
'delete' => 'Transaksi tidak bisa dihapus karena akan menyebabkan stok menjadi minus.'
]);
}
}
$item->delete();
return redirect()
->route('pakan')
->with('success', 'Transaksi berhasil dihapus');
}
}