/** * 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; }
/** * Applies the free gift to the purchasable holder. * * The event dispatcher is disabled here to not cause recursion as the free gift is added to the cart. In normal * circumstances adding a purchasable to the purschasable holder causes deal conditions to be re-evaluated, and * results of those conditions applied. Obviously in this situation, adding a free gift to the cart may cause those * events to fire causing other purchasables to be added as a result - leading to a bad situation * * There are two cases where the free gift must be added the purchasable holder * * 1) when the purchasable has already been added to the cart, but none are yet free. * 2) when the purchasable has already been added to the cart but the purchasables free quantity is less than the * current amount of times this condition has been met. * * @param \Heystack\Deals\Events\ConditionEvent $event * @param string $eventName * @param \Heystack\Core\EventDispatcher $dispatcher * @return void */ public function onConditionsMet(ConditionEvent $event, $eventName, EventDispatcher $dispatcher) { // Should we get the event dispatcher off the event? $deal = $this->getDealHandler(); $dealIdentifier = $deal->getIdentifier(); $conditionsMetCount = $deal->getConditionsMetCount(); $purchasableHolder = $this->getPurchasableHolder(); // Only do stuff if it is relevant to this deal if ($dealIdentifier->isMatch($event->getDealHandler()->getIdentifier())) { $dispatcher->setEnabled(false); $purchasable = $this->getPurchasable(); if ($purchasable instanceof DealPurchasableInterface) { $purchasableAlreadyInCart = $this->purchasableHolder->getPurchasable($purchasable->getIdentifier()); if (!$purchasableAlreadyInCart instanceof DealPurchasableInterface) { $this->purchasableHolder->setPurchasable($purchasable, 0); } $purchasable->setFreeQuantity($dealIdentifier, $conditionsMetCount); } $dispatcher->setEnabled(true); $purchasableHolder->updateTotal(); } }
/** * @param \SS_HTTPRequest $request * @param \SS_HTTPResponse $response * @param \DataModel $model * @return void */ public function postRequest(SS_HTTPRequest $request, SS_HTTPResponse $response, DataModel $model) { if ($this->eventDispatcher instanceof EventDispatcher) { $this->eventDispatcher->dispatch(Events::POST_REQUEST); } }