Files
ryobi-crawler/src/Models/Product.php

91 lines
2.2 KiB
PHP

<?php
namespace Krzysiej\RyobiCrawler\Models;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use function Symfony\Component\Clock\now;
/**
* @property integer $skuID
* @property string $name
* @property integer $availableQuantity
* @property string[] $categories
* @property string $image
* @property string $subTitle
* @property string $variantCode
* @property string $modelCode
* @property string $url
* @property int $starred
* @property float $priceCurrent
* @property float $priceLowest
* @property float $productStandardPrice
* @property float $lowestProductPrice30Days
*/
class Product extends Model
{
public $timestamps = true;
public $fillable = ['skuID'];
public function price(): HasMany
{
return $this->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');
}
}