/** * Initialize coupon * * @return \Magento\Framework\Controller\Result\Redirect * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ public function execute() { $couponCode = $this->getRequest()->getParam('remove') == 1 ? '' : trim($this->getRequest()->getParam('coupon_code')); $cartQuote = $this->cart->getQuote(); $oldCouponCode = $cartQuote->getCouponCode(); $codeLength = strlen($couponCode); if (!$codeLength && !strlen($oldCouponCode)) { return $this->_goBack(); } try { $isCodeLengthValid = $codeLength && $codeLength <= \Magento\Checkout\Helper\Cart::COUPON_CODE_MAX_LENGTH; $itemsCount = $cartQuote->getItemsCount(); if ($itemsCount) { $cartQuote->getShippingAddress()->setCollectShippingRates(true); $cartQuote->setCouponCode($isCodeLengthValid ? $couponCode : '')->collectTotals(); $this->quoteRepository->save($cartQuote); } if ($codeLength) { $escaper = $this->_objectManager->get('Magento\\Framework\\Escaper'); if (!$itemsCount) { if ($isCodeLengthValid) { $coupon = $this->couponFactory->create(); $coupon->load($couponCode, 'code'); if ($coupon->getId()) { $this->_checkoutSession->getQuote()->setCouponCode($couponCode)->save(); $this->messageManager->addSuccess(__('You used coupon code "%1".', $escaper->escapeHtml($couponCode))); } else { $this->messageManager->addError(__('The coupon code "%1" is not valid.', $escaper->escapeHtml($couponCode))); } } else { $this->messageManager->addError(__('The coupon code "%1" is not valid.', $escaper->escapeHtml($couponCode))); } } else { if ($isCodeLengthValid && $couponCode == $cartQuote->getCouponCode()) { $this->messageManager->addSuccess(__('You used coupon code "%1".', $escaper->escapeHtml($couponCode))); } else { $this->messageManager->addError(__('The coupon code "%1" is not valid.', $escaper->escapeHtml($couponCode))); $this->cart->save(); } } } else { $this->messageManager->addSuccess(__('You canceled the coupon code.')); } } catch (\Magento\Framework\Exception\LocalizedException $e) { $this->messageManager->addError($e->getMessage()); } catch (\Exception $e) { $this->messageManager->addError(__('We cannot apply the coupon code.')); $this->_objectManager->get('Psr\\Log\\LoggerInterface')->critical($e); } return $this->_goBack(); }
/** * Generate Coupons Pool * * @throws \Magento\Framework\Exception\LocalizedException * @return $this */ public function generatePool() { $this->generatedCount = 0; $size = $this->getQty(); $maxAttempts = $this->getMaxAttempts() ? $this->getMaxAttempts() : self::MAX_GENERATE_ATTEMPTS; $this->increaseLength(); /** @var $coupon \Magento\SalesRule\Model\Coupon */ $coupon = $this->couponFactory->create(); $nowTimestamp = $this->dateTime->formatDate($this->date->gmtTimestamp()); for ($i = 0; $i < $size; $i++) { $attempt = 0; do { if ($attempt >= $maxAttempts) { throw new \Magento\Framework\Exception\LocalizedException(__('We cannot create the requested Coupon Qty. Please check your settings and try again.')); } $code = $this->generateCode(); ++$attempt; } while ($this->getResource()->exists($code)); $expirationDate = $this->getToDate(); if ($expirationDate instanceof \DateTime) { $expirationDate = $expirationDate->format('Y-m-d H:i:s'); } $coupon->setId(null)->setRuleId($this->getRuleId())->setUsageLimit($this->getUsesPerCoupon())->setUsagePerCustomer($this->getUsesPerCustomer())->setExpirationDate($expirationDate)->setCreatedAt($nowTimestamp)->setType(\Magento\SalesRule\Helper\Coupon::COUPON_TYPE_SPECIFIC_AUTOGENERATED)->setCode($code)->save(); $this->generatedCount += 1; } return $this; }
/** * Delete coupon by coupon id. * * @param int $couponId * @return bool true on success * @throws \Magento\Framework\Exception\NoSuchEntityException * @throws \Magento\Framework\Exception\LocalizedException */ public function deleteById($couponId) { /** @var \Magento\SalesRule\Model\Coupon $coupon */ $coupon = $this->couponFactory->create()->load($couponId); if (!$coupon->getCouponId()) { throw new \Magento\Framework\Exception\NoSuchEntityException(); } $this->resourceModel->delete($coupon); return true; }
/** * Generates the coupon code based on the code id. * * @return bool */ public function generateCoupon() { $params = $this->getRequest()->getParams(); //check for param code and id if (!isset($params['id']) || !isset($params['code'])) { $this->helper->log('Coupon no id or code is set'); return false; } //coupon rule id $couponCodeId = $params['id']; if ($couponCodeId) { $rule = $this->ruleFactory->create()->load($couponCodeId); $generator = $this->massGeneratorFactory->create(); $generator->setFormat(\Magento\SalesRule\Helper\Coupon::COUPON_FORMAT_ALPHANUMERIC); $generator->setRuleId($couponCodeId); $generator->setUsesPerCoupon(1); $generator->setDash(3); $generator->setLength(9); $generator->setPrefix('DOT-'); $generator->setSuffix(''); //set the generation settings $rule->setCouponCodeGenerator($generator); $rule->setCouponType(\Magento\SalesRule\Model\Rule::COUPON_TYPE_AUTO); //generate the coupon $coupon = $rule->acquireCoupon(); $couponCode = $coupon->getCode(); //save the type of coupon /** @var \Magento\SalesRule\Model\Coupon $couponModel */ $couponModel = $this->couponFactory->create()->loadByCode($couponCode); $couponModel->setType(\Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON)->setGeneratedByDotmailer(1); if (is_numeric($params['expire_days'])) { $expireDate = $this->_localeDate->date()->add(new \DateInterval(sprintf('P%sD', $params['expire_days']))); $couponModel->setExpirationDate($expireDate); } elseif ($rule->getToDate()) { $couponModel->setExpirationDate($rule->getToDate()); } $this->coupon->save($couponModel); return $couponCode; } return false; }
/** * Generate Coupons Pool * * @throws \Magento\Framework\Model\Exception * @return $this */ public function generatePool() { $this->_generatedCount = 0; $size = $this->getQty(); $maxProbability = $this->getMaxProbability() ? $this->getMaxProbability() : self::MAX_PROBABILITY_OF_GUESSING; $maxAttempts = $this->getMaxAttempts() ? $this->getMaxAttempts() : self::MAX_GENERATE_ATTEMPTS; /** @var $coupon \Magento\SalesRule\Model\Coupon */ $coupon = $this->_couponFactory->create(); $chars = count($this->_salesRuleCoupon->getCharset($this->getFormat())); $length = (int) $this->getLength(); $maxCodes = pow($chars, $length); $probability = $size / $maxCodes; //increase the length of Code if probability is low if ($probability > $maxProbability) { do { $length++; $maxCodes = pow($chars, $length); $probability = $size / $maxCodes; } while ($probability > $maxProbability); $this->setLength($length); } $now = $this->dateTime->formatDate($this->_date->gmtTimestamp()); for ($i = 0; $i < $size; $i++) { $attempt = 0; do { if ($attempt >= $maxAttempts) { throw new \Magento\Framework\Model\Exception(__('We cannot create the requested Coupon Qty. Please check your settings and try again.')); } $code = $this->generateCode(); $attempt++; } while ($this->getResource()->exists($code)); $expirationDate = $this->getToDate(); if ($expirationDate instanceof \Zend_Date) { $expirationDate = $expirationDate->toString(\Magento\Framework\Stdlib\DateTime::DATETIME_INTERNAL_FORMAT); } $coupon->setId(null)->setRuleId($this->getRuleId())->setUsageLimit($this->getUsesPerCoupon())->setUsagePerCustomer($this->getUsesPerCustomer())->setExpirationDate($expirationDate)->setCreatedAt($now)->setType(\Magento\SalesRule\Helper\Coupon::COUPON_TYPE_SPECIFIC_AUTOGENERATED)->setCode($code)->save(); $this->_generatedCount++; } return $this; }
/** * Acquire coupon instance * * @param bool $saveNewlyCreated Whether or not to save newly created coupon * @param int $saveAttemptCount Number of attempts to save newly created coupon * @return \Magento\SalesRule\Model\Coupon|null * @throws \Exception|\Magento\Framework\Exception\LocalizedException * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ public function acquireCoupon($saveNewlyCreated = true, $saveAttemptCount = 10) { if ($this->getCouponType() == self::COUPON_TYPE_NO_COUPON) { return null; } if ($this->getCouponType() == self::COUPON_TYPE_SPECIFIC) { return $this->getPrimaryCoupon(); } /** @var \Magento\SalesRule\Model\Coupon $coupon */ $coupon = $this->_couponFactory->create(); $coupon->setRule($this)->setIsPrimary(false)->setUsageLimit($this->getUsesPerCoupon() ? $this->getUsesPerCoupon() : null)->setUsagePerCustomer($this->getUsesPerCustomer() ? $this->getUsesPerCustomer() : null)->setExpirationDate($this->getToDate()); $couponCode = self::getCouponCodeGenerator()->generateCode(); $coupon->setCode($couponCode); $ok = false; if (!$saveNewlyCreated) { $ok = true; } else { if ($this->getId()) { for ($attemptNum = 0; $attemptNum < $saveAttemptCount; $attemptNum++) { try { $coupon->save(); } catch (\Exception $e) { if ($e instanceof \Magento\Framework\Exception\LocalizedException || $coupon->getId()) { throw $e; } $coupon->setCode($couponCode . self::getCouponCodeGenerator()->getDelimiter() . sprintf('%04u', rand(0, 9999))); continue; } $ok = true; break; } } } if (!$ok) { throw new \Magento\Framework\Exception\LocalizedException(__('Can\'t acquire coupon.')); } return $coupon; }
/** * Check if rule can be applied for specific address/quote/customer * * @param \Magento\SalesRule\Model\Rule $rule * @param \Magento\Quote\Model\Quote\Address $address * @return bool * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ public function canProcessRule($rule, $address) { if ($rule->hasIsValidForAddress($address) && !$address->isObjectNew()) { return $rule->getIsValidForAddress($address); } /** * check per coupon usage limit */ if ($rule->getCouponType() != \Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON) { $couponCode = $address->getQuote()->getCouponCode(); if (strlen($couponCode)) { /** @var \Magento\SalesRule\Model\Coupon $coupon */ $coupon = $this->couponFactory->create(); $coupon->load($couponCode, 'code'); if ($coupon->getId()) { // check entire usage limit if ($coupon->getUsageLimit() && $coupon->getTimesUsed() >= $coupon->getUsageLimit()) { $rule->setIsValidForAddress($address, false); return false; } // check per customer usage limit $customerId = $address->getQuote()->getCustomerId(); if ($customerId && $coupon->getUsagePerCustomer()) { $couponUsage = $this->objectFactory->create(); $this->usageFactory->create()->loadByCustomerCoupon($couponUsage, $customerId, $coupon->getId()); if ($couponUsage->getCouponId() && $couponUsage->getTimesUsed() >= $coupon->getUsagePerCustomer()) { $rule->setIsValidForAddress($address, false); return false; } } } } } /** * check per rule usage limit */ $ruleId = $rule->getId(); if ($ruleId && $rule->getUsesPerCustomer()) { $customerId = $address->getQuote()->getCustomerId(); /** @var \Magento\SalesRule\Model\Rule\Customer $ruleCustomer */ $ruleCustomer = $this->customerFactory->create(); $ruleCustomer->loadByCustomerRule($customerId, $ruleId); if ($ruleCustomer->getId()) { if ($ruleCustomer->getTimesUsed() >= $rule->getUsesPerCustomer()) { $rule->setIsValidForAddress($address, false); return false; } } } $rule->afterLoad(); /** * quote does not meet rule's conditions */ if (!$rule->validate($address)) { $rule->setIsValidForAddress($address, false); return false; } /** * passed all validations, remember to be valid */ $rule->setIsValidForAddress($address, true); return true; }