ldc-boutique-cnc-sable/domain/Models/ValueObjects/BasketProduct.php
Jérémy Munsch 71e0d65f31
refactor(OrderService): simplify order creation from basket
Updated the OrderService to utilize the new fromBasket method for creating orders, enhancing code clarity and maintainability. Removed the ProductAvailabilityService as its functionality is now integrated into the ProductRepository.
2026-10-29 20:21:32 +01:00

105 lines
2.8 KiB
PHP

<?php
declare(strict_types=1);
namespace Domain\Models\ValueObjects;
use Domain\Enums\ProductBrand;
use Domain\Enums\TaxRate;
use Domain\Enums\Units\OrderUnit;
use Domain\Models\Entities\Product;
use Domain\Models\ValueObjects\Entities\ProductId;
use Money\Money;
final readonly class BasketProduct
{
public function __construct(
public ProductId $id,
public string $name,
public int $qty,
public Money $unitPriceHt,
public Money $unitDiscount,
public TaxRate $taxRate,
public int $weightGrams,
public ?ProductBrand $brand,
public ?IncoId $incoId,
public OrderUnit $orderUnit,
public string $slug,
public ?string $picture,
public ?string $description,
public bool $weightVariable,
public DiscountRate $discountRate,
public Money $priceKgTtc,
/** @var array<string,mixed> */
public array $options = []
) {
if (trim($name) === '') {
throw new \DomainException('name cannot be empty');
}
if (trim($slug) === '') {
throw new \DomainException('slug cannot be empty');
}
if ($qty <= 0) {
throw new \DomainException('qty has to be positive');
}
if (! $unitPriceHt->isPositive()) {
throw new \DomainException('unitPriceHt has to be positive');
}
if (! $unitDiscount->isPositive() && ! $unitDiscount->isZero()) {
throw new \DomainException('unitDiscount cannot be negative');
}
if (! $priceKgTtc->isPositive()) {
throw new \DomainException('priceKgTtc has to be positive');
}
}
public function unitPriceHt(): Money
{
return $this->unitPriceHt;
}
public function unitPriceDiscounted(): Money
{
return $this->unitPriceHt->subtract($this->unitDiscount);
}
public function unitTax(): Money
{
return $this->unitTtc()->subtract($this->unitPriceDiscounted());
}
public function unitTtc(): Money
{
return $this->taxRate->applyTo($this->unitPriceDiscounted());
}
public function discountTotal(): Money
{
return $this->unitDiscount->multiply($this->qty, Product::ROUNDING);
}
public function priceTotalHt(): Money
{
return $this->unitPriceHt->multiply($this->qty, Product::ROUNDING);
}
public function subtotalHt(): Money
{
return $this->priceTotalHt()->subtract($this->discountTotal());
}
public function taxTotal(): Money
{
return $this->totalTtc()->subtract($this->subtotalHt());
}
public function totalTtc(): Money
{
return $this->taxRate->applyTo($this->subtotalHt());
}
public function weightTotal(): int
{
return $this->weightGrams * $this->qty;
}
}