Woocommerce - Extra fee based on product quantity - wordpress

I found this answer in a earlier post here (below), but I want to know of there is any way to add an extra fee based on quantity if the product quantity changes?
Lets say there is 100 items in one package. (the problem is also that there is not they same amount of item in all packages, some can be 100, some can be 150, 200, or 500)
Example:
1-99 = 1$.
100 = no fee.
101 - 199 1$
200 = no fee
201 - 299 = 1$ and so on..
Total will always be 1$ per product but the total can be more if they order several products that have these breaks. The total can be 4$ if there is 4 products with break-cost.
(Also, not sure where to put the code)
Thank you!
The code I found here: Add additional costs based on quantity in Woocommerce
// Hook before adding fees
add_action('woocommerce_cart_calculate_fees' , 'add_custom_fees');
/**
* Add custom fee on article specifics
* #param WC_Cart $cart
*/
function add_custom_fees( WC_Cart $cart ){
$fees = 0;
foreach( $cart->get_cart() as $item ){
// Check if odds and if it's the right item
if( $item[ 'quantity' ] % 2 == 1 && get_post_meta( $item[ 'product_id' ], 'custom_fee_for_supplier_name', true) ){
// You can also put a custom price in each produt with get_post_meta
$fees += 10;
}
}
if( $fees != 0 ){
// You can customize the descriptions here
$cart->add_fee( 'Custom fee (odds paquets)', $fees);
}
}

The woocommerce_after_cart_item_quantity_update fires right after a quantity is updated. If you modify your function a little bit (to use WC()->cart to access the cart object) you can run the same function on both hooks. I thought it might keep adding additional fees, but in my testing it seems to just recalculate the right cost for the same fee.
add_action('woocommerce_cart_calculate_fees' , 'add_custom_fees');
add_action( 'woocommerce_after_cart_item_quantity_update', 'add_custom_fees' );
/**
* Add custom fee on article specifics
* #param WC_Cart $cart
*/
function add_custom_fees(){
$fees = 0;
foreach( WC()->cart->get_cart() as $item ){
// Check if odds and if it's the right item
if( $item[ 'quantity' ] % 2 == 1 && get_post_meta( $item[ 'product_id' ], '_custom_fee_for_odds', true ) ){
// You can also put a custom price in each produt with get_post_meta
$fees += 10;
}
}
if( $fees > 0 ){
// You can customize the descriptions here
WC()->cart->add_fee( 'Custom fee (odds paquets)', $fees);
}
}

Related

Update cart fee on shipping method change in WooCommerce

I need a way to offer shipping discount up to a maximum of $25. I'm using the Fee API to do this since there are no coupon codes for shipping. Here's my code:
add_action( 'woocommerce_cart_calculate_fees', 'conditional_shipping_discount' );
function conditional_shipping_discount() {
$max_shipping_discount = 25;
$cart_subtotal = WC()->cart->subtotal;
$current_shipping_method = WC()->session->get( 'chosen_shipping_methods' );
$current_shipping_method_cost = WC()->session->get('cart_totals')['shipping_total'];
// If our cart is > $99 AND shipping is not already free
if ( ($cart_subtotal >= 99) && ($current_shipping_method_cost > 0) ) {
// Calculate 25% of cart subtotal
$calculated_shipping_discount = $cart_subtotal * 0.25;
// $shipping_discount = lowest value
$shipping_discount = min( $current_shipping_method_cost, $calculated_shipping_discount, $max_shipping_discount );
WC()->cart->add_fee( 'Shipping Discount', -1 * abs($shipping_discount) );
}
}
This works great for the most part, except when the customer selects a different shipping method. The fee only shows the previously selected shipping discount. This GIF shows what I mean:
The fee is corrected when the page is reloaded, or when the update_checkout event is triggered by changing item quantities or updating the checkout fields.
How can I have the cart fee (shipping discount) to update immediately when the shipping method is selected? Thank you in advance.
As I am checking your function, we always got previous shipping costs if I switch/change shipping methods. there is only one issue with $current_shipping_method_cost.
So if you change 1 line
$current_shipping_method_cost = WC()->session->get('cart_totals')['shipping_total'];
to
$current_shipping_method_cost = WC()->cart->get_shipping_total();
You always getting current/active shipping costs.
full code is :
add_action( 'woocommerce_cart_calculate_fees', 'conditional_shipping_discount' );
function conditional_shipping_discount() {
$max_shipping_discount = 25;
$cart_subtotal = WC()->cart->subtotal;
//$current_shipping_method = WC()->session->get( 'chosen_shipping_methods' );
$current_shipping_method_cost = WC()->cart->get_shipping_total();
// If our cart is > $99 AND shipping is not already free
if ( ($cart_subtotal >= 99) && ($current_shipping_method_cost > 0) )
{
// Calculate 25% of cart subtotal
$calculated_shipping_discount = $cart_subtotal * 0.25;
// $shipping_discount = lowest value
$shipping_discount = min( $current_shipping_method_cost, $calculated_shipping_discount, $max_shipping_discount );
WC()->cart->add_fee( 'Shipping Discount', -1 * abs($shipping_discount) );
}
}

exclude a category from woocommerce discount

The following working code is a discount for cart with minimum 3 items not including 'sale' products Now I need to ignore categoty 'gift' (if it is in the cart) from this discount:
//10% discount at minimum 3 items in cart not for sale items
add_action('woocommerce_cart_calculate_fees' , 'custom_cart_discount', 20, 1);
function custom_cart_discount( $cart ){
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Limitations: Only when there is 5 or more non on sale items in cart
$starting_limit = 3;
// Initialising variables
$not_on_sale_subtotal = $discount = $items_count = 0;
// Iterating through each item in cart
foreach( $cart->get_cart() as $cart_item ){
// For cart items is not on sale
if( ! $cart_item['data']->is_on_sale() ){
$not_on_sale_subtotal += (float) $cart_item['line_subtotal'];
$items_count += $cart_item['quantity'];
}
}
// Discount calculation
$discount = $not_on_sale_subtotal * 0.1;
// Applied discount only cart items that are not on sale
if( $discount && $items_count >= $starting_limit )
$cart->add_fee( 'הנחת כמות 10%', -$discount );
I would recommend to work with a different approach. WooCommerce Coupons gives you a full control for what you want to achieve.
First, create a coupon in WC admin, with the 10% discount. Then, use the coupon settings to apply it on the cart or just on specific items/categories. You can see in the coupon limitations how exactly to limit the discount to specific categories (with include / exclude ), or to apply the discount only on items that are not on sale etc...
Finally, all you have to do, is just to ask or encourage the customer to apply the coupon, or automatically apply it yourself behind the scenes with:
WC()->cart->apply_coupon('YouCouponCodeGoesHere');
בהצלחה!

woocommerce calculate line total and cart totals

As you can see in the image, I have a cart that has two products.
Each of the products has some addons.
The "addon#1" costs 20chf.
If a customer chooses 3 "test product 1" products and adds 2 "addon#1" addons,
I want to calculate first the quantity and then to add the cost of the addons.
For example, in the image, for the first item in the cart, 120 * 3 = 360 and then 2 addons * 20 = 40,
I want in Total to have 400.
I tried some actions like woocommerce_after_calculate_totals,
woocommerce_cart_item_subtotal,
woocommerce_cart_product_subtotal but even if I got the results I want, the total cost of the cart is not the right, it doesn't include the addons.
function add_addons_to_total_price( $product_subtotal, $product, $quantity, $cart ) {
$subtotal_product_price = 0;
$product_price = $product->get_price();
$subtotal_product_price = $product_price * $quantity;
foreach( $cart->get_cart() as $key=>$value ) {
if( isset( $value['total_addons_price'] ) ) {
$subtotal_product_price += $value['total_addons_price'];
}
}
return ($subtotal_product_price) ? wc_price($subtotal_product_price) : $product_subtotal;
}
add_filter( 'woocommerce_cart_product_subtotal', 'add_addons_to_total_price', 10, 4 );
Do you have any ideas on how to change the total cost of each item in cart and update the total cost of the cart?

Woocommerce: Update price in some of the products in the cart

For a client, I need to let backorders for products but they don't want to charge for those. So, I need to update the price dynamically if they stock is 0 or the stock is less than the quantity on the cart.
This is my code:
add_filter( 'woocommerce_cart_product_subtotal', 'modify_cart_product_subtotal', 10, 4 );
function modify_cart_product_subtotal( $product_subtotal, $product, $quantity, $cart ) {
if ( $product->get_stock_quantity() < $quantity ) {
return $product->get_stock_quantity() * $product->get_price();
}
return $product_subtotal;
}
In case of 0 stock, it works like a charm. In case of a quantity greater than the stock, it charges only for the available products, but the tax keeps increasing even for the rest. How can I exclude those from taxes calculations as well?
EDIT:
If I just update the price of the product, it does it for all of them, not only those above the available stock.
function zero_price_for_backorders( $cart_object ) {
global $isProcessed;
if( !WC()->session->__isset( "reload_checkout" )) {
foreach ( $cart_object->get_cart() as $key => $value ) {
if ( $value['data']->get_stock_quantity() < $value['quantity']) {
$value['data']->set_price(0);
}
}
$isProcessed = true;
}
}
add_action( 'woocommerce_before_calculate_totals', 'zero_price_for_backorders', 99 );
You should use before_calculate_total and change product price using set_price function so that you don't have to modify subtotal separately. The rest of the flow will fall in place automatically.
You can have a look at this link on how to change it dynamically:
Change product price dynamically woocommerce

Shipping Rates based on Product Quantity on woocommerce

I want to set shipping cost quantity wise on my woocommerce theme. I want to do this option :
For 1 to 5 products shiping cost will be 15%.
More than 5 products whipping cost will be $6.99 .
Can i add this shipping option without a plugin ?
You need to hook a function to woocommerce_calculate_totals action which is triggered right before calculating the final cart total. The woocommerce_calculate_totals action provides the WC_Cart instance, on which you can perform manipulation as per your requirement.
add_action('woocommerce_calculate_totals', 'modify_shipping_totals');
function modify_shipping_totals($cart) {
if($cart->get_cart_contents_count() < 6) {
$cart->shipping_total = ( 15/100 ) * $this->cart_contents_total;
// shipping cost will be 15% of cart content total
// you may also want to modify the shipping tax.
$cart->shipping_tax_total = 0;
} else {
$cart->shipping_total = 6.99;
$cart->shipping_tax_total = 0;
}
}
For further reference regarding changable variables refer to WC_Cart documentation.
// **Note**: This code is working only when you set Flat rate Settings
// cost value is 1
add_filter( 'woocommerce_package_rates', 'custom_package_rates', 10, 2 );
function custom_package_rates( $rates, $packages ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
$cart_count = WC()->cart->get_cart_contents_count();
$cart_total = WC()->cart->cart_contents_total;
foreach($rates as $rate_key => $rate_values ) {
$method_id = $rate_values->method_id;
$rate_id = $rate_values->id;
if( $method_id == 'flat_rate' ){
if( $cart_count < 99 ){
$flat_rate_value = 4.95; //"Applay Flat rate less then 99 quatity"
$cart_10_percent = 0; // No percent discount
}
if( $cart_count > 99 ){
$flat_rate_value = 9.95; // "Applay Flat rate greater then 99 quatity"
$cart_10_percent = 0; // No percent discount
}
$rate_cost = $flat_rate_value > $cart_10_percent ? $flat_rate_value - $cart_10_percent : 0;
// Set the new calculated rate cost
$rates[$rate_id]->cost = number_format( $rates[$rate_id]->cost * $rate_cost, 2 );
}
}
return $rates;
}
The Pranav solution works if you call the add_action inside the init hook, like this:
function init_shop(){
add_action('woocommerce_calculate_totals', 'modify_shipping_totals', 10);
}
add_action( 'init', 'init_shop');

Resources