Beispiel #1
0
 /**
  * Processing object before save data
  *
  * @return $this
  */
 protected function _beforeSave()
 {
     if (!$this->getRuleId() && $this->_rule instanceof \Magento\SalesRule\Model\Rule) {
         $this->setRuleId($this->_rule->getId());
     }
     return parent::_beforeSave();
 }
 /**
  * Update auto generated Specific Coupon if it's rule changed
  *
  * @param \Magento\SalesRule\Model\Rule $rule
  * @return $this
  */
 public function updateSpecificCoupons(\Magento\SalesRule\Model\Rule $rule)
 {
     if (!$rule || !$rule->getId() || !$rule->hasDataChanges()) {
         return $this;
     }
     $updateArray = [];
     if ($rule->dataHasChangedFor('uses_per_coupon')) {
         $updateArray['usage_limit'] = $rule->getUsesPerCoupon();
     }
     if ($rule->dataHasChangedFor('uses_per_customer')) {
         $updateArray['usage_per_customer'] = $rule->getUsesPerCustomer();
     }
     $ruleNewDate = $this->dateTime->formatDate($rule->getToDate());
     $ruleOldDate = $this->dateTime->formatDate($rule->getOrigData('to_date'));
     if ($ruleNewDate != $ruleOldDate) {
         $updateArray['expiration_date'] = $rule->getToDate();
     }
     if (!empty($updateArray)) {
         $this->getConnection()->update($this->getTable('salesrule_coupon'), $updateArray, ['rule_id = ?' => $rule->getId(), 'generated_by_dotmailer is null']);
     }
     //update coupons generated by dotmailer. not to change expiration date
     $dotmailerUpdateArray = $updateArray;
     unset($dotmailerUpdateArray['expiration_date']);
     if (!empty($dotmailerUpdateArray)) {
         $this->getConnection()->update($this->getTable('salesrule_coupon'), $dotmailerUpdateArray, ['rule_id = ?' => $rule->getId(), 'generated_by_dotmailer is 1']);
     }
     return $this;
 }
Beispiel #3
0
 /**
  * @param \Magento\SalesRule\Model\Rule $rule
  * @param \Magento\Sales\Model\Quote\Item\AbstractItem $item
  * @param float $qty
  * @return \Magento\SalesRule\Model\Rule\Action\Discount\Data
  */
 public function calculate($rule, $item, $qty)
 {
     /** @var \Magento\SalesRule\Model\Rule\Action\Discount\Data $discountData */
     $discountData = $this->discountFactory->create();
     $ruleTotals = $this->validator->getRuleItemTotalsInfo($rule->getId());
     $quote = $item->getQuote();
     $address = $item->getAddress();
     $itemPrice = $this->validator->getItemPrice($item);
     $baseItemPrice = $this->validator->getItemBasePrice($item);
     $itemOriginalPrice = $this->validator->getItemOriginalPrice($item);
     $baseItemOriginalPrice = $this->validator->getItemBaseOriginalPrice($item);
     /**
      * prevent applying whole cart discount for every shipping order, but only for first order
      */
     if ($quote->getIsMultiShipping()) {
         $usedForAddressId = $this->getCartFixedRuleUsedForAddress($rule->getId());
         if ($usedForAddressId && $usedForAddressId != $address->getId()) {
             return $discountData;
         } else {
             $this->setCartFixedRuleUsedForAddress($rule->getId(), $address->getId());
         }
     }
     $cartRules = $address->getCartFixedRules();
     if (!isset($cartRules[$rule->getId()])) {
         $cartRules[$rule->getId()] = $rule->getDiscountAmount();
     }
     if ($cartRules[$rule->getId()] > 0) {
         $store = $quote->getStore();
         if ($ruleTotals['items_count'] <= 1) {
             $quoteAmount = $store->convertPrice($cartRules[$rule->getId()]);
             $baseDiscountAmount = min($baseItemPrice * $qty, $cartRules[$rule->getId()]);
         } else {
             $discountRate = $baseItemPrice * $qty / $ruleTotals['base_items_price'];
             $maximumItemDiscount = $rule->getDiscountAmount() * $discountRate;
             $quoteAmount = $store->convertPrice($maximumItemDiscount);
             $baseDiscountAmount = min($baseItemPrice * $qty, $maximumItemDiscount);
             $this->validator->decrementRuleItemTotalsCount($rule->getId());
         }
         $baseDiscountAmount = $store->roundPrice($baseDiscountAmount);
         $cartRules[$rule->getId()] -= $baseDiscountAmount;
         $discountData->setAmount($store->roundPrice(min($itemPrice * $qty, $quoteAmount)));
         $discountData->setBaseAmount($baseDiscountAmount);
         $discountData->setOriginalAmount(min($itemOriginalPrice * $qty, $quoteAmount));
         $discountData->setBaseOriginalAmount($store->roundPrice($baseItemOriginalPrice));
     }
     $address->setCartFixedRules($cartRules);
     return $discountData;
 }
 /**
  * Add rule to filter
  *
  * @param Rule|int $rule
  * @return $this
  */
 public function addRuleToFilter($rule)
 {
     if ($rule instanceof Rule) {
         $ruleId = $rule->getId();
     } else {
         $ruleId = (int) $rule;
     }
     $this->addFieldToFilter('rule_id', $ruleId);
     return $this;
 }
 /**
  * Add rule discount description label to address object
  *
  * @param Address $address
  * @param \Magento\SalesRule\Model\Rule $rule
  * @return $this
  */
 public function addDiscountDescription($address, $rule)
 {
     $description = $address->getDiscountDescriptionArray();
     $ruleLabel = $rule->getStoreLabel($address->getQuote()->getStore());
     $label = '';
     if ($ruleLabel) {
         $label = $ruleLabel;
     } else {
         if (strlen($address->getCouponCode())) {
             $label = $address->getCouponCode();
         }
     }
     if (strlen($label)) {
         $description[$rule->getId()] = $label;
     }
     $address->setDiscountDescriptionArray($description);
     return $this;
 }
Beispiel #6
0
 /**
  * Set rule instance
  *
  * @param \Magento\SalesRule\Model\Rule $rule
  * @return $this
  */
 public function setRule(\Magento\SalesRule\Model\Rule $rule)
 {
     $this->setRuleId($rule->getId());
     return $this;
 }
Beispiel #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;
 }
Beispiel #8
0
 /**
  * Update auto generated Specific Coupon if it's rule changed
  *
  * @param \Magento\SalesRule\Model\Rule $rule
  * @return $this
  */
 public function updateSpecificCoupons(\Magento\SalesRule\Model\Rule $rule)
 {
     if (!$rule || !$rule->getId() || !$rule->hasDataChanges()) {
         return $this;
     }
     $updateArray = [];
     if ($rule->dataHasChangedFor('uses_per_coupon')) {
         $updateArray['usage_limit'] = $rule->getUsesPerCoupon();
     }
     if ($rule->dataHasChangedFor('uses_per_customer')) {
         $updateArray['usage_per_customer'] = $rule->getUsesPerCustomer();
     }
     $ruleNewDate = new \DateTime($rule->getToDate());
     $ruleOldDate = new \DateTime($rule->getOrigData('to_date'));
     if ($ruleNewDate != $ruleOldDate) {
         $updateArray['expiration_date'] = $rule->getToDate();
     }
     if (!empty($updateArray)) {
         $this->getConnection()->update($this->getTable('salesrule_coupon'), $updateArray, ['rule_id = ?' => $rule->getId()]);
     }
     return $this;
 }
Beispiel #9
0
 /**
  * Save product attributes currently used in conditions and actions of rule
  *
  * @param \Magento\SalesRule\Model\Rule $rule
  * @param mixed $attributes
  * @return $this
  */
 public function setActualProductAttributes($rule, $attributes)
 {
     $connection = $this->getConnection();
     $connection->delete($this->getTable('salesrule_product_attribute'), ['rule_id=?' => $rule->getId()]);
     //Getting attribute IDs for attribute codes
     $attributeIds = [];
     $select = $this->getConnection()->select()->from(['a' => $this->getTable('eav_attribute')], ['a.attribute_id'])->where('a.attribute_code IN (?)', [$attributes]);
     $attributesFound = $this->getConnection()->fetchAll($select);
     if ($attributesFound) {
         foreach ($attributesFound as $attribute) {
             $attributeIds[] = $attribute['attribute_id'];
         }
         $data = [];
         foreach ($rule->getCustomerGroupIds() as $customerGroupId) {
             foreach ($rule->getWebsiteIds() as $websiteId) {
                 foreach ($attributeIds as $attribute) {
                     $data[] = ['rule_id' => $rule->getId(), 'website_id' => $websiteId, 'customer_group_id' => $customerGroupId, 'attribute_id' => $attribute];
                 }
             }
         }
         $connection->insertMultiple($this->getTable('salesrule_product_attribute'), $data);
     }
     return $this;
 }
 /**
  * {@inheritdoc}
  */
 public function getId()
 {
     $pluginInfo = $this->pluginList->getNext($this->subjectType, 'getId');
     if (!$pluginInfo) {
         return parent::getId();
     } else {
         return $this->___callPlugins('getId', func_get_args(), $pluginInfo);
     }
 }
Beispiel #11
0
 /**
  * Save product attributes currently used in conditions and actions of rule
  *
  * @param \Magento\SalesRule\Model\Rule $rule
  * @param mixed $attributes
  * @return $this
  */
 public function setActualProductAttributes($rule, $attributes)
 {
     $write = $this->_getWriteAdapter();
     $write->delete($this->getTable('salesrule_product_attribute'), array('rule_id=?' => $rule->getId()));
     //Getting attribute IDs for attribute codes
     $attributeIds = array();
     $select = $this->_getReadAdapter()->select()->from(array('a' => $this->getTable('eav_attribute')), array('a.attribute_id'))->where('a.attribute_code IN (?)', array($attributes));
     $attributesFound = $this->_getReadAdapter()->fetchAll($select);
     if ($attributesFound) {
         foreach ($attributesFound as $attribute) {
             $attributeIds[] = $attribute['attribute_id'];
         }
         $data = array();
         foreach ($rule->getCustomerGroupIds() as $customerGroupId) {
             foreach ($rule->getWebsiteIds() as $websiteId) {
                 foreach ($attributeIds as $attribute) {
                     $data[] = array('rule_id' => $rule->getId(), 'website_id' => $websiteId, 'customer_group_id' => $customerGroupId, 'attribute_id' => $attribute);
                 }
             }
         }
         $write->insertMultiple($this->getTable('salesrule_product_attribute'), $data);
     }
     return $this;
 }