Magento购物车价格规则背后的功能在Mage_SalesRule
模块内。
可以在管理员下的Magento中配置购物车价格规则Promotions -> Shopping Cart Price Rules
。这些规则与目录规则的不同之处在于它们适用于报价,而目录规则适用于有关产品实体的目录信息。
Magento使用总模型按购物车规则计算折扣,并将其显示在购物车总数中。此discount
总计在小计和发货之后以及总计之前计算,如Mage_SalesRule
模块的config.xml
文件中所示。
file:app / code / core / Mage / SalesRule / etc / config.xml
<?xml version="1.0"?>
<config>
<global>
<sales>
<quote>
<totals>
<freeshipping>
<class>salesrule/quote_freeshipping</class>
<after>subtotal</after>
<before>tax_subtotal,shipping</before>
</freeshipping>
<discount>
<class>salesrule/quote_discount</class>
<after>subtotal,shipping</after>
<before>grand_total</before>
</discount>
</totals>
</quote>
</sales>
</global>
</config>
你还会注意到freeshipping
这里也有一个总数。这是因为在购物车价格规则中,如果客户匹配规则,您可以选择启用免费送货。
折扣总计有自己的模型,由class
节点表示Mage_SalesRule/Model/Quote/Discount.php
。
file:app / code / core / Mage / SalesRule / Model / Quote / Discount.php
public function collect(Mage_Sales_Model_Quote_Address $address)
{
parent::collect($address);
$quote = $address->getQuote();
$store = Mage::app()->getStore($quote->getStoreId());
$this->_calculator->reset($address);
$items = $this->_getAddressItems($address);
if (!count($items)) {
return $this;
}
$eventArgs = array(
'website_id' => $store->getWebsiteId(),
'customer_group_id' => $quote->getCustomerGroupId(),
'coupon_code' => $quote->getCouponCode(),
);
$this->_calculator->init($store->getWebsiteId(), $quote->getCustomerGroupId(), $quote->getCouponCode());
$this->_calculator->initTotals($items, $address);
$address->setDiscountDescription(array());
$items = $this->_calculator->sortItemsByPriority($items);
foreach ($items as $item) {
if ($item->getNoDiscount()) {
$item->setDiscountAmount(0);
$item->setBaseDiscountAmount(0);
}
else {
/**
* Child item discount we calculate for parent
*/
if ($item->getParentItemId()) {
continue;
}
$eventArgs['item'] = $item;
Mage::dispatchEvent('sales_quote_address_discount_item', $eventArgs);
if ($item->getHasChildren() && $item->isChildrenCalculated()) {
foreach ($item->getChildren() as $child) {
$this->_calculator->process($child);
$eventArgs['item'] = $child;
Mage::dispatchEvent('sales_quote_address_discount_item', $eventArgs);
$this->_aggregateItemDiscount($child);
}
} else {
$this->_calculator->process($item);
$this->_aggregateItemDiscount($item);
}
}
}
/**
* process weee amount
*/
if (Mage::helper('weee')->isEnabled() && Mage::helper('weee')->isDiscounted($store)) {
$this->_calculator->processWeeeAmount($address, $items);
}
/**
* Process shipping amount discount
*/
$address->setShippingDiscountAmount(0);
$address->setBaseShippingDiscountAmount(0);
if ($address->getShippingAmount()) {
$this->_calculator->processShippingAmount($address);
$this->_addAmount(-$address->getShippingDiscountAmount());
$this->_addBaseAmount(-$address->getBaseShippingDiscountAmount());
}
$this->_calculator->prepareDescription($address);
return $this;
}
该process()
方法属于Validator.php模型文件,该文件实际检查购物车价格规则的“操作”并应用折扣。
file:app / code / core / Mage / SalesRule / Model / Validator.php
<?php
class Mage_SalesRule_Model_Validator extends Mage_Core_Model_Abstract {
public function process() {
....
foreach ($this->_getRules() as $rule) {
....
switch ($rule->getSimpleAction()) {
case Mage_SalesRule_Model_Rule::TO_PERCENT_ACTION:
$rulePercent = max(0, 100-$rule->getDiscountAmount());
//no break;
case Mage_SalesRule_Model_Rule::BY_PERCENT_ACTION:
$step = $rule->getDiscountStep();
if ($step) {
$qty = floor($qty/$step)*$step;
}
$_rulePct = $rulePercent/100;
$discountAmount = ($qty * $itemPrice - $item->getDiscountAmount()) * $_rulePct;
$baseDiscountAmount = ($qty * $baseItemPrice - $item->getBaseDiscountAmount()) * $_rulePct;
//get discount for original price
$originalDiscountAmount = ($qty * $itemOriginalPrice - $item->getDiscountAmount()) * $_rulePct;
$baseOriginalDiscountAmount =
($qty * $baseItemOriginalPrice - $item->getDiscountAmount()) * $_rulePct;
if (!$rule->getDiscountQty() || $rule->getDiscountQty()>$qty) {
$discountPercent = min(100, $item->getDiscountPercent()+$rulePercent);
$item->setDiscountPercent($discountPercent);
}
break;
case Mage_SalesRule_Model_Rule::TO_FIXED_ACTION:
$quoteAmount = $quote->getStore()->convertPrice($rule->getDiscountAmount());
$discountAmount = $qty * ($itemPrice-$quoteAmount);
$baseDiscountAmount = $qty * ($baseItemPrice-$rule->getDiscountAmount());
//get discount for original price
$originalDiscountAmount = $qty * ($itemOriginalPrice-$quoteAmount);
$baseOriginalDiscountAmount = $qty * ($baseItemOriginalPrice-$rule->getDiscountAmount());
break;
case Mage_SalesRule_Model_Rule::BY_FIXED_ACTION:
$step = $rule->getDiscountStep();
if ($step) {
$qty = floor($qty/$step)*$step;
}
$quoteAmount = $quote->getStore()->convertPrice($rule->getDiscountAmount());
$discountAmount = $qty * $quoteAmount;
$baseDiscountAmount = $qty * $rule->getDiscountAmount();
break;
case Mage_SalesRule_Model_Rule::CART_FIXED_ACTION:
....
}
....
}
....
}
....
}
负责生成优惠券代码的Mage_SalesRule_Model_Coupon_Codegenerator
模型是模型。
file:app / code / core / Mage / SalesRule / Model / Coupon / Codegenerator.php
<?php
class Mage_SalesRule_Model_Coupon_Codegenerator extends Varien_Object
implements Mage_SalesRule_Model_Coupon_CodegeneratorInterface
{
/**
* Retrieve generated code
*
* @return string
*/
public function generateCode()
{
$alphabet = ($this->getAlphabet() ? $this->getAlphabet() : 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789');
$lengthMin = ($this->getLengthMin() ? $this->getLengthMin() : 16);
$lengthMax = ($this->getLengthMax() ? $this->getLengthMax() : 32);
$length = ($this->getLength() ? $this->getLength() : rand($lengthMin, $lengthMax));
$result = '';
$indexMax = strlen($alphabet) - 1;
for ($i = 0; $i < $length; $i++) {
$index = rand(0, $indexMax);
$result .= $alphabet{$index};
}
return $result;
}
....
}
关于购物车价格规则要记住的关键事项:
- 一次只能应用一个优惠券代码
- 对于在管理员中创建的订单,可以对特定项目禁用购物车价格规则,但它们始终应用于前端中的所有项目。
Magento将购物车价格规则数据存储在以下数据库表中。
- salesrule – 包含有关规则的一般信息,包括序列化条件和操作数据
- salesrule_coupon – 包含有关用于规则的优惠券代码的信息
- salesrule_coupon_usage – 包含有关下订单时优惠券使用情况的信息
- salesrule_customer- 包含有关客户规则使用情况的信息,例如times_used列
- salesrule_customer_group – 包含有关分配给规则的客户组的信息
- salesrule_label – 包含有关用于命名规则的标签的信息
- salesrule_product_attribute – 包含规则条件中使用的属性ID等信息
- salesrule_website – 包含规则分配给的网站ID
注意:本文基于Magento社区/开源版本1.9。
本文参考:
https://www.siphor.com/magento-shopping-cart-price-rules/