/** * Processing object before save data * * @return Mage_Core_Model_Abstract */ protected function _beforeSave() { if (!$this->getRuleId() && $this->_rule instanceof Mage_SalesRule_Model_Rule) { $this->setRuleId($this->_rule->getId()); } return parent::_beforeSave(); }
/** * Add rule to filter * * @param Mage_SalesRule_Model_Rule|int $rule * * @return Mage_SalesRule_Model_Resource_Coupon_Collection */ public function addRuleToFilter($rule) { if ($rule instanceof Mage_SalesRule_Model_Rule) { $ruleId = $rule->getId(); } else { $ruleId = (int) $rule; } $this->addFieldToFilter('rule_id', $ruleId); return $this; }
/** * Return discount item qty * * @param Mage_Sales_Model_Quote_Item_Abstract $item * @param Mage_SalesRule_Model_Rule $rule * @return int */ protected function _getItemQty($item, $rule) { //@nelkaake: Magento 1.3 and lower doesnt have the item->getTotalQty attribute. if (Mage::helper('rewards/version')->isBaseMageVersionAtLeast('1.4')) { $qty = $item->getTotalQty(); } else { $qty = $item->getQty(); if ($item->getParentItem()) { $qty *= $item->getParentItem()->getQty(); } } return $rule->getDiscountQty() ? min($qty, $rule->getDiscountQty()) : $qty; }
/** * @return Mage_Rule_Model_Abstract|void */ protected function _beforeSave() { parent::_beforeSave(); if (is_array($this->getCustomerGroupIds())) { $this->setCustomerGroupIds(join(',', $this->getCustomerGroupIds())); } }
/** * @param Mage_Sales_Model_Quote_Address $address * @param Mage_SalesRule_Model_Rule $rule * @param Mage_Sales_Model_Quote_Item_Abstract[] $allItems * @param Mage_Sales_Model_Quote_Item_Abstract[] $validItems * * @return bool */ public function handle(Mage_Sales_Model_Quote_Address $address, Mage_SalesRule_Model_Rule $rule, array $allItems, array $validItems) { if ($rule->getSimpleAction() !== Mage_SalesRule_Model_Rule::BUY_X_GET_Y_ACTION) { return false; } $helper = $this->getHelper(); // Get the X and Y values $x = max(floatval($rule->getDiscountStep()), 0.0); $y = max(floatval($rule->getDiscountAmount()), 0.0); if ($x <= 0.0 || $y <= 0.0) { return false; } // Get the discount step size $step = $x + $y; $applied = false; foreach ($validItems as $item) { // Get max quantity $qty = $helper->getItemRuleQty($item, $rule); // Apply discount step size limitation $qty = max($qty - ceil($qty / $step) * $x, 0.0); if ($qty <= 0.0) { continue; } $applied = true; // Get unit prices $itemPrice = $helper->getItemPrice($item); $itemBasePrice = $helper->getItemBasePrice($item); $itemOriginalPrice = $helper->getItemOriginalPrice($item); $itemBaseOriginalPrice = $helper->getItemBaseOriginalPrice($item); // Calculate discount amounts $discountAmount = $itemPrice * $qty; $originalDiscountAmount = $itemOriginalPrice * $qty; $baseDiscountAmount = $itemBasePrice * $qty; $baseOriginalDiscountAmount = $itemBaseOriginalPrice * $qty; // Round the discount amounts $discountAmount = $helper->round($discountAmount, $address->getQuote()->getQuoteCurrencyCode()); $baseDiscountAmount = $helper->round($baseDiscountAmount, $address->getQuote()->getBaseCurrencyCode()); $originalDiscountAmount = $helper->round($originalDiscountAmount, $address->getQuote()->getQuoteCurrencyCode()); $baseOriginalDiscountAmount = $helper->round($baseOriginalDiscountAmount, $address->getQuote()->getBaseCurrencyCode()); // Update the item discounts $item->setDiscountAmount($item->getDiscountAmount() + $discountAmount); $item->setBaseDiscountAmount($item->getBaseDiscountAmount() + $baseDiscountAmount); $item->setOriginalDiscountAmount($item->getOriginalDiscountAmount() + $originalDiscountAmount); $item->setBaseOriginalDiscountAmount($item->getBaseOriginalDiscountAmount() + $baseOriginalDiscountAmount); } return $applied; }
public function getDiscountAmount() { if (substr($this->getCouponCode(), 0, 6) == 'points') { $step = Mage::getStoreConfig('rewardpoints/default/points_money', Mage::app()->getStore()->getId()); return $this->getPointsAmt() / $step; } $test = new Mage_SalesRule_Model_Rule(); if (method_exists($test, 'getDiscountAmount')) { return parent::getDiscountAmount(); } if ($this->discount_amount) { return $this->discount_amount; } }
protected function _afterSave() { $iRuleId = $this->getId(); $oReq = Mage::app()->getFrontController()->getRequest(); $aData = $oReq->getPost(); /* This check has been added for Amastsy extension to work properly while sending coupons through cron */ if (empty($aData)) { return parent::_afterSave(); } /* This check has been added for Amastsy extension to work properly while sending coupons through cron */ /* modifying this line to trigger newsletter subscription coupon */ if (!isset($aData['customer_individ_ids'])) { return parent::_afterSave(); } /* modifying this line to trigger newsletter subscription coupon */ $oResource = Mage::getSingleton('core/resource'); $sTable = $oResource->getTableName('aitoc_salesrule_assign_cutomer'); $oDb = Mage::getSingleton('core/resource')->getConnection('core_write'); if (!isset($aData['customer_group_ids']) or !$aData['customer_group_ids']) { if (version_compare(Mage::getVersion(), '1.12.0.0', '>=')) { $oDb->delete(Mage::getSingleton('core/resource')->getTableName('salesrule_customer_group'), 'rule_id = ' . $iRuleId); } else { $oResModel = Mage::getModel('salesrule/mysql4_rule'); $oDb->update($oResModel->getMainTable(), array('customer_group_ids' => ''), 'rule_id = ' . $iRuleId); } } if ($aData['customer_individ_ids']) { $aCustomerHash = explode('_', $aData['customer_individ_ids']); # $oDb->update($oResModel->getMainTable(), array('customer_group_ids' => 'individ'), 'rule_id = ' . $iRuleId); } else { $aCustomerHash = array(); # $oDb->update($oResModel->getMainTable(), array('customer_group_ids' => implode(',', $aData['customer_group_ids'])), 'rule_id = ' . $iRuleId); } $oDb->delete($sTable, 'entity_id = ' . $iRuleId); if ($aCustomerHash) { foreach ($aCustomerHash as $sKey => $sValue) { if ($sValue) { $aDBInfo = array('entity_id' => $iRuleId, 'customer_id' => $sValue, 'coupon_code' => $aData['coupon_code']); $oDb->insert($sTable, $aDBInfo); } } } return parent::_afterSave(); }
/** * Validate the rule usage for given address * @param Mage_SalesRule_Model_Rule * @param Mage_Sales_Model_Quote_Address * @return bool */ protected function isValidRuleUsageForAddress(Mage_SalesRule_Model_Rule $rule, Mage_Sales_Model_Quote_Address $address) { $ruleId = $rule->getId(); $customerId = $address->getQuote()->getCustomerId(); $ruleCustomer = $this->getRuleCustomerModel(); $ruleCustomer->loadByCustomerRule($customerId, $ruleId); if ($ruleCustomer->getId() && $ruleCustomer->getTimesUsed() >= $rule->getUsesPerCustomer()) { return false; } return true; }
/** * @param Mage_Sales_Model_Quote_Address $address * @param Mage_SalesRule_Model_Rule $rule * @param Mage_Sales_Model_Quote_Item_Abstract[] $allItems * @param Mage_Sales_Model_Quote_Item_Abstract[] $validItems * * @return bool */ public function handle(Mage_Sales_Model_Quote_Address $address, Mage_SalesRule_Model_Rule $rule, array $allItems, array $validItems) { // Skip invalid rule actions if ($rule->getSimpleAction() !== Mage_SalesRule_Model_Rule::CART_FIXED_ACTION) { return false; } // Skip if there are no valid items and it's not applied to shipping if (!count($validItems) && !$rule->getApplyToShipping()) { return false; } // Define a few helpful variables $helper = $this->getHelper(); $quote = $address->getQuote(); $store = $quote->getStore(); // Total available discount amounts $baseDiscountAmount = $helper->round($rule->getDiscountAmount(), $quote->getBaseCurrencyCode()); $discountAmount = $helper->round($store->convertPrice($baseDiscountAmount), $quote->getQuoteCurrencyCode()); // Skip zero discounts if ($discountAmount <= 0.0) { return false; } $applied = false; // Pre-calculate the totals for all valid items $ruleTotalItemsPrice = 0; $ruleTotalBaseItemsPrice = 0; $itemPrices = []; foreach ($validItems as $item) { // Get max quantity (min or rule max qty or item qty) $qty = $helper->getItemRuleQty($item, $rule); // Skip zero quantity if ($qty <= 0.0) { continue; } // Get unit price $itemPrice = $helper->getItemPrice($item); $itemBasePrice = $helper->getItemBasePrice($item); // Get row price $itemRowPrice = $itemPrice * $item->getTotalQty(); $itemBaseRowPrice = $itemBasePrice * $item->getTotalQty(); // Get discountable price $itemDiscountablePrice = $itemPrice * $qty; $itemBaseDiscountablePrice = $itemBasePrice * $qty; // Save price data for later $itemPrices[$item->getId()] = [$itemPrice, $itemBasePrice, $itemRowPrice, $itemBaseRowPrice, $itemDiscountablePrice, $itemBaseDiscountablePrice]; // Add row prices to running totals $ruleTotalItemsPrice += $itemDiscountablePrice; $ruleTotalBaseItemsPrice += $itemBaseDiscountablePrice; } $startDiscountAmount = $discountAmount; $startBaseDiscountAmount = $baseDiscountAmount; foreach ($validItems as $item) { // Skip the skipped items if (!isset($itemPrices[$item->getId()])) { continue; } // Flag indicating the rule was applied $applied = true; // Extract the pre-calculate price data list($itemPrice, $itemBasePrice, $itemRowPrice, $itemBaseRowPrice, $itemDiscountablePrice, $itemBaseDiscountablePrice) = $itemPrices[$item->getId()]; // Calculate remaining row amount $itemRemainingRowPrice = max($itemRowPrice - $item->getDiscountAmount(), 0); $itemRemainingBaseRowPrice = max($itemBaseRowPrice - $item->getBaseDiscountAmount(), 0); // Calculate price factor $priceFactor = $itemDiscountablePrice / $ruleTotalItemsPrice; $basePriceFactor = $itemBaseDiscountablePrice / $ruleTotalBaseItemsPrice; // Calculate (and round) the item discount amount $itemDiscountAmount = $helper->round($startDiscountAmount * $priceFactor, $quote->getQuoteCurrencyCode()); $itemBaseDiscountAmount = $helper->round($startBaseDiscountAmount * $basePriceFactor, $quote->getBaseCurrencyCode()); // Ensure discount does not exceed the remaining discount, max item discount, or remaining row price $itemDiscountAmount = max(min($itemDiscountAmount, $discountAmount, $itemDiscountablePrice, $itemRemainingRowPrice), 0.0); $itemBaseDiscountAmount = max(min($itemBaseDiscountAmount, $baseDiscountAmount, $itemBaseDiscountablePrice, $itemRemainingBaseRowPrice), 0.0); // Update the item discount $item->setDiscountAmount($item->getDiscountAmount() + $itemDiscountAmount); $item->setBaseDiscountAmount($item->getBaseDiscountAmount() + $itemBaseDiscountAmount); // This is a bit wonky, but needed for taxes $item->setOriginalDiscountAmount($item->getOriginalDiscountAmount() + $itemDiscountAmount); $item->setBaseOriginalDiscountAmount($item->getBaseOriginalDiscountAmount() + $itemBaseDiscountAmount); // Subtract from the total remaining discount amount $discountAmount -= $itemDiscountAmount; $baseDiscountAmount -= $itemBaseDiscountAmount; } if ($rule->getApplyToShipping()) { $shippingAmount = $address->getShippingAmountForDiscount(); $baseShippingAmount = $address->getBaseShippingAmountForDiscount(); if ($shippingAmount === null || $baseShippingAmount === null) { $shippingAmount = $address->getShippingAmount(); $baseShippingAmount = $address->getBaseShippingAmount(); } $shippingAmount -= $address->getShippingDiscountAmount(); $baseShippingAmount -= $address->getBaseShippingDiscountAmount(); $shippingDiscountAmount = max(min($discountAmount, $shippingAmount), 0.0); $shippingBaseDiscountAmount = max(min($baseDiscountAmount, $baseShippingAmount), 0.0); $address->setShippingDiscountAmount($address->getShippingDiscountAmount() + $shippingDiscountAmount); $address->setBaseShippingDiscountAmount($address->getBaseShippingDiscountAmount() + $shippingBaseDiscountAmount); // Subtract from the total discount amount $discountAmount -= $shippingDiscountAmount; $baseDiscountAmount -= $shippingBaseDiscountAmount; $applied = true; } // Do something with possible remaining discount amount if ($applied && $discountAmount > 0.0) { foreach ($validItems as $item) { // Skip the skipped items if (!isset($itemPrices[$item->getId()])) { continue; } // Extract the pre-calculate price data list($itemPrice, $itemBasePrice, $itemRowPrice, $itemBaseRowPrice, $itemDiscountablePrice, $itemBaseDiscountablePrice) = $itemPrices[$item->getId()]; // Calculate remaining row amount $itemRemainingRowPrice = max($itemRowPrice - $item->getDiscountAmount(), 0); $itemRemainingBaseRowPrice = max($itemBaseRowPrice - $item->getBaseDiscountAmount(), 0); // Apply the discount if ($itemRemainingRowPrice >= $discountAmount && $itemRemainingBaseRowPrice >= $baseDiscountAmount) { // Update the item discount $item->setDiscountAmount($item->getDiscountAmount() + $discountAmount); $item->setBaseDiscountAmount($item->getBaseDiscountAmount() + $baseDiscountAmount); // This is a bit wonky, but needed for taxes $item->setOriginalDiscountAmount($item->getOriginalDiscountAmount() + $discountAmount); $item->setBaseOriginalDiscountAmount($item->getBaseOriginalDiscountAmount() + $baseDiscountAmount); // Zero out remaining discount $discountAmount = 0.0; $baseDiscountAmount = 0.0; } // If we've used the discount, exit the loop early if ($discountAmount <= 0.0) { break; } } } return $applied; }
public function _resetConditions($conditions = null) { parent::_resetConditions($conditions); $this->getConditions($conditions)->setId('viewed_conditions')->setPrefix('viewed'); return $this; }
/** * Update auto generated Specific Coupon if it's rule changed * * @param Mage_SalesRule_Model_Rule $rule * @return Mage_SalesRule_Model_Resource_Coupon */ public function updateSpecificCoupons(Mage_SalesRule_Model_Rule $rule) { if (!$rule || !$rule->getId() || !$rule->hasDataChanges()) { return $this; } $updateArray = array(); 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 Zend_Date($rule->getToDate()); $ruleOldDate = new Zend_Date($rule->getOrigData('to_date')); if ($ruleNewDate->compare($ruleOldDate)) { $updateArray['expiration_date'] = $rule->getToDate(); } if (!empty($updateArray)) { $this->_getWriteAdapter()->update($this->getTable('salesrule_coupon'), $updateArray, array('rule_id = ?' => $rule->getId())); } return $this; }
/** * Process rule related data after rule save * * @return Mage_CatalogRule_Model_Rule */ protected function _afterSave() { $this->_getResource()->updateRuleProductData($this); parent::_afterSave(); }
/** * Add rule discount description label to address object * * @param Mage_Sales_Model_Quote_Address $address * @param Mage_SalesRule_Model_Rule $rule * @return Mage_SalesRule_Model_Validator */ protected function _addDiscountDescription($address, $rule) { $description = $address->getDiscountDescriptionArray(); $ruleLabel = $rule->getStoreLabel($address->getQuote()->getStore()); $label = ''; if ($ruleLabel) { $label = $ruleLabel; } else { if ($address->getCouponCode()) { $label = $address->getCouponCode(); } } if (!empty($label)) { $description[$rule->getId()] = $label; } $address->setDiscountDescriptionArray($description); return $this; }
/** * 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; }
/** * Return discount item qty * * @param Mage_Sales_Model_Quote_Item_Abstract $item * @param Mage_SalesRule_Model_Rule $rule * @return int */ protected function _getItemQty($item, $rule) { $qty = $item->getTotalQty(); return $rule->getDiscountQty() ? min($qty, $rule->getDiscountQty()) : $qty; }
/** * Make sure that a gift is only added once, create a free item and add it to the cart. * * @param Mage_Sales_Model_Quote $quote * @param Mage_Sales_Model_Quote_Item $item * @param Mage_SalesRule_Model_Rule $rule */ protected static function _handleGift(Mage_Sales_Model_Quote $quote, Mage_Sales_Model_Quote_Item $item, Mage_SalesRule_Model_Rule $rule) { if ($rule->getIsApplied()) { return; } $qty = (int) $rule->getDiscountAmount(); if ($qty) { $freeItem = self::_getFreeQuoteItem($quote, $rule->getGiftSku(), $item->getStoreId(), $qty); self::_addAndApply($quote, $freeItem, $rule); } }
/** * Try to associate reminder rule with matched customers. * If customer was added earlier, update is_active column. * * @param Enterprise_Reminder_Model_Rule $rule * @param Mage_SalesRule_Model_Rule $salesRule * @param int $websiteId * @param int $threshold * * @return Enterprise_Reminder_Model_Resource_Rule */ public function saveMatchedCustomers($rule, $salesRule, $websiteId, $threshold = null) { $rule->setConditions(null); $rule->afterLoad(); /** @var $select Zend_Db_Select */ $select = $rule->getConditions()->getConditionsSql(null, $websiteId); if (!$rule->getConditionSql()) { return $this; } if ($threshold) { $select->where('c.emails_failed IS NULL OR c.emails_failed < ? ', $threshold); } $i = 0; $ruleId = $rule->getId(); $adapter = $this->_getWriteAdapter(); $couponsTable = $this->getTable('enterprise_reminder/coupon'); $currentDate = $this->formatDate(time()); $dataToInsert = array(); $stmt = $adapter->query($select, array('rule_id' => $ruleId)); $adapter->beginTransaction(); try { while ($row = $stmt->fetch()) { if (empty($row['coupon_id']) && $salesRule) { $coupon = $salesRule->acquireCoupon(); $couponId = $coupon !== null ? $coupon->getId() : null; } else { $couponId = $row['coupon_id']; } $dataToInsert[] = array('rule_id' => $ruleId, 'coupon_id' => $couponId, 'customer_id' => $row['entity_id'], 'associated_at' => $currentDate, 'is_active' => '1'); $i++; if ($i % 1000 == 0) { $adapter->insertOnDuplicate($couponsTable, $dataToInsert, array('is_active')); $dataToInsert = array(); } } if (!empty($dataToInsert)) { $adapter->insertOnDuplicate($couponsTable, $dataToInsert, array('is_active')); } } catch (Exception $e) { $adapter->rollBack(); throw $e; } $adapter->commit(); return $this; }
public function updateRuleProductData(Mage_SalesRule_Model_Rule $rule) { // foreach ($rule->getActions()->getActions() as $action) { // break; // } $ruleId = $rule->getId(); $read = $this->_getReadAdapter(); $write = $this->_getWriteAdapter(); $write->delete($this->getTable('salesrule/rule_product'), $write->quoteInto('rule_id=?', $ruleId)); if (!$rule->getIsActive()) { return $this; } if ($rule->getUsesPerCoupon() > 0) { $usedPerCoupon = $read->fetchOne('select count(*) from ' . $this->getTable('salesrule/rule_customer') . ' where rule_id=?', $ruleId); if ($usedPerCoupon >= $rule->getUsesPerCoupon()) { return $this; } } $productIds = explode(',', $rule->getProductIds()); $websiteIds = explode(',', $rule->getWebsiteIds()); $customerGroupIds = explode(',', $rule->getCustomerGroupIds()); $fromTime = strtotime($rule->getFromDate()); $toTime = strtotime($rule->getToDate()); if ($toTime) { $toTime += 86400; } $couponCode = $rule->getCouponCode() ? "'" . $rule->getCouponCode() . "'" : 'NULL'; $sortOrder = (int) $rule->getSortOrder(); $rows = array(); $header = 'replace into ' . $this->getTable('salesrule/rule_product') . ' (rule_id, from_time, to_time, website_id, customer_group_id, product_id, coupon_code, sort_order) values '; try { $write->beginTransaction(); foreach ($productIds as $productId) { foreach ($websiteIds as $websiteId) { foreach ($customerGroupIds as $customerGroupId) { $rows[] = "('{$ruleId}', '{$fromTime}', '{$toTime}', '{$websiteId}', '{$customerGroupId}', '{$productId}', {$couponCode}, '{$sortOrder}')"; if (sizeof($rows) == 100) { $sql = $header . join(',', $rows); $write->query($sql); $rows = array(); } } } } if (!empty($rows)) { $sql = $header . join(',', $rows); $write->query($sql); } $write->commit(); } catch (Exception $e) { $write->rollback(); throw $e; } return $this; }
/** * Add the rule label to the address for later usage * * @param Mage_Sales_Model_Quote_Address $address * @param Mage_SalesRule_Model_Rule $rule * * @return $this */ protected function addRuleDescription(Mage_Sales_Model_Quote_Address $address, Mage_SalesRule_Model_Rule $rule) { $descriptions = $address->getDiscountDescriptionArray(); $label = trim($rule->getStoreLabel($address->getQuote()->getStore())); if (empty($label) && strlen($address->getCouponCode())) { $label = $address->getCouponCode(); } if (!empty($label)) { $descriptions[$rule->getId()] = $label; } $address->setDiscountDescriptionArray($descriptions); return $this; }
/** * Unserialize the conditions from the rule. * * @param Mage_SalesRule_Model_Rule $rule * @return Array of rule conditions */ protected function _getConditions($rule) { if (count($this->_conditions) == 0) { if ($rule->getId()) { $data = unserialize($rule->getData('conditions_serialized')); if (isset($data['conditions'])) { $this->_conditions = $data['conditions']; } } } return $this->_conditions; }
/** * Check rule date integrity * @nelkaake Added on Wednesday October 6, 2010: * * @return Mage_Core_Model_Abstract */ protected function _beforeSave() { if ((int) $this->getPointsAmount() === 0) { throw new Exception(Mage::helper('rewards')->__("The Points Amount (X) field must be greater than zero (0). If you don't want customers to redeem any points, why are you making shopping cart points redemption rule?")); } return parent::_beforeSave(); }
/** * @param Mage_Sales_Model_Quote_Address $address * @param Mage_SalesRule_Model_Rule $rule * @param Mage_Sales_Model_Quote_Item_Abstract[] $allItems * @param Mage_Sales_Model_Quote_Item_Abstract[] $validItems * * @return bool */ public function handle(Mage_Sales_Model_Quote_Address $address, Mage_SalesRule_Model_Rule $rule, array $allItems, array $validItems) { // Skip invalid rule actions if ($rule->getSimpleAction() !== Mage_SalesRule_Model_Rule::BY_PERCENT_ACTION) { return false; } // Skip if there are no valid items and it's not applied to shipping if (!count($validItems) && !$rule->getApplyToShipping()) { return false; } // Define a few helpful variables $helper = $this->getHelper(); $quote = $address->getQuote(); $store = $quote->getStore(); // Get discount percent $discountPercent = max(min($rule->getDiscountAmount(), 100.0), 0.0); $discountMultiplier = $discountPercent / 100; // Skip zero discounts if ($discountPercent <= 0.0) { return false; } // Get the discount step size $step = max(floatval($rule->getDiscountStep()), 0.0); $applied = false; foreach ($validItems as $item) { // Get max quantity $qty = $helper->getItemRuleQty($item, $rule); // Apply discount step size limitation if ($step > 0.0) { $qty = floor($qty / $step) * $step; } // Skip zero quantities if ($qty <= 0.0) { continue; } $applied = true; // Get row prices $itemRowPrice = $helper->getItemPrice($item) * $qty; $itemBaseRowPrice = $helper->getItemBasePrice($item) * $qty; $itemOriginalRowPrice = $helper->getItemOriginalPrice($item) * $qty; $itemBaseOriginalRowPrice = $helper->getItemBaseOriginalPrice($item) * $qty; // Calculate discount amounts $discountAmount = ($itemRowPrice - $item->getDiscountAmount()) * $discountMultiplier; $baseDiscountAmount = ($itemBaseRowPrice - $item->getBaseDiscountAmount()) * $discountMultiplier; $originalDiscountAmount = ($itemOriginalRowPrice - $item->getOriginalDiscountAmount()) * $discountMultiplier; $baseOriginalDiscountAmount = ($itemBaseOriginalRowPrice - $item->getBaseOriginalDiscountAmount()) * $discountMultiplier; // Round the discount amounts $discountAmount = $helper->round($discountAmount, $address->getQuote()->getQuoteCurrencyCode()); $baseDiscountAmount = $helper->round($baseDiscountAmount, $address->getQuote()->getBaseCurrencyCode()); $originalDiscountAmount = $helper->round($originalDiscountAmount, $address->getQuote()->getQuoteCurrencyCode()); $baseOriginalDiscountAmount = $helper->round($baseOriginalDiscountAmount, $address->getQuote()->getBaseCurrencyCode()); // Update the item discounts $item->setDiscountAmount($item->getDiscountAmount() + $discountAmount); $item->setBaseDiscountAmount($item->getBaseDiscountAmount() + $baseDiscountAmount); $item->setOriginalDiscountAmount($item->getOriginalDiscountAmount() + $originalDiscountAmount); $item->setBaseOriginalDiscountAmount($item->getBaseOriginalDiscountAmount() + $baseOriginalDiscountAmount); // Update the item percent discount value $discountPercent = min(100, $item->getDiscountPercent() + $discountPercent); $item->setDiscountPercent($discountPercent); } if ($rule->getApplyToShipping()) { $shippingAmount = $address->getShippingAmountForDiscount(); $baseShippingAmount = $address->getBaseShippingAmountForDiscount(); if ($shippingAmount === null || $baseShippingAmount === null) { $shippingAmount = $address->getShippingAmount(); $baseShippingAmount = $address->getBaseShippingAmount(); } // Subtract existing discounts $shippingAmount -= $address->getShippingDiscountAmount(); $baseShippingAmount -= $address->getBaseShippingDiscountAmount(); // Calculate and round discounts $shippingDiscountAmount = $helper->round($shippingAmount * $discountMultiplier, $address->getQuote()->getQuoteCurrencyCode()); $shippingBaseDiscountAmount = $helper->round($baseShippingAmount * $discountMultiplier, $address->getQuote()->getBaseCurrencyCode()); // Make sure the discount isn't more that the remaining amount $shippingDiscountAmount = min(max($shippingDiscountAmount, 0.0), $shippingAmount); $shippingBaseDiscountAmount = min(max($shippingBaseDiscountAmount, 0.0), $baseShippingAmount); // Store discounts $address->setShippingDiscountAmount($address->getShippingDiscountAmount() + $shippingDiscountAmount); $address->setBaseShippingDiscountAmount($address->getBaseShippingDiscountAmount() + $shippingBaseDiscountAmount); $applied = true; } return $applied; }
/** * Set code generator instance for auto generated coupons * * @param Mage_SalesRule_Model_Coupon_CodegeneratorInterface */ public static function setCouponCodeGenerator(Mage_SalesRule_Model_Coupon_CodegeneratorInterface $codeGenerator) { self::$_couponCodeGenerator = $codeGenerator; }
/** * Get the items the need to be discounted based on the category ids or root category and escape bundle products from calculation * * @author Mohamed Meabed <*****@*****.**> * * @param Mage_SalesRule_Model_Rule $rule * @param Mage_Sales_Model_Quote_Address $address * @param Mage_Sales_Model_Quote_Address_Item $_addressItem * * @return array */ public function getItemsToDiscount($rule, $address, $_addressItem) { $conditions = $rule->getConditions()->getConditions(); $allowedCatIds = null; $parsedCats = array(); $condition = null; $_productCategories = array(); $cartCategories = array(); $catToProcess = array(); $isRootCategory = false; $validCondition = false; $rootCategoryId = Mage::app()->getStore()->getRootCategoryId(); $ignoreType = array('bundle'); /** @var Mage_SalesRule_Model_Rule_Condition_Address $c */ foreach ($conditions as $c) { if (!$allowedCatIds && !$condition && $c->getData('attribute')) { $condition = $c; $val = $c->getValueParsed(); if (is_string($val)) { $parsedCats = explode(',', $val); } if (is_array($val)) { $parsedCats = $val; } if ($parsedCats && is_array($parsedCats)) { if (in_array($rootCategoryId, $parsedCats)) { $isRootCategory = true; $_productCategories = array($rootCategoryId); } } } } $items = $address->getAllVisibleItems(); $discountStep = $rule->getDiscountStep(); $i = 0; /** @var Mage_Sales_Model_Quote_Item $item */ foreach ($items as $item) { // Escape bundles if (in_array($ignoreType, $item->getProductType())) { continue; } if (!$isRootCategory) { /** @var Mage_Catalog_Model_Product $_product */ $_product = Mage::getModel('catalog/product')->load($item->getProductId()); $_productCategories = $_product->getCategoryIds(); } $validCondition = $condition->validateAttribute($_productCategories); $cat = array_shift($_productCategories); if ($isRootCategory || $validCondition) { for ($x = 0; $x < $item->getQty(); $x++) { $cartCategories[$cat][$i]['itemId'] = $item->getId(); $cartCategories[$cat][$i]['qty'] = $item->getQty(); $cartCategories[$cat][$i]['price'] = $item->getPrice(); $cartCategories[$cat][$i]['item'] = $item; $i++; if (count($cartCategories[$cat]) >= $discountStep) { $catToProcess[$cat] = $cat; } } } } $x = $rule->getDiscountStep(); $y = $rule->getDiscountAmount(); $return = array(); foreach ($catToProcess as $cat) { $catItems = $cartCategories[$cat]; $this->aaSort($catItems, 'price'); $qtyTobeDiscounted = (int) ($i / $discountStep); $qtyTobeDiscounted *= $y; for ($j = 0; $j < $qtyTobeDiscounted; $j++) { $itemDisc = array_pop($catItems); /** @var Mage_Sales_Model_Quote_Address_Item $salesItem */ $salesItem = $itemDisc['item']; if ($salesItem && !isset($return[$salesItem->getId()])) { $return[$salesItem->getId()] = 0; } $return[$salesItem->getId()]++; } } return $return; }
/** * Save product attributes currently used in conditions and actions of rule * * @param Mage_SalesRule_Model_Rule $rule * @param mixed $attributes * @return Mage_SalesRule_Model_Resource_Rule */ 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; }
/** * Update auto generated Specific Coupon if it's rule changed * * @param Mage_SalesRule_Model_Rule $rule * @return Mage_SalesRule_Model_Resource_Coupon */ public function updateSpecificCoupons(Mage_SalesRule_Model_Rule $rule) { if (!$rule || !$rule->getId() || !$rule->hasDataChanges()) { return $this; } $updateArray = array(); 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 Zend_Date($rule->getToDate()); $ruleOldDate = new Zend_Date($rule->getOrigData('to_date')); if ($ruleNewDate->compare($ruleOldDate)) { $updateArray['expiration_date'] = $rule->getToDate(); } if (!empty($updateArray)) { $this->_getWriteAdapter()->update($this->getTable('salesrule/coupon'), $updateArray, array('rule_id = ?' => $rule->getId(), 'generated_by_dotmailer is null')); } //update coupons added by dotmailer. not to change expiration date $dotmailerUpdateArray = $updateArray; unset($dotmailerUpdateArray['expiration_date']); if (!empty($dotmailerUpdateArray)) { $this->_getWriteAdapter()->update($this->getTable('salesrule/coupon'), $dotmailerUpdateArray, array('rule_id = ?' => $rule->getId(), 'generated_by_dotmailer is 1')); } return $this; }
/** * Look up how many times a rule was used by a customer * * @param int $customerId * @param Mage_SalesRule_Model_Rule $rule * * @return int */ public function getCustomerRuleUseCount($customerId, Mage_SalesRule_Model_Rule $rule) { /** @var Mage_SalesRule_Model_Rule_Customer $ruleCustomer */ $ruleCustomer = Mage::getModel('salesrule/rule_customer'); $ruleCustomer->loadByCustomerRule($customerId, $rule->getId()); return intval($ruleCustomer->getTimesUsed()); }
/** * Safe method of checking if a rule is a points rule. * @param TBT_Rewards_Model_Salesrule_Rule|TBT_Rewards_Model_Catalogrule_Rule|Mage_CatalogRule_Model_Rule|Mage_SalesRule_Model_Rule $rule */ public function isPointsRule($rule) { if ($rule instanceof TBT_Rewards_Model_Salesrule_Rule || $rule instanceof TBT_Rewards_Model_Catalogrule_Rule) { return $rule->isPointsRule(); } if ($rule instanceof Mage_CatalogRule_Model_Rule) { $rule = Mage::helper('rewards/rule')->getCatalogrule($rule->getId()); return $rule->isPointsRule(); } if ($rule instanceof Mage_SalesRule_Model_Rule) { $rule = Mage::helper('rewards/rule')->getSalesRule($rule->getId()); return $rule->isPointsRule(); } Mage::logException(new Exception("Reached Helper_Rule::isPointsRule() with parameter that is not a catalog rule or cart or catalog rule.")); }
/** * @param Mage_Sales_Model_Quote_Address $address * @param Mage_SalesRule_Model_Rule $rule * @param Mage_Sales_Model_Quote_Item_Abstract[] $allItems * @param Mage_Sales_Model_Quote_Item_Abstract[] $validItems * * @return bool */ public function handle(Mage_Sales_Model_Quote_Address $address, Mage_SalesRule_Model_Rule $rule, array $allItems, array $validItems) { // Skip invalid rule actions if ($rule->getSimpleAction() !== Mage_SalesRule_Model_Rule::BY_FIXED_ACTION) { return false; } // Skip if there are no valid items and it's not applied to shipping if (!count($validItems) && !$rule->getApplyToShipping()) { return false; } // Define a few helpful variables $helper = $this->getHelper(); $quote = $address->getQuote(); $store = $quote->getStore(); // Discount amount $baseDiscountAmount = $helper->round($rule->getDiscountAmount(), $quote->getBaseCurrencyCode()); $discountAmount = $helper->round($store->convertPrice($baseDiscountAmount), $quote->getQuoteCurrencyCode()); // Skip zero discounts if ($discountAmount <= 0.0) { return false; } // Get the discount step size $step = max(floatval($rule->getDiscountStep()), 0.0); $applied = false; foreach ($validItems as $item) { // Get max quantity $qty = $helper->getItemRuleQty($item, $rule); // Apply discount step size limitation if ($step > 0.0) { $qty = floor($qty / $step) * $step; } // Skip zero quantities if ($qty <= 0.0) { continue; } $applied = true; // Calculate discount amounts $discountAmount = $discountAmount * $qty; $baseDiscountAmount = $baseDiscountAmount * $qty; $originalDiscountAmount = $discountAmount * $qty; $baseOriginalDiscountAmount = $baseDiscountAmount * $qty; // Round the discount amounts $discountAmount = $helper->round($discountAmount, $address->getQuote()->getQuoteCurrencyCode()); $baseDiscountAmount = $helper->round($baseDiscountAmount, $address->getQuote()->getBaseCurrencyCode()); $originalDiscountAmount = $helper->round($originalDiscountAmount, $address->getQuote()->getQuoteCurrencyCode()); $baseOriginalDiscountAmount = $helper->round($baseOriginalDiscountAmount, $address->getQuote()->getBaseCurrencyCode()); // Update the item discounts $item->setDiscountAmount($item->getDiscountAmount() + $discountAmount); $item->setBaseDiscountAmount($item->getBaseDiscountAmount() + $baseDiscountAmount); $item->setOriginalDiscountAmount($item->getOriginalDiscountAmount() + $originalDiscountAmount); $item->setBaseOriginalDiscountAmount($item->getBaseOriginalDiscountAmount() + $baseOriginalDiscountAmount); } if ($rule->getApplyToShipping()) { $shippingAmount = $address->getShippingAmountForDiscount(); $baseShippingAmount = $address->getBaseShippingAmountForDiscount(); if ($shippingAmount === null || $baseShippingAmount === null) { $shippingAmount = $address->getShippingAmount(); $baseShippingAmount = $address->getBaseShippingAmount(); } $shippingAmount -= $address->getShippingDiscountAmount(); $baseShippingAmount -= $address->getBaseShippingDiscountAmount(); $shippingDiscountAmount = min(max($discountAmount, 0.0), $shippingAmount); $shippingBaseDiscountAmount = min(max($baseDiscountAmount, 0.0), $baseShippingAmount); $address->setShippingDiscountAmount($address->getShippingDiscountAmount() + $shippingDiscountAmount); $address->setBaseShippingDiscountAmount($address->getBaseShippingDiscountAmount() + $shippingBaseDiscountAmount); $applied = true; } return $applied; }
/** * Determine if the coupon on quote is one of the generated coupon code * for this passed salesrule/rule object. Returns null when no coupon is found * matching the coupon on the quote. * * @param Mage_SalesRule_Model_Rule * @param string * @return string | null */ protected function getCodeFromCouponPool(Mage_SalesRule_Model_Rule $rule, $codeAppliedToQuote) { /** @var Mage_SalesRule_Model_Coupon[] */ $coupons = $rule->getCoupons(); foreach ($coupons as $coupon) { if ($coupon->getCode() === $codeAppliedToQuote) { return $codeAppliedToQuote; } } return null; }