8

What would be a good way of retrieving the lowest and highest possible prices for a given configurable product - based on its availble options?

For example a t-shirt comes in the following sizes and prices:

Small - $10
Medium - $20
Large - $30

I want to get an array like so:

array(10, 30)

My best idea so far is load the configurable product type instance and use getUsedProducts, then create an array of prices, sort and slice.

That should work, however this needs to be run on the product list template so it needs to be semi efficient.

Any others out there faced this problem before?

EDIT - that wont work since i want the configurable pricing value i.e. the additive price magento puts on top of the configurable product price

6 Answers 6

13

Try this approach. use the config array that the attribute dropdowns use to change the price of the configurable product. Let's assume that $productId is the ID of the configurable product.

$product = Mage::getModel('catalog/product')->load($productId);
$block = Mage::app()->getLayout()->createBlock('catalog/product_view_type_configurable');
$block->setProduct($product);
$config = json_decode($block->getJsonConfig(), true);
$basePrice = $config['basePrice'];
$min = null;
$max = null;
foreach ($config['attributes'] as $aId=>$aValues){
    foreach ($aValues['options'] as $key=>$value){
        if (is_null($min) || $min>$value['price']){
            $min = $value['price'];
        }
        if (is_null($max) || $max<$value['price']){
            $max = $value['price'];
        }
    }
}
//until here we have the min and max price differences. Now just add the base price.
$min += $basePrice;
$max += $basePrice;
4
  • 1
    It doesn't look like this will work if the price is built up out of multiple attributes. E.g., if there's a price addition for size "XL" and a price addition for material "silver" this won't get the price of the XL Silver product.
    – Laizer
    Mar 2, 2014 at 18:44
  • @Laizer i tested with a product with 2 attributes and it seams to work. Can you provide a configuration that does not work with this method?
    – Marius
    Mar 2, 2014 at 19:18
  • 1
    if each attribute adds to the base price, this method won't pick up the combination of the two additions. I just tested it on a configurable product with two price-impacting attributes and found that it didn't get the max price. I also tested the method you suggest at magento.stackexchange.com/questions/9665/…, and that one works well, adding the impact of both attributes.
    – Laizer
    Mar 2, 2014 at 19:34
  • I concur. This does not seem to work for multiple config. options.
    – gnicko
    Aug 16, 2018 at 17:46
10

A simpler one.

if($_product->isConfigurable()) // check if the product is configurable (u may check this in for loop of products)
                {
                    //get associative (child) products
                    $childProducts = Mage::getModel('catalog/product_type_configurable')->getUsedProducts(null,$_product);
                    $childPriceLowest = "";    
                    $childPriceHighest = "";       
                    foreach($childProducts as $child){
                        $_child = Mage::getModel('catalog/product')->load($child->getId());

                        if($childPriceLowest == '' || $childPriceLowest > $_child->getPrice() )
                        $childPriceLowest =  $_child->getPrice();

                        if($childPriceHighest == '' || $childPriceHighest < $_child->getPrice() )
                        $childPriceHighest =  $_child->getPrice();

                    }
                    $price_array = array($childPriceLowest,$childPriceHighest); // array containing required values
                }
2
  • I believe this works, but only in the case where the price of the simple product matches the price of that product when bought as a selection of a configurable. Not clear to me that it has to match.
    – Laizer
    Mar 2, 2014 at 18:47
  • This worked perfectly for me since the prices of our configurable products are exactly the same as the simple products which constitute our configurables. Which is to say that we treat our configurable products as merely containers which hold simple products. On Magento 1.9, configurable products on product listing pages don't display the lowest price, which is why this code came in handy (we wanted to display an "As low as ____" label instead of the product's regular price).
    – Aquarelle
    Nov 14, 2014 at 5:42
5

This answer, also by @Marius, to a similar question is a good basis to work from. Using that, here's a solution to this problem that takes into account the potential for configurable products having multiple attributes that change price.

I've written it as function that takes a configurable product id, and returns a string of min to max price. It should be pretty clear how to work it into the context that you need.

function getPriceRange($productId) {

 $max = '';
 $min = '';

 $pricesByAttributeValues = array();

 $product = Mage::getModel('catalog/product')->load($productId); 
 $attributes = $product->getTypeInstance(true)->getConfigurableAttributes($product);
 $basePrice = $product->getFinalPrice();

 foreach ($attributes as $attribute){
    $prices = $attribute->getPrices();
    foreach ($prices as $price){
        if ($price['is_percent']){ //if the price is specified in percents
            $pricesByAttributeValues[$price['value_index']] = (float)$price['pricing_value'] * $basePrice / 100;
        }
        else { //if the price is absolute value
            $pricesByAttributeValues[$price['value_index']] = (float)$price['pricing_value'];
        }
    }
 }


 $simple = $product->getTypeInstance()->getUsedProducts();

 foreach ($simple as $sProduct){
    $totalPrice = $basePrice;

    foreach ($attributes as $attribute){

        $value = $sProduct->getData($attribute->getProductAttribute()->getAttributeCode());
        if (isset($pricesByAttributeValues[$value])){
            $totalPrice += $pricesByAttributeValues[$value];
        }
    }
    if(!$max || $totalPrice > $max)
        $max = $totalPrice;
    if(!$min || $totalPrice < $min)
        $min = $totalPrice;
 }

 return "$min - $max";

}
4

This will do the trick, although it is not the best example

<?php $_configurable = $_product->getTypeInstance()->getUsedProductIds(); ?>
<?php $price_array = array(); $i=0; ?>
<?php foreach ($_configurable as $_config): ?>
    <?php $_simpleproduct = Mage::getModel('catalog/product')->load($_config); ?>
    <?php array_push($price_array, $_simpleproduct->getPrice()); ?>
<?php $i++; endforeach; ?>
<?php if(min($price_array) != max($price_array)): ?>
    <div class="price-box">
        <span id="product-price-<?php echo $_product->getId(); ?>" class="regular-price">
            <?php echo Mage::helper('core')->currency(min($price_array)); ?>
            <span class="price" style="padding: 0 5px; color: black;">-</span>
            <span class="final"><?php echo Mage::helper('core')->currency(max($price_array)); ?></span>
        </span>
    </div>
    <?php else: ?>
        <?php echo $this->getPriceHtml($_product, true); ?>
<?php endif; ?>
1
  • 1
    This makes the mistake of assuming the the price of simple product is the same as the price of the configured option - not a guarantee.
    – Laizer
    Mar 2, 2014 at 18:52
1

Using EE 1.14, I was getting "funny" numbers using the methods proposed above for some reason. The $childPriceLowest and $childPriceHighest were not returning the true minimum and maximum values all the time. Sometimes, with multiple configuration options, etc. I saw intermediate values.

I ended up using this:

//get associated (child) products
$childProducts = Mage::getModel('catalog/product_type_configurable')
    ->getUsedProducts(null,$_product);

//cycle through child products, dump prices in an array.... 
foreach($childProducts as $child){  
   $_child = Mage::getModel('catalog/product')->load($child->getId());
   $childPrices[] = $_child->getPrice();
}

// concentrate the array to unique values and sort ascending....
$childPrices = array_unique($childPrices, SORT_NUMERIC);
sort($childPrices);     // array containing required values

Then later on, this to echo the range:

<?php echo Mage::helper('core')->currency( $childPrices[0], true, false); ?>
<span class="config-price-divider"> - </span>
<?php echo Mage::helper('core')->currency( end($childPrices), true, false)?>

(e. g. "$10.00 - $30.00")

0

You can also try this simple code to get Highest / lowest price as per your need

$childPriceHighest = '';
         $product = Mage::getModel('catalog/product')->load($productId);
        $childProducts = Mage::getSingleton('catalog/product_type_configurable')->getUsedProducts( null, $product );

        if ($childProducts) {
            foreach ($childProducts as $child) {
                $_child = Mage::getSingleton('catalog/product')->load($child->getId());
                if ($childPriceHighest == '' || $childPriceHighest < $_child->getPrice()) {
                    $childPriceHighest = $_child->getPrice();
                }
            }
        } else {
            $childPriceHighest = $product->getPrice();
        }

        return $childPriceHighest;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.