123 lines
3.5 KiB
PHP
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);
|
|
}
|
|
} |