<?php namespace QUI\ERP\Coupons; use QUI; use Quiqqer\Engine\Collector; use QUI\ERP\Order\Basket\Basket; use QUI\ERP\Order\Basket\BasketGuest; use QUI\ERP\Coupons\Handler as CouponsHandler; use QUI\ERP\Discount\EventHandling as DiscountEvents; /** * Class Events * * Global Event Handler for quiqqer/payment-paypal */ class Events { /** * Template event quiqqer/order: onQuiqqer::order::orderProcessBasketEnd * * @param Collector $Collector * @param BasketGuest $Basket * @param $Order */ public static function templateOrderProcessBasketEnd(Collector $Collector, $Basket, $Order) { if (!($Basket instanceof Basket) && !($Basket instanceof QUI\ERP\Order\Basket\BasketOrder) ) { return; } if (isset($Order) && isset($_GET['coupon'])) { try { $code = Handler::sanitizeCode($_GET['coupon']); $CouponCode = Handler::getCouponCodeByCode($code); $CouponCode->checkRedemption(QUI::getUserBySession()); $CouponCode->addToOrder($Order); } catch (\Exception $Exception) { } } $Collector->append( '<div data-qui="package/quiqqer/coupons/bin/frontend/controls/CouponCodeInput"></div>' ); } /** * @param QUI\ERP\Order\OrderProcess $OrderProcess * @throws QUI\ERP\Order\Exception * @throws QUI\Exception */ public static function onOrderProcess(QUI\ERP\Order\OrderProcess $OrderProcess) { $CurrentStep = $OrderProcess->getCurrentStep(); $currentStep = $CurrentStep->getType(); if ($currentStep !== QUI\ERP\Order\Controls\OrderProcess\Basket::class) { return; } $coupons = QUI::getSession()->get('quiqqer-coupons'); if (\is_string($coupons)) { $coupons = \json_decode($coupons, true); } if (!\is_array($coupons)) { $coupons = []; } if (isset($_GET['coupon'])) { $coupons[] = $_GET['coupon']; } $coupons = \array_unique($coupons); if (empty($coupons)) { return; } $Order = $OrderProcess->getOrder(); foreach ($coupons as $coupon) { self::addCouponToOrder($Order, $coupon); } } /** * @param QUI\ERP\Order\Basket\Basket $Basket * @param $pos */ public static function onQuiqqerOrderBasketRemovePos( QUI\ERP\Order\Basket\Basket $Basket, $pos ) { $Order = null; try { $Order = $Basket->getOrder(); } catch (QUI\Exception $Exception) { $Orders = QUI\ERP\Order\Handler::getInstance(); try { $Order = $Orders->getLastOrderInProcessFromUser(QUI::getUserBySession()); } catch (QUI\Exception $Exception) { } } if (!$Order) { QUI::getSession()->remove('quiqqer-coupons'); return; } $Article = $Order->getArticles()->getArticle($pos); $customData = $Article->getCustomData(); $orderCoupons = $Order->getDataEntry('quiqqer-coupons'); $articleCouponCode = false; if (isset($customData['package']) && isset($customData['code'])) { $articleCouponCode = $customData['code']; } if (!$articleCouponCode) { return; } // custom data has code params, so article is an coupon code // we need to delete it if (\in_array($articleCouponCode, $orderCoupons)) { $pos = \array_search($articleCouponCode, $orderCoupons); unset($orderCoupons[$pos]); $Order->setData('quiqqer-coupons', $orderCoupons); try { $Order->save(); } catch (QUI\Exception $Exception) { } } // look at session coupons // we need to delete it $coupons = QUI::getSession()->get('quiqqer-coupons'); if (\is_string($coupons)) { $coupons = \json_decode($coupons, true); } if (!\is_array($coupons) || empty($coupons)) { return; } if (!\in_array($customData['code'], $coupons)) { return; } // remove code from session // because code is deleted $newCouponList = []; foreach ($coupons as $coupon) { if ($customData['code'] !== $coupon) { $newCouponList[] = $coupon; } } if (empty($newCouponList)) { QUI::getSession()->remove('quiqqer-coupons'); } else { QUI::getSession()->set('quiqqer-coupons', \json_encode($newCouponList)); } } /** * event - on price factor init * * @param $Basket * @param QUI\ERP\Order\AbstractOrder $Order * @param QUI\ERP\Products\Product\ProductList $Products */ public static function onQuiqqerOrderBasketToOrder( $Basket, QUI\ERP\Order\AbstractOrder $Order, QUI\ERP\Products\Product\ProductList $Products ) { $coupons = $Order->getDataEntry('quiqqer-coupons'); $sessionCoupons = QUI::getSession()->get('quiqqer-coupons'); if (!\is_array($coupons)) { $coupons = []; } if (\is_string($sessionCoupons)) { $sessionCoupons = \json_decode($sessionCoupons, true); if (\is_array($sessionCoupons)) { $coupons = \array_merge($coupons, $sessionCoupons); } $coupons = \array_unique($coupons); self::addSessionCouponsToOrder($Order, $sessionCoupons); } if (empty($coupons)) { return; } $PriceFactors = $Products->getPriceFactors(); $products = $Products->toArray(); $productCount = $Products->count(); $subSum = $products['calculations']['subSum']; $checkRedeemable = !$Order->isSuccessful(); // if order is successful we dont need a check $OrderInProcess = $Order->getAttribute('OrderInProcess'); $added = false; if ($Order->getAttribute('inOrderCreation')) { $checkRedeemable = false; } if ($OrderInProcess instanceof QUI\ERP\Order\OrderInProcess && $OrderInProcess->getAttribute('inOrderCreation') ) { $checkRedeemable = false; } foreach ($coupons as $coupon) { /* @var $Coupon CouponCode */ try { $Coupon = Handler::getCouponCodeByCode($coupon); } catch (\Exception $Exception) { continue; } // coupon check if ($checkRedeemable && !$Coupon->isRedeemable($Order->getCustomer())) { continue; } /* @var $Discount QUI\ERP\Discount\Discount */ $discounts = $Coupon->getDiscounts(); foreach ($discounts as $Discount) { if (!DiscountEvents::isDiscountUsableWithQuantity($Discount, $productCount)) { continue; } if (!DiscountEvents::isDiscountUsableWithPurchaseValue($Discount, $subSum)) { continue; } $PriceFactor = $Discount->toPriceFactor(null, $Order->getCustomer()); $PriceFactor->setTitle( QUI::getLocale()->get('quiqqer/coupons', 'coupon.discount.title', [ 'code' => $Coupon->getCode() ]) ); if ($Discount->getAttribute('scope') === QUI\ERP\Discount\Handler::DISCOUNT_SCOPE_EVERY_PRODUCT || $Discount->getAttribute('scope') === QUI\ERP\Discount\Handler::DISCOUNT_SCOPE_UNIQUE ) { // add to the product $products = $Products->getProducts(); foreach ($products as $Product) { if ($Discount->canUsedWith($Product) === false) { continue; } if ($Product instanceof QUI\ERP\Products\Product\UniqueProduct) { $Product->getPriceFactors()->add($PriceFactor); } } continue; } $added = true; $PriceFactors->addToEnd($PriceFactor); } } if ($added) { try { $Products->recalculation(); } catch (QUI\Exception $Exception) { QUI\System\Log::writeDebugException($Exception); } } } /** * quiqqer/order: onQuiqqerOrderSuccessful * * Redeem coupons used in (completed) orders * * @param QUI\ERP\Order\Order|QUI\ERP\Order\OrderInProcess $Order * @return void */ public static function onQuiqqerOrderSuccessful($Order) { $coupons = $Order->getDataEntry('quiqqer-coupons'); if (empty($coupons)) { return; } foreach ($coupons as $couponCode) { try { $CouponCode = CouponsHandler::getCouponCodeByCode($couponCode); $CouponCode->redeem($Order->getCustomer(), $Order); } catch (\Exception $Exception) { QUI\System\Log::writeException($Exception); } } } /** * @param $Order * @param $coupons */ protected static function addSessionCouponsToOrder($Order, $coupons) { if (!\is_array($coupons)) { return; } // coupons as article if not added $Articles = $Order->getArticles(); $isInArticles = function ($code) use ($Articles) { foreach ($Articles as $Article) { $customData = $Article->getCustomData(); if (isset($customData['code']) && $customData['code'] === $code) { return true; } } return false; }; foreach ($coupons as $coupon) { if ($isInArticles($coupon) === false) { self::addCouponToOrder($Order, $coupon); } } } /** * @param $Order * @param $coupon */ protected static function addCouponToOrder($Order, $coupon) { try { $code = Handler::sanitizeCode($coupon); $CouponCode = Handler::getCouponCodeByCode($code); $CouponCode->checkRedemption(QUI::getUserBySession()); $coupons = $Order->getDataEntry('quiqqer-coupons'); $coupons[] = $code; $coupons = \array_unique($coupons); $Order->setData('quiqqer-coupons', $coupons); $Order->update(); $CouponCode->addToOrder($Order); } catch (\Exception $Exception) { } } }