1

I want to prevent configurable products from ending up in the cart. I want to add their simple product equivalent to the cart.

Despite this being a fairly normal request, I haven't found anything that is doing this.

I currently have an observer set up to work on checkout_cart_add_product_complete checkout_cart_add_product_complete

I'm able to manipulate the cart from here (add, remove items), but I can't remove a configurable product (nor its options).

Does anyone know how this is possible?

Observer.php

class Mymodule_Addtocartredirect_Model_Customizablereplace {
    public function replaceItems($observer) {
        $quote   = Mage::getSingleton('checkout/session')->getQuote();
        $storeId = Mage::app()->getStore()->getStoreId();

        foreach ($quote->getAllItems() as $item) {
            $result = array();
            Mage::log("We have a product! " . $item->getSku(),null,"test.log");
            if($item->getOptionByCode('simple_product')) {
                $childProduct = $item->getOptionByCode('simple_product')->getProduct()->getId();
                Mage::log("We have ".$childProduct,null,"test.log");
            }

            if ($option = $item->getOptionByCode('simple_product')) {
                $cartHelper = Mage::helper('checkout/cart')->getCart();
                $quantity = $item->getQty();
                $childProduct = $option->getProduct();
                Mage::log("Child Product: ".$childProduct->getSku()." (".$childProduct->getId().")",null,"test.log");
                $cartHelper->removeItem($item->getId());
                $cartHelper->addItem($childProduct->getId(),$quantity);
            }
        }
        $quote->collectTotals()->save();
    }
}
  • 1
    By Magento design, Magento adds the configurable product for any simple product . When you remove the product and try to use : $cartHelper->addItem($childProduct->getId(),$quantity); Magento would add both the simple and configurable product back again. Is there a reach you're trying to remove the configurable product? Perhaps you could look to get rid of the need to do that because this won't work because of the way Magento is built for configurable products. – Paras Sood Mar 8 '16 at 21:03
  • We are exporting orders from Magento to a 3rd party ERP, but it does not handle configurable items well. The easiest solution appears to be changing Magento's behavior. Can I replace the configurable product with the simple product? – travisw Mar 9 '16 at 12:35
  • 2
    Why don't you make changes in the code that sends the order over to the EPR, wherein you don't send the configurable product but only the simple one? – Paras Sood Mar 9 '16 at 13:15
  • I didn't develop the connector for the ERP, so I'm not familiar enough with it to make those modifications. I assumed the Magento modification would be somewhat simple. – travisw Mar 10 '16 at 12:00
  • 1
    I also strongly advise against this change. This is expected Magento core behaviour and some extensions (like my Spranks_ConfigurableTierPrices) rely on this behaviour. – Simon Mar 16 '16 at 12:39
1

Few days back,I did the same,by creating a custom module Create a module and in the CartController.php file, create the following:

<?php 
    require_once 'Mage/Checkout/controllers/CartController.php';
    class Yourname_Mymodule_CartController extends Mage_Checkout_CartController
    {
        public function addAction()
        {
            if (!$this->_validateFormKey()) {
                $this->_goBack();
                return;
            }
            $cart   = $this->_getCart();
            $params = $this->getRequest()->getParams();
            try {
                if (isset($params['qty'])) {
                    $filter = new Zend_Filter_LocalizedToNormalized(
                        array('locale' => Mage::app()->getLocale()->getLocaleCode())
                    );
                    $params['qty'] = $filter->filter($params['qty']);
                }

                $product = $this->_initProduct();
                $child = $product->getTypeInstance(true)->getProductByAttributes($params['super_attribute'], $product);
                $related = $this->getRequest()->getParam('related_product');


                if (!$child) {
                    $this->_goBack();
                    return;
                }

                $cart->addProduct($child, $params);
                if (!empty($related)) {
                    $cart->addProductsByIds(explode(',', $related));
                }

                $cart->saveSpecial();

                $this->_getSession()->setCartWasUpdated(true);


                Mage::dispatchEvent('checkout_cart_add_product_complete',
                    array('product' => $product, 'request' => $this->getRequest(), 'response' => $this->getResponse())
                );

                if (!$this->_getSession()->getNoCartRedirect(true)) {
                    if (!$cart->getQuote()->getHasError()) {
                        $message = $this->__('%s was added to your shopping cart.', Mage::helper('core')->escapeHtml($child->getName()));
                        $this->_getSession()->addSuccess($message);
                    }
                    $this->_goBack();
                }
            } catch (Mage_Core_Exception $e) {
                if ($this->_getSession()->getUseNotice(true)) {
                    $this->_getSession()->addNotice(Mage::helper('core')->escapeHtml($e->getMessage()));
                } else {
                    $messages = array_unique(explode("\n", $e->getMessage()));
                    foreach ($messages as $message) {
                        $this->_getSession()->addError(Mage::helper('core')->escapeHtml($message));
                    }
                }

                $url = $this->_getSession()->getRedirectUrl(true);
                if ($url) {
                    $this->getResponse()->setRedirect($url);
                } else {
                    $this->_redirectReferer(Mage::helper('checkout/cart')->getCartUrl());
                }
            } catch (Exception $e) {
                $this->_getSession()->addException($e, $this->__('Cannot add the item to shopping cart.'));
                Mage::logException($e);
                $this->_goBack();
            }
        }
    }

Create a new save function

<?php
class Yourname_Mymodule_Model_Cart extends Mage_Checkout_Model_Cart
{
    public function save()
    {
        Mage::dispatchEvent('checkout_cart_save_before', array('cart'=>$this));

        $this->getQuote()->getBillingAddress();
        $this->getQuote()->getShippingAddress()->setCollectShippingRates(true);
        $this->getQuote()->collectTotals();
        $this->getQuote()->save();
        $this->getCheckoutSession()->setQuoteId($this->getQuote()->getId());
        Mage::dispatchEvent('checkout_cart_save_after', array('cart'=>$this));
        foreach($this->getQuote()->getAllItems() as $_item)
        {
            $_item->setCustomPrice($_item->getPrice());
            $_item->setRowTotal($_item->getPrice()*$_item->getQty());
            $_item->setBaseRowTotal($_item->getBasePrice()*$_item->getQty());
            $_item->setOriginalCustomPrice($_item->getCustomPrice());
            $_item->setCalculationPrice($_item->getCustomPrice());
        }
        return $this;
    }

    public function saveSpecial()
    {
        Mage::dispatchEvent('checkout_cart_save_before', array('cart'=>$this));

        $this->getQuote()->getBillingAddress();
        $this->getQuote()->getShippingAddress()->setCollectShippingRates(true);
        $this->getQuote()->collectTotals();
        $this->getQuote()->save();
        $this->getCheckoutSession()->setQuoteId($this->getQuote()->getId());

        Mage::dispatchEvent('checkout_cart_save_after', array('cart'=>$this));
        return $this;
    }
}

Done!!

2

Despite this being an almost 3-year-old question, I figured I'd add my own answer since I was trying to do this myself and hopefully someone will find my solution useful.

All I did was add a plugin to Magento\Checkout\Controller\Cart\Add

<?php
namespace Vendor\Module\Controller\Plugin\Cart;

class Add
{

    public function beforeExecute(
        \Magento\Checkout\Controller\Cart\Add $subject
    ) {
        $params = $subject->getRequest()->getParams();
        if (isset($params['selected_configurable_option']) && $params['selected_configurable_option'] !== '') {
            $params['product'] = $params['item'] = $params['selected_configurable_option'];
            $params['selected_configurable_option'] = '';
            unset($params['super_attribute']);
            $subject->getRequest()->setParams($params);
        }
    }
}
  • I like the small answer you have here! Very nice. Do you think this will survive to magento 2.4? – Pathfinder Jan 18 at 5:14
  • Looking at how configurables are done, I think it'll probably be changed. But at least we know what going on now reddit.com/r/Magento/comments/ah71yg/… – Pathfinder Jan 18 at 5:15
0

I know this is not the answer you are looking for but it may be a solution for you.

My suggestion

I would change my products visibility section for each config item.

If you look at product editing section in admin, you will find field called visibility.

  1. You need to set each parent config item's visibility as Not visible individually.
  2. Then set each associated product (child product)'s visibility as 'Catalog Search`.

This will make sure all your parent item not displayed at site but all associated (child) products are and when user add them to cart, they all will be simple products.

Then your ERP will handle it as required.

  • I want our users to find the configurable product page because it can present dozens of different products in an easy selection style. I don't think hiding the configurable product will accomplish what we want (at least not how we want it to work). – travisw Mar 17 '16 at 11:33

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.