1

It is possible to:

  1. set product step quantity in multiples of 10 starting from a minimum of 50 for a specific category [solved].
  2. change the price only at the thresholds of quantities 100 and 200 for a specific product? For example:
    1. charge 1$ per single product from 50 to 90 (quantities);
    2. charge 0.7$ per single product from 100 to 190 (quantities);
    3. charge 0.5$ per single product up to 200 (quantities).

Edit 1:

I solved part one with those answers:


Edit 2:

Since there are a lot of product with different discount % do I have to write this function x times? Maybe is better to looking for a plugin right?

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
Alezyo77
  • 21
  • 2
  • Please, see [*"What should I do when someone answers my question?"*](https://stackoverflow.com/help/someone-answers). – LoicTheAztec Aug 26 '23 at 08:47

1 Answers1

0

Exceptionally, I answer your question as we expect from you to provide a real code attempt in your question. Also next time, ask one question at the time, it's the rule on Stack OverFlow.

So, the following code will answer to your question n°2. It will change the product price based on quantity thresholds, for specific products.

  • In the first function, you will define in the array the targeted product Ids.

  • In The 2nd function, you will set your quantity thresholds and price rates.

This code works for simple products (not for variable products / product variations):

// Conditional function - Settings: Define your product IDS HERE
function is_product_threshold_qty_pricing_enabled( $product ){
    // Here set in the array your product IDS
    $targeted_product_ids = array(15, 16, 17, 18, 24);

    return in_array($product->get_id(), $targeted_product_ids);
}

// Utility function - Settings: Define your threshold quantity and price rates (for pricing)
function get_quantity_threshold_price_rate( $quantity ) {
    if ( $quantity < 100 ) {
        $rate = 1; // No discount (less than 100)
    } elseif ( $quantity < 200 ) {
        $rate = 0.7; // - 30% discount (between 100 and 199 )
    } else {
        $rate = 0.5; // - 50% discount (up to 200)
    }
    return $rate;
}

// Utility function: Get threshold quantity pricing for display
function get_displayed_qty_threshold_pricing( $product, $quantity ) {
    $price_rate = get_quantity_threshold_price_rate( $quantity );
    if ( $price_rate < 1 ) {
        $regular_price = wc_get_price_to_display( $product, array( 'price' => $product->get_regular_price() ) );
        $active_price  = wc_get_price_to_display( $product, array( 'price' => ($product->get_price() * $price_rate) ) );

        $price = wc_format_sale_price( $regular_price, $active_price ) . $product->get_price_suffix();
    } else {
        $price = $product->get_price_html(); // No discount
    }
    error_log('[ '.$price_rate.' ] quantity: '.$quantity . ' | price: ' . wp_strip_all_tags($price));
    return $price;
}

// PHP Admin Ajax receiver: Return formatted prices
add_action('wp_ajax_qty_threshold_pricing', 'get_qty_threshold_pricing');
add_action('wp_ajax_nopriv_qty_threshold_pricing', 'get_qty_threshold_pricing');
function get_qty_threshold_pricing() {
    if (isset($_POST['product_id']) && isset($_POST['quantity'])) {
        $product = wc_get_product(intval($_POST['product_id'])); // GET THE PRODUCT OBJECT

        echo get_displayed_qty_threshold_pricing( $product, intval($_POST['quantity']) );
    }
    wp_die(); // Exit silently (to avoid an Error 500)
}

// Jquery Ajax: Display on single product pages the price based on quantity
add_action('wp_footer', 'display_single_product_threshold_pricing', 10);
function display_single_product_threshold_pricing() {
    global $product;

    if( is_product() && is_product_threshold_qty_pricing_enabled( $product ) ) :
    ?>
    <script>
    jQuery(function($){
        const blockWhite = {message: null, overlayCSS: {background: '#fff', opacity: 0.6}};
        $('form.cart').on('change input', '[name=quantity]', function() {
            $('form.cart').block(blockWhite);
            $.ajax({
                url:  '<?php echo admin_url( 'admin-ajax.php' ); ?>',
                type: 'POST',
                data: {
                    'action':     'qty_threshold_pricing',
                    'product_id': '<?php echo $product->get_id(); ?>',
                    'quantity':   $(this).val()
                },
                success: function(response) {
                    $('form.cart').unblock();
                    $('.price').html(response);
                }
            });
        });
    });
    </script>
    <?php
    endif;
}

// Display cart item updated price in Cart and Mini Cart
add_action('woocommerce_cart_item_price', 'filter_minicart_displayed_price', 10, 2);
function filter_minicart_displayed_price($price, $cart_item) {
    $product = wc_get_product( $cart_item['data']->get_id() );
    if ( is_product_threshold_qty_pricing_enabled( $product ) ) {
        $price = get_displayed_qty_threshold_pricing( $product, $cart_item['quantity'] );
    }
    return $price;
}

add_action('woocommerce_before_calculate_totals', 'set_cart_item_updated_price');
function set_cart_item_updated_price($cart) {
    if ((is_admin() && !defined('DOING_AJAX')))
        return;

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

    // Loop through cart items and set the updated price
    foreach ($cart->get_cart() as $cart_item) {
        if ( is_product_threshold_qty_pricing_enabled( $cart_item['data'] ) ) {
            $price_rate = get_quantity_threshold_price_rate( $cart_item['quantity'] );
            if ( $price_rate < 1 ) {
                $product = wc_get_product($cart_item['data']->get_id());

                $cart_item['data']->set_price( $product->get_price() * $price_rate );
                $cart_item['data']->set_sale_price( $product->get_sale_price() * $price_rate );
            }

        }
    }
}

Code goes in functions.php file of your child theme (or in a plugin). Tested and works.


Addition:

To target product categories (or product tags) instead of product IDs, replace the first function with:

function is_product_threshold_qty_pricing_enabled( $product ){
    // Here set in the array the term slugs
    $term_slugs = array('hoodies', 't-shirts');
    $taxonomy   = 'product_cat'; // Product category taxonomy

    $product_id = $product->is_type('variation') ? $product->get_parent_id() : $product->get_id();

    return has_term( $term_slugs, $taxonomy, $product_id );
}

For product tags, replace 'product_cat' with 'product_tag'.

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399