/**
  * 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();
 }
Example #2
0
 /**
  * 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;
 }
Example #5
0
 /**
  * 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;
 }
Example #6
0
 /**
  * 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;
 }
Example #7
0
 /**
  * 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;
 }