How to calculate savings total in Woocommerce - wordpress

UPD
Solved:
function wc_discount_total_30() {
global $woocommerce;
$discount_total = 0;
foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values) {
$_product = $values['data'];
if ( $_product->is_on_sale() ) {
$regular_price = $_product->get_regular_price();
$sale_price = $_product->get_sale_price();
$discount = ($regular_price - $sale_price) * $values['quantity'];
$discount_total += $discount;
}
}
if ( $woocommerce->cart->subtotal + $woocommerce->cart->shipping_total > $woocommerce->cart->total + $woocommerce->cart->shipping_total || $discount_total >0 ) {
echo '<tr class="cart-discount">
<th>'. __( 'Saved:', 'woocommerce' ) .'</th>
<td data-title=" '. __( 'Saved', 'woocommerce' ) .' ">'
. wc_price( $woocommerce->cart->subtotal - $woocommerce->cart->total + $woocommerce->cart->shipping_total + $discount_total ) .'</td>
</tr>';
}
}
// Hook our values to the Basket and Checkout pages
add_action( 'woocommerce_cart_totals_after_order_total', 'wc_discount_total_30', 99);
add_action( 'woocommerce_review_order_after_order_total', 'wc_discount_total_30', 99);
--------------------------------------------------------------------
ORIGINAL QUESTION:
I want to calculate and display «Total Savings» in Cart and Checkout page (Woocommerce). I've tried to use this code, but it only works if I have at least one discounted item in my cart:
function wc_discount_total_30() {
global $woocommerce;
$discount_total = 0;
foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values) {
$_product = $values['data'];
if ( $_product->is_on_sale() ) {
$regular_price = $_product->get_regular_price();
$sale_price = $_product->get_sale_price();
$discount = ($regular_price - $sale_price) * $values['quantity'];
$discount_total += $discount;
}
}
if ( $discount_total > 0 ) {
echo '<tr class="cart-discount">
<th>'. __( 'Saved', 'tsavedis' ) .'</th>
<td data-title=" '. __( 'Saved', 'tsavedis' ) .' ">'
. wc_price( $discount_total + $woocommerce->cart->discount_cart ) .'</td>
</tr>';
}
}
// Hook our values to the Basket and Checkout pages
add_action( 'woocommerce_cart_totals_after_order_total', 'wc_discount_total_30', 99);
add_action( 'woocommerce_review_order_after_order_total', 'wc_discount_total_30', 99);
But I need to calculate the discount amount considering the coupon and the amount of items in the cart (whether there are discounted items in the cart or not). Here is my code for displaying discount based on the number of items in shopping cart:
function woo_discount_total(WC_Cart $cart) {
$woo_count_item = $cart->get_cart_contents_count(); // Number of items in the shopping cart
if($woo_count_item >= 3 && $woo_count_item <= 4) {
$discount = $cart->subtotal * 0.10; // 0.10 — 10%
$cart->add_fee("10% discount for 3-4 items in the shopping cart", -$discount);
} elseif($woo_count_item >= 5 && $woo_count_item <= 100) {
$discount = $cart->subtotal * 0.20; // 0.20 — 20%
$cart->add_fee("20% discount for 5 and more items in the shopping cart", -$discount);
}
}
add_action("woocommerce_cart_calculate_fees" , "woo_discount_total");
What I want to display:
Cart Subtotal: $1000
Coupon: -$50
10% discount for 3 items in Cart: -$100
Order Total: $850
Saved: $150
I think the easiest way to do that is to subtract «order total» from «cart subtotal». Is there any way to do this?

Related

Reflect default price and strikethrough in mini cart item price in WooCommerce

Hello this code creates two discount classes, and then with a filter on the cart page it shows the regular price and the discounted price, how can I do to have the same visual result also on the mini cart??
this is what i am trying to achieve in the minicart
add_action( 'woocommerce_before_calculate_totals', 'bbloomer_quantity_based_pricing', 9999 );
function bbloomer_quantity_based_pricing( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) return;
// Define discount rules and thresholds
$threshold1 = 2; // Change price if items > 100
$discount1 = 0.05; // Reduce unit price by 5%
$threshold2 = 3; // Change price if items > 1000
$discount2 = 0.1; // Reduce unit price by 10%
// Loop through cart items
foreach ( $cart->get_cart() as $cart_item_key => $cart_item )
{
if( has_term( array('cartucce-inkjet'), 'product_cat', $cart_item['product_id'] ) ){
if ( $cart_item['quantity'] >= $threshold1 && $cart_item['quantity'] < $threshold2 )
{
$price = round( $cart_item['data']->get_price() * ( 1 - $discount1 ), 2 );
$cart_item['data']->set_price( $price );
}
elseif ( $cart_item['quantity'] >= $threshold2 )
{
$price = round( $cart_item['data']->get_price() * ( 1 - $discount2 ), 2 );
$cart_item['data']->set_price( $price );
}
}
}
}
function filter_woocommerce_cart_item_price( $price_html, $cart_item, $cart_item_key ) {
// Get the product object
$product = $cart_item['data'];
// Is a WC product
if ( is_a( $product, 'WC_Product' ) ) {
// Get reqular price
$regular_price = $product->get_regular_price();
// New price
$new_price = $cart_item['data']->get_price();
// NOT empty and NOT equal
if ( ! empty ( $regular_price ) && $regular_price != $new_price ) {
// Output
$price_html = '<del>' . wc_price( $regular_price ) . '</del> <ins>' . wc_price( $new_price ) . '</ins>';
}
}
return $price_html;
}
add_filter( 'woocommerce_cart_item_price', 'filter_woocommerce_cart_item_price', 10, 3 );

Discount for a specific product category in WooCommerce cart based on quantity and multiples

The discount I currently have essentially says
If 6 products within a specific category are in the cart --- discount the total price of $10
This piece of the code works fine. My issue is, this does not work
If there are 7 products, the 7th product being from a different category.
My goal is to give the discount no matter how many products are in the cart so long as there are 6 products within "Category A".
The following code works so long as there is 6 products in the "discounted category" or there is 1 product with a quantity of 6 etc. It falls apart when I add a product from another category. Feel free to rip it apart.
add_action( 'woocommerce_before_calculate_totals', 'this_item_free' );
function this_item_free() {
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
$valid_product_category_id = array('soup-mix');
$has_category = false;
$count = WC()->cart->get_cart_contents_count();
foreach ( WC()->cart->get_cart() as $product ) {
$quantity = $product['quantity'];
$price = $product['data']->get_price();
}
if ( has_term( $valid_product_category_id, 'product_cat', $product['product_id'],
$product['quantity'] ) ) {
$has_category = true;
$cart_total = floatval( preg_replace( '#[^\d.]#', '', WC()->cart->get_cart_total() ) );
if($count == 6 && $has_category = true){
add_action( 'woocommerce_cart_calculate_fees', 'discount_based_on_total', 25, 1 );
function discount_based_on_total( $cart ) {
$total = $cart->cart_contents_total;
$discount = 9.95;
$cart->add_fee( __('discount', 'woocommerce'), -$discount );
wc_add_notice( apply_filters( 'discount_applied', 'You just got a free soup!') );
}
}
}
}
Your code contains some unnecessary steps and what you want to achieve can be obtained with just the woocommerce_cart_calculate_fees action hook
My answer contains:
Give a discount no matter how many products are in the cart so long as there are 6 products or there is 1 product with a quantity of 6, etc.. within "Category A".
function action_woocommerce_cart_calculate_fees( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
/* SETTINGS */
// Specific categories
$specific_categories = array( 'Categorie-A' );
// Discount
$discount = 10;
// Min quantity
$minimun_quantity = 6;
/* END SETTINGS */
// Counter
$current_quantity = 0;
// Loop though each cart item
foreach ( $cart->get_cart() as $cart_item ) {
// Get product id
$product_id = $cart_item['product_id'];
// Has certain category
if ( has_term( $specific_categories, 'product_cat', $product_id ) ) {
// Quantity
$product_quantity = $cart_item['quantity'];
// Add to total
$current_quantity += $product_quantity;
}
}
// Greater than or equal to
if ( $current_quantity >= $minimun_quantity ) {
// Add fee
$cart->add_fee( __( 'Discount_applied', 'woocommerce' ), -$discount, false );
}
}
add_action( 'woocommerce_cart_calculate_fees', 'action_woocommerce_cart_calculate_fees', 10, 1 );
To apply the discount per 6 products (6 = $10, 12 = $20, 18 = $30, etc..)
Replace
// Greater than or equal to
if ( $current_quantity >= $minimun_quantity ) {
// Add fee
$cart->add_fee( __( 'Discount_applied', 'woocommerce' ), -$discount, false );
}
With
// Greater than or equal to
if ( $current_quantity >= $minimun_quantity ) {
// Modulo
$mod = $current_quantity % $minimun_quantity;
// Times it fit
$times = ( $current_quantity - $mod ) / $minimun_quantity;
// Discount * times
$discount = $discount * $times;
// Add fee
$cart->add_fee( __( 'Discount_applied', 'woocommerce' ), -$discount, false );
}

Add discount per certain number of products on the cheapest products in WooCommerce

I'm adding the discount rule for every 3 products: 3,6,9,12,15.. on the cart and it should apply to discount 50% only the cheapest products.
So if you have 9, only the 3 cheapest gets 50% off.
This code applies a discount to all products, so it should only be every 3 products
add_action('woocommerce_cart_calculate_fees', 'ts_add_custom_discount', 10, 1 );
function ts_add_custom_discount( $wc_cart ){
$discount = 0;
$product_ids = array();
$item_prices = array();
$in_cart = false;
foreach ( $wc_cart->get_cart() as $cart_item_key => $cart_item ) {
$cart_product = $cart_item['data'];
if ( has_term( 'get2', 'product_cat', $cart_product->get_id() ) ) { // get2 selected category
$in_cart = true;
}else {
$in_cart = true;
$product_ids[] = $cart_product->get_id();
$item_prices[$cart_product->get_id()] = $cart_product->get_price();
}
}
if( $in_cart ) {
$count_ids = count($product_ids);
asort( $item_prices ); //Sort the prices from lowest to highest
$cartQuantity = WC()->cart->cart_contents_count;
$count = 0;
if( $count_ids > 3 || $cartQuantity >= 3 ) {
foreach( $item_prices as $id => $price ) {
if( $count >= 1 ) {
break;
}
//$product = wc_get_product( $id );
//$price = $product->get_price();
$discount -= ($price * 50) /100;
$count++;
}
}
}
if( $discount != 0 ){
$wc_cart->add_fee( 'Discount', $discount, true );
}
}
I have attached a screenshot, you can see there is a red outline for every 3rd cheapest product.
This answer will apply a 50% discount per 3 products on the cheapest products. (explanation via comment tags added to the code)
So you get:
function action_woocommerce_cart_calculate_fees( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
// Products in cart
$products_in_cart = count( $cart->get_cart() );
// Every so many products
$every = 3;
// When products in cart greater than or equal to every so many products
if ( $products_in_cart >= $every ) {
// Set array
$product_prices = array();
// Loop though cart items
foreach ( $cart->get_cart() as $cart_item ) {
// Product
$product = $cart_item['data'];
// Get price
$product_price = $product->get_price();
// Push
$product_prices[] = $product_price;
}
// Sort: low to high
asort( $product_prices );
// Number of products receive a discount
$products_receive_discount = floor( $products_in_cart / $every );
// Set variable
$total = 0;
// Loop trough
foreach ( array_slice( $product_prices, 0, $products_receive_discount ) as $product_price ) {
// Calculate
$total += $product_price;
}
// Calculate discount
$discount = ( $total * 50 ) / 100;
// Discount
$cart->add_fee( __( 'Discount', 'woocommerce' ), -$discount, true );
}
}
add_action( 'woocommerce_cart_calculate_fees', 'action_woocommerce_cart_calculate_fees', 10, 1 );

Buy one get second 50% off for WooCommerce product variations

I wish to set up a specific discount on a particular variable products but for certain selected variations not for all variation:
eg : my varible id - 1571
variation id - 1572
variation id - 1573
So if customer buys one product they get the another (the same) on 50% discount (Buy one get another for 50% off).
I've tried many discount plugins and the closest that I have found are:
Pricing Deals for WooCommerce,
Conditional Discounts for WooCommerce
WooCommerce Extended Coupon Features FREE
With some of them, I was able to setup discount on subtotal or discount on a each product but not exactly what I am looking for (Buy 1 get 1 off). There are other pro plugins I don't want to go for it.
The nearest code that I found is WooCommerce discount: buy one get one 50% off with a notice.
Is it possible to make a discount on the 2nd item for specific product variations of a variable product (only for each product variation)?
mak
To get a 50% Off on the 2nd item for some specific product variations of a variable product, you will use the following instead:
add_action('woocommerce_cart_calculate_fees', 'add_custom_discount_2nd_at_50', 10, 1 );
function add_custom_discount_2nd_at_50( $cart ){
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// YOUR SETTINGS:
$product_variations_ids = array(1572, 1573); // <== HERE your targeted product variations
// Initializing variables
$discount = 0;
$product_names = array();
// Loop through cart items
foreach ( $cart->get_cart() as $key => $cart_item ) {
if ( in_array( $cart_item['variation_id'], $product_variations_ids ) ) {
$qty = (int) $cart_item['quantity'];
$price = (float) $cart_item['data']->get_price();
$name = (string) $cart_item['data']->get_name();
if ( $qty > 1 ) {
$discount -= number_format( $price / 2, 2 );
}
elseif( $qty = 1 ) {
$product_names[] = $name;
}
}
}
// Applying the discount
if( $discount != 0 ){
$cart->add_fee('Buy one get one 50% off', $discount );
}
// Display a custom reminder notice on cart page (otional)
if( ! empty($product_names) ){
wc_clear_notices(); // clear other notices on checkout page.
if( ! is_checkout() ){
wc_add_notice( sprintf(
__( "Add one more to get 50%% off on the 2nd item for %s" ),
'"<strong>' . implode(', ', $product_names) . '</strong>"'
), 'notice' );
}
}
}
Code goes in functions.php file of your active child theme (or active theme) Tested and works.
To get 1 item at 50% OFF for each item purchased, instead of 50% OFF on the 2nd item, replace:
$discount -= number_format( $price / 2, 2 );
by:
$multiplier = ( $qty % 2 ) === 0 ? $qty / 2 : ( $qty - 1 ) / 2;
$discount -= number_format( $price / 2 * $multiplier, 2 );
To get the 2nd one Free instead of 50% OFF on the 2nd item, replace the code line:
$discount -= number_format( $price / 2, 2 );
by:
$discount -= $price;
To get 1 item free for each item purchased, instead of 50% OFF on the 2nd item, replace:
$discount -= number_format( $price / 2, 2 );
by:
$multiplier = ( $qty % 2 ) === 0 ? $qty / 2 : ( $qty - 1 ) / 2;
$discount -= $price * $multiplier;
You were really close!
The discount amount calculation were wrong
add_action('woocommerce_cart_calculate_fees', 'add_custom_discount_2nd_at_50', 10, 1 );
function add_custom_discount_2nd_at_50( $wc_cart ){
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
$discount = 0;
$items_prices = array();
$qty_notice = 0; // <== Added HERE
// Set HERE your targeted variable product ID
$targeted_product_id = 1571 ;
foreach ( $wc_cart->get_cart() as $key => $cart_item ) {
if( $cart_item['product_id'] == $targeted_product_id ){
$qty = intval( $cart_item['quantity'] );
$qty_notice += intval( $cart_item['quantity'] ); // <== Added HERE
for( $i = 0; $i < $qty; $i++ )
$items_prices[] = floatval( $cart_item['data']->get_price());
}
}
$count_items_prices = count($items_prices);
//to get the discount of lowest price sorting in descending order
rsort($items_prices);
if( $count_items_prices > 1 ) foreach( $items_prices as $key => $price )
if( $key % 2 == 1 ) $discount -= number_format($price / 2, 2 );
if( $discount != 0 ){
// The discount
# Note: Last argument in add_fee() method is related to applying the tax or not to the discount (true or false)
$wc_cart->add_fee('50% off de segunda almohada' , (($price/2)*($discount))^⁻1, true ); //EDITED
// Displaying a custom notice (optional)
wc_clear_notices();
if(!is_checkout()){
wc_add_notice( __("Hurrah!! You got 50% off discount on the 2nd item"), 'notice');
}}
// Display a custom notice on cart page when quantity is equal to 1.
elseif( $qty_notice == 1){
wc_clear_notices();
if(!is_checkout()){
wc_add_notice( __( "Add one more to get 50% off on 2nd item" ), 'notice');
}}
}

Woocommerce Calculate amount by customer input in product page

In product page to get input from customer as number of words. To calculate the amount from products add-ons fixed amount to additional 10$ for each above 500 words.
ex: 1. Number of Words: 530
Normal Price + additional price: 180$ + 10$
Total: 190$
Number of Words: 1040
Normal Price + additional price: 180$ + 20$
Total: 200$
This process as to create dynamic input form customer to calculate amount the price and total amount.
`$extra_amount = (int)'10';
$amount = (int)'180'; // how to get amount from woocommerce data
if(isset($_POST['wordnumber'])){ // how to get this paramater form woocommerce post values
$test =$_POST['wordnumber'];
$original_amount = '';
if($test <= (int)'500'){
$original_amount = $amount;
}
elseif($test > (int)'500'){
$div_amount = $test/(int)'500';
$round = floor($div_amount);
//echo '<br/>';
$total_extra = $round*$extra_amount;
$original_amount = $amount+$total_extra;
}
echo $original_amount;
}`
I installed WC Fields Factory plugin then i got value from one field using key. in that i written a function and i overrided the price value.
function calculate_gift_wrap_fee( $cart_object ) {
/* Gift wrap price */
$additionalPrice = 10;
foreach ( $cart_object->cart_contents as $key => $value ) {
$test = $value['custom field'];
if( $test <= 100 ) {
$quantity = floatval( $value['quantity'] );
$orgPrice = floatval( $value['data']->price );
$value['data']->price = ( $orgPrice );
}
elseif( $test > 100 ) {
$div_amount = floatval($test/500);
$round = floor($div_amount);
$total_extra = floatval($round * $additionalPrice);
$quantity = floatval( $value['quantity'] );
$orgPrice = floatval( $value['data']->price );
$pp = ($value['price']);
$total = floatval($pp + $total_extra);
$value['data']->price = ( $orgPrice + $total );
}
}}
add_action( 'woocommerce_before_calculate_totals', calculate_gift_wrap_fee', 1, 1 );

Resources