Magento Forum

   
Page 1 of 2
Configurable products with catalogue price rules not working
 
2kp
Jr. Member
 
Total Posts:  10
Joined:  2009-02-16
 

I’ve set up some products with configurable options which add to the price. This all works fine, till the if the item is part of a catalogue price rule, the discount is only applied to the basic price, not the configurable add ons.

Has anyone else had this. You’d of thought this would just work?!

 
Magento Community Magento Community
Magento Community
Magento Community
 
thaddeusmt
Member
 
Avatar
Total Posts:  33
Joined:  2009-02-02
Bozeman, MT
 

yes I’ve just noticed this problem as well. I couldn’t find any info on it anywhere, so I just submitted a bug:

http://www.magentocommerce.com/bug-tracking/issue?issue=7033

I’m now going to try and see if OrganicInternet’s nice “Simple Configurable Product” extension will fix this for me in the mean time.
http://www.magentocommerce.com/extension/596/simple-configurable-products

 
Magento Community Magento Community
Magento Community
Magento Community
 
unfeasible
Sr. Member
 
Avatar
Total Posts:  93
Joined:  2008-03-03
 

Same problem here. Just signing in to wait to hear a reply.

 
Magento Community Magento Community
Magento Community
Magento Community
 
thaddeusmt
Member
 
Avatar
Total Posts:  33
Joined:  2009-02-02
Bozeman, MT
 

So, I’ve hacked in a little workaround here. So far so good - I’ll post again later if some important part of the functionality isn’t working. But everything seems good in 1.3.2.3.

First, in Mage/Catalog/Model/Product/Type/Configurable/Price.php insert:

$action_operator "";
        
$action_amount 0;
        
$action_stop 0;
        
//get the price rule that applies to this product
        
$sql "SELECT rule_id, from_time, to_time, action_operator, action_stop, action_amount, website_id FROM catalogrule_product WHERE product_id = ".$product->getId()." ORDER BY sort_order asc";
        
$data Mage::getSingleton('core/resource') ->getConnection('core_read')->fetchAssoc($sql);
        foreach (
$data as $rule{
            
//see if last rule stops all others
            
if ($action_stop != 1{
                
//get the customer groups the rule applies to
                
$usergroups = array();
                
$sql "SELECT customer_group_ids, is_active FROM catalogrule WHERE rule_id = ".$rule['rule_id'];
                
$userdata Mage::getSingleton('core/resource')->getConnection('core_read')->fetchRow($sql);
                
$usergroups explode(",",$userdata['customer_group_ids']);
                
//check to make sure the rule applies to the current user's group
                
if ($userdata['is_active'== && in_array(Mage::getSingleton('customer/session')->getCustomerGroupId(),$usergroups)) {
                    
//first, set the "to_time" ahead to the future if it's not set (infinity)
                    
if ($rule['to_time'== 0
                        
$rule['to_time'mktime(00000date("Y")+20);
                    
//make sure this rule applies to the current website
                    
if ($rule['website_id'== Mage::app()->getWebsite()->getId()) {
                        $storetime 
Mage::app()->getLocale()->storeTimeStamp(Mage::app()->getStore()->getId());
                        
//check that the rule is within it's active dates
                        
if ($rule['from_time'$storetime && $storetime $rule['to_time']{
                            
//save these for use below
                            
if ($action_operator == "" || $action_operator == $rule['action_operator']{
                                $action_operator 
$rule['action_operator'];
                                
$action_amount $action_amount $rule['action_amount'];
                            
else {
                                $action_operator 
$rule['action_operator'];
                                
$action_amount $rule['action_amount'];
                            
}
                            
//set if this rule stops all others
                            
$action_stop $rule['action_stop']
                        
}
                    }
                }
            } 
        }

into getFinalPrice() below this code (around line 60):

$selectedAttributes = array();
        if (
$product->getCustomOption('attributes')) {
            $selectedAttributes 
unserialize($product->getCustomOption('attributes')->getValue());
        
}

Also in Mage/Catalog/Model/Product/Type/Configurable/Price.php insert:

//if it's by_percent, apply that calculation to the $value['pricing_value'] number
                    if ($action_operator == "by_percent"{
                        $value[
'pricing_value'$value['pricing_value'- ($value['pricing_value'* ($action_amount .01));
                    

                    
//if it's to_percent, apply that calculation to the $value['pricing_value'] number
                    
else if ($action_operator == "to_percent"{    
                        $value[
'pricing_value'$value['pricing_value'* ($action_amount .01);    
                    
}

just below this (around line 114 now):

if($value{
                
if($value['pricing_value'!= 0{
.

And in Mage/Catalog/Block/Product/View/Type/Configurable.php insert:

$action_operator "";
        
$action_amount 0;
        
$action_stop 0;
        
//get the price rule that applies to this product
        
$sql "SELECT rule_id, from_time, to_time, action_operator, action_stop, action_amount, website_id FROM catalogrule_product WHERE product_id = ".$product->getId()." ORDER BY sort_order asc";
        
$data Mage::getSingleton('core/resource') ->getConnection('core_read')->fetchAssoc($sql);
        foreach (
$data as $rule{
            
//see if last rule stops all others
            
if ($action_stop != 1{
                
//get the customer groups the rule applies to
                
$usergroups = array();
                
$sql "SELECT customer_group_ids, is_active FROM catalogrule WHERE rule_id = ".$rule['rule_id'];
                
$userdata Mage::getSingleton('core/resource')->getConnection('core_read')->fetchRow($sql);
                
$usergroups explode(",",$userdata['customer_group_ids']);
                
//check to make sure the rule applies to the current user's group
                
if ($userdata['is_active'== && in_array(Mage::getSingleton('customer/session')->getCustomerGroupId(),$usergroups)) {
                    
//first, set the "to_time" ahead to the future if it's not set (infinity)
                    
if ($rule['to_time'== 0
                        
$rule['to_time'mktime(00000date("Y")+20);
                    
//make sure this rule applies to the current website
                    
if ($rule['website_id'== Mage::app()->getWebsite()->getId()) {
                        $storetime 
Mage::app()->getLocale()->storeTimeStamp(Mage::app()->getStore()->getId());
                        
//check that the rule is within it's active dates
                        
if ($rule['from_time'$storetime && $storetime $rule['to_time']{
                            
//save these for use below
                            
if ($action_operator == "" || $action_operator == $rule['action_operator']{
                                $action_operator 
$rule['action_operator'];
                                
$action_amount $action_amount $rule['action_amount'];
                            
else {
                                $action_operator 
$rule['action_operator'];
                                
$action_amount $rule['action_amount'];
                            
}
                            
//set if this rule stops all others
                            
$action_stop $rule['action_stop']
                        
}
                    }
                }
            } 
        }

below

$this->_resPrices = array(
            
$this->_preparePrice($this->getProduct()->getFinalPrice())
        );

and insert

//if it's by_percent, apply that calculation to the $value['pricing_value'] number
 if ($action_operator == "by_percent"{
           
//echo "approved";die();
         
$value['pricing_value'$value['pricing_value'- ($value['pricing_value'* ($action_amount .01));

//if it's to_percent, apply that calculation to the $value['pricing_value'] number
else if ($action_operator == "to_percent"{    
            $value[
'pricing_value'$value['pricing_value'* ($action_amount .01);    
}

below

if (is_array($prices)) {
                
foreach ($prices as $value{
                    
if(!$this->_validateAttributeValue($attributeId$value$options)) {
                        
continue;
                    
}

(Yes, the code inserted into Mage/Catalog/Model/Product/Type/Configurable/Price.php and Mage/Catalog/Block/Product/View/Type/Configurable.php is exactly the same - I’ll figure out how to reduce this duplication at a later date. Right now I just wanted to get it working. Actually, I hope Magento will fix this bug in the next version, instead of me trying to streamline my kludge. :)

This SHOULD take into account all price rules, in the correct order, including “stop further processing” rules. Also this should apply the price rules only to the correct users on the correct websites. It does the by_percent and to_percent catalog price rules, which were the broken ones I as far as I could tell.

I’m sure it’s buggy, but it seems to be working OK so far. :)

 
Magento Community Magento Community
Magento Community
Magento Community
 
thaddeusmt
Member
 
Avatar
Total Posts:  33
Joined:  2009-02-02
Bozeman, MT
 

Oh yeah, there was an issue with the Javascript, as well.

In Mage/Catalog/Block/Product/View/Type/Configurable.php you need to save the price increase amount for the configurable products before you change it. About my changes (around line 163) I save it temporarily like this:

$orig_price $value['pricing_value'];

Then I add it to the options array below:

$info['options'][] = array(
                        
'id'    => $value['value_index'],
                        
'label' => $value['label'],
                        
'price' => $this->_preparePrice($value['pricing_value']$value['is_percent']),
                        
'products'   => isset($options[$attributeId][$value['value_index']]) ? $options[$attributeId][$value['value_index']] : array(),
                        
'orig_price' => $orig_price,  //ADD IT HERE
                    
);

THEN, I had to search around js/varien/product.js for a while, reverse engineering it, and eventually put some shoddy JS together to use the orig_price value I returned in the JSON so the correct “old price” is shown.

Rather than try to explain line-by-line what I did to poor product.js, I have attached it.

The JS code I changed it commented with “//addedcodehere”.

Good luck!

File Attachments
product.js  (File Size: 24KB - Downloads: 199)
 
Magento Community Magento Community
Magento Community
Magento Community
 
Gregoire
Jr. Member
 
Total Posts:  15
Joined:  2009-05-13
 

Hello ,

Thank you for sharing your work concerning de special prices for Configurable product. I applied your changes and it seems to work on the product page, but it’s still the normal price in the cart when I add the product. Is it the same for you ?

Thank you

 
Magento Community Magento Community
Magento Community
Magento Community
 
Gregoire
Jr. Member
 
Total Posts:  15
Joined:  2009-05-13
 

I think I found my problem : I applied a rule with a condition on the attribute “manufacturer” but, by Default, it’s not applied to configurable products

 
Magento Community Magento Community
Magento Community
Magento Community
 
jamesrlowe
Jr. Member
 
Total Posts:  5
Joined:  2010-03-02
 

I Can’t believe this hasnt been fixed. It renders configurable products with discounts unusable!

Thanks thaddeusmt! This has worked for me on 1.4.0.1.
Make sure you put

$orig_price $value['pricing_value'];
before
$value['pricing_value'$value['pricing_value'- ($value['pricing_value'* ($action_amount .01));

also, i had an issue with the base price staying at 0.00 when I selected it. can be fixed with something like

if(is_null($orig_price)) $orig_price 0.0;

 
Magento Community Magento Community
Magento Community
Magento Community
 
ohsnapy
Jr. Member
 
Total Posts:  2
Joined:  2010-01-15
 

Thanks for sharing this patch.  This worked for me.  The one issue I had is in Mage/Catalog/Block/Product/View/Type/Configurable.php I had change $product->getId to $product->getParentId.  Specifically:

$sql = “SELECT rule_id, from_time, to_time, action_operator, action_stop, action_amount, website_id FROM catalogrule_product WHERE product_id = “.$product->getId().” ORDER BY sort_order asc”;

with

$sql = “SELECT rule_id, from_time, to_time, action_operator, action_stop, action_amount, website_id FROM catalogrule_product WHERE product_id = “.$product->getParentId().” ORDER BY sort_order asc”;

 
Magento Community Magento Community
Magento Community
Magento Community
 
Jing Jing
Jr. Member
 
Total Posts:  2
Joined:  2010-01-05
 

Thanks for sharing.

I got a few lines to work it out instead.

In Mage/Catalog/Model/Product/Type/Configurable/Price.php

if ($subProduct $product->getTypeInstance(true)->getProductByAttributes($selectedAttributes$product)) {
            $subFinalPrice 
parent::getFinalPrice($qty$subProduct);
               
$finalPrice $subFinalPrice;
        
}
    
else {

Just after

$selectedAttributes = array();
        if (
$product->getCustomOption('attributes')) {
            $selectedAttributes 
unserialize($product->getCustomOption('attributes')->getValue());
        
}

 
Magento Community Magento Community
Magento Community
Magento Community
 
justSelling
Jr. Member
 
Avatar
Total Posts:  2
Joined:  2009-06-15
Germany
 

Konnte schon jemand nachvollziehen, ob das Problem in der 1.5.x behoben wurde?

 
Magento Community Magento Community
Magento Community
Magento Community
 
web-vision
Jr. Member
 
Total Posts:  14
Joined:  2008-02-13
 

Problem still exists in 1.5.0.1.
Has anybody a workaround fixing this issue for 1.5.0.1 - also willing to pay for fixing this issue.

 
Magento Community Magento Community
Magento Community
Magento Community
 
SleepingGiant
Jr. Member
 
Avatar
Total Posts:  20
Joined:  2011-09-18
Netherlands
 

Im having the same problem. Is there an extention orso for?

 
Magento Community Magento Community
Magento Community
Magento Community
 
zium
Jr. Member
 
Total Posts:  7
Joined:  2010-04-10
 

@thaddeusmt thanks for your code snippets! It seems to work well in magento 1.4.1.1

 
Magento Community Magento Community
Magento Community
Magento Community
 
Jamie Jackson
Jr. Member
 
Avatar
Total Posts:  23
Joined:  2010-03-05
Sheffield, UK
 

And still seems to be present in 1.6, were trying to work on a Fix but for a feature like this I would have like to have seen it work as default

 
Magento Community Magento Community
Magento Community
Magento Community
 
lucky fruit
Jr. Member
 
Avatar
Total Posts:  7
Joined:  2009-05-12
 

I found a solution on other site:

This issue is case by Mage_SalesRule_Model_Rule_Condition_Product_Subselect:: validate(), line 133: foreach ($object->getQuote()-> getAllItems() as $item) { , after add one Configurable Product to shop cart, because Configurable Product have two items in shop cart(one is configurable product it self,another one is simple product belong to the configurable Product), so the qty will be duplicable . If modify line 133 to following, this issue can be fiexed:  foreach ($object ->getQuote()-> getAllVisibleItems() as $item) {

It works prefectly on me, hope can help you all smile

 
Magento Community Magento Community
Magento Community
Magento Community
Magento Community
Magento Community
    Back to top
Page 1 of 2