I need to remove some products from cart after the customer press the "Place order" button. I can remove the products with a custom event and observer and update the cart products, but i cant update the cart total.
In the observer i try to update the price with:
$granTotal = $cart->getGrandTotal() - $cart->getShippingAmount();
$cart->setGrandTotal($GranTotal - $sum)->save();
$baseGranTotal = $cart->getBaseGrandTotal() - $cart->getShippingAmount();
$cart->setBaseGrandTotal($baseGranTotal - $sum)->save();
$cart->setTotalsCollectedFlag(false)->collectTotals();
$cart->save();
But the total of the cart don't change. I find that the total is stored in the cart address too and used to set the cart total in Mage_Sales_Model_Quote collectTotals() function.
Here:
$this->setSubtotal((float) $this->getSubtotal() + $address->getSubtotal());
$this->setBaseSubtotal((float) $this->getBaseSubtotal() + $address->getBaseSubtotal());
Then i tried to change the address total before calling the collectTotals(), but the cart total still don't change.
My custom event is triggered at the beginning in Mage_Checkout_Model_Type_Onepage saveOrder() function.
I am running out of ideas of how to update the total of the cart.
My observer looks like this:
public function changeCart(){
$cart = Mage::getSingleton('checkout/session')->getQuote();
$data = array();
$inquiry = array();
$sum = 0;
//remove out of stock items to save them in custom model
foreach ($cart->getAllItems() as $item) {
if($item->getProduct()->getData('is_in_stock') == 0){
$cart->removeItem($item->getItemId())->save();
$inquiry[] = $item->getProduct();
$data['qty'][$item->getProduct()->getId()] = $item->getData('qty');
$sum += $item->getProduct()->getFinalPrice();
$dobavljivost = $item->getProduct()->getResource()->getAttributeRawValue($item->getProduct()->getId(), 'dobavljivost', Mage::app()->getStore());
Mage::getSingleton('core/session')->setDobavljivost($dobavljivost);
}
}
foreach($cart->getAllAddresses() as $a){
$a->setGrandTotal(0);;
$a->setBaseGrandTotal(0);
$a->setData('subtotal', 0);
$a->setData('base_subtotal', 0);
}
$granTotal = $cart->getGrandTotal() - $cart->getShippingAmount();
$cart->setGrandTotal($GranTotal - $sum)->save();
$baseGranTotal = $cart->getBaseGrandTotal() - $cart->getShippingAmount();
$cart->setBaseGrandTotal($baseGranTotal - $sum)->save();
$cart->setTotalsCollectedFlag(false)->collectTotals();
$cart->save();
}
Thank you for any help!
For recomputing totals of the cart you can try do this
$cart = Mage::getSingleton('checkout/session')->getQuote();
foreach ($cart->getAllAddresses() as $address)
{
$address->unsetData('cached_items_nonnominal');
$address->unsetData('cached_items_nominal');
}
$cart->setTotalsCollectedFlag(false);
$cart->collectTotals();
Related
I want to change the tax amount of the products in my cart programmatically, but I can't get my head around it. Although I think I'm using the proper action hook to alter my tax rates, nothing is changing eventually on the frontend.
When I execute the function below and dump the result in my for loop, I can see that the values in the cart item array are altered.
add_action('woocommerce_before_calculate_totals', 'okappi_alter_price_cart', 9999);
function okappi_alter_price_cart($cart) {
foreach($cart->get_cart() as $cart_item_key => $cart_item) {
$cart_item['line_tax_data']['subtotal'] = 10;
$cart_item['line_tax_data']['total'] = 10;
$cart_item['line_subtotal_tax'] = 10;
$cart_item['line_tax'] = 10;
dd($cart_item);
}
}
But when I dump the cart item after the for loop, nothing has changed.
add_action('woocommerce_before_calculate_totals', 'okappi_alter_price_cart', 9999);
function okappi_alter_price_cart($cart) {
foreach($cart->get_cart() as $cart_item_key => $cart_item) {
$cart_item['line_tax_data']['subtotal'] = 10;
$cart_item['line_tax_data']['total'] = 10;
$cart_item['line_subtotal_tax'] = 10;
$cart_item['line_tax'] = 10;
// dd($cart_item);
}
dd($cart_item);
}
So what am I overlooking here? How can I change the tax amount of my individual products before they are calculated on the cart & checkout page?
I am calculating shipping charge for each product with respect to their weight,i want to get each product weight added to a cart separately instead of total weight.
$individual_weight=array();
$items = Mage::getSingleton('checkout/session')->getQuote()->getAllItems();
foreach($items as $item) {
$weight = 0;
$weight = ($item->getWeight() * $item->getQty()) ;
$individual_weight[] = $weight;
}
You will get all the individual product weight stored in the array
I am currently building a module for an ecommerce website (Lemonstand). My shop sells both normal books and ebooks, and charge different rates of for shipping based on the subtotal of all items in the cart ($7 shipping cost for subtotal of less than $20, $14 shipping cost for between $20 and $50..etc). Currently the website just uses the subtotal of all items in the cart to determine which rate should be applied. The problem is, I want only the subtotal of normal books to be used for calculating shipping, because obviously ebooks don't need shipping.
Lemonstand platform has some built_in functions that I'm using to help with this. update_shipping_quote function is called just before shipping cost is calculated. It will be used to change the subtotal of cart items so that shipping cost can be calculated using the subtotal of non-ebooks instead.
Here is the API documentation for the function: https://v1.lemonstand.com/api/event/shop:onupdateshippingquote/
Here is the bit of code that's giving me trouble. I want to know if the value I get at the end ($non_ebook_subtotal) actually contains the value it's supposed to.
If anyone can come up with a better method for doing what I'm trying to do, please share.
//$params is an array containing things like individual item price
//Here I get the cart items and put them into var
public function
update_shipping_quote($shipping_option, $params) {
$cart_items = $params['cart_items'];
//find all products that are ebooks
foreach ($cart_items-> items as $item)
{
$product = $item->product;
if($product->product_type->code == 'ebook') {
$isEbook = true;
}
}
//add price of all ebooks into $ebook_subtotal
foreach ($cart_items as $item) {
$product = $item -> product;
if ($isEbook == true) {
$ebook_subtotal = $ebook_subtotal + total_price($product);
}
}
//Calculating the subtotal of only the non-ebook products
$non_ebook_subtotal = $params['total_price'] - $ebook_subtotal;
//This returns the non_ebook_subtotal to be used for calculating shipping cost
return array('total_price' => $non_ebook_subtotal);
}
Thanks
// get all variables needed
$totalprice = $params['total_price'];
$items = $params['cart_items'];
foreach ($items AS $item) {
// if is ebook
if ($item->product->product_type->code == 'ebook') {
// minus price of the item from total
$totalprice -= total_price($item->product);
}
}
return $totalprice;
I want to get the remain quantity of a given product. I'm going to create a report in admin panel which highlights the remaining quantity and re-order level quantity against each product. I was able to get the re-order level quantity by inventory details. And I want to get remain quantity for a given product. Please any suggestions?
Try
<?php
$num= Mage::getModel('cataloginventory/stock_item')->loadByProduct($_product)->getQty();
echo "Remaining products: ".$num;
?>
If you are looking for the remaining quantity for products in the cart, you need to take into account configurable vs simple products:
<?php
$quote = Mage::getModel('checkout/cart')->getQuote();
$items = $quote->getAllVisibleItems();
foreach ($items as $item) {
$cart_product = $item->getProduct();
if ($option = $item->getOptionByCode('simple_product')) {
$cart_simple_product = $option->getProduct();
} else {
$cart_simple_product = $this->getProduct();
}
$stock = Mage::getModel('cataloginventory/stock_item')->loadByProduct($cart_simple_product);
$max_available_quantity = (int)$stock->getQty();
}
?>
I am creating a magento extension. In which I want to update the item quantity in cart programmatically. I am using the following code to display the items in cart.
$quote = Mage::getSingleton('checkout/session')->getQuote();
$cartItems = $quote->getAllVisibleItems();
foreach ($cartItems as $item) {
//Do something
}
What i want is to update the quantity on cart for a specific product. I know it can be done like this
$pid=15;
$quote = Mage::getSingleton('checkout/session')->getQuote();
$cartItems = $quote->getAllVisibleItems();
foreach ($cartItems as $item) {
if($pid==$item->getId())
$item->setQty($qty);
}
But I don't like this method as it would go through each and every product to update the quantity of a single product. I wonder if there is a way to update the quantity in one line i:e without using for loop.
You have the product_id, not the item_id right ?
If it's the case it's impossible to get the product id without performing the whole items.
Look at Mage_Sales_Model_Quote::getItemByProduct($product); you'll see it performs the whole catalog.
Basically I'll do it like this :
//get Product
$product = Mage::getModel('catalog/product')->load($pid);
//get Item
$item = $quote->getItemByProduct($product);
$quote->getCart()->updateItem(array($item->getId()=>array('qty'=>$qty)));
$quote->getCart()->save();
You should optimise this with some quick tricks :
$quote->hasProductId($pid) to check if product is in the cart
and
($qty!=$item->getQty())
to check if quantity is not already good...
Please note that it is untested code, and some kind of reflexions to help you find the solution, I didn't do the job for you.
Kind Regards,
I am sure it will work. Try this. It's save's my time.
public function updateCartAction(){
$item_id = $this->getRequest()->getParam('item_id');
$qty = $this->getRequest()->getParam('qty');
$quote = Mage::getSingleton('checkout/session')->getQuote();
$quote->updateItem($item_id, array( 'qty' => $qty));
$quote->save();
echo "Sssssss";
}
another solution
$quote = Mage::getModel('sales/quote')->setStoreId($storeId)->load($cartid);
$cartItems = $quote->getAllItems();
foreach ($cartItems as $item) {
if($cartiemid==$item->getId()){
$item->setQty($qty);
$item->save(); // you need to save the item after qty update
}
}
$quote->save();