Apply a progressive discount based on Woocommerce cart weight - php

I'm looking for a way to apply a discount (percentage) based on cart total weight.
Example:
10 to 25 kg, set a 5% discount
26 to 50 kg, set a 7,5% discount
51 to 100 kg, set a 10% discount
101 to 150 kg, set a 12,5% discount
more than 150 kg, set a 15% discount
When one of the rules will be applied there should be a message also like this payment discount shown in the picture.
Payment method discount
And if also possible showing a message box like the 'added to cart message box' which shows how much customers have to order to get the first of a second discounted rule like: Order **kg more and get 5% discount.
I have no idea how to achieve this, so I unfortunately did not tried anything.
Thanks in advance.
Regards,
Vasco

You can use a negative fee to make a progressive discount based on cart weight as follow:
add_action( 'woocommerce_cart_calculate_fees', 'shipping_weight_discount', 30, 1 );
function shipping_weight_discount( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$cart_weight = $cart->get_cart_contents_weight();
$cart_subtotal = $cart->get_subtotal(); // Or $cart->subtotal;
$percentage = 0;
if ( $cart_weight >= 10 && $cart_weight <= 25 ) {
$percentage = 5;
} elseif ( $cart_weight > 25 && $cart_weight <= 50 ) {
$percentage = 7.5;
} elseif ( $cart_weight > 50 && $cart_weight <= 100 ) {
$percentage = 10;
} elseif ( $cart_weight > 100 && $cart_weight <= 150 ) {
$percentage = 12.5;
} elseif ( $cart_weight > 150 ) {
$percentage = 15;
}
// Apply a calculated discount based on weight
if( $percentage > 0 ) {
$discount = $cart_subtotal * $percentage / 100;
$cart->add_fee( sprintf( __( 'Weight %s discount', 'woocommerce' ), $percentage.'%'), -$discount );
}
}
Code goes in function.php file of your active child theme (or active theme).
Based on: Add custom fee based on total weight in Woocommerce

Welcome to StackOverflow!
$applied_discount = 0;
add_filter( 'woocommerce_calculated_total', 'add_conditional_discount_by_weight', 10, 2 );
function add_conditional_discount_by_weight( $total, $cart ) {
global $applied_discount;
$total_weight = WC()->cart->get_cart_contents_weight(); // gets cart weight
if($total_weight >= 10 || $total_weight <= 25){
$applied_discount = 5;
return $total*(1-($applied_discount/100));
}
}
add_action( 'woocommerce_cart_totals_after_order_total', 'display_applied_discount' );
function display_applied_discount() {
global $applied_discount;
if($applied_discount > 0){
$discount = WC()->cart->total * ($applied_discount/100);
?>
<tr class="order-total">
<th><?php esc_html_e( "Applied Discount ($applied_discount%)", 'woocommerce' ); ?></th>
<td><?php echo "$".$discount ?></td>
</tr>
<?php
}
}
Here's a code snippet that answers your question. I only added one weight condition. I believe you'll be able to fill in the other conditions yourself.
The snippet can be added to your functions.php (as long as it is a child theme, otherwise your code will be deleted after a theme update!) or as a code snippet using plugins such as Code Snippets

Related

Woocommerce - add surcharge in cart based on weight only to some categories (or to all cart except some categories)

A friends ask me to add an extra fee on cart based on weight and only for specific categories (or excluding some categories, it doesn't matters).
The topic is, for summer, he wants to add ice into the packages to keep the products cold (ex. milk, cheese, etc).
He sells also gadgets and guided visits to his factory, etc so he doesn't want to apply the extra fee to those products.
Based on "Add custom fee based on total weight in Woocommerce" answer, my code version below, apply an extra fee to the whole cart, excluding the visit-product from this fee because the weight of the visit is obviously 0.
But I am not an expert with code and I don't know how to insert an array to include categories like 'milk' and 'cheese' (or viceversa to exclude 'visits' and 'gadgets').
In addiction, my code increase the fee by steps of 3kg (due to sizing of the packets by DHL/UPS/GLS etc)
/* Extra Fee based on weight */
add_action( 'woocommerce_cart_calculate_fees', 'shipping_weight_fee', 30, 1 );
function shipping_weight_fee( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Convert in grams
$cart_weight = $cart->get_cart_contents_weight() * 1000;
$fee = 0.00; // initial fee
// if cart is > 0 add €1,20 to initial fee by steps of 3000g
if( $cart_weight > 0 ){
for( $i = 0; $i < $cart_weight; $i += 3000 ){
$fee += 1.20;
}
}
// add the fee / doesn't show extra fee if it's 0
if ( !empty( $fee )) {
$cart->add_fee( __( 'Extra for ice' ), $fee, false );
}
}
Last question is: why the $i variable could be 0...1...1000000 without any change in the results? the code seems working exactly the same...
thanks
The following code is based on:
Predefined categories
Based on product weight (of products belonging to the predefined categories)
Fee increases by steps
(comment with explanation added in the code)
function shipping_weight_fee( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
/* SETTINGS */
// Specific categories
$specific_categories = array( 'categorie-1', 'categorie-2' );
// Initial fee
$fee = 1.20;
// Steps of kg
$steps_of_kg = 3;
/* END SETTINGS */
// Set variable
$total_weight = 0;
// Loop though each cart item
foreach ( $cart->get_cart() as $cart_item ) {
// Get product id
$product_id = $cart_item['product_id'];
// Get weight
$product_weight = $cart_item['data']->get_weight();
// NOT empty & has certain category
if ( ! empty( $product_weight ) && has_term( $specific_categories, 'product_cat', $product_id ) ) {
// Quantity
$product_quantity = $cart_item['quantity'];
// Add to total
$total_weight += $product_weight * $product_quantity;
}
}
if ( $total_weight > 0 ) {
$increase_by_steps = ceil( $total_weight / $steps_of_kg );
// Add fee
$cart->add_fee( __( 'Extra for ice' ), $fee * $increase_by_steps, false );
}
}
add_action( 'woocommerce_cart_calculate_fees', 'shipping_weight_fee', 10, 1 );

Add custom fee based on total weight in Woocommerce

In WooCommerce, I am trying to add a an additional shipping fee based on cart weight.
For the first 1500g the fee is 50$.
Above 1500g we add 10$ to this initial $50 by steps of 1000g
So for example:
if cart weight is 700g we add a fee of $50,
if cart weight is 2600g we add a fee of $70 ($50 + $10 +$10) …
I am stuck on the calculation:
function weight_add_cart_fee() {
$feeaddtocart = get_option('feeaddtocart');
$customweight = get_option('customweight');
global $woocommerce;
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$cart_weight = WC()->cart->get_cart_contents_weight();
if ($cart_weight <= 500 ) {
$get_cart_total = $woocommerce->cart->get_cart_total();
$newtotal = $get_cart_total + 50;
WC()->cart->add_fee( __('Extra charge (weight): ', 'your_theme_slug'), $newtotal, false );
}
}
How can I achieve this? Any help is appreciated.
It can be done very easily with a custom function hooked in woocommerce_cart_calculate_fees action hook…
Updated:
Added conversion of cart weight in grams (instead of kilos by default)
Now for the first 1500g the fee is 50$ (instead of 500g)
Now above 1500g it add $10 by steps of 1000g.
add_action( 'woocommerce_cart_calculate_fees', 'shipping_weight_fee', 30, 1 );
function shipping_weight_fee( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Convert cart weight in grams
$cart_weight = $cart->get_cart_contents_weight() * 1000;
$fee = 50; // Starting Fee below 500g
// Above 500g we add $10 to the initial fee by steps of 1000g
if( $cart_weight > 1500 ){
for( $i = 1500; $i < $cart_weight; $i += 1000 ){
$fee += 10;
}
}
// Setting the calculated fee based on weight
$cart->add_fee( __( 'Weight shipping fee' ), $fee, false );
}
Code goes in function.php file of your active child theme (or active theme).
Tested and works.

Woocommerce Progressive extra cost based on total number of items in the cart

I am looking for some code which can make an extra charge based on the total number of items in the cart like:
If number of items in cart is > 6 ===> extra cost = 5
If number of items in cart is > 12 ==> extra cost = 10
I have tried this code, but I can't get it working for my case.
How can I make an extra cost based on total number of items in the cart?
Based on (this answer) WooCommerce Cart Quantity Base Discount, you can add a progressive fee based on total number of items:
add_action( 'woocommerce_cart_calculate_fees','woocommerce_cart_extra_cost', 10, 1 );
function woocommerce_cart_extra_cost( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
$cart_item_count = $cart->get_cart_contents_count();
// CONDITIONAL ITEMS QUANTITY FEE AMOUNT
if( $cart_item_count < 6 )
$fee = 0;
elseif( $cart_item_count >= 6 && $cart_item_count < 12 )
$fee = 5;
elseif( $cart_item_count >= 12 )
$fee = 10;
if( $fee > 0 )
$cart->add_fee( __( "Extra Cost", "woocommerce" ), $fee, true);
}
Code goes in functions.php file of your active child theme (or theme) or also in any plugin file.
Tested and works.

Progressive percent discount based on cart amount

I am trying to make a simple discount code for WooCommerce that gives you a percent discount before buying. Lets say that if you add products worth $100 you get 2% discount and if you add products worth $250 you get 4%, etc.
The only thing I found was this:
// Hook before calculate fees
add_action('woocommerce_cart_calculate_fees' , 'add_custom_fees');
/**
* Add custom fee if more than three article
* #param WC_Cart $cart
*/
function add_custom_fees( WC_Cart $cart ){
if( $cart->cart_contents_count < 3 ){
return;
}
// Calculate the amount to reduce
$discount = $cart->subtotal * 0.1;
$cart->add_fee( 'You have more than 3 items in your cart, a 10% discount has been added.', -$discount);
}
But could not manage to make it work with the modifying the hooks with those for the price.
How can I achieve this?
Here is the way to do it using conditions based on cart subtotal excl tax amount to add this progressive percentage as a negative fee, so a discount:
add_action( 'woocommerce_cart_calculate_fees','cart_price_progressive_discount' );
function cart_price_progressive_discount() {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$has_discount = false;
$stotal_ext = WC()->cart->subtotal_ex_tax;
// Discount percent based on cart amount conditions
if( $stotal_ext >= 100 && $stotal_ext < 250 ) {
$percent = -0.02;
$percent_text = ' 2%';
$has_discount =true;
} elseif( $stotal_ext >= 250 ) {
$percent = -0.04;
$percent_text = ' 4%';
$has_discount =true;
}
// Calculation
$discount = $stotal_ext * $percent;
// Displayed text
$discount_text = __('Discount', 'woocommerce') . $percent_text;
if( $has_discount ) {
WC()->cart->add_fee( $discount_text, $discount, false );
}
// Last argument in add fee method enable tax on calculation if "true"
}
This goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and works.
Similar: WooCommerce - Conditional Progressive Discount based on number of items in cart
Reference: WooCommerce class - WC_Cart - add_fee() method

Cart discount for a product category based on quantity calculations

I wan to add a function to woocommerce that will calculate a 10% discount when 12-23 items from one category is added to the cart.
Then if 24 - 47 items of the category are added it would be a 15% discount.
Last if 48+ items from this category are added it would be a 20% discount.
actual code example would be awesome as I am new to woocommerce
Updated — Corrected code mistakes and added enhancements in the outputted discount text
Here is the function hooked in woocommerce_cart_calculate_fees hook that is going to make the discount for that particular category (or subcategory too) based on cart item quantity calculations.
This is the code:
add_action( 'woocommerce_cart_calculate_fees', 'cart_items_quantity_wine_discount', 10, 1 );
function cart_items_quantity_wine_discount($cart_object) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Set HERE your category (can be an ID, a slug or the name)
$category = 34; // or a slug: $category = 'wine';
$category_count = 0;
$category_total = 0;
$discount = 0;
// Iterating through each cart item
foreach($cart_object->get_cart() as $cart_item):
if( has_term( $category, 'product_cat', $cart_item['product_id']) ):
$category_count += $cart_item['quantity'];
$category_total += $cart_item["line_total"]; // calculated total items amount (quantity x price)
endif;
endforeach;
$discount_text = __( 'Quantity discount of ', 'woocommerce' );
// ## CALCULATIONS ##
if ( $category_count >= 12 && $category_count < 24 ) {
$discount -= $category_total * 0.1; // Discount of 10%
$discount_text_output = $discount_text . '10%';
} elseif ( $category_count >= 24 && $category_count < 48 ) {
$discount -= $category_total * 0.15; // Discount of 15%
$discount_text_output = $discount_text . '15%';
} elseif ( $category_count >= 48 ) {
$discount -= $category_total * 0.2; // Discount of 20%
$discount_text_output = $discount_text . '20%';
}
// Adding the discount
if ( $discount != 0 && $category_count >= 12 )
$cart_object->add_fee( $discount_text_output, $discount, false );
// Note: Last argument in add_fee() method is related to applying the tax or not to the discount (true or false)
}
Note: Last argument in add_fee() method is related to applying the tax or not to the discount…
Code is tested and fully functional.
Code goes in function.php file of your active child theme (or theme). Or also in any plugin php files.
Other similar: Discount for Certain Category Based on Total Number of Products

Categories