How can I check whether all bundle items are available?
I read somewhere about this $_product->getStockItem()->getIsInStock()
but it doesn't work for me.
I need to make bundle product not saleable if one of bundle items is not saleable.
You can use the following code to check whether the required child items of a bundle product are salable.
$isSalable = true;
$bundleProductId = 447;
$bundleProduct = Mage::getModel('catalog/product')->load($bundleProductId);
$childrenIds = $bundleProduct->getTypeInstance(true)
->getChildrenIds($bundleProduct->getId(), true); // set second parameter to false to get not only required items
$childCollection = Mage::getModel('catalog/product')->getCollection()
->addFieldToFilter('entity_id', $childrenIds);
foreach ($childCollection as $child) {
if (!$child->isSalable()) {
$isSalable = false;
}
}
After that you can use the variable $isSalable
to decide whether the product is salable or not.
In this case will be better to rewrite the class "Mage_Bundle_Model_Product_Type" and rewrite the method "Mage_Bundle_Model_Product_Type::isSalable". If you have your custom module you can do it as described below. To rewrite the class edit the file "app/code/community/Namespace/Module/etc/config.xml":
<config>
<modules>
...
</modules>
<global>
<models>
<bundle>
<rewrite>
<product_type>Namespace_Module_Model_Product_Type</product_type>
</rewrite>
</bundle>
</models>
....
Then create the file: "app/code/community/Namespace/Module/Model/Product/Type.php" and insert the following code:
<?php
class Namespace_Module_Model_Product_Type extends Mage_Bundle_Model_Product_Type
{
public function isSalable($product = null)
{
$salable = parent::isSalable($product);
$childrenIds = $this->getChildrenIds($this->getProduct($product)->getId(), true); // set second parameter to false to get not only required items
$childCollection = Mage::getModel('catalog/product')->getCollection()
->addFieldToFilter('entity_id', $childrenIds);
foreach ($childCollection as $child) {
if (!$child->isSalable()) {
$salable = false;
break;
}
}
return $salable;
}
}
Wherever you want it to appear, for bundled products the file would be
app/design/frontend/{theme}/template/bundle/catalog/product/view/type/bundle/availability.phtml
There you can update
<p class="availability in-stock">
<span class="label"><?php echo $this->helper('catalog')->__('Availability:') ?></span>
<span class="value"><?php echo $this->helper('catalog')->__('In stock') ?></span>
</p>
to
<?php
$selectionCollection = $_product->getTypeInstance()->getSelectionsCollection($_product->getTypeInstance()->getOptionsIds());
$qty = false;
foreach ($selectionCollection as $option) {
$product_id = $option->product_id;
$bundleOption = Mage::getModel('catalog/product')->load($product_id);
$stock = Mage::getModel('cataloginventory/stock_item')->loadByProduct($bundleOption);
if ($qty === false) {
$qty = $stock->getQty();
} else {
$qty = min(array($qty, $stock->getQty()));
}
}
?>
<p class="availability in-stock">
<span class="label"><?php echo $this->helper('catalog')->__('Availability:') ?></span>
<span class="value"><?php echo $qty . ' ' . $this->helper('catalog')->__('In stock') ?></span>
</p>