3

I'm trying to display a list of of the stock status for the simple products related to a configurable product. This is working fine except when for the first instance of the array when the related attribute 'Size' isn't display.

<?php $_helper = $this->helper('catalog/output'); ?>
<?php $_product = $this->getProduct(); ?>
<?php $instock = "Next Day"; ?>
<?php $outofstock = "4 to 7 Days"; ?>
<?php $conf = Mage::getModel('catalog/product_type_configurable')->setProduct($_product); ?>
<?php $col = $conf->getUsedProductCollection()->addAttributeToSelect('Size')->addFilterByRequiredOptions(); ?>
<ul>
<?php foreach($col as $simple_product){
    $qty = intval(Mage::getModel('cataloginventory/stock_item')->loadByProduct($simple_product)->getQty());   
    $size = Mage::getModel('catalog/product')->load($simple_product->getId())->getAttributeText('Size');
?>
  <li>
      <?php 
      if ( $qty >= 1 ) 
         {echo $qty, " ",$size," ",$instock;} 
      else 
         {echo $qty, " ",$size," ",$outofstock;}  ?>
  </li>
<?php } ?>
</ul>

The results set is looking like this:

99 Next Day
99 9 Next Day
99 8.5 Next Day
99 8 Next Day
99 7.5 Next Day
0 7 4 to 7 Days
99 12 Next Day
99 11.5 Next Day
99 11 Next Day
99 10.5 Next Day
99 10 Next Day

Any pointers on what I've got wrong and how to get the first attribute displayed?

Simon Earle
  • 53
  • 1
  • 5

4 Answers4

2

To solve your issue was so much easier than to understand what is causing it! But let me address it in the correct order:

  1. First of all, both addAttributeToSelect and getAttributeText actually operates with attribute_code, not attribute_value (which I believe you have as size, not Size).

  2. So the first time Magento does $product->getData('Size') inside the getAttributeText, it returns null.

  3. When you pass the Size to getAttributeText function, the size code gets replaced with Size for the particular attribute instance. How is it happening? Very simple: in the deepest layer of the methods chain, Magento makes next request to the DB:

    SELECT `eav_attribute`.* FROM `eav_attribute` WHERE (`eav_attribute`.`attribute_code`='Size') AND (entity_type_id = :entity_type_id);
    

    And if you have collate for your table as case-insensitive (*_ci), it will get the value no matter that actual attribute_code is "size". You can read more about collate in official article and on SO.

  4. So after the first getAttributeText('Size') function every consecutive $product->getData('Size') will return correct value.

Now returning to your script. Aside from size-Size issue you have few more little issues, but it would be great to deal with them for you to better understand Magento and php in general:

  1. First of all, it's really a bad practice to use load function inside the loop - especially two times in a row, especially with the product object. If your configurable product has a lot of simples, you'll get unnecessary memory and time losses. It is way better to add all the data you need to your collection, and then use loaded products in the loop. BTW you've already added size to your collection using addAttributeToSelect function. So the correct way to approach your issue would be:

    $col = $conf->getUsedProductCollection()
        ->addAttributeToSelect('size')
        ->joinField(
        'qty',
        'cataloginventory/stock_item',
        'qty',
        'product_id=entity_id',
        '{{table}}.stock_id=1',
        'left'
    )->addFilterByRequiredOptions();
    foreach($col as $simple_product){
        $qty = (int)$simple_product->getQty();
        $size = $simple_product->getAttributeText('size');
        // do your logic
    }
    
  2. And second issue I wanted to mention, since you're in the .phtml template file, it's required from you to follow Magento template standards - using close tags for you loops and cases:

    <?php foreach($col as $simple_product):?>
        <li>
        <?php if ( $qty >= 1 ):?>
              <!-- some html -->
        <?php else:?>
              <!-- some html -->
        <?php endif:?>
        </li>
    <?php endforeach;?>
    
Community
  • 1
  • 1
Slayer Birden
  • 3,664
  • 2
  • 22
  • 29
  • Thank you for taking the time to answer the question and to explain things, it's very much appreciated. – Simon Earle Oct 22 '12 at 16:29
  • Thank you for mentioning that loops should use this syntax while in template files. I open up way too many template files where other developers have not done this and left the code completely untabbed/unformatted. Seeing that makes me want to step on babies. – pspahn Oct 23 '12 at 15:13
1

This will work in ver. 1.7.0.2 you dont have to input AttributeText your self it will collect them automatic.

<?php if($_product->getTypeId() == "configurable"):
     $ids = $_product->getTypeInstance()->getUsedProductIds();  ?>
     <?php $instock = "Next Day"; ?>
    <?php $outofstock = "4 to 7 Days"; ?>
    <ul>
    <?php foreach ($ids as $id) :
    $simpleproduct = Mage::getModel('catalog/product')->load($id); 
    $name = $simpleproduct->getName();
    $qty = (int)Mage::getModel('cataloginventory/stock_item')->loadByProduct($simpleproduct)->getQty();?>
    <li><?php echo $simpleproduct->getName()." - ".(int)Mage::getModel('cataloginventory/stock_item')
    ->loadByProduct($simpleproduct)->getQty();?>
     </li>   
     <li><?php 
     if ( $qty >= 1 ) 
             {echo $qty, " ",$name," ",$instock;} 
          else 
             {echo $qty, " ",$name," ",$outofstock;}
             ?>
     </li> 
     <?php endforeach;    ?>
     </ul>
    <?php endif; ?>
0

Are you sure that the Size attribute is set on the first product? I have tested your code using shirt_size as my attribute and my results return as expected.

Adam Paterson
  • 412
  • 2
  • 11
  • Hi, thanks for taking the time to check the code. Yes, 'Size' attribute is definitely set, it's mandatory and it's the only configurable attribute. Annoyingly the 'Size' dropdown does have the missing attribute in it, in this case Size 9.5, so I'm really at a loss as to what is happening. – Simon Earle Oct 21 '12 at 18:34
  • If the product was based off an import or was updated using a mass action, try just to open that product in product management and re-save. Values tend not to stick sometimes. – pspahn Oct 22 '12 at 03:48
0

I would like to show barcode attribute value. How can I show barcode value? Thank you for your help.

  <?
$childProducts = Mage::getModel('catalog/product_type_configurable')
                 ->getUsedProducts(null,$product);
$stock_count=0;
$sizeqty="";
foreach($childProducts as $child){
 if($child->getAttributeText('ust_beden_no')!=""){   
 $sizeqty.="<Stok><isim>Beden</isim><Beden>".$child->getAttributeText('ust_beden_no')."</Beden><Miktar>".
(int)Mage::getModel('cataloginventory/stock_item')->loadByProduct($child)->getQty()."



</Miktar></Stok>";
 

}
}
 return $sizeqty;
?>
hakan
  • 168
  • 1
  • 5