129 lines
3.2 KiB
PHP
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();
|
|
});
|
|
}
|
|
}
|