Загрузка тысяч кодов для сопоставления с правилом корзины покупок в Magento - PullRequest
4 голосов
/ 08 июня 2011

Я просматривал таблицу salesrule_coupon и обнаружил, что могу сопоставить множество кодов купонов одному правилу, если само правило имеет тип «Авто». Это очень удобно, поскольку мой клиент нуждается в том, чтобы мы периодически синхронизировали коды с потоком данных.

Таким образом, при загрузке этих тысяч кодов (с использованием пользовательского модуля и прямых вызовов SQL) они загружаются просто отлично, и я могу проверить и убедиться, что многие из них работают.

Однако, работая над списком этих кодов, они перестают работать. Первые 30 или около того будут работать нормально, но после этого Magento говорит, что коды недействительны.

Я все еще отлаживаю это, и я буду публиковать обновления, если я обнаружу что-нибудь ... но я попробовал и испытал это с двумя отдельными ценовыми правилами. Одно правило отменено в 31-м коде, второе - в 39-м.

Что действительно странно, так это то, что если я изменю эти коды, чтобы они указывали на другое правило (одно с менее чем 30 кодами), они распознаются и принимаются. Ничего другого не изменилось, что я могу определить.

Любые идеи о том, как действовать здесь? Кто-нибудь пытался сделать это раньше? Это интересный.

Ответы [ 2 ]

5 голосов
/ 09 июня 2011

Я исправил ту же проблему, когда создавал нечто подобное для одного из моих клиентов.Источник проблемы для получения действительного купона Модуль Magento Core Sales Rule использует FIND_IN_SET() с GROUP_CONCAT() функциями MySQL вместо добавления дополнительного условия для объединенной таблицы.Таким образом, FIND_IN_SET просто усекает количество кодов купонов, которые используются в групповой конкатенации, до 31 элемента (маска 32 бита).Также я заметил, что они используют HAVING вместо где, так что это немного влияет на производительность.

Итак, вам нужно сделать следующее:

  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. Исправление теста и Enjoy Magento Development:)

4 голосов
/ 09 июня 2011

Другим решением является увеличение лимита mysql, с которым вы сталкиваетесь, с помощью

SET GLOBAL group_concat_max_len = 9999999;

, как объяснил Иван, FIND_IN_SET не возвращает все ваши коды купонов.Вам нужно увеличить group_concat_max_len, чтобы иметь возможность хранить длину всех ваших кодов купонов, разделенных запятой (COUPON1, COUPON2, COUPON3).

Поскольку вы, вероятно, использовали разные коды разной длины, это объясняет, почему одно правило работало для 30, а другое - для 38.

...