Recently we were working on Magento project where we were building custom APIs for the Magento. One such API was to return the current items in current cart session. Now we know that Magento has various type of the products like simple product, Simple product with custom options, configurable product, bundle product etc and in our API we have to add support for all. Now here we have faced the issue with bundle products. As when we add a bundle product with cart, magento also adds selected simple products in cart session.
For example , you have a bundle product called A and it has associated product X, Y and Z. Customer has selected bundle product A and selected options X and Y. Magento will add three product in cart. One is A and other two are Y, Z. So in our API when we were trying to get items in cart we were getting three items. That is wrong as user has only selected parent bundle product so we should only display it with the options selected. We used following code to get items.
$quote_id = $_REQUEST['quote_id'];
$cartsession = Mage::getSingleton('checkout/session')->getQuote();
foreach ($cartsession->getAllItems() as $item) {
}
So it was returning three items that is wrong. So initially we thought of removing those items from the collections. But then we may have this scenario. User has added bundle product A with X and Y. X product is also sellable independently. So if user has added it, we should display product A and product X in cart. So it was difficult to identify in collections. So what is the solution? After checking class definition of Mage_Sales_Model_Quote in app/code/core/Mage/Sales/Model/Quote.php , we found following two functions.
/**
* Retrieve quote items array
*
* @return array
*/
public function getAllItems()
{
$items = array();
foreach ($this->getItemsCollection() as $item) {
if (!$item->isDeleted()) {
$items[] = $item;
}
}
return $items;
}
/**
* Get array of all items what can be display directly
*
* @return array
*/
public function getAllVisibleItems()
{
$items = array();
foreach ($this->getItemsCollection() as $item) {
if (!$item->isDeleted() && !$item->getParentItemId()) {
$items[] = $item;
}
}
return $items;
}
So there is only once difference here in both the function and that is the condition !$item->isDeleted() && !$item->getParentItemId() in second function. It filters the product based in parent id. So in our case product X and Y has parent id product A so that products were avoided. in list and we get only single bundle product. If the product X is added separately, it does not have any parent so it will be still visible in list.
So in short, to get the correct list of items in cart use getAllVisibleItems function if you have to support bundle products and configurable products. If you have only simple products and custom options you can use getAllItems function.
For example , you have a bundle product called A and it has associated product X, Y and Z. Customer has selected bundle product A and selected options X and Y. Magento will add three product in cart. One is A and other two are Y, Z. So in our API when we were trying to get items in cart we were getting three items. That is wrong as user has only selected parent bundle product so we should only display it with the options selected. We used following code to get items.
$quote_id = $_REQUEST['quote_id'];
$cartsession = Mage::getSingleton('checkout/session')->getQuote();
foreach ($cartsession->getAllItems() as $item) {
}
So it was returning three items that is wrong. So initially we thought of removing those items from the collections. But then we may have this scenario. User has added bundle product A with X and Y. X product is also sellable independently. So if user has added it, we should display product A and product X in cart. So it was difficult to identify in collections. So what is the solution? After checking class definition of Mage_Sales_Model_Quote in app/code/core/Mage/Sales/Model/Quote.php , we found following two functions.
/**
* Retrieve quote items array
*
* @return array
*/
public function getAllItems()
{
$items = array();
foreach ($this->getItemsCollection() as $item) {
if (!$item->isDeleted()) {
$items[] = $item;
}
}
return $items;
}
/**
* Get array of all items what can be display directly
*
* @return array
*/
public function getAllVisibleItems()
{
$items = array();
foreach ($this->getItemsCollection() as $item) {
if (!$item->isDeleted() && !$item->getParentItemId()) {
$items[] = $item;
}
}
return $items;
}
So there is only once difference here in both the function and that is the condition !$item->isDeleted() && !$item->getParentItemId() in second function. It filters the product based in parent id. So in our case product X and Y has parent id product A so that products were avoided. in list and we get only single bundle product. If the product X is added separately, it does not have any parent so it will be still visible in list.
So in short, to get the correct list of items in cart use getAllVisibleItems function if you have to support bundle products and configurable products. If you have only simple products and custom options you can use getAllItems function.
No comments:
Post a Comment