Magento购物车价格规则

Magento购物车价格规则

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/

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注