• Resolved elena18

    (@elena18)


    In my child theme functions.php I added a custom code to calculate dynamic discounts based on my client needs. What I am not able to do is, when a fixed price coupon (let’s say fixed price on cart) is applied, it is automatically added BEFORE the custom discounts, while I want it applied AFTER.

    Example of desired output:

    Subtotal = 1000 10%

    discount (custom) = -100

    coupon = -50

    Total = 850

    What is happening instead

    Subtotal = 1000

    coupon = -50

    10% discount = -95

    Total = 855

    Here’s my custom discount code (it works on simple products that have a custom field “is_student” where the ouput is ‘yes’ / ‘no’)

    // Display custom field value in the cart
    function display_student_option_in_cart($item_data, $cart_item) {
    $product = wc_get_product($cart_item['product_id']);

    if (isset($cart_item['is_student'])) {
    if ($product->is_on_sale()) {
    $item_data[] = array(
    'key' => __('Student discount', 'woocommerce'),
    'value' => __('Not applicable', 'woocommerce')
    );
    } else {
    $item_data[] = array(
    'key' => __('Student discount', 'woocommerce'),
    'value' => __('Yes', 'woocommerce')
    );
    }
    }
    return $item_data;
    }
    add_filter('woocommerce_get_item_data', 'display_student_option_in_cart', 10, 2);


    //function to calculate discounts for students and adults (only if they book > 1 product)
    function cart_discount_subsequent_variations_same_product() {
    if (is_admin() && !defined('DOING_AJAX')) {
    return;
    }

    global $woocommerce;

    $cart = WC()->cart->get_cart();
    $cart_array = array();

    $total_student_discount = 0; // Initialize total student discount
    $total_adult_discount = 0; // Initialize total adult discount
    $student_percentage = 0.10;
    $adult_percentage = 0.10;


    foreach ($cart as $cart_item_key => $values) {

    $product_id = $values['product_id'];
    $cart_lines_quantity = $values["quantity"];
    $cart_lines_total = $values["line_total"];
    $is_student = isset($values['is_student']) ? $values['is_student'] : false;
    // Retrieve the product object
    $product = wc_get_product($product_id);
    // Check if product is on sale
    $is_on_sale = $product && $product->is_on_sale();

    //case 1: is student && is not on sale
    if ($is_student && !$is_on_sale) {
    $student_discount = $student_percentage * $cart_lines_total;
    $total_student_discount += $student_discount; // Accumulate the student discount for each item
    }
    //case 2: is student && is on sale
    /* else if($is_student && $is_on_sale) {
    }*/
    //case 3: is not student
    else if(!$is_student && !$is_on_sale) {
    $cart_array[] = array('product_id' => $product_id, 'quantity' => $cart_lines_quantity, 'total' => $cart_lines_total);
    }
    //case 4: is not student && is on sale
    else if(!$is_student && $is_on_sale) {
    $cart_array[] = array('product_id' => $product_id, 'quantity' => $cart_lines_quantity, 'total' => $cart_lines_total);
    }
    }
    // Apply student discount
    if ($total_student_discount > 0) {
    $student_discount_neg = -($total_student_discount);
    $discount_text = __('10% student discount', 'woocommerce');
    WC()->cart->add_fee($discount_text, $student_discount_neg, false);
    }

    // Apply adult discount for subsequent cruises
    if (count($cart_array) > 1) {
    usort($cart_array, function($a, $b) {
    return $a['product_id'] <=> $b['product_id'];
    });

    // Calculate discount for subsequent adult bookings
    for ($i = 1; $i < count($cart_array); $i++) {
    $total_adult_discount += ($adult_percentage * $cart_array[$i]['total']);
    }
    if ($total_adult_discount > 0) {
    $adult_discount_neg = -($total_adult_discount);
    $discount_text = __('10% discount on subsequent week(s)', 'woocommerce');
    WC()->cart->add_fee($discount_text, $adult_discount_neg, false);
    }
    }
    }
    add_action('woocommerce_cart_calculate_fees', 'cart_discount_subsequent_variations_same_product', 10);
Viewing 3 replies - 1 through 3 (of 3 total)
  • Plugin Support Shameem R. a11n

    (@shameemreza)

    Hi @elena18

    By default, WooCommerce applies coupons before custom discounts. You will need to alter the sequence of these operations to achieve your desired output.

    Unfortunately, WooCommerce doesn’t provide a built-in way to change this order. However, you can achieve this using the woocommerce_before_calculate_totals hook instead of woocommerce_cart_calculate_fees.

    This hook allows you to modify the prices of the products before the totals are calculated, hence before the coupon is applied. You can set the new price of the product after applying the discount using the set_price() function of the cart item.

    Please note that writing or providing custom code is not within the scope of our support policy. However, here is an example for better understanding:

    add_action('woocommerce_before_calculate_totals', 'custom_discount_before_coupon', 10, 1);

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

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

    foreach ($cart->get_cart() as $cart_item) {
    $product = $cart_item['data'];
    $price = $product->get_price();
    $discounted_price = $price - ($price * 0.1); // Calculate your discount here.
    $cart_item['data']->set_price($discounted_price);
    }
    }

    If you are still having problems, we recommend asking development questions on the #developers channel of the WooCommerce Community Slack. Many of our developers hang out there and will be able to offer insights into your question. You can also seek help from the following:

    I wish I could help more, but hopefully, this gets you going in the right direction to get the job done.

    Thread Starter elena18

    (@elena18)

    Thanks @shameemreza for the suggestion. I will dig into it. Another possible solution was to create a custom coupon to be applied when needed

    Plugin Support ckadenge (woo-hc)

    (@ckadenge)

    Hi @elena18,

    I will dig into it

    Sounds like a plan.

    Should you have any further questions, please feel free to open a new topic.

    All the best!

Viewing 3 replies - 1 through 3 (of 3 total)
  • You must be logged in to reply to this topic.