Perhaps consider the following setup:
Applying normal discounts (20-30% off some products)
Either do this manually on each product or create a category called "Sale Items" and under that a subcategory for each discount bracket, e.g "20 percent", "30 percent", etc. You can then use catalog price rules on each of these categories to get the desired discounts.
Flash sales
Again, create a category for the flash sale and then create a catalog price rule discounting products in this category. You can set a "to" and "from" date on this price rule.
Showing sale products on the homepage
To show products that have a special price applied to them I usually create a new block called Namespace_Module_Block_Product_List_Special
(Special.php). It needs to extend Mage_Catalog_Block_Product_List
. You can then overwrite the _getProductCollection()
. Here's the whole block file:
<?php
class Namespace_Module_Block_Product_List_Special extends Mage_Catalog_Block_Product_List
{
//default item limit
protected $_defaultItemLimit = 4;
public function _construct() {
parent::_construct();
}
/**
* Retrieve product collection
*
* @return Mage_Eav_Model_Entity_Collection_Abstract
*/
protected function _getProductCollection()
{
$todayStartOfDayDate = Mage::app()->getLocale()->date()
->setTime('00:00:00')
->toString(Varien_Date::DATETIME_INTERNAL_FORMAT);
$todayEndOfDayDate = Mage::app()->getLocale()->date()
->setTime('23:59:59')
->toString(Varien_Date::DATETIME_INTERNAL_FORMAT);
$collection = Mage::getResourceModel('catalog/product_collection');
$collection->setVisibility(Mage::getSingleton('catalog/product_visibility')->getVisibleInCatalogIds());
$collection = $this->_addProductAttributesAndPrices($collection)
->addStoreFilter()
->addAttributeToFilter('special_from_date', array('date' => true, 'to' => $todayStartOfDayDate))
->addAttributeToFilter('special_to_date', array('or'=> array(
0 => array('date' => true, 'from' => $todayStartOfDayDate),
1 => array('is' => new Zend_Db_Expr('null')))
), 'left')
->addAttributeToSort('special_from_date', 'desc')
;
$itemLimit = $this->getItemLimit();
$collection->setPageSize($itemLimit);
return $collection;
}
public function getItemLimit() {
if($this->hasData('item_limit')) {
return $this->getData('item_limit');
}
return $this->_defaultItemLimit;
}
}
To use it you'll need to add this to your config.xml
under the <global>
tag:
<blocks>
<modulename>
<class>Namespace_Module_Block</class>
</modulename>
<catalog>
<rewrite>
<product_list_special>Namespace_Module_Block_Product_List_Special</product_list_special>
</rewrite>
</catalog>
</blocks>
And then display it on the homepage like so:
{{block type="catalog/product_list_special" name="homepage.products.special" template="catalog/product/list.phtml"}}
Or via layout XML:
<block type="catalog/product_list_special" name="hometabs.products.special" template="catalog/product/list.phtml"/>
You could use the same method to display the special products in each category, but that would require a change to the _getProductCollection()
method that checks for the current category. Have a look at Mage_Catalog_Block_Product_list::_getProductCollection()
for some ideas on the code to use for this.
it took me a while to figure this out. Should work for you, if you customy it for your needs.
To list products affected by a price rule, you must make your way over the rule-model.
Here is the code:
<?php
// we need the date to filter for the special price
$dateToday = date('m/d/y');
$tomorrow = mktime(0, 0, 0, date('m'), date('d')+1, date('y'));
$dateTomorrow = date('m/d/y', $tomorrow);
// this gets the product collection and filters for special price;
// grabs products with special_from_date at least today, and special_to_date at least tomorrow
$_productCollection = Mage::getModel('catalog/product')->getCollection()
->addAttributeToFilter('special_from_date', array('date' => true, 'to' => $dateToday))
->addAttributeToFilter('special_to_date', array('date' => true, 'from' => $dateTomorrow))
->load();
// this loads the standard magento catalog proce rule model
$rules = Mage::getResourceModel('catalogrule/rule_collection')->load();
// read: if there are active rules
if($rules->getData()) {
$rule_ids = array(); // i used this down below to style the products according to which rule affected
$productIds[] = array(); // this will hold the ids of the products
foreach($rules as $rule) {
$rule_ids[] = $rule->getId();
$productIds = $rule->getMatchingProductIds(); // affected products come in here
}
// merge the collections: $arr is an array and keeps all product IDs we fetched before with the special-price-stuff
$arr = $_productCollection->getAllIds();
if($productIds) {
// if there are products affected by catalog price rules, $arr now also keeps their IDs
$arr = array_merge($arr,$productIds);
}
// we initialize a new collection and filter solely by the product IDs we got before, read: select all products with their entity_id in $arr
$_productCollection = Mage::getModel('catalog/product')->getCollection()
->addAttributeToFilter('entity_id',array('in'=>$arr))
->load();
}
== UPDATE ==
I added some comments to the code and renamed $skus
to $productIds
(which fits better).
If you are still getting errors, please let me know what's exactly happening. This code is tested for Magento v1.7.0.2.
Cheers
Simon
Best Answer
I had this before.
Because the catalog price rules have a start and end date, they need a constant reindex. (look in the tables
catalogrule_product_*
).So when you apply all the rules they are valid for the current day only.
Magento already has a cron that applies the catalog rules that should run each day.
If you set up your cron to run this will be solved.
Add to your crontab: