hasMany(Price::class); } public function isStarred(): bool { return (bool)$this->starred; } public function currentPrice(): HasOne { return $this->hasOne(Price::class)->latestOfMany('created_at'); } public function lowestPrice(): HasOne { return $this->hasOne(Price::class)->ofMany('price', 'MIN'); } public function newestPrice(): HasOne { return $this->hasOne(Price::class)->latest(); } public function stock(): HasMany { return $this->hasMany(Stock::class); } public function currentStock(): HasOne { return $this->stock()->one()->ofMany()->withDefault(fn (Stock $stock) => $stock->stock = 0); } public function toggleStarred(): self { $this->starred = !$this->starred; return $this; } public function categories(): Attribute { return Attribute::make( get: fn(string $value) => array_reverse(json_decode($value, 1)), set: fn(array $value) => json_encode($value), ); } public function isDiscontinued(): bool { return $this->updated_at->format('Y-m-d') < now()->format('Y-m-d'); } public function isNew(): bool { return $this->created_at->format('Y-m-d') > now()->modify('-30 days')->format('Y-m-d'); } }