/** * After the transaction is stored, store the deal. * @param \Heystack\Core\Storage\Event $event * @param string $eventName * @param \Heystack\Core\EventDispatcher $dispatcher * @return void */ public function onTransactionStored(StorageEvent $event, $eventName, EventDispatcher $dispatcher) { if ($this->dealHandler->getConditionsMetCount() > 0) { $this->dealHandler->setParentReference($event->getParentReference()); $results = $this->storageService->process($this->dealHandler); // Store the Coupons associated with the deal if (!empty($results[Backend::IDENTIFIER])) { $storedDeal = $results[Backend::IDENTIFIER]; $coupons = $this->couponHolder->getCoupons($this->dealHandler->getIdentifier()); foreach ($coupons as $coupon) { if ($coupon instanceof CouponInterface) { $coupon->setParentReference($storedDeal->ID); $this->storageService->process($coupon); } } } $this->eventService->dispatch(Events::STORED); $this->stateService->removeByKey($this->dealHandler->getIdentifier()->getFull()); } }
/** * @param \Heystack\Deals\Interfaces\DealHandlerInterface $dealHandler * @return mixed */ public function process(DealHandlerInterface $dealHandler) { $purchasable = $this->getPurchasable(); $purchasableTotal = $purchasable->getTotal(); $currentDiscountTotal = $purchasable->getDealDiscountWithExclusions([$this->getDealHandler()->getIdentifier()->getFull()]); if ($purchasable instanceof $this->purchasableClass) { $total = $this->getPurchasable()->getUnitPrice()->multiply($dealHandler->getConditionsMetCount()); } else { $total = $this->currencyService->getZeroMoney(); } if ($total->add($currentDiscountTotal)->greaterThan($purchasableTotal)) { $total = $purchasableTotal->subtract($currentDiscountTotal); } $this->eventService->dispatch(Events::RESULT_PROCESSED, new ResultEvent($this)); return $total; }
/** * @param \Heystack\Deals\Interfaces\DealHandlerInterface $dealHandler * @return void */ public function addDealHandler(DealHandlerInterface $dealHandler) { $this->dealHandlers[$dealHandler->getIdentifier()->getFull()] = $dealHandler; }
/** * Main function that determines what the result does * @param \Heystack\Deals\Interfaces\DealHandlerInterface $dealHandler * @return \SebastianBergmann\Money\Money */ public function process(DealHandlerInterface $dealHandler) { $discount = $this->getCurrencyService()->getZeroMoney(); $dealIdentifier = $dealHandler->getIdentifier(); // Reset the free count for this deal of all the purchasables. We need to do this because // a new 'cheaper' product may have been added to the purchasable holder in the meantime foreach ($this->purchasableHolder->getPurchasables() as $purchasable) { if ($purchasable instanceof DealPurchasableInterface) { $purchasable->setFreeQuantity($dealIdentifier, 0); $purchasable->setDealDiscount($dealIdentifier, $discount); } } $remainingFreeDiscounts = $dealHandler->getConditionsMetCount(); $purchasables = $this->getPurchsablesSortedByUnitPrice(); $purchasable = current($purchasables); while ($purchasable && $remainingFreeDiscounts > 0) { // Skip if it isn't a deal purchasable if (!$purchasable instanceof DealPurchasableInterface) { $purchasable = next($purchasable); continue; } // Get the smaller number, either the quantity of the current purchasable // or the remaining free discounts $freeQuantity = min($purchasable->getQuantity(), $remainingFreeDiscounts); // Get the current discount $currentPurchasableDiscount = $purchasable->getDealDiscountWithExclusions([$dealIdentifier->getFull()]); $purchasableTotal = $purchasable->getTotal(); $purchasableDiscount = $purchasable->getUnitPrice()->multiply($freeQuantity); // When the deduction exceeds the remaining money just remove the remaining money if ($currentPurchasableDiscount->add($purchasableDiscount)->greaterThan($purchasableTotal)) { $purchasableDiscount = $purchasableTotal->subtract($currentPurchasableDiscount); } $discount = $discount->add($purchasableDiscount); $purchasable->setFreeQuantity($dealIdentifier, $freeQuantity); $purchasable->setDealDiscount($dealHandler->getIdentifier(), $purchasableDiscount); $remainingFreeDiscounts -= $freeQuantity; // Advance to the next purchasable $purchasable = next($purchasables); } $this->purchasableHolder->updateTotal(); $this->eventService->dispatch(Events::RESULT_PROCESSED, new ResultEvent($this)); return $this->totalDiscount = $discount; }