WooCommerce Cart Quantity Base Discount dispaly also in mini-cart(.php) - wordpress

Related to: WooCommerce Cart Quantity Base Discount
In WooCommerce, how do I set a cart discount based on the total number of items in the cart?
## Tested and works on WooCommerce 2.6.x and 3.0+
add_action( 'woocommerce_cart_calculate_fees','wc_cart_quantity_discount', 10, 1 );
function wc_cart_quantity_discount( $cart_object ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
## -------------- DEFINIG VARIABLES ------------- ##
$discount = 0;
$cart_item_count = $cart_object->get_cart_contents_count();
$cart_total_excl_tax = $cart_object->subtotal_ex_tax;
## ----------- CONDITIONAL PERCENTAGE ----------- ##
if( $cart_item_count <= 4 )
$percent = 0;
elseif( $cart_item_count >= 5 && $cart_item_count <= 10 )
$percent = 5;
elseif( $cart_item_count > 10 && $cart_item_count <= 15 )
$percent = 10;
elseif( $cart_item_count > 15 && $cart_item_count <= 20 )
$percent = 15;
elseif( $cart_item_count > 20 && $cart_item_count <= 25 )
$percent = 20;
elseif( $cart_item_count > 25 )
$percent = 25;
## ------------------ CALCULATION ---------------- ##
$discount -= ($cart_total_excl_tax / 100) * $percent;
## ---- APPLYING CALCULATED DISCOUNT TAXABLE ---- ##
if( $percent > 0 )
$cart_object->add_fee( __( "Quantity discount $percent%", "woocommerce" ), $discount, true);
}
Is good for cart page, it's ok!
QUESTION:
It is possible to integrate this function so that the discounted subtotal is also visible in the mini-cart,
as form:
....->add_fee( __( "Quantity discount $percent%", "woocommerce" ), $discount, true);
Thanks in advance.
Dom

Related

round cart total in woocommerce

Round cart total if cart total is 31.47 then print 31 and if total is 31.50 or 31.51 more print total is 32 then how to achieve in woocommerce?
I tried this code :
function kncctr_custom_roundoff( $total ) {
$round_num = round($total / 0.05) * 0.05;
$total = number_format($round_num, 2);
// this is required for showing zero in the last decimal
return $total;
}
You can try this code for round cart total
add_filter( 'woocommerce_calculated_total', 'ak_calculated_total' );
function ak_calculated_total( $total ) {
$total = round( $total, 1 );
return ceil($total);
}

Woocommerce Min/Max, Default QTY and Quantity Step

I am trying to set the following for all products:
Min Qty 6
Max QTY 240
Quantity Step 6
Input Value 6
But all pulls through except the Default Input Value (product and Cart page)
Herewith the code
/**
* Adjust the quantity input values
*/
add_filter( 'woocommerce_quantity_input_args', 'jk_woocommerce_quantity_input_args', 10, 2 ); // Simple products
function jk_woocommerce_quantity_input_args( $args, $product ) {
if ( is_singular( 'product' ) ) {
$args['input_value'] = 6;
}
$args['max_value'] = 240; // Maximum value
$args['min_value'] = 6; // Minimum value
$args['step'] = 6; // Quantity steps
return $args;
}
add_filter( 'woocommerce_available_variation', 'jk_woocommerce_available_variation' ); // Variations
function jk_woocommerce_available_variation( $args ) {
$args['max_qty'] = 240; // Maximum value (variations)
$args['min_qty'] = 6; // Minimum value (variations)
return $args;
}

Shipping class formula help: If quantity is 1-3, charge X amount?

I am selling prints in my store. I print them and ship them off in tubes. Each tube can hold up to three prints and the cost to send one tube is X amount.
How can I write:
If quantity is 1-3, charge X…
If the quantity is 4-6, charge 2X…
If the quantity is 7-9, charge 3X…
Etc, etc.?
Or is there a better way?
You can use
woocommerce_package_rates
hook to manipulate the shipping costs.
function woocommerce_package_rates( $rates ) {
//Assuming charge X you mentioned is 5
$custom_shipping_cost = 5;
$total_items = WC()->cart->get_cart_contents_count();
if($total_items > 3 && $total_items < 7) $custom_shipping_cost *= 2;
else if ($total_items > 6 && $total_items < 10) $custom_shipping_cost *= 3;
else if ($total_items > 9 && $total_items < 13) $custom_shipping_cost *= 4;
//you may add more else if statements here
//or try this which is smarter I believe:
/*
* $multiplier = floor( $total_items / 4 ) + 1;
* $custom_shipping_cost *= $multiplier;
*/
foreach($rates as $key => $rate )
{
$rates[$key]->cost = $custom_shipping_cost;
}
return $rates;
}
add_filter( 'woocommerce_package_rates', 'woocommerce_package_rates' );
Hope this helps. Code goes to functions.php of your theme or child-theme (which is better).

WooCommerce - Multiple cart dicounts

I want a cart discount based on the total
5% over $600 order and 10% over $1000?
I can get it to work for the over $600 but not the over $1000. I get an error on line 15.
add_action( 'woocommerce_before_cart', 'apply_matched_coupons' );
function apply_matched_coupons() {
global $woocommerce;
$coupon_code = 'over600'; // your coupon code here
$coupon_codeb = 'over1000'; // your coupon code here
if ( $woocommerce->cart->has_discount( $coupon_code ) ) return;
if ( $woocommerce->cart->cart_contents_total >= 600 ) {
$woocommerce->cart->add_discount( $coupon_code );
$woocommerce->show_messages();
}
if ( $woocommerce->cart->cart_contents_total >= 1000 ) {
$woocommerce->cart->add_discount( $coupon_codeb );
$woocommerce->show_messages();
}
}
Ended up doing it a completely different way
function nh_custom_coupon_filter() {
global $woocommerce;
$excluded_amount = $discount_percent = 0;
$working_total = $woocommerce->cart->cart_contents_total;
$excluded_categories = array(
217, # Training
223, # Starter Kits
);
# Only apply manual discount if no coupons are applied
if (!$woocommerce->cart->applied_coupons) {
# Find any items in cart that belong to the restricted categories
foreach ($woocommerce->cart->cart_contents as $item) {
$product_categories = get_the_terms($item['product_id'], 'product_cat');
if (empty($product_categories) || is_wp_error($product_categories) || !$product_categories) {
if (is_wp_error($product_categories)) {
wp_die($product_categories->get_error_message());
}
else {
$product_categories = new WP_Error('no_product_categories', "The product \"".$item->post_title."\" doesn't have any categories attached, thus no discounts can be calculated.", "Fatal Error");
wp_die($product_categories);
}
}
foreach ($excluded_categories as $excluded_category) {
foreach ($product_categories as $category) {
if ($excluded_category == $category->term_id) {
$excluded_amount += $item['line_subtotal']; # Increase our exclusion amount
$working_total -= $item['line_subtotal']; # Decrease our discountable amount
}
}
}
}
# Logic to determine WHICH discount to apply based on subtotal
if ($working_total >= 600 && $working_total < 1000) {
$discount_percent = 5;
}
elseif ($working_total >= 1000) {
$discount_percent = 10;
}
else {
$discount_percent = 0;
}
# Make sure cart total is eligible for discount
if ($discount_percent > 0) {
$discount_amount = ( ( ($discount_percent/100) * $working_total ) * -1 );
$woocommerce->cart->add_fee('Bulk Discount', $discount_amount);
}
}
}
add_action('woocommerce_cart_calculate_fees', 'nh_custom_coupon_filter');

Calculate percentage saved between two numbers?

I have two numbers, the first, is the original price, the second, is the discounted price.
I need to work out what percentage a user saves if they purchase at the second price.
example
25, 10 = 60%
365, 165 = 55%
What I dont know is the formula to calculate this.
I know this is fairly old but I figured this was as good as any to put this. I found a post from yahoo with a good explanation:
Let's say you have two numbers, 40 and 30.
30/40*100 = 75.
So 30 is 75% of 40.
40/30*100 = 133.
So 40 is 133% of 30.
The percentage increase from 30 to 40 is:
(40-30)/30 * 100 = 33%
The percentage decrease from 40 to 30 is:
(40-30)/40 * 100 = 25%.
These calculations hold true whatever your two numbers.
Original Post
((list price - actual price) / (list price)) * 100%
For example:
((25 - 10) / 25) * 100% = 60%
I see that this is a very old question, but this is how I calculate the percentage difference between 2 numbers:
(1 - (oldNumber / newNumber)) * 100
So, the percentage difference from 30 to 40 is:
(1 - (30/40)) * 100 = +25% (meaning, increase by 25%)
The percentage difference from 40 to 30 is:
(1 - (40/30)) * 100 = -33.33% (meaning, decrease by 33%)
In php, I use a function like this:
function calculatePercentage($oldFigure, $newFigure) {
if (($oldFigure != 0) && ($newFigure != 0)) {
$percentChange = (1 - $oldFigure / $newFigure) * 100;
}
else {
$percentChange = null;
}
return $percentChange;
}
The formula would be (original - discounted)/original. i.e. (365-165)/365 = 0.5479...
function calculatePercentage($oldFigure, $newFigure)
{
$percentChange = (($oldFigure - $newFigure) / $oldFigure) * 100;
return round(abs($percentChange));
}
100% - discounted price / full price
If total no is: 200
and getting 50 number
then take percentage of 50 in 200 is:
(50/200)*100 = 25%
I have done the same percentage calculator for one of my app where we need to show the percentage saved if you choose a "Yearly Plan" over the "Monthly Plan". It helps you to save a specific amount of money in the given period. I have used it for the subscriptions.
Monthly paid for a year - 2028
Yearly paid one time - 1699
1699 is a 16.22% decrease of 2028.
Formula: Percentage of decrease = |2028 - 1699|/2028 = 329/2028 = 0.1622
= 16.22%
Code:
func calculatePercentage(monthly: Double, yearly: Double) -> Double {
let totalMonthlyInYear = monthly * 12
let result = ((totalMonthlyInYear-yearly)/totalMonthlyInYear)*100
print("percentage is -",result)
return result.rounded(toPlaces: 0)
}
Usage:
let savingsPercentage = self.calculatePercentage(monthly: Double( monthlyProduct.price), yearly: Double(annualProduct.price))
self.btnPlanDiscount.setTitle("Save \(Int(savingsPercentage))%",for: .normal)
The extension usage for rounding up the percentage over the Double:
extension Double {
/// Rounds the double to decimal places value
func rounded(toPlaces places:Int) -> Double {
let divisor = pow(10.0, Double(places))
return (self * divisor).rounded() / divisor
}
}
I have attached the image for understanding the same:
This is function with inverted option
It will return:
'change' - string that you can use for css class in your template
'result' - plain result
'formatted' - formatted result
function getPercentageChange( $oldNumber , $newNumber , $format = true , $invert = false ){
$value = $newNumber - $oldNumber;
$change = '';
$sign = '';
$result = 0.00;
if ( $invert ) {
if ( $value > 0 ) {
// going UP
$change = 'up';
$sign = '+';
if ( $oldNumber > 0 ) {
$result = ($newNumber / $oldNumber) * 100;
} else {
$result = 100.00;
}
}elseif ( $value < 0 ) {
// going DOWN
$change = 'down';
//$value = abs($value);
$result = ($oldNumber / $newNumber) * 100;
$result = abs($result);
$sign = '-';
}else {
// no changes
}
}else{
if ( $newNumber > $oldNumber ) {
// increase
$change = 'up';
if ( $oldNumber > 0 ) {
$result = ( ( $newNumber / $oldNumber ) - 1 )* 100;
}else{
$result = 100.00;
}
$sign = '+';
}elseif ( $oldNumber > $newNumber ) {
// decrease
$change = 'down';
if ( $oldNumber > 0 ) {
$result = ( ( $newNumber / $oldNumber ) - 1 )* 100;
} else {
$result = 100.00;
}
$sign = '-';
}else{
// no change
}
$result = abs($result);
}
$result_formatted = number_format($result, 2);
if ( $invert ) {
if ( $change == 'up' ) {
$change = 'down';
}elseif ( $change == 'down' ) {
$change = 'up';
}else{
//
}
if ( $sign == '+' ) {
$sign = '-';
}elseif ( $sign == '-' ) {
$sign = '+';
}else{
//
}
}
if ( $format ) {
$formatted = '<span class="going '.$change.'">'.$sign.''.$result_formatted.' %</span>';
} else{
$formatted = $result_formatted;
}
return array( 'change' => $change , 'result' => $result , 'formatted' => $formatted );
}
I think this covers this formula sufficiently,
((curr value - base value) / (curr value)) * 100%
Basically we just (in programming):
perform the calculation if both numbers are not 0.
If curr value is 0 then we return -100 % difference from the base,
if both are 0 then return 0 (we can't divide by 0)
Powershell example:
Strip any non numeric from vars and perform calculation
Function Get-PercentageSaved {
#((curr value - base value) / (curr value)) * 100%
param(
[Parameter(Mandatory = $false)][string]$CurrVal = $null,
[Parameter(Mandatory = $false)][string]$BaseVal = $null
)
$Result = $null
Try {
$CurrVal = [float]($CurrVal -replace '[^0-9.]', '')
$BaseVal = [float]($BaseVal -replace '[^0-9.]', '')
if (-Not($null -eq $CurrVal) -And (-Not($null -eq $BaseVal))) {
if ($CurrVal -eq 0) {
If ($BaseVal -eq 0) {
$Result = 0
} Else {
$Result = -100
}
}
else {
$Result = [math]::Round([float]((($CurrVal - $BaseVal) / $CurrVal) * 100),2)
}
}
}
Catch {}
Return [float]$Result
}

Resources