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

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.

Related

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?

Coupon with 2 different percentage discounts based on product category in Woocommerce

I am looking for a Woocommerce hook that will help to change the discount percentage based on 2 different product category restrictions when a specific coupon is applied.
For example if customer add a specific coupon I will like to:
If a cart item is from product category A then it will give 10% discount on that item.
if it's in product category B it will give 20% discount on that item
Update total cart price
Is there any hook that could be available to achieve this? Any available action hook or filter hook?
This is my code so far:
add_filter( 'woocommerce_get_discounted_price', 'apply_coupon', 10);
function apply_coupon($price) {
global $woocommerce;
$product=$woocommerce->cart->product;
if(has_term( 'duplex-blinds', 'A' ,$product->id)){
get_product_cart_price;
10% DISCOUNT
}
if(has_term( 'duplex-blinds', 'A' ,$product->id)){
20% DISCOUNT
}
upadte total_discunt_incart($new_discount);
upadte new_price_in_cart($new_price);
upadte new_price_in_checkout($new_price);
return $price;
}
The important thing is i need to modify the total cart price , total checkout price , total discount price and discount price need to send to Paypal.
My shop have many hooks that's why woo commerce default coupon calculation is going to wrong. And i noticed that in cart page discount price is coming correctly based on the custom product value, but it not get updated from the original cart amount, so the total price remain the same.
But in checkout page discount price is calculated based on the product original price not the product custom price so the discount is coming wrong and also it is not minimize from the total price also...
The following is a completely different way to make that works… This answer code will enable a coupon code with 2 different discounts percentage based on 2 specific product categories.
Lest say for example that your related product categories are:
For the coupon discount of 10%, the product category slug will be 'hoodies'
For the coupon discount of 20%, the product category slug will be 't-shirts'
(you can use product category Ids, slugs or Names in the code)
That will need 2 Steps:
Coupon settings (Set correctly your coupon code):
Discount type: Percentage
Amount: 10
Restrictions > Product categories (names displayed): "Hoodies" and "T shirts"
You can have other settings if you need
The settings inside the code function:
Coupon code: set your coupon code in lowercase
The 't-shirts' product category slug (for 20% of discount).
Now Here comes the code (where you will add your settings):
add_filter( 'woocommerce_coupon_get_discount_amount', 'alter_shop_coupon_data', 20, 5 );
function alter_shop_coupon_data( $round, $discounting_amount, $cart_item, $single, $coupon ){
## ---- Your settings ---- ##
// Related coupons codes to be defined in this array (you can set many)
$coupon_codes = array('10percent');
// Product categories at 20% (IDs, Slugs or Names) for 20% of discount
$product_category20 = array('hoodies'); // for 20% discount
$second_percentage = 0.2; // 20 %
## ---- The code: Changing the percentage to 20% for specific a product category ---- ##
if ( $coupon->is_type('percent') && in_array( $coupon->get_code(), $coupon_codes ) ) {
if( has_term( $product_category20, 'product_cat', $cart_item['product_id'] ) ){
$original_coupon_amount = (float) $coupon->get_amount();
$discount = $original_coupon_amount * $second_percentage * $discounting_amount;
$round = round( min( $discount, $discounting_amount ), wc_get_rounding_precision() );
}
}
return $round;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Here is an illustrated real working example (with screen shots):
The 1st cart item (from 'hoodies' product category) get 10% of discount $40 x 10% = $4
The 2nd cart item (from 't-shirts' product category) get 20% of discount $30 x 20% = $6
So the total discount is $4 + $6 = $10 … That works!
I using this code, but it give 100% on the 20% category, but the code you provide does work if you change the 0.2 to 0.02
$second_percentage = 0.2; // 20 %
change too:
$second_percentage = 0.02; // 20 %
or:
$second_percentage = 0.015; // 15 %
If you need 15% discount

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…

Set a custom shipping rate cost calculated on cart total weight in WooCommerce

In Woocommerce I have installed a shipping plug in but it calculates shipping per item in cart instead of per order total.
What I need is to calculate the shipping cost this way:
- First kg is $5
- And $1 by kilo for all others.
Is it possible to do it?
With the plugin if there is 2 items in cart of 1 kg each, it calculates the shipping as 2 x $5 = $10
Instead what I should need is: $5 (first kilo) + $1 (additional kilo) = $6 (for 2 kg).
I have no response from plugin developer, so looking for work around.
UPDATED: You don't need any plugin (so you can remove it).
To get a shipping rate calculated on total cart weight, with:
an initial amount of $5 (for the first kilo)
a variable rate of $1 for each additional kilo
Do the following:
1) Settings in WooCommerce:
For all your "Flat rate" shipping method (in each shipping zone), set a cost of 1 (amount by kilo).
So the cost
(Once done disable/save and enable/save to refresh woocommerce transient cache)
2) Custom code (as the shipping unit cost is $1 by kilo, we add 4 kilos to total cart weight in the calculations to set the correct cost):
add_filter( 'woocommerce_package_rates', 'custom_delivery_flat_rate_cost_calculation', 10, 2 );
function custom_delivery_flat_rate_cost_calculation( $rates, $package )
{
// The total cart items weight
$cart_weight = WC()->cart->get_cart_contents_weight();
foreach($rates as $rate_key => $rate_values){
$method_id = $rate_values->method_id;
$rate_id = $rate_values->id;
if ( 'flat_rate' === $method_id ) {
## SHIPPING COSTS AND TAXES CALCULATIONS ##
$rates[$rate_id]->cost = $rates[$rate_id]->cost*($cart_weight+4);
foreach ($rates[$rate_id]->taxes as $key => $tax){
if( $rates[$rate_id]->taxes[$key] > 0 ){
$tax_cost = number_format( $rates[$rate_id]->taxes[$key]*($cart_weight+4));
$rates[$rate_id]->taxes[$key] = $tax_cost;
}
}
}
}
return $rates;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and works on woocommerce versions 2.6.x and 3+

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

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?

Categories