Files
2026-09-23 12:45:02 +07:00

123 lines
3.5 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Facades\Storage;
use Carbon\Carbon;
class Medicine extends Model
{
/**
* Mass assignment.
* Menambahkan expired_at dan category_id agar sinkron dengan update database terbaru.
*/
protected $fillable = [
'nama_obat',
'foto_produk',
'kategori',
'category_id',
'qty',
'unit',
'expired_date',
'expired_at'
];
/**
* Modern Casting (Laravel 11/12 style)
*/
protected function casts(): array
{
return [
'expired_date' => 'date',
'expired_at' => 'date',
'qty' => 'float', // Mendukung dosis desimal (misal 2.5 ml)
'created_at' => 'datetime',
];
}
/**
* Logic Otomatisasi & Integritas Data
*/
protected static function booted()
{
static::saving(function ($medicine) {
$name = strtolower($medicine->nama_obat);
// 1. OTOMATISASI KATEGORI BERDASARKAN KEYWORDS
$categories = \App\Models\Category::all();
$matched = false;
foreach ($categories as $cat) {
$keywords = explode(',', strtolower($cat->keywords));
foreach ($keywords as $keyword) {
if (str_contains($name, trim($keyword))) {
$medicine->category_id = $cat->id;
$medicine->kategori = $cat->name;
$matched = true;
break 2;
}
}
}
if (!$matched) {
$medicine->kategori = $medicine->kategori ?: 'Umum';
}
// 2. SINKRONISASI TANGGAL EXPIRED (Double Guard)
// Jika expired_at kosong tapi expired_date ada, samakan. Begitu juga sebaliknya.
if ($medicine->expired_date && !$medicine->expired_at) {
$medicine->expired_at = $medicine->expired_date;
} elseif ($medicine->expired_at && !$medicine->expired_date) {
$medicine->expired_date = $medicine->expired_at;
}
});
}
/**
* Accessor: Mempermudah pemanggilan foto produk dengan fallback image.
*/
public function getFotoUrlAttribute(): string
{
if ($this->foto_produk && Storage::disk('public')->exists($this->foto_produk)) {
return asset('storage/' . $this->foto_produk);
}
return 'https://ui-avatars.com/api/?name=' . urlencode($this->nama_obat) . '&background=f1f5f9&color=64748b';
}
/**
* Accessor: Cek Status Expired secara instan.
* Bisa digunakan di Blade: @if($medicine->is_expired) ... @endif
*/
public function getIsExpiredAttribute(): bool
{
return $this->expired_at ? $this->expired_at->isPast() : false;
}
/**
* Relasi ke Kategori Obat.
*/
public function category(): BelongsTo
{
return $this->belongsTo(Category::class, 'category_id');
}
/**
* Relasi ke riwayat pengobatan kucing.
*/
public function treatments(): HasMany
{
return $this->hasMany(Treatment::class, 'medicine_id');
}
/**
* Melihat riwayat penggunaan obat ini di berbagai rekam medis
*/
public function treatmentDetails()
{
return $this->hasMany(TreatmentDetail::class);
}
}