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

124 lines
4.8 KiB
PHP

<?php
namespace KupShop\BonusProgramBundle\Actions;
use KupShop\KupShopBundle\Context\CurrencyContext;
use KupShop\KupShopBundle\Util\Contexts;
use KupShop\KupShopBundle\Util\Price\PriceCalculator;
use KupShop\OrderDiscountBundle\Entity\OrderDiscount;
use KupShop\OrderingBundle\Entity\Purchase\PurchaseState;
class BonusPointsOtherReceiverAction extends BonusPointsAction
{
protected static $type = 'bonus_points_other_rec';
protected $adminTemplate = 'actions/bonus_points_other_receiver.tpl';
public function applyResult(PurchaseState &$purchaseState, OrderDiscount $orderDiscount, array $data)
{
// neman komu pridelit
if (empty($data['other_receiver_user_id'])) {
return;
}
$extraPoints = $this->getExtraPoints($purchaseState, $data);
// Nemam co pridelit
if ($extraPoints->isZero()) {
return;
}
// nacti seznam uzivatelu a bodu z pstatu, pokud tam nejsou inicializuj
if (!$pointsForOtherReceivers = $purchaseState->getCustomData('points_for_other_receivers')) {
$pointsForOtherReceivers = [];
}
// nasetuj uzivatele a jejich body na PurchaseState, pokud uz v poli zaznam pro daneho uzivatele je tak body pricti k existujicimu zaznamu
$column = array_column($pointsForOtherReceivers, 'user_id');
if (in_array($data['other_receiver_user_id'], $column)) {
foreach ($pointsForOtherReceivers as &$item) {
($item['user_id'] == $data['other_receiver_user_id']) && $item['points'] += $extraPoints->asFloat();
}
} else {
$pointsForOtherReceivers[] = ['user_id' => $data['other_receiver_user_id'], 'points' => $extraPoints->asFloat()];
}
$purchaseState->setCustomData(['points_for_other_receivers' => $pointsForOtherReceivers]);
$purchaseState->addUsedDiscount($orderDiscount->getId());
$this->messages = [];
if ($message = $data['messages']['success'] ?? '') {
$this->messages['success'] = $message;
}
}
public function getPurchaseStateProductsPrice(PurchaseState $purchaseState, array $filter): \Decimal
{
$products = $this->purchaseUtil->getProductsApplicableByProductsFilter($purchaseState, $filter);
$defaultCurrency = Contexts::get(CurrencyContext::class)->getDefault();
$price = \DecimalConstants::zero();
foreach ($products as $item) {
$productPrice = $item->getPriceWithDiscounts();
$productPrice = PriceCalculator::convert($productPrice, $defaultCurrency);
$priceWithDiscountsWithVat = $productPrice->getPriceWithVat(false)->value(2);
$price = $price->add($priceWithDiscountsWithVat);
}
return $price;
}
protected function getExtraPoints(PurchaseState $purchaseState, array $data): \Decimal
{
$extraPoints = \DecimalConstants::zero();
// pridani statickeho poctu bodu
if (!empty($data['other_receiver_fixed_amount'])) {
$points = toDecimal($data['other_receiver_fixed_amount']);
if ($points->isPositive()) {
$extraPoints = $extraPoints->add($points);
}
}
// pridani procent bodu z ceny
if (!empty($data['other_receiver_percent_from_price'])) {
$coefficient = toDecimal($data['other_receiver_percent_from_price'])->div(toDecimal(100), 4);
if ($coefficient->asFloat() > 0) {
// celkova cena produktu v purchase statu po aplikovani produkt filteru
$productsPrice = $this->getPurchaseStateProductsPrice($purchaseState, $data['other_receiver_filter'] ?? []);
$extraPoints = $extraPoints->add($productsPrice->mul($coefficient));
}
}
return $extraPoints;
}
public function checkValidity(&$data): bool
{
if (empty($data['other_receiver_user_id'])) {
throw new \Exception($this->getName().' ['.$this->getType().'] - user is not defined.');
}
if (!empty($data['other_receiver_fixed_amount'])) {
$data['other_receiver_fixed_amount'] = toDecimal($data['other_receiver_fixed_amount'])->asInteger();
if ($data['other_receiver_fixed_amount']) {
return true;
}
}
if (!empty($data['other_receiver_percent_from_price'])) {
$data['other_receiver_percent_from_price'] = toDecimal($data['other_receiver_percent_from_price'])->asFloat();
if ($data['other_receiver_percent_from_price']) {
return true;
}
}
throw new \Exception($this->getName().' ['.$this->getType().'] - data is not valid.');
}
public function getDelayedExecution(): ?int
{
return 4;
}
}