Files
kupshop/bundles/KupShop/ContentBundle/Entity/ProductUnified.php
2025-08-02 16:30:27 +02:00

373 lines
9.4 KiB
PHP

<?php
namespace KupShop\ContentBundle\Entity;
use KupShop\CatalogBundle\Entity\Variation;
use KupShop\CatalogBundle\Util\ProductAvailabilityUtil;
use KupShop\KupShopBundle\Util\Price\ProductPrice;
use KupShop\KupShopBundle\Wrapper\PriceWrapper;
class ProductUnified
{
protected \Product $product;
protected ?array $variations = null;
protected array|Variation|null $variation = null;
public function __construct(\Product $product, ?array $variations = null)
{
$this->product = $product;
$this->variations = $variations['variations'] ?? $variations ?? null;
}
public function selectVariation(int $id): bool
{
if ($this->variations[$id] ?? false) {
$this->variation = $this->variations[$id];
return true;
}
return false;
}
public function getProduct(): \Product
{
return $this->product;
}
public function getId(): int
{
return (int) $this->product->id;
}
public function getVariationId(): ?int
{
if ($this->variation) {
return (int) $this->variation['id'];
}
return null;
}
public function getTitle(): string
{
if ($this->variation) {
return $this->variation['title'] ?? '';
}
return $this->product->title;
}
public function getCode(): ?string
{
if ($this->variation) {
return $this->variation['code'] ?? null;
}
return $this->product->code;
}
public function getEan(): ?string
{
if ($this->variation) {
return $this->variation['ean'];
}
return $this->product->ean;
}
public function getUnit(): ?array
{
if (!findModule(\Modules::PRODUCTS, \Modules::SUB_UNITS)) {
return null;
}
return $this->product->unit;
}
public function getCharges(): array
{
return $this->product->fetchCharges();
}
public function getLabels(): array
{
return $this->product->fetchLabels();
}
public function getDeliveryTimeText(): string
{
if ($this->variation) {
// in cart delivery_time contains numeric delivery time, but on product detail it contains string... :/
// so try to use `delivery_time_text` and then fallback to `delivery_time` if `delivery_time_text` does not exists
return $this->variation['delivery_time_text'] ?? $this->variation['delivery_time'];
}
$this->product->prepareDeliveryText();
return $this->product->deliveryTimeText;
}
public function getSupplierForecastedDeliveryDate(): ?\DateTimeImmutable
{
$this->product->getInStoreSuppliers();
if ($this->variation) {
return $this->variation->getForecastedDeliveryDate();
}
return $this->product->forecasted_delivery_date;
}
public function getSupplierForecastedPieces(): int
{
$this->product->getInStoreSuppliers();
if ($this->variation) {
return $this->variation->getForecastedPieces() ?? 0;
}
return $this->product->forecasted_pieces ?? 0;
}
public function getDeliveryTime(): int
{
if ($this->variation) {
return (int) $this->variation['delivery_time_index'];
}
$this->product->prepareDeliveryText();
return (int) $this->product->deliveryTime;
}
public function getDeliveryTimeRaw(): int
{
if ($this->variation) {
return (int) $this->variation['delivery_time_raw'];
}
return (int) $this->product->deliveryTimeRaw;
}
public function getInStore(): float
{
if ($this->variation) {
return (float) $this->variation['in_store'];
}
return (float) $this->product->inStore;
}
public function getInStoreSuppliers(): float
{
if ($this->variation && isset($this->variation['in_store_suppliers'])) {
return (float) $this->variation['in_store_suppliers'];
}
return (float) $this->product->getInStoreSuppliers($this->variation['id'] ?? null);
}
public function getCampaignCodes(): array
{
return $this->product->campaign_codes;
}
public function getBonusPoints(): ?\Decimal
{
if (!findModule(\Modules::BONUS_PROGRAM)) {
return null;
}
if ($this->variation && isset($this->variation['bonus_points'])) {
return toDecimal($this->variation['bonus_points']);
}
return $this->product->getBonusPoints($this->getVariationId());
}
public function getDiscount(): \Decimal
{
if ($this->variation) {
$variationDiscount = toDecimal($this->variation['discount'] ?? 0);
if ($variationDiscount->isPositive()) {
return $variationDiscount;
}
}
return $this->product->discount;
}
public function getProductPrice(): ProductPrice
{
if ($this->variation) {
return PriceWrapper::unwrap($this->variation['productPrice']);
}
return $this->product->getProductPrice();
}
public function getPriceCommon(): ?ProductPrice
{
if ($this->variation) {
$priceCommon = !empty($this->variation['priceCommon']) ? $this->variation['priceCommon'] : null;
return PriceWrapper::unwrap($priceCommon);
}
return $this->product->priceCommon ? $this->product->priceCommon : null;
}
public function getPriceForDiscount(): ?ProductPrice
{
if ($this->variation) {
$priceForDiscount = !empty($this->variation['price_for_discount']) ? $this->variation['price_for_discount'] : null;
return PriceWrapper::unwrap($priceForDiscount);
}
return $this->product->priceForDiscount ? $this->product->priceForDiscount : null;
}
public function getData(): array
{
if ($this->variation) {
return $this->variation['data'] ?? [];
}
return $this->product->getData();
}
public function getSuppliers()
{
return $this->product->getSuppliers($this->variation['id'] ?? null);
}
public function getConfigurations(): array
{
$this->product->fetchParameters();
return $this->product->configurations ?? [];
}
public function getPhotos()
{
if ($this->variation && !empty($this->variation['photos'])) {
return $this->variation['photos'];
}
if (!$this->product->photos) {
$this->product->fetchImages(3, 4);
}
return $this->product->photos;
}
public function getMainPhoto(): ?array
{
if (empty($this->product->image)) {
$this->product->fetchImages(3);
}
return $this->product->image ?: null;
}
public function isVirtual(): bool
{
return (bool) $this->product->isVirtual();
}
public function canBuy(): bool
{
if ($this->variation) {
if (isset($this->variation['canBuy'])) {
return $this->variation['canBuy'];
} else {
ProductAvailabilityUtil::canBuy($this->variation['delivery_time_index'], false, $canWatch, $canBuy);
$this->variation['canWatch'] = $canWatch;
return $this->variation['canBuy'] = $canBuy;
}
}
return $this->product->canBuy();
}
public function canWatch(): ?bool
{
if ($this->variation) {
if (!isset($this->variation['canWatch'])) {
$this->canBuy();
}
return $this->variation['canWatch'];
}
return $this->product->canWatch();
}
public function getPricelists(): array
{
return $this->product->pricelists ?? [];
}
/**
* @return array<Variation|array>
*/
public function getVariations(): array
{
return $this->variations ?? [];
}
public function getTotalAvailablePieces(): float
{
if ($this->variation) {
if (isset($this->variation[ProductAvailabilityUtil::IN_STORE_MAX_FIELD])) {
return min(
$this->variation[ProductAvailabilityUtil::IN_STORE_MAX_FIELD],
$this->variation->getTotalAvailablePieces(),
);
}
return $this->variation->getTotalAvailablePieces();
}
if (isset($this->product[ProductAvailabilityUtil::IN_STORE_MAX_FIELD])) {
return min(
$this->product[ProductAvailabilityUtil::IN_STORE_MAX_FIELD],
$this->product->inStore + $this->product->getInStoreSuppliers(),
);
}
return $this->product->inStore + $this->product->getInStoreSuppliers();
}
public function getSections(): array
{
return $this->product->sections ?? [];
}
public function getProducer(): ?array
{
if (!findModule(\Modules::PRODUCERS)) {
return null;
}
return $this->product->producer;
}
public function getOnTheWay(): ?array
{
if (!findModule(\Modules::STOCK_IN)) {
return null;
}
if ($this->variation && isset($this->variation['onTheWay'])) {
return $this->variation['onTheWay'] ?? null;
}
return $this->product['onTheWay'] ?? null;
}
}