File: D:/HostingSpaces/blijegasten/blijegasten.be/app/Komma/Shop/Orders/Product/OrderedProduct.php
<?php
namespace App\Komma\Shop\Orders\Product;
use App\Komma\Kms\Core\Attributes\Models\Traits\HasThumbnailInterface;
use App\Komma\Kms\Core\Attributes\Models\Traits\HasThumbnailTrait;
use App\Komma\Shop\Discounts\DiscountableInterface;
use App\Komma\Shop\Discounts\Discount;
use App\Komma\Shop\Orders\Models\Order;
use App\Komma\Shop\Orders\OrderedProductableInterface;
use App\Komma\Shop\Orders\ProductGroup\OrderedProductGroup;
use App\Komma\Shop\Products\Product\Product;
use App\Komma\Shop\Vat\VatServiceInterface;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use App\Komma\Shop\Discounts\Actions\ModifyPriceAction;
/**
* Represents a basic ordered product that a user did order.
*
* Use the product method to get the product this orderedProduct was based of.
*
* Class Product
*
* @package App
* @property int $id
* @property int $order_id
* @property int $product_id
* @property int $active
* @property string $title
* @property int $price Total price with discounts applied
* @property string $stock_keeping_unit
* @property int $quantity Total amount with discounts applied
* @property string $discount Applied discount information. Example: 10% + 1 for free. Product level only
* @property \Carbon\Carbon|null $created_at
* @property \Carbon\Carbon|null $updated_at
* @property-read \App\Komma\Shop\Orders\Models\Order $order
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Komma\Shop\Orders\ProductGroup\OrderedProductGroup[] $orderedGroups
* @property-read \App\Komma\Shop\Products\Product\Product $product
* @method static \Illuminate\Database\Eloquent\Builder|\App\Komma\Shop\Orders\Product\OrderedProduct whereActive($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Komma\Shop\Orders\Product\OrderedProduct whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Komma\Shop\Orders\Product\OrderedProduct whereDiscount($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Komma\Shop\Orders\Product\OrderedProduct whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Komma\Shop\Orders\Product\OrderedProduct whereOrderId($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Komma\Shop\Orders\Product\OrderedProduct wherePrice($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Komma\Shop\Orders\Product\OrderedProduct whereProductId($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Komma\Shop\Orders\Product\OrderedProduct whereQuantity($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Komma\Shop\Orders\Product\OrderedProduct whereStockKeepingUnit($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Komma\Shop\Orders\Product\OrderedProduct whereTitle($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Komma\Shop\Orders\Product\OrderedProduct whereUpdatedAt($value)
* @mixin \Eloquent
* @property string $video
* @method static \Illuminate\Database\Eloquent\Builder|\App\Komma\Shop\Orders\Product\OrderedProduct newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\App\Komma\Shop\Orders\Product\OrderedProduct newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\App\Komma\Shop\Orders\Product\OrderedProduct query()
* @method static \Illuminate\Database\Eloquent\Builder|\App\Komma\Shop\Orders\Product\OrderedProduct whereVideo($value)
*/
class OrderedProduct extends Model implements HasThumbnailInterface, OrderedProductableInterface
{
use HasThumbnailTrait;
/** @var Discount[] $discounts */
private $discounts = [];
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = ['active', 'price', 'price_excluding_vat', 'custom_vatrate', 'stock_keeping_unit', 'quantity', 'discount'];
/**
* Return the order or product group this ordered product belongs to
*
* @see Order
* @see OrderedProductGroup
* @return MorphTo
*/
public function orderable(): MorphTo
{
return $this->morphTo();
}
/**
* Return the product
*
* @return BelongsTo
*/
public function product():BelongsTo
{
return $this->belongsTo(Product::class);
}
/**
* Return the groups
*
* @return BelongsToMany
*/
public function orderedGroups()
{
return $this->belongsToMany(OrderedProductGroup::class);
}
/**
* Price is in cents
*
* @return int
*/
public function getPrice(): int
{
return $this->price;
}
/**
* Returns the total of all product prices. This value is in cents.
* And may be a float (e.g. value in cents with decimals)
* @param bool $includeDiscounts
* @return float
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
public function getTotal(bool $includeDiscounts = true): float
{
$price = $this->quantity * $this->price;
if($includeDiscounts && $this->discounts)
{
foreach($this->discounts as $discount)
{
$action = $discount->getDiscountAction();
switch (get_class($action))
{
case ModifyPriceAction::class;
$price = $action->do($price);
break;
}
}
}
return $price;
}
/**
* Applies the discount to itself
*
* @param Discount $discount
* @return DiscountableInterface
*/
public function applyDiscount(Discount $discount): DiscountableInterface
{
$this->discounts = [];
}
}