Magento – Add custom options while adding grouped product to cart

addtocartcustom-optionsgrouped-products

I've got a problem when adding a grouped product to cart.

I need to set a custom option for all products that are added to cart while adding a grouped product to cart.

What I have tried last (with a little bit of success):

<checkout_cart_product_add_after>
    <observers>
        <customoptions>
            <type>singleton</type>
            <class>Company_CustomOptions_Model_Observer</class>
            <method>addCustomOptionGroupSku</method>
        </customoptions>
    </observers>
</checkout_cart_product_add_after>

and

public function addCustomOptionGroupSku(Varien_Event_Observer $observer) {
    $product = $observer->getProduct ();
    if ($product->isGrouped ()) { 
        $quoteItem = $observer->getQuoteItem ();
        $additionalOptions = array (
                'options' => array (
                        'label' => 'GROUPSKU',
                        'value' => $product->getSku () 
                ) 
        );
        $quoteItem->addOption ( new Varien_Object ( array (
                'product' => $quoteItem->getProduct (),
                'code' => 'additional_options',
                'value' => serialize ( $additionalOptions ) 
        ) ) );
    }
}

I have created one grouped product, containing two products.
But that code only adds the custom option "GROUPSKU" to one of the items in the cart. The other one is untouched.

How do I get all the QuoteItems that are about to be added to the cart?

I have also added this question to the StackOverflow part of StackExchange: https://stackoverflow.com/questions/27905415/add-custom-options-while-adding-grouped-product-to-cart

Best Answer

I found a solution which does not need an observer.

I had to do a rewrite to Mage_Sales_Model_Quote. More specific the method addProductAdvanced()

Bad news: You can not simply use parent::addProductAdvanced() and then do your own stuff. You have to copy the original code and fill it up with your code.

Here is what I did (look out for the comment starting with /********):

public function addProductAdvanced(Mage_Catalog_Model_Product $product, $request = null, $processMode = null) {
    if ($request === null) {
        $request = 1;
    }
    if (is_numeric ( $request )) {
        $request = new Varien_Object ( array (
                'qty' => $request 
        ) );
    }
    if (! ($request instanceof Varien_Object)) {
        Mage::throwException ( Mage::helper ( 'sales' )->__ ( 'Invalid request for adding product to quote.' ) );
    }

    $cartCandidates = $product->getTypeInstance ( true )->prepareForCartAdvanced ( $request, $product, $processMode );

    /**
     * Error message
     */
    if (is_string ( $cartCandidates )) {
        return $cartCandidates;
    }

    /**
     * If prepare process return one object
     */
    if (! is_array ( $cartCandidates )) {
        $cartCandidates = array (
                $cartCandidates 
        );
    }

    $parentItem = null;
    $errors = array ();
    $items = array ();
    foreach ( $cartCandidates as $candidate ) {
        // Child items can be sticked together only within their parent
        $stickWithinParent = $candidate->getParentProductId () ? $parentItem : null;
        $candidate->setStickWithinParent ( $stickWithinParent );
        $item = $this->_addCatalogProduct ( $candidate, $candidate->getCartQty () );

        /******** own modification for custom option GROUPSKU*/
        if($product->isGrouped()){
            $additionalOptions = array (
                    'options' => array (
                            'label' => 'GROUPSKU',
                            'value' => $product->getSku ()
                    )
            );
            $item->addOption ( new Varien_Object ( array (
                    'product' => $item->getProduct (),
                    'code' => 'additional_options',
                    'value' => serialize ( $additionalOptions )
            ) ) );
        }
        /******** own modification end*/

        if ($request->getResetCount () && ! $stickWithinParent && $item->getId () === $request->getId ()) {
            $item->setData ( 'qty', 0 );
        }
        $items [] = $item;

        /**
         * As parent item we should always use the item of first added product
         */
        if (! $parentItem) {
            $parentItem = $item;
        }
        if ($parentItem && $candidate->getParentProductId ()) {
            $item->setParentItem ( $parentItem );
        }

        /**
         * We specify qty after we know about parent (for stock)
         */
        $item->addQty ( $candidate->getCartQty () );

        // collect errors instead of throwing first one
        if ($item->getHasError ()) {
            $message = $item->getMessage ();
            if (! in_array ( $message, $errors )) { // filter duplicate messages
                $errors [] = $message;
            }
        }
    }
    if (! empty ( $errors )) {
        Mage::throwException ( implode ( "\n", $errors ) );
    }

    Mage::dispatchEvent ( 'sales_quote_product_add_after', array (
            'items' => $items 
    ) );

    return $item;
}

This way all the products that are added to the cart using a grouped product now have the custom option.

Related Topic