How can I create a sales rule that applies a further reduction on special prices?

magento.stackexchange https://magento.stackexchange.com/questions/4735

  •  16-10-2019
  •  | 
  •  

Question

Our catalog extensively uses 'Special Price' prices throughout. We need to put on a sale with 'further reduction' of 15% with this as a catalog price rule.

If the product was £10 and marked down to £5 by 'special price' then we would want to show a further 15% discount and see £4.25 (rather than £5 or £8.50).

As a workaround I can get the prices in and out of Excel, however, this 'further reduction' is a feature of the store and retail in general. Therefore, how do I do it? Using a cart rule is not what is needed here, I know I could apply a further reduction that way but I need the price to be actually paid on the front end.

Was it helpful?

Solution

You must rewrite /app/code/core/Mage/CatalogRule/Model/Resource/Rule.php class. There is function _getRuleProductsStmt returns product price data with sql query. I added some changes:

    $specialAttr  = Mage::getSingleton('eav/config')->getAttribute(Mage_Catalog_Model_Product::ENTITY, 'special_price');
    $specialTable = $priceAttr->getBackend()->getTable();
    $specialId    = $specialAttr->getId();
    $specialCondition = '%1$s.entity_id=rp.product_id AND (%1$s.attribute_id=' . $specialId. ') and %1$s.store_id=%2$s';
    //some code here

    $select->joinLeft(
        array('psp_default'=> $specialTable),
        sprintf($specialCondition, 'psp_default', Mage_Core_Model_App::ADMIN_STORE_ID),
        array('default_price'=> 'least(ifnull(psp_default.`value`,pp_default.`value`),pp_default.`value`)')
    );

See full method body with my changes:

protected function _getRuleProductsStmt($fromDate, $toDate, $productId = null, $websiteId = null)
{
    $read = $this->_getReadAdapter();
    /**
     * Sort order is important
     * It used for check stop price rule condition.
     * website_id   customer_group_id   product_id  sort_order
     *  1           1                   1           0
     *  1           1                   1           1
     *  1           1                   1           2
     * if row with sort order 1 will have stop flag we should exclude
     * all next rows for same product id from price calculation
     */
    $select = $read->select()
        ->from(array('rp' => $this->getTable('catalogrule/rule_product')))
        ->where($read->quoteInto('rp.from_time = 0 or rp.from_time <= ?', $toDate)
        . ' OR ' . $read->quoteInto('rp.to_time = 0 or rp.to_time >= ?', $fromDate))
        ->order(array('rp.website_id', 'rp.customer_group_id', 'rp.product_id', 'rp.sort_order', 'rp.rule_id'));

    if (!is_null($productId)) {
        $select->where('rp.product_id=?', $productId);
    }

    /**
     * Join default price and websites prices to result
     */
    $priceAttr    = Mage::getSingleton('eav/config')->getAttribute(Mage_Catalog_Model_Product::ENTITY, 'price');
    $priceTable   = $priceAttr->getBackend()->getTable();
    $attributeId  = $priceAttr->getId();
    $specialAttr  = Mage::getSingleton('eav/config')->getAttribute(Mage_Catalog_Model_Product::ENTITY, 'special_price');
    $specialTable = $priceAttr->getBackend()->getTable();
    $specialId    = $specialAttr->getId();

    $joinCondition  = '%1$s.entity_id=rp.product_id AND (%1$s.attribute_id=' . $attributeId
        . ') and %1$s.store_id=%2$s';
    $specialCondition = '%1$s.entity_id=rp.product_id AND (%1$s.attribute_id=' . $specialId
        . ') and %1$s.store_id=%2$s';

    $select->join(
        array('pp_default'=> $priceTable),
        sprintf($joinCondition, 'pp_default', Mage_Core_Model_App::ADMIN_STORE_ID),
        array()
    );
    $select->joinLeft(
        array('psp_default'=> $specialTable),
        sprintf($specialCondition, 'psp_default', Mage_Core_Model_App::ADMIN_STORE_ID),
        array('default_price'=> 'least(ifnull(psp_default.`value`,pp_default.`value`),pp_default.`value`)')
    );

    if ($websiteId !== null) {
        $website      = Mage::app()->getWebsite($websiteId);
        $defaultGroup = $website->getDefaultGroup();
        if ($defaultGroup instanceof Mage_Core_Model_Store_Group) {
            $storeId = $defaultGroup->getDefaultStoreId();
        } else {
            $storeId = Mage_Core_Model_App::ADMIN_STORE_ID;
        }

        $select->joinInner(
            array('product_website' => $this->getTable('catalog/product_website')),
            'product_website.product_id=rp.product_id ' .
                'AND rp.website_id=product_website.website_id ' .
                'AND product_website.website_id=' . $websiteId,
            array()
        );

        $tableAlias = 'pp' . $websiteId;
        $fieldAlias = 'website_' . $websiteId . '_price';
        $select->joinLeft(
            array($tableAlias=> $priceTable),
            sprintf($joinCondition, $tableAlias, $storeId),
            array($fieldAlias=> $tableAlias . '.value')
        );
    } else {
        foreach (Mage::app()->getWebsites() as $website) {
            $websiteId    = $website->getId();
            $defaultGroup = $website->getDefaultGroup();
            if ($defaultGroup instanceof Mage_Core_Model_Store_Group) {
                $storeId = $defaultGroup->getDefaultStoreId();
            } else {
                $storeId = Mage_Core_Model_App::ADMIN_STORE_ID;
            }

            $tableAlias = 'pp' . $websiteId;
            $fieldAlias = 'website_' . $websiteId . '_price';
            $select->joinLeft(
                array($tableAlias => $priceTable),
                sprintf($joinCondition, $tableAlias, $storeId),
                array($fieldAlias => $tableAlias . '.value')
            );
        }
    }
    return $read->query($select);
} 

My Magento version is 1.7.0.2, I didn't tested result deeply, but this changes give me correct result.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top