3

I am trying to discount the cheapest item in the cart if my coupon type is used:

add_filter('woocommerce_coupon_get_discount_amount', 'wc_cpn_disc', 10, 5);
function wc_cpn_disc($discount, $discounting_amount, $cart_item, $single, $coupon) {
    // IF TYPE MATCHES PERFORM CUSTOM CALCULATION
    if ($coupon->type == 'cheapest_free'){
      global $woocommerce;
      foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
          $_product = $values['data'];
          $product_price[] = get_option('woocommerce_tax_display_cart') == 'excl' ? $_product->get_price_excluding_tax() : $_product->get_price_including_tax(); /*Store all product price from cart items in Array */
      }
      $lowestprice = min($product_price);
      $discount = number_format((float)$lowestprice/10,2,'.','');
    }

    return $discount;
}

The discount amount is very weird - no matter what I try, it never comes out to the value I expect. At first I thought it was a percentage discount, but I expect this to be a fixed amount. I have tried running my get lowest price bit of function elsewhere on the site and it returns 1.195 when the lowest value item is 11.95 - so I know that part works. But the discount on a total basket of 265.60 is 23.90 - I just don't get it!

I just want to get the lowest priced item in the cart, and discount that amount.

Rob1982
  • 63
  • 3
  • Can you just return the `$lowestprice` as the discount? That will be a float anyways, so `$lowestprice = min($product_price)/10;` – Bossman Oct 27 '21 at 21:30
  • So I think the issue might be more that this is trying to discount each line item. If I have just say 10 of one product in my basket, it works perfectly - but if I have 4 of one item, 5 of another, 4 of another for example, it tries to discount all of them. I think maybe the hook I am using is wrong, I need to apply a one-time fixed price discount to the whole cart. This seems to be doing it per line item I think. – Rob1982 Oct 27 '21 at 21:33
  • 1
    This might be what you're looking for. It applies a 100% discount on the cheapest cart item... https://stackoverflow.com/questions/61480164/apply-a-100-coupon-discount-on-the-cheapest-cart-item-in-woocommerce – Bossman Oct 27 '21 at 21:38
  • 1
    Yes! That is excellent, thank you Bossman - I did make one tweak, which I'll add over on that question, but that does work really well. Thanks! – Rob1982 Oct 27 '21 at 21:58

1 Answers1

2

I managed to solve this with the help of Bossman and a couple of other threads. It turns out I needed to change my method - full code below.

add_filter('woocommerce_coupon_get_discount_amount', 'tfcc_cheapest_free', 10, 5);
function tfcc_cheapest_free($discount, $discounting_amount, $cart_item, $single, $coupon) {
    // IF TYPE MATCHES PERFORM CUSTOM CALCULATION
    if ($coupon->type == 'cheapest_free'){

      $items_prices = [];
          $items_count  = 0;

          // Loop through cart items
          foreach( WC()->cart->get_cart() as $key => $item ){
              // Get the cart item price (the product price)
              if ( wc_prices_include_tax() ) {
                  $price = wc_get_price_including_tax( $item['data'] );
              } else {
                  $price = wc_get_price_excluding_tax( $item['data'] );
              }

              if ( $price > 0 ){
                  $items_prices[$key] = $price;
                  $items_count       += $item['quantity'];
              }
          }

          // Only when there is more than one item in cart
          if ( $items_count > 1 ) {
              asort($items_prices);  // Sorting prices from lowest to highest

              $item_keys = array_keys($items_prices);
              $item_key  = reset($item_keys); // Get current cart item key

              // Targeting only the current cart item that has the lowest price
              if ( $cart_item['key'] == $item_key ) {
                  return reset($items_prices)/$cart_item['quantity']; // return the lowest item price as a discount
              }
          } else {
              return 0;
          }

    }

}

I hope this might help someone else out who needs a similar feature in the future.

Rob1982
  • 63
  • 3