예제 #1
0
 /**
  * Check if a rule applies to a quote address
  *
  * @param Mage_SalesRule_Model_Rule      $rule
  * @param Mage_Sales_Model_Quote_Address $address
  *
  * @return bool
  */
 public function canApplyRule(Mage_SalesRule_Model_Rule $rule, Mage_Sales_Model_Quote_Address $address)
 {
     // If rule require a coupon, verify the coupon code and usage
     if ($rule->getCouponType() != Mage_SalesRule_Model_Rule::COUPON_TYPE_NO_COUPON) {
         // Grab the coupon code from the quote
         $couponCode = trim($address->getQuote()->getCouponCode());
         // Rule requires a coupon and none was applied
         if (empty($couponCode)) {
             return false;
         }
         // Load the referenced coupon
         /** @var Mage_SalesRule_Model_Coupon $coupon */
         $coupon = Mage::getModel('salesrule/coupon')->load($couponCode, 'code');
         // Rule requires a coupon and the provided code is not valid
         if (!$coupon->getId() || $coupon->getRuleId() != $rule->getId()) {
             return false;
         }
         // Check coupon global usage limit
         if ($coupon->getUsageLimit() && $coupon->getTimesUsed() >= $coupon->getUsageLimit()) {
             return false;
         }
         // Check per customer usage limit - only for logged in customers
         if ($coupon->getUsagePerCustomer() && $address->getQuote()->getCustomerId()) {
             $useCount = $this->getCustomerCouponUseCount($address->getQuote()->getCustomerId(), $coupon);
             if ($useCount >= $coupon->getUsagePerCustomer()) {
                 return false;
             }
         }
     }
     if ($rule->getUsesPerCustomer() && $address->getQuote()->getCustomerId()) {
         $useCount = $this->getCustomerRuleUseCount($address->getQuote()->getCustomerId(), $rule);
         if ($useCount >= $rule->getUsesPerCustomer()) {
             return false;
         }
     }
     // Since the rule passed all the pre-checks, if the rule conditions validate then the rule applies
     return $rule->validate($address);
 }
예제 #2
0
 /**
  * Set coupon code to address if $rule contains validated coupon
  *
  * @param  Mage_Sales_Model_Quote_Address $address
  * @param  Mage_SalesRule_Model_Rule $rule
  *
  * @return Mage_SalesRule_Model_Validator
  */
 protected function _maintainAddressCouponCode($address, $rule)
 {
     /*
     Rule is a part of rules collection, which includes only rules with 'No Coupon' type or with validated coupon.
     As a result, if rule uses coupon code(s) ('Specific' or 'Auto' Coupon Type), it always contains validated
     coupon
     */
     if ($rule->getCouponType() != Mage_SalesRule_Model_Rule::COUPON_TYPE_NO_COUPON) {
         $address->setCouponCode($this->getCouponCode());
     }
     return $this;
 }
예제 #3
0
    /**
     * Check if rule can be applied for specific address/quote/customer
     *
     * @param   Mage_SalesRule_Model_Rule $rule
     * @param   Mage_Sales_Model_Quote_Address $address
     * @return  bool
     */
    protected function _canProcessRule($rule, $address)
    {
        if ($rule->hasIsValidForAddress($address) && !$address->isObjectNew()) {
            return $rule->getIsValidForAddress($address);
        }

        /**
         * check per coupon usage limit
         */
        if ($rule->getCouponType() != Mage_SalesRule_Model_Rule::COUPON_TYPE_NO_COUPON) {
            $couponCode = $address->getQuote()->getCouponCode();
            if ($couponCode) {
                $coupon = Mage::getModel('salesrule/coupon');
                $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 = new Varien_Object();
                        Mage::getResourceModel('salesrule/coupon_usage')->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();
            $ruleCustomer   = Mage::getModel('salesrule/rule_customer');
            $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;
    }
예제 #4
0
파일: Rule.php 프로젝트: bevello/bevello
 /**
  * Try to associate reminder rule with matched customers.
  * If customer was added earlier, update is_active column.
  *
  * @param Bronto_Reminder_Model_Rule     $rule
  * @param null|Mage_SalesRule_Model_Rule $salesRule
  * @param int                            $websiteId
  * @param null                           $threshold
  *
  * @return $this
  * @throws Exception
  */
 public function saveMatchedCustomers(Bronto_Reminder_Model_Rule $rule, $salesRule, $websiteId, $threshold = null)
 {
     $select = $rule->getConditions()->getConditionsSql($rule, $websiteId);
     $interval = Mage::helper('bronto_reminder')->getCronInterval();
     if (!$rule->getConditionSql()) {
         return $this;
     }
     if ($threshold) {
         $select->where('c.emails_failed IS NULL OR c.emails_failed < ? ', $threshold);
     }
     // Only pull for reminders not already attached to an active record
     $select->where('c.is_active IS NULL OR c.is_active <> 1');
     // Handle Send Limit
     $sendLimit = $rule->getSendLimit();
     if ($sendLimit > 0) {
         $subSelect = $this->createSelect()->from(array($this->getTable('bronto_reminder/log')), array('num_send' => 'count(log_id)', 'unique_id'))->group(array('unique_id'));
         $select->joinLeft(array('l' => $subSelect), 'c.unique_id=l.unique_id', array())->where('l.num_send IS NULL OR l.num_send < ?', $sendLimit);
     }
     // Handle Send To Value
     switch ($rule->getSendTo()) {
         case 'user':
             $select->where('`root`.`customer_id` IS NOT NULL AND `root`.`customer_id` != 0');
             break;
         case 'guest':
             $select->where('`root`.`customer_id` IS NULL OR `root`.`customer_id` = 0');
             break;
         case 'both':
         default:
             // No need to filter
             break;
     }
     $i = 0;
     $ruleId = $rule->getId();
     $adapter = $this->_getWriteAdapter();
     $currentDate = $this->formatDate(time());
     $dataToInsert = array();
     Mage::helper('bronto_reminder')->writeDebug('ruleId: ' . $rule->getId() . ' website: ' . $websiteId, 'bronto_reminder_sql.log');
     // Log the query with binds replaced
     $this->logFullQuery($select, array('rule_id' => $ruleId, 'interval' => $interval));
     /* @var $stmt Varien_Db_Statement_Pdo_Mysql */
     $stmt = $adapter->query($select, array('rule_id' => $ruleId, 'interval' => $interval));
     Mage::helper('bronto_reminder')->writeDebug('saveMatchedCustomers():', 'bronto_reminder_sql.log');
     try {
         $adapter->beginTransaction();
         while ($row = $stmt->fetch()) {
             if (empty($row['coupon_id']) && $salesRule) {
                 if ($salesRule->getCouponType() == Mage_SalesRule_Model_Rule::COUPON_TYPE_SPECIFIC && $salesRule->getUseAutoGeneration()) {
                     $coupons = $salesRule->getCoupons();
                     if (!$coupons) {
                         $coupons = array();
                     }
                     foreach ($coupons as $couponTemp) {
                         if ($couponTemp->getUsageLimit() > $couponTemp->getTimesUsed() && (is_null($couponTemp->getExpirationDate()) || $couponTemp->getExpirationDate() > date('Y-m-d H:i:s', mktime(0, 0, 0, date('m'), date('d'), date('Y'))))) {
                             $coupon = $couponTemp;
                         }
                     }
                 } else {
                     $coupon = $salesRule->acquireCoupon();
                 }
                 $couponId = $coupon !== null ? $coupon->getId() : null;
             } else {
                 $couponId = $row['coupon_id'];
             }
             $dataToInsert[] = array('rule_id' => $ruleId, 'product_recommendation_id' => $rule->getProductRecommendationId(), 'coupon_id' => $couponId, 'unique_id' => $row['unique_id'], 'store_id' => $row['store_id'], 'customer_id' => $row['customer_id'], 'quote_id' => $row['quote_id'], 'wishlist_id' => $row['wishlist_id'], 'customer_email' => $row['customer_email'], 'associated_at' => $currentDate, 'is_active' => '1');
             $i++;
             if ($i % 1000 == 0) {
                 $this->_saveMatchedCustomerData($dataToInsert);
                 $adapter->commit();
                 $adapter->beginTransaction();
                 $dataToInsert = array();
             }
         }
         $this->_saveMatchedCustomerData($dataToInsert);
         $adapter->commit();
         Mage::helper('bronto_reminder')->writeDebug("  Query Matched {$i} customers", 'bronto_reminder_sql.log');
     } catch (Exception $e) {
         $adapter->rollBack();
         throw $e;
     }
     return $this;
 }