Search code examples
woocommercecoupon

how to get woocommerce coupon discount to calculate from the lowest priced item first


Woocommerce coupon % discount when applied with limit to x quantity items, calculate the discount starting from the highest priced items instead of the lowest priced items.

I am trying to change this default setting so that the coupon discounts can be calculated from the lowest priced items. I found this Finding Lowest Price in Woocommerce Cart Items but the code is outdated which caused php error.

I have found that the code is in reference from class-wc-discounts.php

$coupon_amount = $coupon->get_amount();

    foreach ( $items_to_apply as $item ) {
        // Find out how much price is available to discount for the item.
        $discounted_price = $this->get_discounted_price_in_cents( $item );

        // Get the price we actually want to discount, based on settings.
        $price_to_discount = ( 'yes' === get_option( 'woocommerce_calc_discounts_sequentially', 'no' ) ) ? $discounted_price : round( $item->price );

        // See how many and what price to apply to.
        $apply_quantity    = $limit_usage_qty && ( $limit_usage_qty - $applied_count ) < $item->quantity ? $limit_usage_qty - $applied_count : $item->quantity;
        $apply_quantity    = max( 0, apply_filters( 'woocommerce_coupon_get_apply_quantity', $apply_quantity, $item, $coupon, $this ) );
        $price_to_discount = ( $price_to_discount / $item->quantity ) * $apply_quantity;

Can anyone offer any help and shed some guidance?


Solution

  • after hours of looking through the codes, the answer was indeed in class-wc-discounts.php

    This is the original code:

        /**
     * Sort by price.
     *
     * @since  3.2.0
     * @param  array $a First element.
     * @param  array $b Second element.
     * @return int
     */
    protected function sort_by_price( $a, $b ) {
        $price_1 = $a->price * $a->quantity;
        $price_2 = $b->price * $b->quantity;
        if ( $price_1 === $price_2 ) {
            return 0;
        }
        return ( $price_1 < $price_2 ) ? 1 : -1;
    }
    

    So I simply changed this line ( $price_1 < $price_2 ) ? 1 : -1; to ( $price_1 < $price_2 ) ? -1 : 1; which then makes the sorting from the lowest price to the highest.

    not sure if this is the best trick, but problem solved..