Files
kupshop/bundles/KupShop/BonusProgramBundle/Actions/BonusPointsAction.php
2025-08-02 16:30:27 +02:00

134 lines
4.2 KiB
PHP

<?php
namespace KupShop\BonusProgramBundle\Actions;
use KupShop\AdminBundle\Admin\ProductsFilter;
use KupShop\KupShopBundle\Context\UserContext;
use KupShop\OrderDiscountBundle\Actions\AbstractAction;
use KupShop\OrderDiscountBundle\Entity\OrderDiscount;
use KupShop\OrderingBundle\Entity\Purchase\PurchaseState;
use KupShop\OrderingBundle\Util\Purchase\PurchaseUtil;
class BonusPointsAction extends AbstractAction
{
protected static $type = 'bonus_points';
protected static $position = 120;
protected $adminTemplate = 'actions/bonus_points.tpl';
protected $translationSection = 'bonus_program';
/** @required */
public PurchaseUtil $purchaseUtil;
/**
* @var UserContext
*/
protected $userContext;
public function __construct(UserContext $userContext)
{
$this->userContext = $userContext;
}
public function applyResult(PurchaseState &$purchaseState, OrderDiscount $orderDiscount, array $data)
{
// nemam modul
if (!findModule(\Modules::BONUS_PROGRAM)) {
return;
}
$this->messages = [];
$extraPoints = $this->getExtraPoints($purchaseState, $data);
// nasetuju extra body na PurchaseState
if ($extraPoints->isPositive()) {
if ($extra = $purchaseState->getCustomData('extra_bonus_points')) {
$extraPoints = $extraPoints->add(toDecimal($extra));
}
$purchaseState->setCustomData(['extra_bonus_points' => $extraPoints->asInteger()]);
// nemam uzivatele
if (!$this->userContext->getActiveId()) {
if ($message = $data['messages']['warning'] ?? '') {
$this->messages['warning'] = $message;
}
return;
}
$purchaseState->addUsedDiscount($orderDiscount->getId());
if ($message = $data['messages']['success'] ?? '') {
$this->messages['success'] = $message;
}
}
}
public function getPurchaseStateBonusPoints(PurchaseState $purchaseState, array $filter): \Decimal
{
$products = $this->purchaseUtil->getProductsApplicableByProductsFilter($purchaseState, $filter);
$points = \DecimalConstants::zero();
foreach ($products as $item) {
if ($bonus_points = $item->bonus_points) {
$points = $points->add($bonus_points);
}
}
return $points;
}
public function checkValidity(&$data)
{
if (!empty($data['discount'])) {
$data['discount'] = toDecimal($data['discount'])->asInteger();
if ($data['discount']) {
return true;
}
}
if (!empty($data['coefficient'])) {
$data['coefficient'] = toDecimal($data['coefficient'])->asFloat();
if ($data['coefficient']) {
return true;
}
}
throw new \Exception($this->getName().' ['.$this->getType().'] - data is not valid.');
}
protected function getExtraPoints(PurchaseState $purchaseState, array $data): \Decimal
{
$extraPoints = \DecimalConstants::zero();
// pridani statickeho poctu bodu
if (!empty($data['discount'])) {
$points = toDecimal($data['discount']);
if ($points->isPositive()) {
$extraPoints = $extraPoints->add($points);
}
}
// pridani nasobku bodu
if (!empty($data['coefficient'])) {
$coefficient = toDecimal($data['coefficient']);
if ($coefficient->asFloat() > 1) {
// celkovy pocet bodu na produktech, ktere jsou aplikovatelne na produkt filter u akce
$bonusPoints = $this->getPurchaseStateBonusPoints($purchaseState, $data['filter'] ?? []);
$extraPoints = $extraPoints->add($bonusPoints->mul($coefficient)->sub($bonusPoints));
}
}
return $extraPoints;
}
public function handleData($data)
{
$data = parent::handleData($data);
$data['filter'] = ProductsFilter::cleanFilter($data['filter'] ?? []);
return $data;
}
public function getDelayedExecution(): ?int
{
return 3;
}
}