Magento calculates the grandtotal twice after calling collectTotals() in Ajax - php

I am trying to apply Shipping Amount after Discounts in Magento checkout
I'm using UPS free shipping by price, so if you total after discount is under the minimum amount for free shipping it will not grant you free shipping.
Magento calculate free shipping before discount so I calculated on my local ups.php file the correct amount after discount and applied it to the code:
$coupon_code=Mage::getSingleton('checkout/cart')->getQuote()->getCouponCode();
Mage::getSingleton("checkout/session")->setData("coupon_code",$coupon_code);
Mage::getSingleton('checkout/session')->getQuote()->setCouponCode($coupon_code)->setTotalsCollectedFlag(false)->collectTotals();
//Mage::getSingleton('checkout/cart')->getQuote()->setCouponCode($coupon_code)->collectTotals()->save();
$totals =Mage::getSingleton('checkout/session')->getQuote()->getTotals(); //Total object
$subtotal = $totals["subtotal"]->getValue(); //Subtotal value
if(isset($totals['discount']) && $totals['discount']->getValue()) {
$discount = $totals['discount']->getValue(); //Discount value if applied
} else {
$discount = '';
}
$r->setValue($request->getPackageValueWithDiscount( ) - $giftCardPrice);
if($discount!='') $r->setValueWithDiscount($subtotal-abs($discount));
else $r->setValueWithDiscount($request->getPackageValueWithDiscount( )- $giftCardPrice);
This works my problem now that in every Ajax call for shipping Magento calculates the grandtotal of the cart twice
What can I do?

Related

Get WooCommerce subtotal AFTER coupons

I'm using this code:
WC()->cart->subtotal;
to check how much money the customer has to spend until she gets free shipping. The free shipping amount considers coupon codes though so I need to subtract any discount from WC()->cart->subtotal; before displaying the total amount. Any idea?
I've tried to do something like this:
$current = WC()->cart->subtotal - WC()->cart->discounts;
But it isn't doing anything.
Appreciate your help!
If you want display the total amount (subtotal - discount) you can write this :
WC()->cart->total;
So, you can do this for example :
$amount_for_free_shipping= 49;
$cart = round(WC()->cart->total,2);
$remaining = $amount_for_free_shipping - $cart;

Woocommerce coupon discount when item price is less than the discount amount

From my understanding of how woocommerce_coupon_get_discount_amount works. The discount is calculated as to how much it would discount each item in the cart. For example, if you had 4 items in the cart at $10, and you were to discount one item to be free. Then you would return $2.50 to each product in the cart. Thus discounting one of the products by 100%.
However, let's say that you had a product in the cart that was $1, then instead of discounting $10, the discount applied would be $8.50. Making the discount incorrect.
For this above example the coupon would be calculated as so:
add_filter('woocommerce_coupon_get_discount_amount', 'mb_wcchpi_cpn_disc', 10, 5);
function mb_wcchpi_cpn_disc($discount, $discounting_amount, $cart_item, $single, $coupon)
{
//IF CUSTOM COUPON TYPE
if ($coupon->type == 'most_expensive_coupon') {
//Gets the most expensive item in the cart
$mostExpensiveItem = FindMaxPricedItem($multiple_products);
//Get the price of the most expensive item in the cart
$maxPrice = $mostExpensiveItem['price'];
//GET THE COUPON DISCOUNT AMOUNT
$amt = floatval($coupon->amount);
//GET THE DISCOUNT AMOUNT
$discount = ($amt / 100) * $maxPrice;
//GET THE ITEMS IN THE CART
$itemCount = WC()->cart->cart_contents_count;
//DISTRIBUTE EQUALLY ACROSS ALL ITEMS IN CART
$discount = $discount / $itemCount;
}
return $discount;
}
How would one handle the edge case of having an item in the cart that is less than the discount amount? Is there a different action than woocommerce_coupon_get_discount_amount to be used for applying a coupon to the cart total instead of per item? Is there a different formula I should be using to come up with the discount?

Show shipping costs WooCommerce

I am using the cart widget from WooCommerce -> mini-cart.php
I am adding products to it via AJAX and added some elements already to it myself. Standard it shows the subtotal price in the cart but I want to show the shipping costs after it and after that the total price (subtotal + shipping).
So the cart will look like this:
- Products in cart
- Subtotal
- Shipping costs
- Total price (shipping + subtotal)
I have added the total price with this code:
<p><?php echo WC()->cart->get_cart_total(); ?></p>
But this echo's the same price as the subtotal because the shipping isn't added to it. Can someone help me to add the shipping costs to it. Some hook or code.
To get and display the chosen shipping method label (and other related data, if needed) in cart page (or in checkout page):
foreach( WC()->session->get('shipping_for_package_0')['rates'] as $method_id => $rate ){
if( WC()->session->get('chosen_shipping_methods')[0] == $method_id ){
$rate_label = $rate->label; // The shipping method label name
$rate_cost_excl_tax = floatval($rate->cost); // The cost excluding tax
// The taxes cost
$rate_taxes = 0;
foreach ($rate->taxes as $rate_tax)
$rate_taxes += floatval($rate_tax);
// The cost including tax
$rate_cost_incl_tax = $rate_cost_excl_tax + $rate_taxes;
echo '<p class="shipping-total">
<strong class="label">'.$rate_label.': </strong>
<span class="totals">'. WC()->cart->get_cart_shipping_total() .'</span>
</p>';
break;
}
}

Disable tax calculation on a discount using the Fee Api in Woocommerce

I am using a custom fee to calculate a discount based on amount of items in cart.
Discount becomes more if there are more products in the cart.
Discount should be €5 for 2 products, but is €6,05 because 21% tax gets calculated over the discount amount.
The code i'am using is the following
// Hook before calculate fees
add_action('woocommerce_cart_calculate_fees' , 'add_custom_fees');
/**
* Add custom fee bij meer dan 2 artikelen
* #param WC_Cart $cart
*/
function add_custom_fees( WC_Cart $cart ){
if( $cart->cart_contents_count < 2 ){
return;
}
//$Korting = Winkelwagen geteld * 5) - 5 (-5 is om eerste product korting te verwijderen;
// Calculate the amount to reduce
$discount = ($cart->get_cart_contents_count() * 5) -5;
$cart->add_fee( 'Sinterklaaskorting', -$discount, false);
}
Can someone help to get the tax out of the fee.
The Fee API can be tweaked to make a discount using a negative fee, just as your code does.
But in that case the taxes are always applied when using a negative amount, so the third argument $taxable in WC_Cart add_fees() method is always true even if you set it to false.
See: Apply a discount on the cart content total excluding taxes in WooCommerce
There is no turn around for this case, as the WC_Cart Fee API is made for fee but not for discount.
You could use: Apply automatically a coupon based on specific cart items count in Woocommerce with a percentage discount, but the taxes are also applied when using coupons.
So there is no way to get a discount without removing taxes at the same time.

Adding a custom cart negative fee tax issue in woocommerce

I have a shipping discount in my woocommerce site, I would like to show it on cart page and checkout page, for that I used add_fee() method.
WC()->cart->add_fee( 'Shipping Discount', -20, false );
It subtract 20 from total amount, but when I go to check order in orders inside admin it gives discount on tax too according to tax rate I configured. Is there any alternative to add discount
How can I do this in woocommerce?
For negative cart fee there is a bug related to taxes as they are applied on all tax classes even if the it's not taxable.
Now you can make a custom global cart discount This way where you will be able to define the type of discount you want, the discount amount and the source price to be discounted.
This code will display the he correct cart discounted gran total
Once submitted this discounted gran total will be passed to the order.
The code:
// Apply a discount globally on cart
add_filter( 'woocommerce_calculated_total', 'discounted_calculated_total', 10, 2 );
function discounted_calculated_total( $total, $cart ){
$amount_to_discount = $cart->cart_contents_total;
$percentage = 10; // 10% of discount
$discounted_amount = $amount_to_discount * $discount / 100;
$new_total = $total - $discounted_amount;
return round( $new_total, $cart->dp );
}
Code goes in function.php file of the active child theme (or active theme).
Tested and works.
You should need to make some additional code to display the discount amount (in cart and checkout pages and order-view) and to pass it in the order as meta data and so on…

Categories