Magento – Related Product gets not added to cart

carterrorproduct

I have a strange problem on my test system. I'm quite new to magento and think this problem might exist, because it is a test system.

I have some products with related products. If I try to add a product to the shopping cart with it's related product(s). The related product(s) do not get added to the cart.

My first guess was a broken javascript but everything seems to be ok there. My next step was to get myself temper data for firefox. I have verified, that the PostData contains:

product         = $id_of_product
related_product = $id_of_related_product
qty             = $qty_of_product

Still the related product does not get added to the cart. Could this be a problem with the setup of the test system? Changing the quantities works fine for the normal product. Changing the id of the related_product to the id of another product does not add anything to the cart, too.

Thanks in advance

EDIT

Ok, as others might have the same problem I leave the original question and describe here how to debug this.

The first thing to do is to deactivate all modules in local and community. The easiest way is to temporarily rename the folders app/code/local and app/code/community and test if it works afterwards. If it does not work you have to search further.

If the error still persists check the post message sent to the server. An easy way to do this is to get the Tamper Data addon for firefox. If the post message does not look like the message in the picture:

Post Request

The error is probably inside the JavaScript of your app/design/frontend/base/default/template/catalog/product/list/related.phtml file. Change the path to the theme you are using.

The POSTDATA field should contain related_product=Comma_Separated_Ids_Of_Selected_Related_Products

If everything looks good so far, the mistake is somewhere in the code of magento. How magento adds products to the cart is described in a blog post here: http://www.ecomdev.org/2012/12/12/magento-checkout-shopping-cart-flow.html

The POSTDATA is computed in app/code/core/Magento/Checkout/controllers/CartController.php at the lines below

        193  $cart->addProduct($product, $params);
        194  if (!empty($related)) {
        195      $cart->addProductsByIds(explode(',', $related));
        196  }

Make sure the $related variable contains the ids of your related products.

If this is the case this will lead you to app/code/core/Mage/Checkout/Model/Cart.php where in my case the error was.

Best Answer

Ok, I finally can add the related_product to the cart. In the code/core/Mage/Checkout/Model/Cart.php file are two functions for adding products into the cart. The first is called public function addProduct($productInfo, $requestInfo=null), the second function is public function addProductsByIds($productIds).

The related_product is added by id, the others are added with the addProduct() function. The adding by id does not seem to work (at least for me it did not. Although magento used the unaltered Cart.php file from 1.7.0.2.

I solved this by altering the Cart.php file like this:

 /**
 * Add product to shopping cart (quote)

 * This is the original function pasted from
 * Mage/Checkout/Model/Cart.php line 245
 * The function is working and adding products to the cart

 *
 * @param   int|Mage_Catalog_Model_Product $productInfo
 * @param   mixed $requestInfo
 * @return  Mage_Checkout_Model_Cart
 */
public function addProduct($productInfo, $requestInfo=null)
{
    $product = $this->_getProduct($productInfo);
    $request = $this->_getProductRequest($requestInfo);

    $productId = $product->getId();

    if ($product->getStockItem()) {
        $minimumQty = $product->getStockItem()->getMinSaleQty();
        //If product was not found in cart and there is set minimal qty for it
        if ($minimumQty && $minimumQty > 0 && $request->getQty() < $minimumQty
            && !$this->getQuote()->hasProductId($productId)
        ){
            $request->setQty($minimumQty);
        }
    }

    if ($productId) {
        try {
            $result = $this->getQuote()->addProduct($product, $request);
        } catch (Mage_Core_Exception $e) {
            $this->getCheckoutSession()->setUseNotice(false);
            $result = $e->getMessage();
        }
        /**
         * String we can get if prepare process has error
         */
        if (is_string($result)) {
            $redirectUrl = ($product->hasOptionsValidationFail())
                ? $product->getUrlModel()->getUrl(
                    $product,
                    array('_query' => array('startcustomization' => 1))
                )
                : $product->getProductUrl();
            $this->getCheckoutSession()->setRedirectUrl($redirectUrl);
            if ($this->getCheckoutSession()->getUseNotice() === null) {
                $this->getCheckoutSession()->setUseNotice(true);
            }
            Mage::throwException($result);
        }
    } else {
        Mage::throwException(Mage::helper('checkout')->__('The product does not exist.'));
    }

    Mage::dispatchEvent('checkout_cart_product_add_after', array('quote_item' => $result, 'product' => $product));
    $this->getCheckoutSession()->setLastAddedProductId($productId);
    return $this;
}

/**
 * Adding products to cart by ids

 * This function is the altered function, which works for me
 * the edited lines are marked.

 *
 * @param   array $productIds
 * @return  Mage_Checkout_Model_Cart
 */
public function addProductsByIds($productIds)
{
    $allAvailable = true;
    $allAdded     = true;

    if (!empty($productIds)) {
        foreach ($productIds as $productId) {
            $productId = (int) $productId;
            if (!$productId) {
                continue;
            }
            $product = $this->_getProduct($productId);
            if ($product->getId() && $product->isVisibleInCatalog()) {
                try {
                    $this->getQuote()->addProduct($product);
                } catch (Exception $e){
                    $allAdded = false;
                }

                /**
                 * START EDIT
                 */

                /**
                * String we can get if prepare process has error
                */
                if (is_string($result)) {
                    $redirectUrl = ($product->hasOptionsValidationFail())
                        ? $product->getUrlModel()->getUrl(
                            $product,
                            array('_query' =>array                                   ('startcustomization' => 1))
                            )
                        : $product->getProductUrl();
                    $this->getCheckoutSession()->setRedirectUrl($redirectUrl);
                    if ($this->getCheckoutSession()->getUseNotice() === null) {
                        $this->getCheckoutSession()->setUseNotice(true);
                    }
                    Mage::throwException($result);
                }
                Mage::dispatchEvent('checkout_cart_product_add_after', array('quote_item' => $result, 'product' => $product));
                $this->getCheckoutSession()->setLastAddedProductId($productId);

                /**
                 * STOP EDIT
                 */

            } else {
                $allAvailable = false;
            }
        }

        if (!$allAvailable) {
            $this->getCheckoutSession()->addError(
                Mage::helper('checkout')->__('Some of the requested products are unavailable.')
            );
        }
        if (!$allAdded) {
            $this->getCheckoutSession()->addError(
                Mage::helper('checkout')->__('Some of the requested products are not available in the desired quantity.')
            );
        }
    }
    return $this;
}

So i copied the lines from the other function. Does anyone think this will have some drawbacks? For me it looks like this introduces another check if everything works correct by examining the return string. But i don't know if dispatching the event might have some negative effects. As i stated, I'm new to magento and would like to know if this is solid solution.

Does anyone know, why the functions are different? Because they do basically the same. The only difference is, that the second function can add more than product. Maybe in this case dispatching the event is slow?

Related Topic