Files
kupshop/bundles/KupShop/OrderDiscountBundle/Triggers/PriceRangeTrigger.php
2025-08-02 16:30:27 +02:00

97 lines
3.4 KiB
PHP

<?php
namespace KupShop\OrderDiscountBundle\Triggers;
use KupShop\I18nBundle\Util\PriceConverter;
use KupShop\KupShopBundle\Context\CurrencyContext;
use KupShop\KupShopBundle\Query\JsonOperator;
use KupShop\OrderingBundle\Entity\Purchase\PurchaseState;
use Query\Operator;
class PriceRangeTrigger extends AbstractTrigger
{
protected static $type = 'price_range';
protected static $position = 30;
protected $adminTemplate = 'triggers/price_range.tpl';
protected $priceConverter;
protected $currencyContext;
public function __construct(PriceConverter $priceConverter, CurrencyContext $currencyContext)
{
$this->priceConverter = $priceConverter;
$this->currencyContext = $currencyContext;
}
public function getDiscountFilterSpec(PurchaseState $purchaseState)
{
$totalPrice = $purchaseState->getProductsTotalPrice();
$totalPriceWithVat = $this->priceConverter->convert(
$totalPrice->getCurrency(), $this->currencyContext->getDefault(), $totalPrice->getPriceWithVat()
)->asFloat();
$totalPriceWithoutVat = $this->priceConverter->convert(
$totalPrice->getCurrency(), $this->currencyContext->getDefault(), $totalPrice->getPriceWithoutVat()
)->asFloat();
$min = JsonOperator::value('odt.data', 'min', true);
$max = JsonOperator::value('odt.data', 'max', true);
$rate = 1;
if (findModule(\Modules::CURRENCIES)) {
$currency = JsonOperator::value('odt.data', 'unit');
$rate = "COALESCE((SELECT rate from currencies WHERE id = {$currency}), 1)";
}
$withVat = Operator::andX(
Operator::not(JsonOperator::contains('odt.data', 'withVat', '0')),
Operator::not(
Operator::andX(
"{$min} IS NULL OR {$totalPriceWithVat} >= {$min} * {$rate}",
"{$max} IS NULL OR {$totalPriceWithVat} <= {$max} * {$rate}"
)
)
);
$withoutVat = Operator::andX(
JsonOperator::contains('odt.data', 'withVat', '0'),
Operator::not(
Operator::andX(
"{$min} IS NULL OR {$totalPriceWithoutVat} >= {$min} * {$rate}",
"{$max} IS NULL OR {$totalPriceWithoutVat} <= {$max} * {$rate}"
)
)
);
return Operator::andX(
Operator::equals(['odt.type' => static::getType()]),
Operator::orX(
$withVat,
$withoutVat
)
);
}
public function getErrorMessage(PurchaseState $purchaseState, array $data): string
{
$error_message = '';
if (!empty($data['min'])) {
$totalPrice = $purchaseState->getTotalPriceForDiscounts()->getPriceWithVat();
$minPrice = toDecimal($data['min']);
$currency = $data['unit'] ?? $this->currencyContext->getDefaultId();
$minPrice = $this->priceConverter->convert($currency, $purchaseState->getTotalPriceForDiscounts()->getCurrency(), $minPrice);
$payForDiscount = $minPrice->sub($totalPrice);
if ($payForDiscount->isPositive()) {
$error_message = sprintf(
translate_shop('discount_price', 'order'),
printPrice($payForDiscount),
printPrice($minPrice)
);
}
}
return $error_message;
}
}