4

我一直在查看salesrule_coupon表格,发现如果规则本身是“自动”类型,我可以将许多优惠券代码映射到单个规则。这非常方便,因为我的客户需要我们定期将代码与数据源同步。

因此,在加载这数千个代码(使用自定义模块和直接 SQL 调用)时,它们加载得很好,我可以测试并验证它们中的许多是否有效。

然而,在我按照这些代码列表的方式工作时,它们停止工作。前 30 个左右可以正常工作,但之后,Magento 说这些代码无效。

我仍在调试这个,如果我发现任何东西,我会发布更新......但我现在已经尝试并体验了这两个单独的价格规则。一条规则在第 31 条代码中出现,第二条在第 39 条代码中出现。

真正奇怪的是,如果我将这些代码更改为指向不同的规则(一个少于 30 个代码的规则),它们就会被识别和接受。没有其他改变,我可以确定。

关于如何在这里进行的任何想法?有没有人尝试过这个?这是一个有趣的。

4

2 回答 2

5

当我为我的一位客户创建类似的东西时,我解决了同样的问题。检索有效优惠券 Magento Core Sales Rule 模块的问题来源FIND_IN_SET()GROUP_CONCAT()MySQL 函数一起使用,而不是为连接表添加附加条件。因此FIND_IN_SET,只需将组连接中使用的优惠券代码数量截断为 31 个项目(32 位掩码)。我还注意到他们使用的是 HAVING 而不是 where,所以它会稍微影响性能。

所以你需要做的是以下几点:

  1. 为此资源模型创建重写Mage_SalesRule_Model_Mysql4_Rule_Collection:( salesrule/rule_collection)
  2. 然后在重写核心的资源模型中,您需要重新定义此方法setValidationFilter($websiteId, $customerGroupId, $couponCode='', $now=null),以限制前端的销售规则。这里是我使用的方法体:

    /**
     * Fix for validation with auto-coupons
     * @todo remove this fix, after the bug in core will be fixed
     *
     * (non-PHPdoc)
     * @see Mage_SalesRule_Model_Mysql4_Rule_Collection::setValidationFilter()
     */
    public function setValidationFilter($websiteId, $customerGroupId, $couponCode='', $now=null)
    {
        if (is_null($now)) {
            $now = Mage::getModel('core/date')->date('Y-m-d');
        }
    
        $this->getSelect()->where('is_active=1');
        $this->getSelect()->where('find_in_set(?, website_ids)', (int)$websiteId);
        $this->getSelect()->where('find_in_set(?, customer_group_ids)', (int)$customerGroupId);
    
        if ($couponCode) {
            $couponCondition = $this->getConnection()->quoteInto(
                'extra_coupon.code = ?',
                $couponCode
            );
    
            $this->getSelect()->joinLeft(
                array('extra_coupon' => $this->getTable('salesrule/coupon')),
                'extra_coupon.rule_id = main_table.rule_id AND extra_coupon.is_primary IS NULL AND ' . $couponCondition,
                array()
            );
            $this->getSelect()->where('('
                . $this->getSelect()->getAdapter()->quoteInto(' main_table.coupon_type <> ?', Mage_SalesRule_Model_Rule::COUPON_TYPE_SPECIFIC)
                . $this->getSelect()->getAdapter()->quoteInto(' OR primary_coupon.code = ?', $couponCode) . ')'
            );
            $this->getSelect()->where('('
                . $this->getSelect()->getAdapter()->quoteInto(' main_table.coupon_type <> ?', Mage_SalesRule_Model_Rule::COUPON_TYPE_AUTO)
                . $this->getSelect()->getAdapter()->quoteInto(' OR extra_coupon.code IS NOT NULL') . ')'
            );
        } else {
            $this->getSelect()->where('main_table.coupon_type = ?', Mage_SalesRule_Model_Rule::COUPON_TYPE_NO_COUPON);
        }
        $this->getSelect()->where('from_date is null or from_date<=?', $now);
        $this->getSelect()->where('to_date is null or to_date>=?', $now);
        $this->getSelect()->order('sort_order');
    
        return $this;
    }
    
  3. 测试修复并享受 Magento 开发 :)

于 2011-06-08T20:12:12.553 回答
4

另一种解决方案是增加您遇到的mysql限制

设置全局 group_concat_max_len=9999999;

正如 Ivan 解释的那样,FIND_IN_SET 不会返回您所有的优惠券代码。您需要增加 group_concat_max_len 才能保存所有以逗号分隔的优惠券代码的长度(COUPON1、COUPON2、COUPON3)。

由于您可能使用了不同长度的不同代码,这可以解释为什么一条规则适用于 30 而另一条适用于 38。

于 2011-06-08T22:09:31.393 回答