Discount for Certain Category Based on Total Number of Products

Discount for Certain Category Based on Total Number of Products

UpdateAdded Woocommerce 3 compatibility.

Here is something that should be convenient to your requirements.

This function will add discount to cart:

add_action( 'woocommerce_cart_calculate_fees','custom_cart_discount', 20, 1 );
function custom_cart_discount( $cart ) {

if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;

// Define HERE your targeted product category (id, slug or name are accepted)
$category = 'posters';
// Set the price for Five HERE
$price_x5 = 5;

// initializing variables
$calculated_qty = 0;
$calculated_total = 0;
$discount = 0;

// Iterating through each cart item
foreach($cart->get_cart() as $cart_item):

// Make this discount calculations only for products of your targeted category
if(has_term($category, 'product_cat', $cart_item['product_id'])):
$item_price = version_compare( WC_VERSION, '3.0', '<' ) ? $cart_item['data']->price : $cart_item['data']->get_price(); // The price for one (assuming that there is always 2.99)
$item_qty = $cart_item["quantity"];// Quantity
$item_line_total = $cart_item["line_total"]; // Item total price (price x quantity)
$calculated_qty += $item_qty; // ctotal number of items in cart
$calculated_total += $item_line_total; // calculated total items amount
endif;
endforeach;

// ## CALCULATIONS (updated) ##
if($calculated_qty >= 5):
for($j = 5, $k=0; $j <= $calculated_qty; $j+=5,$k++); // Update $k=0 (instead of $k=1)
$qty_modulo = $calculated_qty % 5;
$calculation = ( $k * $price_x5 ) + ($qty_modulo * $item_price);
$discount -= $calculated_total - $calculation;
endif;

// Adding the discount
if ($discount != 0)
$cart->add_fee( __( 'Quantity discount', 'woocommerce' ), $discount, false );
// Note: Last argument in add_fee() method is related to applying the tax or not to the discount (true or false)
}

Code goes in function.php file of your active child theme (or active theme). Tested and works.

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

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 );
}

Adding a discount by cart items conditionally based on the item quantity

This code will not work in Woocommerce 3+

See: Cart item discount based on quantity in Woocommerce 3:

Yes this is also possible, making a custom calculation for each cart item and replacing individually their price (matching your conditions and calculations), using a custom function hooked in woocommerce_before_calculate_totals action hook.

This is the code:

add_action( 'woocommerce_before_calculate_totals', 'custom_discounted_cart_item_price', 10, 1 );
function custom_discounted_cart_item_price( $cart_object ) {

$discount_applied = false;

// Set Here your targeted quantity discount
$t_qty = 12;

// Iterating through each item in cart
foreach ( $cart_object->get_cart() as $item_values ) {

## Get cart item data
$item_id = $item_values['data']->id; // Product ID
$item_qty = $item_values['quantity']; // Item quantity
$original_price = $item_values['data']->price; // Product original price

// Getting the object
$product = new WC_Product( $item_id );

// CALCULATION FOR EACH ITEM
// when quantity is up to the targetted quantity and product is not on sale
if( $item_qty >= $t_qty && !$product->is_on_sale() ){
for($j = $t_qty, $loops = 0; $j <= $item_qty; $j += $t_qty, $loops++);

$modulo_qty = $item_qty % $t_qty; // The remaining non discounted items

$item_discounted_price = $original_price * 0.9; // Discount of 10 percent

$total_discounted_items_price = $loops * $t_qty * $item_discounted_price;

$total_normal_items_price = $modulo_qty * $original_price;

// Calculating the new item price
$new_item_price = ($total_discounted_items_price + $total_normal_items_price) / $item_qty;

// Setting the new price item
$item_values['data']->price = $new_item_price;

$discount_applied = true;
}
}
// Optionally display a message for that discount
if ( $discount_applied )
wc_add_notice( __( 'A quantity discount has been applied on some cart items.', 'my_theme_slug' ), 'success' );
}

This make exactly the discount that you are expecting separately for each item in cart (based on it's quantity) and not for items that are in sale. But you will not get any label (text) indicating a discount in the line items of cart.

Optionally I display a notice when a discount is applied to some cart items…

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.

Discount based on cart items count and product categories

As product categories are a custom taxonomy 'product_cat' you will need to use has_term() conditional function (instead of has_category()) this way:

add_action('woocommerce_cart_calculate_fees' , 'my_custom_discount', 10, 1);
function my_custom_discount( $cart_obj ){

if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;

// Only when there is 4 or more items in cart
if ( $cart_obj->get_cart_contents_count() > 3):

// Set HERE your array of categories (slugs, IDs or names) <== <== <== <== <==
$categories = array('mycategory1','mycategory2');

// Initialising variable
$has_category = false;

// Iterating through each item in cart
foreach( $cart_obj->get_cart() as $cart_item ){
// The product ID
$product_id = $cart_item['product_id'];

// When a cart item is from one defined product categories we set $has_category to true.
if ( has_term( $categories, 'product_cat', $product_id ) ) {
$has_category = true;
break;
}
}

## Discount calculation ##
$discount = $cart_obj->subtotal * -0.03;

## Applied discount (for products (items) of defined product categories) ##
if( $has_category )
$cart_obj->add_fee( '3% discount', $discount);

endif;
}

This 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 for WooCommerce version 2.6+ and 3.0+

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

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:

  1. Coupon settings (Set correctly your coupon code):

    • Discount type: Percentage
    • Amount: 10
    • Restrictions > Product categories (names displayed): "Hoodies" and "T shirts"
      Sample Image
    • You can have other settings if you need
  2. 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):

Sample Image

Sample Image

  • 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!

how to calculate discount based on category of products on shopping cart page in opencart?

It can be achieved as following.
we can sort all the products based on there category and can then apply any discount easily..

First you should sort all paroducts ---

////////////// Grouping Same category products into one array //////////////

$category_id = $this->model_discount_cdiscount->getcategory($product['product_id']);

$array_key = $category_id[0]['category_id'];

if (array_key_exists($array_key, $this->data['discount']))
{

$this->data['discount'][$array_key]['total'] = $this->data['discount'][$array_key]['total']+(preg_replace("/[^0-9.]/","",$total));
$this->data['discount'][$array_key]['quantity'] = $this->data['discount'][$array_key]['quantity']+$product['quantity'];
}
else
{
$this->data['discount'][$array_key] = array(
'category_name' => $category_id[0]['name'],
'category_id' => $array_key,
'total' => (preg_replace("/[^0-9.]/","",$total)),
'quantity' => $product['quantity'],
'length' => $product['length']
);
}

and then can apply ---

////////////////////// Get Discount values from Discount table //////////////////////

foreach($this->data['discount'] as $key2 => $value2)
{
$this->data['product_match'][] = $this->model_discount_cdiscount->matchDiscount($key2);
}

////////////////////// Calculate Discount //////////////////////
$total_d =0;
foreach($this->data['discount'] as $discounts)
{
foreach($this->data['product_match'] as $match)
{
if(count($match)!=0)
{
if ($discounts['category_id']==$match['category'] AND $discounts['quantity']>=$match['quantity'] AND $discounts['length']==$match['class_value'])
{

$dt = ($match['discount']/100)*$discounts['total'];
$total_d += $dt;
}
}
}

}


Related Topics



Leave a reply



Submit