<?php
namespace Neon\Configurator\Cart\Checkout;
use Neon\Configurator\Core\Content\Configuration\ConfigurationEntity;
use Neon\Configurator\Services\ConfigurationLoader;
use Shopware\Core\Content\Product\ProductMaxPurchaseCalculator;
use Shopware\Core\Framework\DataAbstractionLayer\Entity;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Core\System\SystemConfig\SystemConfigService;
class ConfiguratorProductMaxPurchaseCalculator extends ProductMaxPurchaseCalculator
{
const MAX_VALUE_FALLBACK = 2147483647;
private SystemConfigService $systemConfigService;
private ConfigurationLoader $configurationLoader;
public function __construct(SystemConfigService $systemConfigService, ConfigurationLoader $configurationLoader)
{
parent::__construct($systemConfigService);
$this->systemConfigService = $systemConfigService;
$this->configurationLoader = $configurationLoader;
}
public function calculate(Entity $product, SalesChannelContext $context): int
{
$fallback = $this->systemConfigService->getInt(
'core.cart.maxQuantity',
$context->getSalesChannel()->getId()
);
$fallback = $this->setFallbackToMaxMysqlIntValueIfConfigProductWithCalcualtedQuantity($product, $context, $fallback);
$max = $product->get('maxPurchase') ?? $fallback;
if ($product->get('isCloseout') && $product->get('availableStock') < $max) {
$max = (int)$product->get('availableStock');
}
$steps = $product->get('purchaseSteps') ?? 1;
$min = $product->get('minPurchase') ?? 1;
// the amount of times the purchase step is fitting in between min and max added to the minimum
$max = \floor(($max - $min) / $steps) * $steps + $min;
return (int)\max($max, 0);
}
/**
* @param SalesChannelContext $context
* @param int $fallback
* @return
*/
private function setFallbackToMaxMysqlIntValueIfConfigProductWithCalcualtedQuantity($product, SalesChannelContext $context, $fallback)
{
/** @var ConfigurationEntity $configuration */
$configuration = $this->configurationLoader->loadWithoutAssociations($product, $context);
if ($configuration != null && ($configuration->getQuantityMode() == 'field' || $configuration->getQuantityMode() == 'calculation')) {
$fallback = self::MAX_VALUE_FALLBACK;
}
return $fallback;
}
}