145 lines
4.9 KiB
PHP
145 lines
4.9 KiB
PHP
<?php
|
|
|
|
namespace KupShop\BonusProgramBundle\Actions;
|
|
|
|
use KupShop\AdminBundle\Admin\ProductsFilter;
|
|
use KupShop\BonusProgramBundle\Actions\Frontend\BonusProgramHandler;
|
|
use KupShop\KupShopBundle\Context\CurrencyContext;
|
|
use KupShop\KupShopBundle\Util\Contexts;
|
|
use KupShop\KupShopBundle\Util\Price\Price;
|
|
use KupShop\KupShopBundle\Util\Price\PriceCalculator;
|
|
use KupShop\OrderDiscountBundle\Actions\AbstractAction;
|
|
use KupShop\OrderDiscountBundle\Actions\Frontend\HandlerInterface;
|
|
use KupShop\OrderDiscountBundle\Entity\OrderDiscount;
|
|
use KupShop\OrderDiscountBundle\Util\DiscountUtil;
|
|
use KupShop\OrderingBundle\Entity\Purchase\DiscountPurchaseItem;
|
|
use KupShop\OrderingBundle\Entity\Purchase\ProductPurchaseItem;
|
|
use KupShop\OrderingBundle\Entity\Purchase\PurchaseState;
|
|
use KupShop\OrderingBundle\Util\Purchase\PurchaseUtil;
|
|
|
|
class BonusProgramAction extends AbstractAction
|
|
{
|
|
protected static $type = 'bonus_program';
|
|
protected static $position = 120;
|
|
protected $adminTemplate = 'actions/bonus_program.tpl';
|
|
protected $translationSection = 'bonus_program';
|
|
|
|
public function __construct(
|
|
private BonusProgramHandler $bonusProgramHandler,
|
|
private DiscountUtil $discountUtil,
|
|
private PurchaseUtil $purchaseUtil,
|
|
) {
|
|
}
|
|
|
|
public function handleData($data)
|
|
{
|
|
$data = parent::handleData($data);
|
|
|
|
$data['filter'] = ProductsFilter::cleanFilter($data['filter'] ?? []);
|
|
|
|
return $data;
|
|
}
|
|
|
|
public function applyResult(PurchaseState &$purchaseState, OrderDiscount $orderDiscount, array $data)
|
|
{
|
|
$bonus_points = $data['handled']['bonus_points'] ?? null;
|
|
$bonus_points_rate = $data['discount'] ?? null;
|
|
|
|
if (!$bonus_points || !$bonus_points_rate) {
|
|
return;
|
|
}
|
|
|
|
$discountPrice = toDecimal($bonus_points)->mul(toDecimal($bonus_points_rate));
|
|
|
|
if (!$discountPrice->isPositive()) {
|
|
if ($message = $data['messages']['warning'] ?? '') {
|
|
$this->messages['warning'] = $message;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if (ProductsFilter::isEnabled($data['filter'] ?? ['enabled' => 'N'])) {
|
|
if (!($items = $this->purchaseUtil->getProductsApplicableByProductsFilter($purchaseState, $data['filter'] ?? []))) {
|
|
if ($message = $data['messages']['warning'] ?? '') {
|
|
$this->messages['warning'] = $message;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
$total = $this->getItemsTotalPrice($items);
|
|
} else {
|
|
$items = $purchaseState->getProducts();
|
|
$total = new Price(
|
|
$purchaseState->getTotalPriceForDiscounts()->getPriceWithVat(),
|
|
$purchaseState->getTotalPriceForDiscounts()->getCurrency(),
|
|
0
|
|
);
|
|
}
|
|
|
|
$currencyContext = Contexts::get(CurrencyContext::class);
|
|
$currency = $currencyContext->getSupported()[$data['unit']] ?? $currencyContext->getDefault();
|
|
|
|
$total = PriceCalculator::convert($total, $currency);
|
|
|
|
if ($total->getPriceWithVat()->lessThan($discountPrice)) {
|
|
$discountPrice = $total->getPriceWithVat();
|
|
$bonus_points = $discountPrice->div(toDecimal($bonus_points_rate))->ceil()->asInteger();
|
|
$data['handled']['bonus_points'] = $bonus_points;
|
|
}
|
|
|
|
$name = $orderDiscount->getDisplayName().' ('.$bonus_points.')';
|
|
$data['id'] = $orderDiscount->getId();
|
|
$note = $this->createItemNote($data, $name);
|
|
$note = array_merge($note, $data['handled']);
|
|
|
|
if ($this->getDivideDiscountPrice($data)) {
|
|
$discountPrice = $this->discountUtil->divideDiscountPrice(
|
|
products: $items,
|
|
data: ['discount' => $discountPrice, 'unit' => $data['unit'], 'id' => $data['id']],
|
|
name: $name,
|
|
);
|
|
} else {
|
|
$discountPrice = $this->discountUtil->calculateDiscountPrice(
|
|
$discountPrice,
|
|
['discount' => $discountPrice, 'unit' => $data['unit']]
|
|
);
|
|
}
|
|
|
|
$purchaseState->addDiscount(new DiscountPurchaseItem(
|
|
name: $name,
|
|
price: $this->discountUtil->createDiscountPrice($discountPrice),
|
|
id_discount: $orderDiscount->getId(),
|
|
note: $note,
|
|
));
|
|
|
|
if ($message = $data['messages']['success'] ?? '') {
|
|
$this->messages['success'] = $message;
|
|
}
|
|
}
|
|
|
|
public function getFrontendHandler(): ?HandlerInterface
|
|
{
|
|
return $this->bonusProgramHandler;
|
|
}
|
|
|
|
/**
|
|
* @param ProductPurchaseItem[] $items
|
|
*/
|
|
private function getItemsTotalPrice(array $items): Price
|
|
{
|
|
$totalPrice = \DecimalConstants::zero();
|
|
|
|
foreach ($items as $item) {
|
|
$totalPrice = $totalPrice->add($item->getPriceWithVat());
|
|
}
|
|
|
|
return new Price(
|
|
$totalPrice,
|
|
Contexts::get(CurrencyContext::class)->getActive(),
|
|
0
|
|
);
|
|
}
|
|
}
|