6

My Cart is looking like this with popup window:

enter image description here

I am updating multiple configurable items in cart with custom options at a time by AJAX Call. So i am using updateItemOptionsAction() function.

But I am not able to get all items data back to AJAX response.

I am getting just 1st itemPrice and rowTotal. For remaining items itemPrice and rowTotal are set to 0.

Code:

public function updateItemOptionsAction()
{
    $cartData = $this->getRequest()->getParam('cart');
    Mage::log($cartData);
    if (is_array($cartData)) {
        $result = array();
        $result['data'] = array();
        foreach ($cartData as $index => $data) {
            $cart   = $this->_getCart();
            $params = $data;
            $id = (int)$data['id'];

            if (!isset($params['options'])) {
                $params['options'] = array();
            }
            $result['data'][$index] = array();
            $oldQty = null;
            $kitType = $params['efk_kType'];
            $params['super_attribute'] = array($data['sAttr']=>$kitType);
            unset($params['sAttr']);
            $stock = null;
            try {
                if (isset($params['qty'])) {
                    $product = Mage::getModel("catalog/product")->load($params['product']);
                    $childProducts = Mage::getModel('catalog/product_type_configurable')->getUsedProducts(null, $product);
                    foreach($childProducts as $cProd){
                        if($cProd->getKitType() == $kitType){
                            $stock = intval(Mage::getModel('cataloginventory/stock_item')->loadByProduct($cProd)->getQty());
                        }
                    }
                    if(intval($params['qty']) > $stock){
                        $oldQty = intval($params['qty']);
                        $params['qty'] = $stock;
                        $result['data'][$index]['revised'] = true;
                    }

                    $filter = new Zend_Filter_LocalizedToNormalized(
                        array('locale' => Mage::app()->getLocale()->getLocaleCode())
                    );
                    $params['qty'] = $filter->filter($params['qty']);
                }

                $quoteItem = Mage::getSingleton('checkout/cart')->getQuote()->getItemById($id);
                if (!$quoteItem) {
                    Mage::throwException($this->__('Quote item is not found.'));
                }

                //Its going to infinity loop duwe to Varien Object need to check later
                //$item = $cart->updateItem($id, new Varien_Object($params));
                $item = Mage::getSingleton('checkout/cart')->updateItem($id, $params);

                if (is_string($item)) {
                    Mage::throwException($item);
                }
                if ($item->getHasError()) {
                    Mage::throwException($item->getMessage());
                }
                Mage::log('hi2');

                $related = $params['related_product'];
                if (!empty($related)) {
                    Mage::getSingleton('checkout/cart')->addProductsByIds(explode(',', $related));
                }

                Mage::getSingleton('checkout/cart')->save();
                Mage::getSingleton('checkout/session')->setCartWasUpdated(true);

                Mage::dispatchEvent('checkout_cart_update_item_complete',
                    array('item' => $item, 'request' => $this->getRequest(), 'response' => $this->getResponse())
                );
                $cart->getQuote()->setTotalsCollectedFlag(false);
                Mage::getSingleton('checkout/cart')->init();

                if (!Mage::getSingleton('checkout/session')->getNoCartRedirect(true)) {
                    if (!Mage::getSingleton('checkout/cart')->getQuote()->getHasError()) {
                        Mage::log('hi4');
                        $result['success'] = true;
                        if($oldQty > $item->getQty()){
                            $message = $this->__('%s has been revised due to stock limitations. You may proceed with the order for the revised quantity.', Mage::helper('core')->escapeHtml($item->getProduct()->getName()));
                        }else{
                            $message = $this->__('%s was updated in your shopping cart.', Mage::helper('core')->escapeHtml($item->getProduct()->getName()));
                        }
                        $result['data'][$index]['message'] = $message;
                        $result['data'][$index]['itemId'] = $item->getId();
                        $result['data'][$index]['itemPrice'] = Mage::helper('checkout')->formatPrice($item->getCalculationPrice());
                        $result['data'][$index]['qty'] = $item->getQty();
                        $result['data'][$index]['rowTotal'] = Mage::helper('checkout')->formatPrice($item->getRowTotal());
                    }
                }

            } catch (Mage_Core_Exception $e) {
                $result['success'] = false;
                $result['data'][$index]['success'] = 'qty';
                $result['data'][$index]['message'] = $e->getMessage();
            } catch (Exception $e) {
                $result['success'] = false;
                $result['data'][$index]['message'] = $e->getMessage();
                $result['data'][$index]['secondMessage'] = $this->__('Cannot update the item.');
            }
        }



        $result['data']['grandTotal'] = Mage::helper('checkout')->formatPrice(Mage::getSingleton('checkout/cart')->getQuote()->getGrandTotal());
        $result['data']['totalItems'] = Mage::getSingleton('checkout/cart')->getSummaryQty();
        $totals = Mage::getSingleton('checkout/cart')->getQuote()->getTotals();
        $result['data']['subTotal'] = Mage::helper('checkout')->formatPrice($totals['subtotal']->getValue());
        if(isset($totals['discount']) && $totals['discount']->getValue()){
            $result['data']['discount'] = Mage::helper('checkout')->formatPrice($totals['discount']->getValue());
        }else{
            $result['data']['discount'] = Mage::helper('checkout')->formatPrice(0);
        }
    }
    $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
}

AJAX Response I'm getting

{
    "data": {
        "1187": {
            "success": true,
            "message": "THREE PHASE SOLID STATE RELAY WITH ZVS was updated in your shopping cart.",
            "itemId": "1191",
            "itemPrice": "<span class=\"price\">20b9  3,799</span>",
            "qty": 1,
            "rowTotal": "<span class=\"price\">20b9  3,799</span>",
            "forLoop": "yes"
        },
        "1189": {
            "success": true,
            "message": "AUTO INTENSITY CONTROL OF STREET LIGHTS was updated in your shopping cart.",
            "itemId": "1193",
            "itemPrice": "<span class=\"price\">20b9  0</span>",
            "qty": 1,
            "rowTotal": "<span class=\"price\">20b9  0</span>",
            "forLoop": "yes"
        },
        "grandTotal": "<span class=\"price\">20b9  8,798</span>",
        "totalItems": 2,
        "subTotal": "<span class=\"price\">20b9  8,798</span>",
        "discount": "<span class=\"price\">20b9  0</span>"
    }
}

I am getting itemPrice and rowTotal for 2nd item as 0. Every time I am getting correct values for 1st item only. If i am update 5 items at a time (say for example) then i am getting correct values for 1st item and for remianing items i am getting 0's.

If i refresh cart once i get AJAX response, then it is showing itemPrice and rowTotal updated values correctly for all items.

Note: 20b9 is HEX Code for Indian Rupee symbol

Please point out where i am wrong.

Thanks in advance.

  • Could you provide the result of the Mage::log() at the beginning and why do you include the $cart instanciation in the foreach ? – dagfr Dec 19 '13 at 15:49
  • I just tried. Even i moved $cart = $this->_getCart(); from the foreach (at the begining) it is not working. – Sivakumar Dec 19 '13 at 16:01
  • This is not part of the solution, just a questionment. Try avoiding loading the same item x times. Could you provide the result of Mage::log($cartData); ? How many time does "Mage::log('hi2');" runs ? – dagfr Dec 19 '13 at 16:08
  • Array ( [1091] => Array ( [id] => 1091 [related_product] => [efk_kType] => 127 [product] => 183 [sAttr] => 962 [qty] => 1 ) [1093] => Array ( [id] => 1093 [related_product] => [efk_kType] => 127 [product] => 389 [sAttr] => 962 [qty] => 1 ) ) and hi2, hi4, hi2, hi4 is printing. – Sivakumar Dec 19 '13 at 16:45
2

Try this and let me know the result. We can re-factor after that.

$cart = Mage::getSingleton('checkout/session');
$products = array()
foreach ($cart->getQuote()->getAllItems() as $item) {
   $products['id'] = $item->getProductId();
   $products['price'] = $item->getPrice();
}
var_dump($products);

Second attempt:

I have no idea about your problem but it seems to me you have super_attribute problem. To see what attributes available in the configurable products, try to run following code. Do you see any price value in the array?

PS: the code took from www.atwix.com

// Collect options applicable to the configurable product
$productAttributeOptions =  $product->getTypeInstance(true)->getConfigurableAttributesAsArray($product);
$attributeOptions = array();
foreach ($productAttributeOptions as $productAttribute) {
   foreach ($productAttribute['values'] as $attribute) {
      $attributeOptions[$productAttribute['label']][$attribute['value_index']] = $attribute['store_label'];
   }
}
var_dump($attributeOptions);
  • We tried this code in foreach and out side also. we are getting the following output. array( [id] => 477 [price] => 0 ) This is latest updated item in the checkout/session. – Sivakumar Dec 23 '13 at 6:39
  • Have tried your second attempt also: I am getting same array values as [Kit Type] => Array ( [126] => Do It Yourself Kit [127] => Project Kit [125] => Readymade Kit ) So this is not a problem. – Sivakumar Dec 23 '13 at 10:38
1

This currently sounds to me like you are running into an cached instance of the item list. To explain: when you add your first item you subsequently call $cart->save() which in turn will trigger a

Mage_Sales_Model_Quote_Address::collectTotals()

following along for example during the tax calculation in

Mage_Tax_Model_Sales_Total_Quote_Tax

it will end up calling

Mage_Sales_Model_Quote_Address::getAllItems()

public function getAllItems()
{
    // We calculate item list once and cache it in three arrays - all items, nominal, non-nominal
    $cachedItems = $this->_nominalOnly ? 'nominal' : ($this->_nominalOnly === false ? 'nonnominal' : 'all');
    $key = 'cached_items_' . $cachedItems;
    if (!$this->hasData($key)) {

which caches the items list. Since this cache is not invalidated the next time you run the tax calculation or add an item only the first item is returned and tax, discount, row-total is only calculated for this first item.

You can reset this cache with

    foreach ($cart->getQuote()->getAllAddresses() as $address) {
        $address->unsetData('cached_items_all');
        $address->unsetData('cached_items_nominal');
        $address->unsetData('cached_items_nonnominal');
    }
  • where to place this code? – Sivakumar Dec 23 '13 at 6:46
  • I tried to place this code after $cart->save() & after if(!$this->hasData($key)) { of getAllItems() – Sivakumar Dec 23 '13 at 6:59
  • I probably would place it in your _getCart method. – Kristof at Fooman Dec 23 '13 at 7:10
  • I just placed that in _getCart()... But no luck... i am getting the same response. – Sivakumar Dec 23 '13 at 7:29
  • ok you might have to include you getCart code then. Some general things to consider - the cart model has a method updateItems for updating multiple items at once. Also try moving the cart save operation outside of the foreach loop. – Kristof at Fooman Dec 23 '13 at 8:37

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.