initial commit

This commit is contained in:
2026-09-23 12:45:02 +07:00
parent d16f454083
commit 507fc6ccdf
235 changed files with 19587 additions and 2835 deletions
+47 -14
View File
@@ -3,19 +3,41 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Str;
class Food extends Model
{
protected $table = 'foods';
// Gunakan guarded atau fillable, pastikan 'slug' dan 'category_id' diizinkan
protected $guarded = ['id'];
// Menggunakan fillable lebih aman untuk tracking kolom apa saja yang masuk ke DB
protected $fillable = [
'nama_makanan',
'foto_produk',
'slug',
'qty',
'unit',
'category_id',
'kategori',
'expired_at'
];
/**
* Casting tipe data agar terbaca sebagai objek oleh Carbon
*/
protected function casts(): array
{
return [
'expired_at' => 'date',
'qty' => 'float',
'created_at' => 'datetime',
];
}
/**
* Relasi ke model Category
*/
public function category()
public function category(): BelongsTo
{
return $this->belongsTo(Category::class, 'category_id');
}
@@ -27,14 +49,13 @@ class Food extends Model
{
static::saving(function ($food) {
// 1. OTOMATIS GENERATE SLUG
// Hanya generate jika nama berubah atau slug masih kosong
if ($food->isDirty('nama_makanan') || empty($food->slug)) {
$food->slug = Str::slug($food->nama_makanan) . '-' . Str::random(5);
$food->slug = Str::slug($food->nama_makanan) . '-' . Str::lower(Str::random(5));
}
// 2. AUTO-CATEGORIZATION (SMART LOGIC)
// Hanya jalankan jika category_id belum diisi manual
if (empty($food->category_id)) {
// Jalankan hanya jika category_id belum diisi manual atau nama makanan berubah
if (empty($food->category_id) || $food->isDirty('nama_makanan')) {
$productName = strtolower($food->nama_makanan);
$categories = Category::whereNotNull('keywords')->get();
$found = false;
@@ -49,27 +70,39 @@ class Food extends Model
$food->category_id = $cat->id;
$food->kategori = $cat->name;
$found = true;
break; // Keluar dari loop keyword
break 2; // Keluar dari kedua loop sekaligus
}
}
if ($found) break; // Keluar dari loop kategori
}
// 3. FALLBACK LOGIC
// Jika tidak ada keyword yang cocok, cari kategori default
if (!$found) {
if (!$found && empty($food->category_id)) {
$default = Category::where('name', 'Dry Food')
->orWhere('name', 'Umum')
->first();
->orWhere('name', 'Umum')
->first();
if ($default) {
$food->category_id = $default->id;
$food->kategori = $default->name;
} else {
$food->kategori = 'Umum';
$food->kategori = $food->kategori ?: 'Umum';
}
}
}
// 4. SINKRONISASI TEKS KATEGORI
// Jika category_id diisi manual di form, pastikan kolom 'kategori' (string) juga terupdate
if ($food->isDirty('category_id') && !empty($food->category_id)) {
$food->kategori = $food->category?->name ?? $food->kategori;
}
});
}
/**
* Accessor: Cek Status Expired
*/
public function getIsExpiredAttribute(): bool
{
return $this->expired_at ? $this->expired_at->isPast() : false;
}
}