FleetCart/Modules/Cart/CartItem.php
2023-12-03 14:07:47 +00:00

129 lines
3.2 KiB
PHP

<?php
namespace Modules\Cart;
use stdClass;
use JsonSerializable;
use Modules\Support\Money;
use Modules\Product\Entities\Product;
use Modules\Product\Entities\ProductVariant;
class CartItem implements JsonSerializable
{
public $id;
public $qty;
public $product;
public $variant;
public $item;
public $options;
public $variations;
public function __construct($item)
{
$this->id = $item->id;
$this->qty = $item->quantity;
$this->product = $item->attributes['product'];
$this->variant = $item->attributes['variant'];
$this->item = $item->attributes['item'];
$this->variations = $item->attributes['variations'];
$this->options = $item->attributes['options'];
}
public function refreshStock()
{
$item = $this->getItem();
$this->item->fill([
'manage_stock' => $item->manage_stock,
'in_stock' => $item->in_stock,
'qty' => $item->qty,
]);
return $this;
}
public function getItem()
{
if ($this->item instanceof ProductVariant) {
return ProductVariant::addSelect('id', 'in_stock', 'manage_stock', 'qty')
->where('id', $this->variant->id)
->firstOrFail();
}
return Product::withName()
->addSelect('id', 'in_stock', 'manage_stock', 'qty')
->where('id', $this->product->id)
->firstOrFail();
}
public function findTax(array $addresses)
{
return $this->product->taxClass->findTaxRate($addresses);
}
public function __toString()
{
return json_encode($this->jsonSerialize());
}
public function jsonSerialize(): array
{
return [
'id' => $this->id,
'qty' => $this->qty,
'product' => $this->product->clean(),
'variant' => $this->variant?->clean(),
'item' => $this->item,
'variations' => $this->variations->isNotEmpty() ? $this->variations->keyBy('position') : new stdClass,
'options' => $this->options->isNotEmpty() ? $this->options->keyBy('position') : new stdClass,
'unitPrice' => $this->unitPrice(),
'total' => $this->totalPrice(),
];
}
public function unitPrice()
{
return $this->item->selling_price->add($this->optionsPrice());
}
public function optionsPrice(): Money
{
return Money::inDefaultCurrency($this->calculateOptionsPrice());
}
public function totalPrice()
{
return $this->unitPrice()->multiply($this->qty);
}
private function calculateOptionsPrice()
{
return $this->options->sum(function ($option) {
return $this->sumOfTheValuesOf($option);
});
}
private function sumOfTheValuesOf($option)
{
return $option->values->sum(function ($value) {
if ($value->price_type === 'fixed') {
return $value->price->amount();
}
return ($value->price / 100) * $this->item->selling_price->amount();
});
}
}