I need to delete one item from cart.
I use the checkout_cart_add_product_complete event wich is fired after the cart was saved.
Then I use:
$quote = Mage::getSingleton('checkout/session')->getQuote();
$allQuoteItems = $quote->getAllItems();
foreach ($allQuoteItems as $_item) {
$_product = $_item->getProduct();
if ($_product->getIsPreparedToDelete()) {
$quote->removeItem($_item->getId());
}
}
$quote->save();
But the item is still there...
I have no idea which event I can use - or if it is really possible to delte an item in the cart (I also added items, that works - with the same event..).
Thanks.
Take a look # Magento - remove one quantity from cart
$cartHelper = Mage::helper('checkout/cart');
$items = $cartHelper->getCart()->getItems();
foreach ($items as $item) {
...
Mage::getSingleton('checkout/cart')->removeItem($item->getId());
Found it out.
removeItem() works outside this event, when all is saved. Within works this ($_item->isDeleted(true)):
$quote = Mage::getSingleton('checkout/session')->getQuote();
$allQuoteItems = $quote->getAllItems();
foreach ($allQuoteItems as $_item) {
$_product = $_item->getProduct();
f ($_product->getIsPreparedToDelete()) {
$_item->isDeleted(true);
} else {
// ....
}
}
$quote->save();
I think you can use one of the below event to observe and can use to remove particular item from cart:
sales_quote_item_save_before: When the item will be added to cart, this event will be called before the save event of that item fired.
sales_quote_save_after: And every time the whole cart will be saved this event will be fired after that.
And for your information, sales quote object is being used for handling cart.
And below is the link to the list of magento's events:
http://www.magentocommerce.com/wiki/5_-_modules_and_development/reference/events
Please feel free to revert back with any queries.
Regards,
Milan
Related
I am programming an extension which adds relevant products to the cart once you add an item to the cart. Example if you are buying a pen I am going to add paper to the cart. Bundled packages are not an option since I need to match certain conditions. I tried the following:
I set up an event listener "sales_quote_item_collection_products_after_load" scan all the products in cart and add the relevant products. Sadly you have to reload the cart in order to make the products appear.
I used this code in, my event listener, to add products to cart:
// Get cart instance
$cart = Mage::getSingleton('checkout/cart');
$cart->init();
// Add a product (simple); id:12, qty: 3
$cart->addProduct(12, 3);
$cart->save()
The strange thing is that removing products using the cart helper works (without refreshing):
$cartHelper = Mage::helper('checkout/cart');
$items = $cartHelper->getCart()->getItems();
foreach ($items as $item) {
if ($item->getProduct()->getId() == $productId) {
$itemId = $item->getItemId();
$cartHelper->getCart()->removeItem($itemId)->save();
break;
}
}
Is there a way to tell Magento to "requote" or what would you recommend? I also thought of adding the product, at the add to cart listener. But in that case I will need to implement it as well on update and remove, so it will work correctly. Using sales_quote_item_collection_products_after_load after load seemed to be the best option, since I have everything in one place.
You need to change in your code
$product_model = Mage::getModel('catalog/product');
$product_id =35;
$my_product = $product_model->load($product_id);
$cart = Mage::getModel('checkout/cart');
$cart->init();
$cart->addProduct($my_product, array('qty' => 1));
$cart->save();
Mage::getSingleton('checkout/session')->setCartWasUpdated(true);
I'm looking to create "Addon Products" in Magento. What I mean is: If the product were a Greeting Card, and you were to add that to your cart, you might be presented with options on the checkout page to add an "Envelope" or "Stamps". These would be separate products with their own prices, however, they would not be available otherwise in the store. In other words, some sort of "Linked / Child Products" that only become available once the "Parent" product has been added.
Does this sort of product configuration exist within Magento? Doesn't seem to be a Bundled Product.
Yes Magento does this out of the box.
Against each product assign 'cross sell' products, using the cross sell tab on the left. When you first get to it, if the list is empty press the 'reset filter' button to show all the products in the store. Find the ones you want and put a tick next to them, then click save.
The block you are after is;
<block type="checkout/cart_crosssell" name="checkout.cart.crosssell" as="crosssell" template="checkout/cart/crosssell.phtml"/>
Which most template load within "content" in the layout/checkout.xml layout file of your theme,
<checkout_cart_index translate="label">
////
<reference name="content">
///// HERE
</reference>
/////
</checkout_cart_index>
And then add this to the checkout/cart.phtml template (if it's not there already);
<?php echo $this->getChildHtml('crosssell') ?>
But you can add it to wherever you wish.
To handle these products not appearing elsewhere, set their visibility to 'catalog' and either put them in a category that isnt visible or dont add them to a category.
TO ANSWER YOUR SECOND QUESTION...
You asked how you could remove all 'add on' items from the basket if there are no 'main product' items in the basket. Here is a quick solution that will do this.
Create a custom select product attribute, give it ID code 'product_type_var' and give it 2 options 'Main Product' and 'Addon Product'. Add it to your product attribute set and set the values against the appropriate products.
You can then run the following code against the basket. Ideally you would create a module with an event observer - but for the sake of this example, you could also place this code at the top of
app/design/frontend/XXX/YYY/template/checkout/cart.phtml
Here's the code;
$quote = Mage::getSingleton('checkout/session')->getQuote();
$needsAction = true;
$toRemove = array();
foreach ($quote->getAllItems() as $item) {
$product = $item->getProduct();
$productLoad = Mage::getModel('catalog/product')->load($product->getId());
$customVariable = $productLoad->getResource()->getAttribute('product_type_var')->getFrontend()->getValue($productLoad);
if($customVariable == 'Main Product') {
$needsAction = false;
break; // No need to do anything
}
if($customVariable == 'Addon Product') {
$toRemove[] = $productLoad->getId(); // Build list of addon IDs
}
}
if($needsAction && (!empty($toRemove))) {
// There are no Main Products and 1 or more Addons
foreach($toRemove as $removeId) {
$quote->removeItem($removeId)->save();
}
}
Revision 3
To make sure any 'addon' products only remain in the cart if they relate to a specific 'main product' found in the cart, try this;
$quote = Mage::getSingleton('checkout/session')->getQuote();
$allowedUpsells = array();
$upsellsInCart = array();
$allIdsInCart = array();
foreach ($quote->getAllItems() as $item) {
$product = $item->getProduct();
$productLoad = Mage::getModel('catalog/product')->load($product->getId());
$customVariable = $productLoad->getResource()->getAttribute('product_type_var')->getFrontend()->getValue($productLoad);
if($customVariable == 'Main Product') {
$allIdsInCart[] = $productLoad->getId(); // Build list of all products in the cart
$upsells = $productLoad->getUpSellProductCollection(); // Get this products available upsells
foreach($upsells as $upsell) {
$allowedUpsells[] = $upsell->getId(); // Build full list of allowed addon IDs
}
}
if($customVariable == 'Addon Product') {
$allIdsInCart[] = $productLoad->getId(); // Build list of all products in the cart
$upsellsInCart[] = $productLoad->getId(); //Build full list of addon IDs
}
}
if(!empty($upsellsInCart)) { // Upsells might need attention
$allowedVsInCart = array_intersect($allowedUpsells, $allIdsInCart); // Remove other upsells that are avaiable to the product but not in the cart
$toBeRemoved = array_diff_assoc($allowedVsInCart, $upsellsInCart); // Now find the products in the cart that shouldnt be
if(!empty($toBeRemoved)) {
foreach($toBeRemoved as $removeId) {
$quote->removeItem($removeId)->save();
}
}
}
Let me know how can I get status of shopping cart in magento from anywhere ?
I mean that Is It possible to get an error like
- your item "marlboro" count has been exceeded ! At present .
There is no so much in stock, please decrease it
Thanks
You can use something like that on an event that is fired on every page like controller_front_init_before
$cart = Mage::getModel('checkout/cart')->getQuote();
foreach ($cart->getAllItems() as $item) {
$product = $item->getProduct();
$stocklevel = (int)Mage::getModel('cataloginventory/stock_item')
->loadByProduct($product)->getQty();
if ($stocklevel<$item->getQty()){
...the logic that will permit to show the customer that the requested
product is not avaiable in this quantity...
}
}
I want show custom options on cart page i tried using $_options = $this->getOptionList() but it only shows the selected option only , i want to retrieve all options.
To get product custom option value at cart page which are set at 'AddtoCart' time try with following code.
$cart = Mage::helper('checkout/cart')->getCart()->getQuote()->getAllItems();
/* cart item loop */
foreach($cart as $item) {
/* This will get custom option value of cart item */
$_customOptions = $item->getProduct()->getTypeInstance(true)->getOrderOptions($item->getProduct());
/* Each custom option loop */
foreach($_customOptions['options'] as $_option){
echo $_option['label'] .'=>'. $_option['value']."<br/>";
// Do your further logic here
}
}
Already replied at
Display Magento Custom Option Values in Shoping Cart
You can get only selected options from using this function $this->getOptionList(), but if you actually want to retrieve all custom options then first of all you need to retrieve product id
You can get product like this on cart page
$_item = $this->getItem();
$_item->getProduct();
This will retrieve product from this you can get product and load product.
$product = Mage::getModel('catalog/product')->load($_item->getProduct()->getData('entity_id'));
$product = Mage::getModel('catalog/product')->load($product);
foreach ($product->getOptions() as $o) {
print_r($o); // show all product options
}
}
I want that when customer register product (which is choosen in backend) should get added to cart. I have done this :
$product = Mage::getModel('catalog/product')
->setStoreId(Mage::app()->getStore()->getId())
->load(154);
$cart = Mage::getSingleton('checkout/cart');
$cart->addProduct($product, 1)->save();
Mage::getSingleton('checkout/session')->setCartWasUpdated(true);
in AccountController.php in createPostAction().
But it is not showing but whenever customer buys anything it gets added into cart. I am doing anything wrong...?
-Thnx in advance.
The problem is, the quote object in the session has already collected totals and would not do it again when the cart is saved. Because of this the quote's item count is zero, even though a quote item has been successfully added and saved. Modify your code like this:
$cart->product($product, 1);
$cart->getQuote()->setData('totals_collected_flag', false);
$cart->save();
And this should solve the problem.
A suggestion: would it not be better to implement this functionality in an observer listening to the customer_register_success event?