Правила цен на каталог, применяемые к special_price

Первый вопрос о stackoverflow... я взволнован:)

В настоящее время magento использует специальную цену, если ее ниже, чем применяемое правило цены каталога. Если правило цены каталога делает продукт более дешевым, чем специальная цена, тогда правило цены каталога определяет цену магазина.

Я ищу элегантный способ сделать правила цен каталога по специальной цене (дополнительно). Может быть, есть какой-то конфиг для магазина? Может быть есть некоторый опрятный способ наблюдателя?

Большое вам спасибо!

Ответ 1

Обратите внимание, что этот ответ работает только для старых версий Magento < 1,9. Для новых версий Magento, пожалуйста, проверьте @Josef ответ.


Мне грустно говорить, что я решил свой первый реальный вопрос о стеке для моего собственного:

  • Перейти к Mage_CatalogRule_Model_Resource_Rule
  • Метод Goto _getRuleProductsStmt
  • Добавьте это к первоначальному выбору метода перед первым оригиналом ->from:

    $select- > from (null, array ('default_price' = > новый Zend_Db_Expr ( "CASE WHEN pp_default_special.value THEN pp_default_special.value ELSE pp_default_normal.value END" )));

  • Добавьте это после первого соединения() произошло

    $specialPriceAttr  = Mage::getSingleton('eav/config')
                        ->getAttribute(Mage_Catalog_Model_Product::ENTITY, 'special_price');
    $specialPriceTable = $specialPriceAttr->getBackend()->getTable();
    $specialPriceAttributeId= $specialPriceAttr->getId();
    $joinCondition2 = '%1$s.entity_id=rp.product_id AND (%1$s.attribute_id=' . $specialPriceAttributeId . ') 
                                                    AND %1$s.store_id=%2$s';
    $select->join(
            array('pp_default_special'=>$specialPriceTable),
            sprintf($joinCondition2, 'pp_default_special', Mage_Core_Model_App::ADMIN_STORE_ID), null
    );
    

Как это работает:

При применении правила цены каталога (через бэкэнд или cron) заполняется таблица db catalogrule_product_price. Вышеупомянутая SQL-магия присоединяется к special_price (если существует) к набору результатов как столбец default_value, если не найдена специальная_ценка, обычная цена объединяется.

Результат был проверен и работает.

Удачи! И не взламывайте ядро!

Ответ 2

Кажется, есть некоторые изменения в новых выпусках Magento! Для 1.9 я должен был:

скопировать app/code/core/Mage/CatalogRule/Model/Action/Index/Refresh.php в app/code/local/Mage/CatalogRule/Model/Action/Index/Refresh.php Измените _prepareTemporarySelect.

Я размещаю функцию здесь полностью. Добавляются соединения для special_price, а затем добавляется цена в поле выбора цены. Он по-прежнему предпочитает групповые цены, потому что я никогда их не использую, но это легко изменить!

protected
function _prepareTemporarySelect(Mage_Core_Model_Website $website)
    {
    /** @var $catalogFlatHelper Mage_Catalog_Helper_Product_Flat */
    $catalogFlatHelper = $this->_factory->getHelper('catalog/product_flat');
    /** @var $eavConfig Mage_Eav_Model_Config */
    $eavConfig = $this->_factory->getSingleton('eav/config');
    $priceAttribute = $eavConfig->getAttribute(Mage_Catalog_Model_Product::ENTITY, 'price');
    $specialPriceAttr = Mage::getSingleton('eav/config')->getAttribute(Mage_Catalog_Model_Product::ENTITY, 'special_price');
    $specialPriceTable = $specialPriceAttr->getBackend()->getTable();
    $specialPriceAttributeId = $specialPriceAttr->getId();
    $select = $this->_connection->select()->from(array(
        'rp' => $this->_resource->getTable('catalogrule/rule_product')
    ) , array())->joinInner(array(
        'r' => $this->_resource->getTable('catalogrule/rule')
    ) , 'r.rule_id = rp.rule_id', array())->where('rp.website_id = ?', $website->getId())->order(array(
        'rp.product_id',
        'rp.customer_group_id',
        'rp.sort_order',
        'rp.rule_product_id'
    ))->joinLeft(array(
        'pg' => $this->_resource->getTable('catalog/product_attribute_group_price')
    ) , 'pg.entity_id = rp.product_id AND pg.customer_group_id = rp.customer_group_id' . ' AND pg.website_id = rp.website_id', array())->joinLeft(array(
        'pgd' => $this->_resource->getTable('catalog/product_attribute_group_price')
    ) , 'pgd.entity_id = rp.product_id AND pgd.customer_group_id = rp.customer_group_id' . ' AND pgd.website_id = 0', array());
    $storeId = $website->getDefaultStore()->getId();
    if ($catalogFlatHelper->isEnabled() && $storeId && $catalogFlatHelper->isBuilt($storeId))
        {
        $select->joinInner(array(
            'p' => $this->_resource->getTable('catalog/product_flat') . '_' . $storeId
        ) , 'p.entity_id = rp.product_id', array());
        $priceColumn = $this->_connection->getIfNullSql($this->_connection->getIfNullSql('pg.value', 'pgd.value') , $this->_connection->getIfNullSql('p.special_price', 'p.price'));
        }
      else
        {
        $select->joinInner(array(
            'pd' => $this->_resource->getTable(array(
                'catalog/product',
                $priceAttribute->getBackendType()
            ))
        ) , 'pd.entity_id = rp.product_id AND pd.store_id = 0 AND pd.attribute_id = ' . $priceAttribute->getId() , array())->joinLeft(array(
            'pspd' => $specialPriceTable
        ) , 'pspd.entity_id = rp.product_id AND (pspd.attribute_id=' . $specialPriceAttributeId . ')' . 'AND pspd.store_id = 0', array())->joinLeft(array(
            'p' => $this->_resource->getTable(array(
                'catalog/product',
                $priceAttribute->getBackendType()
            ))
        ) , 'p.entity_id = rp.product_id AND p.store_id = ' . $storeId . ' AND p.attribute_id = pd.attribute_id', array())->joinLeft(array(
            'psp' => $specialPriceTable
        ) , 'psp.entity_id = rp.product_id AND (psp.attribute_id=' . $specialPriceAttributeId . ')' . 'AND psp.store_id = ' . $storeId, array());
        $priceColumn = $this->_connection->getIfNullSql($this->_connection->getIfNullSql('pg.value', 'pgd.value') , $this->_connection->getIfNullSql('psp.value', $this->_connection->getIfNullSql('pspd.value', $this->_connection->getIfNullSql('p.value', 'pd.value'))));
        }

    $select->columns(array(
        'grouped_id' => $this->_connection->getConcatSql(array(
            'rp.product_id',
            'rp.customer_group_id'
        ) , '-') ,
        'product_id' => 'rp.product_id',
        'customer_group_id' => 'rp.customer_group_id',
        'from_date' => 'r.from_date',
        'to_date' => 'r.to_date',
        'action_amount' => 'rp.action_amount',
        'action_operator' => 'rp.action_operator',
        'action_stop' => 'rp.action_stop',
        'sort_order' => 'rp.sort_order',
        'price' => $priceColumn,
        'rule_product_id' => 'rp.rule_product_id',
        'from_time' => 'rp.from_time',
        'to_time' => 'rp.to_time'
    ));
    return $select;
    }

Ответ 3

Я исправил это по-другому. Это было просто легко ввести в ценовое поле, например, 100, а затем в специальное поле цены 90, когда на странице продукта была 10% скидка, но теперь я удалил специальную цену со страницы продукта и только что создал правило цены каталога 10% скидка на этот продукт (s), и теперь действуют и другие правила:)