/** * Create a unique code. If a code generated isn't unique, the method will call itself to attempt to create a new * one. If the method cannot create a unique code in the number of times set by the LIMIT constant, an exception * will be thrown. * * @throws Exception\DiscountBuildException * * @return string */ private function _getCode() { $code = $this->_generateCode(); if (false === $this->_loader->getByCode($code)) { return $code; } $this->_codes[] = $code; if (count($this->_codes) > self::LIMIT) { throw new Exception\DiscountBuildException('Could not create a unique discount code in ' . self::LIMIT . ' attempts'); } return $this->_getCode(); }
/** * Validates a discount by it's discountCode and an order * and returns an order-discount-object. * Checks validity of the code, whether it is active and * (if the discount applies to specific products) whether * the at least one of the items in the order matches one * of the discount's products. * * @param string $discountCode The code of the discount validated * * @throws OrderValidityException if the validation failed * * @return Order\Entity\Discount\Discount the order-discount-object for the given discountCode */ public function validate($discountCode, $adding = true) { $adding = (bool) $adding; if (null === $this->_order) { throw new \Exception('Order must be set before discount code can be validated'); } $this->_validateNoRestrictedBundles(); $this->_validateMaxNumberDiscounts($adding); if ($adding) { $this->_validateAlreadyUsed($discountCode); } if (0 === $this->_order->items->count()) { throw new OrderValidityException('Your basket is empty'); } $discount = $this->_discountLoader->getByCode($discountCode); if (!$discount) { throw new OrderValidityException('The entered code was not recognised.'); } if (!$discount->isActive()) { $message = $discount->start < new \DateTime() ? 'The discount has expired.' : 'The discount is not active yet.'; throw new OrderValidityException($message); } // check whether discount-threshold is reached if (0 !== count($discount->thresholds)) { foreach ($discount->thresholds as $currencyID => $threshold) { if ($this->_order->currencyID === $currencyID) { if ($this->_order->productGross < $threshold) { throw new OrderValidityException('Your order value is less than the discount threshold.'); } } } } // check whether order has at least one of the products the discount applies to if (!$discount->appliesToOrder) { $appliesToItem = false; foreach ($discount->products as $product) { foreach ($this->_order->items->all() as $item) { if ($item->productID === $product->id) { $appliesToItem = true; break; } } if ($appliesToItem) { break; } } if (!$appliesToItem) { throw new OrderValidityException('Your order does not include any of the products the discount applies to.'); } } if (empty($discount->discountAmounts[$this->_order->currencyID]) && !$discount->percentage && !$discount->freeShipping) { throw new OrderValidityException('Discount not available in this currency'); } $this->_validateEmail($discount); $this->_orderDiscountFactory->setOrder($this->_order)->setDiscount($discount); return $this->_orderDiscountFactory->createOrderDiscount(); }