1

I want to discount a specific product during checkout based on quantity thresholds:

  • When product >= 10 units ----- discount 2 dollars per unit
  • When product >= 20 units ----- discount 3 dollars per unit

Sample Desired Output example:

  • Product × 10 is equal to $730.00 | Discount is $20.00 | Total after discount: $710.00
  • Product × 20 is equal to $1460.00 | Discount is $60.00 | Total after discount: $1400.00 $1,400.00

so far I have this, but when I add 10 units of the product to cart I get a critical error.

My code:

add_action( 'woocommerce_before_calculate_totals', 'quantity_based_pricing', 9999 );
    function 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 = 10; // Change price if items > 10
        $discount1 = 0.02739726027; // Reduce 73 dollar unit price by 2 dollars
        $threshold2 = 20; // Change price if items > 20
        $discount2 = 0.04109589041; // Reduce 73 dollar unit price by 3 dollars
          //compare
        foreach ( $cart->get_cart() as $cart_item_key => $cart_item )
          // Get product id
          $product_id = $cart_item['product_id'];
    
            if ( $cart_item['quantity'] >= $threshold1 && $cart_item['quantity'] < $threshold2 && $cart_item = '283' ) {
             $price = round( $cart_item['data']->get_price() * ( 1 - $discount1 ), 2 );
             $cart_item['data']->set_price( $price );
          } elseif ( $cart_item['quantity'] >= $threshold2 && in_array( $product_id, $specific_product_ids ) ) {
             $price = round( $cart_item['data']->get_price() * ( 1 - $discount2 ), 2 );
             $cart_item['data']->set_price( $price );
          }
        }

What am I doing wrong? How to make that work without errors?

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
nichlor
  • 15
  • 4

1 Answers1

1

There are some mistakes in your code. Try the following instead:

function quantity_based_pricing_discount( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
        return;

    // Define discount rules and thresholds
    $threshold1 = 10; // Change price if items > 10
    $threshold2 = 20; // Change price if items > 20
    $discount_1 = 2; // Reduce unit price by 2 dollars
    $discount_2 = 3; // Reduce unit price by 3 dollars

    // Loop through cart items
    foreach ( $cart->get_cart() as $cart_item ) {
        // Targeting specific product id
        if( $cart_item['product_id'] == '283' ) {
            $price = $cart_item['data']->get_price();
            $qty   = $cart_item['quantity'];

            if ( $qty >= $threshold1 && $qty < $threshold2 ) {
                $discount = $discount_1;
            } elseif ( $qty >= $threshold2 ) {
                $discount = $discount_2;
            }

            if ( isset($discount) ) {
                $cart_item['data']->set_price( round( $price - $discount, 2 ) );
            }
        }
    }
}

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

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • ahh the discount was for a product that costs 73 dollars. The value was a % that was equivalent to the amount I needed. I just tried this method. Something was not right. The product price became discount price. 10 * 73 dollar product became 20 dollars. 20 is right number but should be discount, not the items price. it made subtotal 20. I should edit op for clarification. – nichlor Oct 15 '20 at 03:19
  • Output: TOTAL Product × 10 $20.00 Subtotal $20.00 Total $20.00 Desired Output: Product × 10 $730.00 Discount - $20.00 Total - $710.00 – nichlor Oct 15 '20 at 03:31
  • Yes Perfect! I had to make an adjustment to the $discount_1 & $discount_2 changed from 20 & 30 to 2 & 3 , and added the product ID number and worked like a charm! thank you so much. – nichlor Oct 16 '20 at 18:10