diff --git a/app/Http/Controllers/AyamController.php b/app/Http/Controllers/AyamController.php
index 9ca9ee8..26222d8 100644
--- a/app/Http/Controllers/AyamController.php
+++ b/app/Http/Controllers/AyamController.php
@@ -3,6 +3,7 @@
namespace App\Http\Controllers;
use App\Models\MutasiAyam;
+use App\Models\JenisMutasi;
use App\Models\Kandang;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
@@ -13,7 +14,8 @@ class AyamController extends Controller
{
public function index(Request $request)
{
- $query = MutasiAyam::with('kandang');
+ $query = MutasiAyam::with(['kandang', 'jenisMutasi']);
+ $jenisMutasi = JenisMutasi::all();
/** @var \App\Models\User $user */
$user = Auth::user();
@@ -45,32 +47,33 @@ public function index(Request $request)
->select('id', 'nama_kandang')
->selectSub(function ($q) {
$q->from('mutasi_ayam')
+ ->join('jenis_mutasi', 'mutasi_ayam.jenis_mutasi_id', '=', 'jenis_mutasi.id')
->whereColumn('mutasi_ayam.kandang_id', 'kandang.id')
->selectRaw("
COALESCE(SUM(
CASE
- WHEN jenis_mutasi = 'masuk' THEN jumlah
- WHEN jenis_mutasi IN ('mati','afkir','pindah') THEN -jumlah
+ WHEN jenis_mutasi.tipe = 'tambah' THEN jumlah
+ WHEN jenis_mutasi.tipe = 'kurang' THEN -jumlah
+ WHEN jenis_mutasi.tipe = 'transfer' THEN -jumlah
ELSE 0
END
- ), 0)
+ ),0)
");
}, 'jumlah_ayam_terakhir')
->get();
-
- return view('inventori-ayam', compact('data', 'kandang'));
- }
+ return view('inventori-ayam', compact('data', 'kandang', 'jenisMutasi'));
+ }
public function store(Request $request)
{
$request->validate([
- 'jenis_mutasi' => 'required|in:masuk,mati,afkir,pindah',
- 'jumlah' => 'required|integer|min:1|max:9999',
+ 'jenis_mutasi_id' => 'required|exists:jenis_mutasi,id',
+ 'jumlah' => 'required|integer|min:1|max:9999',
'tanggal' => 'required|date|before_or_equal:today',
- 'keterangan' => 'required_if:jenis_mutasi,masuk,mati,afkir|string|max:255',
- ], [
- 'jenis_mutasi.required' => 'Jenis mutasi wajib dipilih.',
- 'jenis_mutasi.in' => 'Jenis mutasi tidak valid.',
+ 'keterangan' => 'nullable|string|max:255',
+ ], [
+ 'jenis_mutasi_id.required' => 'Jenis mutasi wajib dipilih.',
+ 'jenis_mutasi_id.exists' => 'Jenis mutasi tidak valid.',
'jumlah.required' => 'Jumlah ayam wajib diisi.',
'jumlah.integer' => 'Jumlah ayam harus berupa angka.',
@@ -87,10 +90,14 @@ public function store(Request $request)
DB::transaction(function () use ($request) {
- // PINDAH
- if ($request->jenis_mutasi === 'pindah') {
+ // ✅ ambil jenis mutasi dari tabel master
+ $jenisPindah = JenisMutasi::where('nama', 'pindah')->first();
+ $jenisMasuk = JenisMutasi::where('nama', 'masuk')->first();
- $request->validate([
+ // PINDAH
+ $jenis = JenisMutasi::findOrFail($request->jenis_mutasi_id);
+
+ if ($jenis->nama === 'pindah'){ $request->validate([
'kandang_asal_id' => 'required|exists:kandang,id|different:kandang_tujuan_id',
'kandang_tujuan_id' => 'required|exists:kandang,id',
], [
@@ -103,14 +110,17 @@ public function store(Request $request)
$kandangTujuan = Kandang::findOrFail($request->kandang_tujuan_id);
$stokAsal = $kandangAsal->mutasiAyam()
+ ->join('jenis_mutasi', 'mutasi_ayam.jenis_mutasi_id', '=', 'jenis_mutasi.id')
->selectRaw("
-COALESCE(SUM(
-CASE
-WHEN jenis_mutasi='masuk' THEN jumlah
-WHEN jenis_mutasi IN ('mati','afkir','pindah') THEN -jumlah
-ELSE 0 END
-),0) as stok
-")->value('stok');
+ COALESCE(SUM(
+ CASE
+ WHEN jenis_mutasi.tipe = 'tambah' THEN jumlah
+ WHEN jenis_mutasi.tipe IN ('kurang','transfer') THEN -jumlah
+ ELSE 0
+ END
+ ),0) as stok
+ ")
+ ->value('stok');
if ($stokAsal <= 0) {
throw \Illuminate\Validation\ValidationException::withMessages([
@@ -127,8 +137,8 @@ public function store(Request $request)
MutasiAyam::create([
'kandang_id' => $request->kandang_asal_id,
'user_id' => Auth::id(),
- 'jenis_mutasi' => 'pindah',
- 'jumlah' => $request->jumlah,
+ 'jenis_mutasi_id' => $jenisPindah->id,
+ 'jumlah' => $request->jumlah,
'tanggal' => $request->tanggal,
'keterangan' => 'Pindah ke ' . $kandangTujuan->nama_kandang,
]);
@@ -136,8 +146,8 @@ public function store(Request $request)
MutasiAyam::create([
'kandang_id' => $request->kandang_tujuan_id,
'user_id' => Auth::id(),
- 'jenis_mutasi' => 'masuk',
- 'jumlah' => $request->jumlah,
+ 'jenis_mutasi_id' => $jenisMasuk->id,
+ 'jumlah' => $request->jumlah,
'tanggal' => $request->tanggal,
'keterangan' => 'Pindahan dari ' . $kandangAsal->nama_kandang,
]);
@@ -152,22 +162,24 @@ public function store(Request $request)
'kandang_id.required' => 'Nama kandang wajib dipilih.',
'kandang_id.exists' => 'Kandang tidak ditemukan.',
]);
-
$kandang = Kandang::findOrFail($request->kandang_id);
- $stok = $kandang->mutasiAyam()->selectRaw("
-COALESCE(SUM(
-CASE
-WHEN jenis_mutasi='masuk' THEN jumlah
-WHEN jenis_mutasi IN ('mati','afkir','pindah') THEN -jumlah
-ELSE 0 END
-),0) as stok
-")->value('stok');
-
+ $stok = $kandang->mutasiAyam()
+ ->join('jenis_mutasi', 'mutasi_ayam.jenis_mutasi_id', '=', 'jenis_mutasi.id')
+ ->selectRaw("
+ COALESCE(SUM(
+ CASE
+ WHEN jenis_mutasi.tipe = 'tambah' THEN jumlah
+ WHEN jenis_mutasi.tipe IN ('kurang','transfer') THEN -jumlah
+ ELSE 0
+ END
+ ),0) as stok
+ ")
+ ->value('stok'); // ← WAJIB
+ $jenis = JenisMutasi::findOrFail($request->jenis_mutasi_id);
// Kalau mutasi keluar/mati/afkir → cek stok
- if (in_array($request->jenis_mutasi, ['mati', 'afkir'])) {
-
- if ($stok <= 0) {
+ if (in_array($jenis->nama, ['mati', 'afkir'])) {
+ if ($stok <= 0) {
throw \Illuminate\Validation\ValidationException::withMessages([
'jumlah' => 'Stok ayam di kandang ini sudah habis.'
]);
@@ -183,8 +195,8 @@ public function store(Request $request)
MutasiAyam::create([
'kandang_id' => $request->kandang_id,
'user_id' => Auth::id(),
- 'jenis_mutasi' => $request->jenis_mutasi,
- 'jumlah' => $request->jumlah,
+ 'jenis_mutasi_id' => $request->jenis_mutasi_id,
+ 'jumlah' => $request->jumlah,
'tanggal' => $request->tanggal,
'keterangan' => $request->keterangan,
]);
@@ -200,8 +212,8 @@ public function update(Request $request, $id)
$mutasi = MutasiAyam::findOrFail($id);
// CEGAH EDIT DATA PINDAH
if (
- $mutasi->jenis_mutasi === 'pindah' ||
- str_contains($mutasi->keterangan, 'Pindahan dari')
+ $mutasi->jenisMutasi->nama === 'pindah' ||
+ str_contains($mutasi->keterangan, 'Pindahan dari')
) {
abort(403, 'Data hasil pindahan tidak boleh diedit.');
}
@@ -214,16 +226,16 @@ public function update(Request $request, $id)
// VALIDASI MANUAL
$validator = Validator::make($request->all(), [
'kandang_id' => 'required|exists:kandang,id',
- 'jenis_mutasi' => 'required|in:masuk,mati,afkir',
- 'jumlah' => 'required|integer|min:1|max:9999',
+ 'jenis_mutasi_id' => 'required|exists:jenis_mutasi,id',
+ 'jumlah' => 'required|integer|min:1|max:9999',
'tanggal' => 'required|date|before_or_equal:today',
- 'keterangan' => 'required_if:jenis_mutasi,masuk,mati,afkir|string|max:255',
+ 'keterangan' => 'nullable|string|max:255',
], [
'kandang_id.required' => 'Nama kandang wajib dipilih.',
'kandang_id.exists' => 'Kandang tidak ditemukan.',
- 'jenis_mutasi.required' => 'Jenis mutasi wajib dipilih.',
- 'jenis_mutasi.in' => 'Jenis mutasi tidak valid.',
+ 'jenis_mutasi_id.required' => 'Jenis mutasi wajib dipilih.',
+ 'jenis_mutasi_id.exists' => 'Jenis mutasi tidak valid.',
'jumlah.required' => 'Jumlah ayam wajib diisi.',
'jumlah.integer' => 'Jumlah ayam harus berupa angka.',
'jumlah.min' => 'Jumlah ayam minimal 1 ekor.',
@@ -241,29 +253,30 @@ public function update(Request $request, $id)
->withInput()
->with('edit_id', $mutasi->id);
}
-
+ $jenis = JenisMutasi::findOrFail($request->jenis_mutasi_id);
// HITUNG STOK
$kandang = Kandang::findOrFail($request->kandang_id);
$stok = $kandang->mutasiAyam()
- ->where('id', '!=', $mutasi->id)
+ ->join('jenis_mutasi', 'mutasi_ayam.jenis_mutasi_id', '=', 'jenis_mutasi.id')
->selectRaw("
-COALESCE(SUM(
-CASE
-WHEN jenis_mutasi='masuk' THEN jumlah
-WHEN jenis_mutasi IN ('mati','afkir','pindah') THEN -jumlah
-ELSE 0 END
-),0) as stok
-")->value('stok');
+ COALESCE(SUM(
+ CASE
+ WHEN jenis_mutasi.tipe = 'tambah' THEN jumlah
+ WHEN jenis_mutasi.tipe IN ('kurang','transfer') THEN -jumlah
+ ELSE 0
+ END
+ ),0) as stok
+ ")
+ ->value('stok'); // ✅ WAJIB
// kembalikan stok lama jika mutasi lama adalah pengurang
- if (in_array($mutasi->jenis_mutasi, ['mati', 'afkir', 'pindah'])) {
+ if (in_array($mutasi->jenisMutasi->nama, ['mati', 'afkir', 'pindah'])) {
$stok += $mutasi->jumlah;
}
// CEK STOK
- if (in_array($request->jenis_mutasi, ['mati', 'afkir'])) {
-
- if ($stok <= 0) {
+ if (in_array($jenis->nama, ['mati', 'afkir'])) {
+ if ($stok <= 0) {
throw \Illuminate\Validation\ValidationException::withMessages([
'jumlah' => 'Stok ayam di kandang ini sudah habis.'
]);
@@ -279,8 +292,8 @@ public function update(Request $request, $id)
// UPDATE DATA
$mutasi->update([
'kandang_id' => $request->kandang_id,
- 'jenis_mutasi' => $request->jenis_mutasi,
- 'jumlah' => $request->jumlah,
+ 'jenis_mutasi_id' => $request->jenis_mutasi_id,
+ 'jumlah' => $request->jumlah,
'tanggal' => $request->tanggal,
'keterangan' => $request->keterangan,
]);
@@ -300,8 +313,8 @@ public function destroy($id)
$mutasi = MutasiAyam::findOrFail($id);
if (
- $mutasi->jenis_mutasi === 'pindah' ||
- str_contains($mutasi->keterangan, 'Pindahan dari')
+ $mutasi->jenisMutasi->nama === 'pindah'||
+ str_contains($mutasi->keterangan, 'Pindahan dari')
) {
abort(403, 'Data hasil pindahan tidak boleh dihapus.');
}
diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php
index 47c3b31..230aa40 100644
--- a/app/Http/Controllers/HomeController.php
+++ b/app/Http/Controllers/HomeController.php
@@ -23,9 +23,17 @@ public function index()
/* STAT UMUM */
- $jumlahMasuk = MutasiAyam::where('jenis_mutasi', 'masuk')->sum('jumlah');
- $jumlahKeluar = MutasiAyam::whereIn('jenis_mutasi', ['keluar', 'mati', 'afkir', 'pindah'])->sum('jumlah');
- $jumlahAyam = $jumlahMasuk - $jumlahKeluar;
+ $jumlahAyam = MutasiAyam::join('jenis_mutasi', 'mutasi_ayam.jenis_mutasi_id', '=', 'jenis_mutasi.id')
+ ->selectRaw("
+ COALESCE(SUM(
+ CASE
+ WHEN jenis_mutasi.tipe = 'tambah' THEN jumlah
+ WHEN jenis_mutasi.tipe IN ('kurang','transfer') THEN -jumlah
+ ELSE 0
+ END
+ ),0) as total
+ ")
+ ->value('total');
$produksiHariIni = ProduksiTelur::whereDate('tanggal_produksi', $today)
->sum(DB::raw('berat_telur_layak + berat_telur_rusak'));
diff --git a/app/Http/Controllers/JenisMutasiController.php b/app/Http/Controllers/JenisMutasiController.php
new file mode 100644
index 0000000..29d72fc
--- /dev/null
+++ b/app/Http/Controllers/JenisMutasiController.php
@@ -0,0 +1,58 @@
+get();
+ return view('jenis-mutasi', compact('data'));
+ }
+
+ public function store(Request $request)
+ {
+ $request->validate([
+ 'nama' => 'required|string|max:255',
+ 'tipe' => 'required|in:tambah,kurang,transfer',
+ ]);
+
+ JenisMutasi::create([
+ 'nama' => $request->nama,
+ 'tipe' => $request->tipe,
+ ]);
+
+ return redirect()->route('jenis-mutasi')
+ ->with('success', 'Jenis mutasi berhasil ditambahkan.');
+ }
+
+ public function update(Request $request, $id)
+ {
+ $data = JenisMutasi::findOrFail($id);
+
+ $request->validate([
+ 'nama' => 'required|string|max:255',
+ 'tipe' => 'required|in:tambah,kurang,transfer',
+ ]);
+
+ $data->update([
+ 'nama' => $request->nama,
+ 'tipe' => $request->tipe,
+ ]);
+
+ return redirect()->route('jenis-mutasi')
+ ->with('success', 'Jenis mutasi berhasil diperbarui.');
+ }
+
+ public function destroy($id)
+ {
+ $data = JenisMutasi::findOrFail($id);
+ $data->delete();
+
+ return redirect()->route('jenis-mutasi')
+ ->with('success', 'Jenis mutasi berhasil dihapus.');
+ }
+}
diff --git a/app/Http/Controllers/KaryawanController.php b/app/Http/Controllers/KaryawanController.php
index bb26809..653d413 100644
--- a/app/Http/Controllers/KaryawanController.php
+++ b/app/Http/Controllers/KaryawanController.php
@@ -28,7 +28,7 @@ public function index(Request $request)
}
$perPage = in_array($request->perPage, [10, 25, 50]) ? $request->perPage : 10;
-
+
$data = $query
->orderBy('created_at', 'desc')
->paginate($perPage)
@@ -41,8 +41,8 @@ public function store(Request $request)
{
$request->validate(
[
- 'nama_karyawan' => 'required|string|min:3|max:100',
- 'no_hp' => ['required', 'regex:/^08[0-9]{8,11}$/'],
+ 'nama_karyawan' => ['required', 'string', 'min:3', 'max:100', 'regex:/^[A-Za-z\s]+$/'],
+ 'no_hp' => ['required', 'regex:/^08[0-9]{8,11}$/'],
'alamat' => 'required|string|max:255',
'status_karyawan' => 'required|in:aktif,nonaktif',
],
@@ -51,6 +51,7 @@ public function store(Request $request)
'nama_karyawan.string' => 'Nama karyawan harus berupa teks',
'nama_karyawan.min' => 'Nama karyawan minimal 3 karakter',
'nama_karyawan.max' => 'Nama karyawan maksimal 100 karakter',
+ 'nama_karyawan.regex' => 'Nama hanya boleh berisi huruf dan spasi',
'no_hp.required' => 'Nomor HP wajib diisi',
'no_hp.regex' => 'Nomor HP harus 10–13 digit, diawali 08, dan hanya angka.',
@@ -112,8 +113,8 @@ public function update(Request $request, $id)
{
$request->validate(
[
- 'nama_karyawan' => 'required|string|min:3|max:100',
- 'no_hp' => ['required', 'regex:/^08[0-9]{8,11}$/'],
+ 'nama_karyawan' => ['required', 'string', 'min:3', 'max:100', 'regex:/^[A-Za-z\s]+$/'],
+ 'no_hp' => ['required', 'regex:/^08[0-9]{8,11}$/'],
'alamat' => 'required|string|max:255',
],
[
@@ -121,6 +122,7 @@ public function update(Request $request, $id)
'nama_karyawan.string' => 'Nama karyawan harus berupa teks',
'nama_karyawan.min' => 'Nama karyawan minimal 3 karakter',
'nama_karyawan.max' => 'Nama karyawan maksimal 100 karakter',
+ 'nama_karyawan.regex' => 'Nama hanya boleh berisi huruf dan spasi',
'no_hp.required' => 'Nomor HP wajib diisi',
'no_hp.regex' => 'Nomor HP harus 10–13 digit, diawali 08, dan hanya angka.',
diff --git a/app/Http/Controllers/PakanController.php b/app/Http/Controllers/PakanController.php
index 400b5cb..f516236 100644
--- a/app/Http/Controllers/PakanController.php
+++ b/app/Http/Controllers/PakanController.php
@@ -79,8 +79,13 @@ public function index(Request $request)
$min = $batasMinimum[$item->nama_barang] ?? 5;
return $item->stok <= $min;
});
+ $stokAman = $stok->filter(function ($item) use ($batasMinimum) {
+ $min = $batasMinimum[$item->nama_barang] ?? 5;
+ return $item->stok > $min;
+ });
- return view('inventori-pakan', compact('data', 'stokMenipis'));
+ // return view('inventori-pakan', compact('data', 'stokMenipis'));
+ return view('inventori-pakan', compact('data', 'stokMenipis', 'stokAman'));
}
public function store(Request $request)
diff --git a/app/Models/JenisMutasi.php b/app/Models/JenisMutasi.php
new file mode 100644
index 0000000..2ef5454
--- /dev/null
+++ b/app/Models/JenisMutasi.php
@@ -0,0 +1,20 @@
+hasMany(MutasiAyam::class, 'jenis_mutasi_id');
+ }
+}
diff --git a/app/Models/MutasiAyam.php b/app/Models/MutasiAyam.php
index a98eea9..a022a2b 100644
--- a/app/Models/MutasiAyam.php
+++ b/app/Models/MutasiAyam.php
@@ -14,7 +14,7 @@ class MutasiAyam extends Model
protected $fillable = [
'kandang_id',
'user_id',
- 'jenis_mutasi',
+ 'jenis_mutasi_id', // ✅ ganti ini
'jumlah',
'tanggal',
'keterangan',
@@ -33,4 +33,10 @@ public function user()
{
return $this->belongsTo(User::class, 'user_id');
}
+
+ // ✅ RELASI BARU
+ public function jenisMutasi()
+ {
+ return $this->belongsTo(JenisMutasi::class, 'jenis_mutasi_id');
+ }
}
diff --git a/database/migrations/2026_04_21_072756_create_jenis_mutasi_table.php b/database/migrations/2026_04_21_072756_create_jenis_mutasi_table.php
new file mode 100644
index 0000000..5fc87ec
--- /dev/null
+++ b/database/migrations/2026_04_21_072756_create_jenis_mutasi_table.php
@@ -0,0 +1,29 @@
+id();
+ $table->string('nama')->unique();
+ $table->enum('tipe', ['tambah', 'kurang', 'transfer']);
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::dropIfExists('jenis_mutasi');
+ }
+};
diff --git a/database/migrations/2026_04_21_075208_add_jenis_mutasi_id_to_mutasi_ayam.php b/database/migrations/2026_04_21_075208_add_jenis_mutasi_id_to_mutasi_ayam.php
new file mode 100644
index 0000000..927caef
--- /dev/null
+++ b/database/migrations/2026_04_21_075208_add_jenis_mutasi_id_to_mutasi_ayam.php
@@ -0,0 +1,64 @@
+unsignedBigInteger('jenis_mutasi_id')->nullable()->after('user_id');
+ });
+
+ // 2. Mapping data lama (enum → id)
+ $data = DB::table('mutasi_ayam')->get();
+
+ foreach ($data as $item) {
+ $jenis = DB::table('jenis_mutasi')
+ ->where('nama', $item->jenis_mutasi)
+ ->first();
+
+ if ($jenis) {
+ DB::table('mutasi_ayam')
+ ->where('id', $item->id)
+ ->update([
+ 'jenis_mutasi_id' => $jenis->id
+ ]);
+ }
+ }
+
+ // 3. Tambahkan foreign key
+ Schema::table('mutasi_ayam', function (Blueprint $table) {
+ $table->foreign('jenis_mutasi_id')
+ ->references('id')
+ ->on('jenis_mutasi')
+ ->cascadeOnDelete();
+ });
+
+ // 4. (JANGAN DIHAPUS DULU)
+ // Nanti kalau semua sudah aman baru aktifkan ini
+ /*
+ Schema::table('mutasi_ayam', function (Blueprint $table) {
+ $table->dropColumn('jenis_mutasi');
+ });
+ */
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::table('mutasi_ayam', function (Blueprint $table) {
+ $table->dropForeign(['jenis_mutasi_id']);
+ $table->dropColumn('jenis_mutasi_id');
+ });
+ }
+};
diff --git a/database/migrations/2026_04_21_095453_drop_jenis_mutasi_enum_from_mutasi_ayam.php b/database/migrations/2026_04_21_095453_drop_jenis_mutasi_enum_from_mutasi_ayam.php
new file mode 100644
index 0000000..017ed00
--- /dev/null
+++ b/database/migrations/2026_04_21_095453_drop_jenis_mutasi_enum_from_mutasi_ayam.php
@@ -0,0 +1,27 @@
+dropColumn('jenis_mutasi');
+ }
+ });
+ }
+
+ public function down(): void
+ {
+ Schema::table('mutasi_ayam', function (Blueprint $table) {
+ if (!Schema::hasColumn('mutasi_ayam', 'jenis_mutasi')) {
+ $table->enum('jenis_mutasi', ['masuk', 'keluar', 'mati', 'afkir', 'pindah'])
+ ->after('jenis_mutasi_id')
+ ->nullable();
+ }
+ });
+ }
+};
diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php
index d43ace0..18d4f56 100644
--- a/database/seeders/DatabaseSeeder.php
+++ b/database/seeders/DatabaseSeeder.php
@@ -11,6 +11,7 @@ public function run(): void
$this->call([
UserSeeder::class,
KandangSeeder::class,
+ JenisMutasiSeeder::class,
KaryawanSeeder::class,
GajiKaryawanSeeder::class,
InventoriKandangSeeder::class,
diff --git a/database/seeders/JenisMutasiSeeder.php b/database/seeders/JenisMutasiSeeder.php
new file mode 100644
index 0000000..fe821ff
--- /dev/null
+++ b/database/seeders/JenisMutasiSeeder.php
@@ -0,0 +1,39 @@
+insert([
+ [
+ 'nama' => 'masuk',
+ 'tipe' => 'tambah',
+ 'created_at' => now(),
+ 'updated_at' => now(),
+ ],
+ [
+ 'nama' => 'mati',
+ 'tipe' => 'kurang',
+ 'created_at' => now(),
+ 'updated_at' => now(),
+ ],
+ [
+ 'nama' => 'afkir',
+ 'tipe' => 'kurang',
+ 'created_at' => now(),
+ 'updated_at' => now(),
+ ],
+ [
+ 'nama' => 'pindah',
+ 'tipe' => 'transfer',
+ 'created_at' => now(),
+ 'updated_at' => now(),
+ ],
+ ]);
+ }
+}
diff --git a/database/seeders/MutasiAyamSeeder.php b/database/seeders/MutasiAyamSeeder.php
index 21e7b56..d1b77bb 100644
--- a/database/seeders/MutasiAyamSeeder.php
+++ b/database/seeders/MutasiAyamSeeder.php
@@ -12,7 +12,7 @@ public function run(): void
MutasiAyam::create([
'kandang_id' => 1,
'user_id' => 1,
- 'jenis_mutasi' => 'masuk',
+ 'jenis_mutasi_id' => 1,
'jumlah' => 7000,
'tanggal' => now(),
'keterangan' => 'DOC baru'
diff --git a/public/assets/css/custom.css b/public/assets/css/custom.css
index f4ad976..853459a 100644
--- a/public/assets/css/custom.css
+++ b/public/assets/css/custom.css
@@ -505,4 +505,21 @@ @media (max-width: 768px) {
letter-spacing: .5px;
background: #f8f9fb;
}
-
\ No newline at end of file
+ .info-card {
+ background: #fff;
+ border: 1px solid #e5e7eb;
+ border-left: 4px solid #ccc;
+ border-radius: 10px;
+ padding: 12px 14px;
+ height: 100%;
+ }
+
+ .info-card.warning {
+ border-left-color: #f59e0b;
+ /* soft orange */
+ }
+
+ .info-card.success {
+ border-left-color: #10b981;
+ /* soft green */
+ }
diff --git a/resources/views/inventori-ayam.blade.php b/resources/views/inventori-ayam.blade.php
index 0e07025..72f9b4c 100644
--- a/resources/views/inventori-ayam.blade.php
+++ b/resources/views/inventori-ayam.blade.php
@@ -141,7 +141,7 @@ class="form-control form-control-sm">
{{ number_format($item->jumlah, 0, ',', '.') }} |
- {{ ucfirst($item->jenis_mutasi ?? '-') }}
+ {{ $item->jenisMutasi->nama ?? '-' }}
|
{{ $item->keterangan ?? '-' }} |
@@ -154,8 +154,8 @@ class="form-control form-control-sm">
@php
$isPindahan =
- $item->jenis_mutasi === 'pindah' ||
- str_contains($item->keterangan, 'Pindahan dari');
+ optional($item->jenisMutasi)->nama === 'pindah' ||
+str_contains($item->keterangan ?? '', 'Pindahan dari');
@endphp
{{-- ✅ TOMBOL EDIT --}}
@@ -165,7 +165,7 @@ class="btn btn-warning btn-sm {{ $isPindahan ? 'disabled opacity-50' : '' }}"
data-target="#modalEdit" @endif
data-id="{{ $item->id }}" data-kandang="{{ $item->kandang_id }}"
data-jumlah="{{ $item->jumlah }}"
- data-jenis="{{ $item->jenis_mutasi }}"
+ data-jenis="{{ $item->jenis_mutasi_id }}"
data-keterangan="{{ $item->keterangan }}"
data-tanggal="{{ $item->tanggal }}"
style="{{ $isPindahan ? 'pointer-events: none;' : '' }}"
@@ -249,19 +249,17 @@ class="btn btn-danger btn-sm {{ $isPindahan ? 'disabled opacity-50' : '' }}"
{{-- ================= JENIS MUTASI ================= --}}
-
@@ -425,16 +423,16 @@ class="form-control @error('tanggal') is-invalid @enderror"
-
-
-
-
-
+
+ @foreach ($jenisMutasi as $jm)
+
+@endforeach
- @error('jenis_mutasi')
+ @error('jenis_mutasi_id')
{{ $message }}
@enderror
@@ -506,6 +504,8 @@ class="form-control @error('tanggal') is-invalid @enderror"
diff --git a/resources/views/inventori-pakan.blade.php b/resources/views/inventori-pakan.blade.php
index 147edb7..b329f85 100644
--- a/resources/views/inventori-pakan.blade.php
+++ b/resources/views/inventori-pakan.blade.php
@@ -8,6 +8,47 @@
Manajemen Pakan
+ @if (auth()->user()->isAdmin() &&
+ ((isset($stokMenipis) && $stokMenipis->count()) || (isset($stokAman) && $stokAman->count())))
+
+
+
+ {{-- STOK MENIPIS --}}
+ @if (isset($stokMenipis) && $stokMenipis->count())
+
+
+
+
⚠
+
+
Stok Menipis
+
+ {{ $stokMenipis->map(fn($s) => $s->nama_barang . ' (' . number_format($s->stok, 0, ',', '.') . ')')->join(', ') }}
+
+
+
+
+
+ @endif
+
+ {{-- STOK AMAN --}}
+ @if (isset($stokAman) && $stokAman->count())
+
+
+
+
✔
+
+
Stok Aman
+
+ {{ $stokAman->map(fn($s) => $s->nama_barang . ' (' . number_format($s->stok, 0, ',', '.') . ')')->join(', ') }}
+
+
+
+
+
+ @endif
+
+
+@endif
- @if (auth()->user()->isAdmin() && isset($stokMenipis) && $stokMenipis->count())
-
-
⚠ Stok Menipis
+
+ {{-- @if (auth()->user()->isAdmin() && isset($stokMenipis) && $stokMenipis->count())
+
+
⚠ Stok Menipis
@foreach ($stokMenipis as $s)
-
@@ -101,7 +143,13 @@ class="form-control form-control-sm">
@endif
-
+ @if (auth()->user()->isAdmin() && isset($stokAman) && $stokAman->count())
+
+ Stok Aman:
+ {{ $stokAman->map(fn($s) => $s->nama_barang . ' (' . number_format($s->stok, 0, ',', '.') . ')')->join(', ') }}
+ karung
+
+@endif --}}
@if ($errors->has('delete'))
@@ -662,7 +710,7 @@ function hitungEdit() {
let harga = parseInt(btn.data('harga')) || 0;
$('#hargaEdit').val(harga ? formatRupiah(harga.toString()) : '');
-
+
// tanggal
$('#tanggalEdit').val(btn.data('tanggal'));
diff --git a/resources/views/jenis-mutasi.blade.php b/resources/views/jenis-mutasi.blade.php
new file mode 100644
index 0000000..19fcd91
--- /dev/null
+++ b/resources/views/jenis-mutasi.blade.php
@@ -0,0 +1,251 @@
+@extends('template')
+
+@section('title', 'Jenis Mutasi')
+
+@section('content')
+
+
+
+
+
Kelola Jenis Mutasi
+
+
+ {{--
--}}
+
+
+
+
+
+
+
+ {{--
+ Jenis Mutasi
+
--}}
+
+
+
+
+
+
+
+
+
+
+
+ | No |
+ Nama |
+ Tipe |
+ Aksi |
+
+
+
+
+ @forelse($data as $i => $item)
+
+ | {{ $i + 1 }} |
+ {{ $item->nama }} |
+
+
+ {{ ucfirst($item->tipe) }}
+
+ |
+
+
+
+ {{-- EDIT --}}
+
+
+ {{-- DELETE --}}
+
+
+ |
+
+ @empty
+
+ |
+ Belum ada data jenis mutasi
+ |
+
+ @endforelse
+
+
+
+
+
+
+
+
+
+
+
+ {{-- MODAL TAMBAH --}}
+
+
+ {{-- MODAL EDIT --}}
+
+
+ {{-- MODAL HAPUS --}}
+
+
+@endsection
+
+@section('scripts')
+
+@endsection
diff --git a/resources/views/karyawan.blade.php b/resources/views/karyawan.blade.php
index 3e865d2..7ebec40 100644
--- a/resources/views/karyawan.blade.php
+++ b/resources/views/karyawan.blade.php
@@ -181,16 +181,18 @@ class="d-inline">
-
+ @error('nama_karyawan')
+
{{ $message }}
+ @enderror
+
+
diff --git a/routes/web.php b/routes/web.php
index 198c52a..f7e5a54 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -12,7 +12,9 @@
KeuanganController,
LaporanController,
ProfilController,
- LaporanExportController
+ LaporanExportController,
+ JenisMutasiController
+
};
use App\Http\Middleware\CheckRole;
@@ -97,6 +99,14 @@
Route::get('/laporan', [LaporanController::class, 'index'])->name('laporan');
Route::get('/laporan/export', [LaporanController::class, 'export'])->name('laporan.export');
+
+ // JENIS MUTASI (MASTER DATA)
+ Route::prefix('jenis-mutasi')->group(function () {
+ Route::get('/', [JenisMutasiController::class, 'index'])->name('jenis-mutasi');
+ Route::post('/', [JenisMutasiController::class, 'store'])->name('jenis-mutasi.store');
+ Route::put('/{id}', [JenisMutasiController::class, 'update'])->name('jenis-mutasi.update');
+ Route::delete('/{id}', [JenisMutasiController::class, 'destroy'])->name('jenis-mutasi.delete');
+ });
});
});
Route::fallback(function () {