-1

The heading describes it pretty well. How could I achieve that? I have a groupoed product with 2 included products. As soon as one of the included products is out of stock, the grouped product should be out of stock.

How could I do that?

1

I would use an observer catalog_product_save_after and then do something like...

<?php

class Observer
{
    public function catalogProductSaveAfter($observer)
    {
        /** @var Mage_Catalog_Model_Product $product */
        $product = $observer->getEvent()->getProduct();

        // we only want to operate on simple products
        if ($product->getTypeId() === 'simple') {

            // check if the product can be bought
            if (!$product->isSaleable()) {

                // get all parent ids of grouped parents
                // that this product belongs to
                $parentIds = Mage::getModel('catalog/product_type_grouped')
                    ->getParentIdsByChild($product->getId());
                if (count($parentIds) > 0) {

                    // get all parent products we want to now mark as oos
                    $parents = Mage::getModel('catalog/product')
                        ->getCollection()
                        ->addFieldToFilter('entity_id', array('in' => $parentIds))
                        ->load();

                    /** @var Mage_Catalog_Model_Product $product */
                    foreach ($parents as $parent) {
                        /** @var Mage_CatalogInventory_Model_Stock_Item $stockItem */
                        $stockItem = Mage::getModel('cataloginventory/stock_item')
                            ->loadByProduct($parent->getId());
                        $stockItem->setData('is_in_stock', 0);
                        $stockItem->save();
                    }
                }
            }
        }
    }
}

I have done a basic test on the above code and it worked but I have not had time to as much testing as I would have like. Sorry about that. Should give you a good start though.

  • That looks good, just implemented it. Will that also run if the simple product quantity is reduced automatically if the product is bought? – Arnie Apr 13 '16 at 12:50
1

Possible implementation can be via Observer:

define a module

<?xml version="1.0"?><config>
<modules>
    <Vendor_Namspace>
        <version>0.0.1</version>
    </Vendor_Namespace>
</modules>
<global>
    <helpers>
        <vendor_namespace>
            <class>Vendor_Namespace_Helper</class>
        </vendor_namespace>
    </helpers>
    <models>
        <vendor_namespace>
            <class>Vendor_Namespace_Model</class>
        </vendor_namespace>
    </models>
</global>
<frontend>
    <events>
        <catalog_product_save_before>
            <observers>
                <vendor_namespace>
                    <type>model</type>
                    <class>vendor_namespace/observer</class>
                    <method>checkStockFromSimpleBeforeSave</method>
                </vendor_namespace>
            </observers>
        </catalog_product_save_before>
    </events>
</frontend>

Observer.php

<?php 
Class Vendor_Namespace_Model_Observer extends Mage_Core_Model_Observer {
    public function checkStockFromSimpleBeforeSave(Varien_Event_Observer $observer)
    $product = $observer->getProduct();
    if($product->getTypeInstance() != 'simple'){
         return;
    }
    $stock = null;
    $stockInstance = Mage::getModel('cataloginventory/stock_item');
    $parents = Mage::getModel('catalog/product_type_grouped')->getParentIdsByChild($product->getId());
    if (count($parents) > 0) {
        $_parents = Mage::getModel('catalog/product')->getCollection()->addFieldToFilter('entity_id', array('in' => $parents));

        foreach ($_parents as $parent) {
            $stockItem = Mage::getModel('cataloginventory/stock_item')->loadByProduct($parent->getId());
            $stockItem->setData('is_in_stock', 0);
            $stockItem->save();
        }
    }        
}

code is not testet but should work

maybe some more events are necessary if a item is purchased

<events>
    <cataloginventory_stock_item_save_commit_after>
        <observers>
            <vendor_namespace>
                <class>vendor_namespace/observer</class>
                <method>catalogInventorySaveBefore</method>
            </vendor_namespace>
        </observers>
    </cataloginventory_stock_item_save_commit_after>
    <sales_model_service_quote_submit_before>
        <observers>
            <vendor_namespace>
                <class>vendor_namespace/observer</class>
                <method>subtractQuoteInventory</method>
            </vendor_namespace>
        </observers>
    </sales_model_service_quote_submit_before>
    <sales_model_service_quote_submit_failure>
        <observers>
            <vendor_namespace>
                <class>vendor_namespace/observer</class>
                <method>revertQuoteInventory</method>
            </vendor_namespace>
        </observers>
    </sales_model_service_quote_submit_failure>
    <sales_order_item_cancel>
        <observers>
            <vendor_namespace>
                <class>vendor_namespace/observer</class>
                <method>cancelOrderItem</method>
            </vendor_namespace>
        </observers>
    </sales_order_item_cancel>
    <sales_order_creditmemo_save_after>
        <observers>
            <vendor_namespace>
                <class>vendor_namespace/observer</class>
                <method>refundOrderInventory</method>
            </vendor_namespace>
        </observers>
    </sales_order_creditmemo_save_after>
</events>

and the method should be someting like:

public function catalogInventorySaveBefore(Varien_Event_Observer $observer){
    if ($this->isEnabled()) {
        $event = $observer->getEvent();
        $_item = $event->getItem();

        if ((int)$_item->getData('qty') != (int)$_item->getOrigData('qty')) {

            $product = $_item->getProduct();
            $qty = $_item->getQty();
            $newQty = $_item->getOrigData('qty') - $_item->getQty();
            if($newQty < 1){
                $stockInstance = Mage::getModel('cataloginventory/stock_item');
                $parents = Mage::getModel('catalog/product_type_grouped')->getParentIdsByChild($product->getId());
                if (count($parents) > 0) {
                    $_parents = Mage::getModel('catalog/product')->getCollection()->addFieldToFilter('entity_id', array('in' => $parents));

                    foreach ($_parents as $parent) {
                        $stockItem = Mage::getModel('cataloginventory/stock_item')->loadByProduct($parent->getId());
                        $stockItem->setData('is_in_stock', 0);
                        $stockItem->save();
                }
            }
        }
    }
}

... and so on

  • Yes, but that does not run if the product is being bought, only when it is saved in the admin area. How can I modify that so it runs when an item is bought? Thanks! – Arnie Apr 13 '16 at 13:55
  • 1
    @Arnie, it's not hard finding what events fire when. Try Mage::dispatch. – musicliftsme Apr 13 '16 at 14:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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