I have created the following functions to override the product price and make a max discount for WooCommerce. However, I can't seem to figure out why the woocommerce_coupon_get_discount_amount filter is applying to all coupons.
The way I am trying to get it to function is if the coupon is a percent coupon, it will cap the total discount amount for that coupon. If the coupon is a fixed_cart type and it has the custom field I added _price_per_product_amt filled in, then it will change the price of the product.
Both of these functions work if I have only one coupon in the cart. If I have the fixed_cart_coupon in the cart, it will change the price and set the coupon amount to $0 (the coupon is set to have $0 for its amount). However, if I add a percent coupon as well, the function works for the percent coupon, but then it also adds a discount amount to the fixed_cart_coupon. It should only be modifying the discount amount for percent coupons in the cart.
// filter to change discount if over max coupon amount
function filter_woocommerce_coupon_get_discount_amount( $discount, $discounting_amount, $cart_item, $single, $instance ) {
$cartCoupons = WC()->cart->get_applied_coupons();
foreach ($cartCoupons as $key => $appliedCoupon) {
$coupon = new WC_Coupon($appliedCoupon);
$couponType = get_post_meta( $coupon->get_id(), 'discount_type', true );
if ($couponType == 'percent') {
$maxCouponAmount = get_post_meta( $coupon->get_id(), '_max_discount', true );
$excludedProducts = explode(",", get_post_meta( $coupon->get_id(), 'exclude_product_ids', true ));
$cartLines = count(WC()->cart->get_cart());
$cartLineItems = WC()->cart->get_cart();
foreach ($cartLineItems as $cartItem){
$cartProductID[] = $cartItem['product_id'];
if (!empty($excludedProducts)) {
$cartLinesWithoutExcluded = array_intersect($cartProductID,$excludedProducts);
} else {
$cartLinesWithoutExcluded = $cartProductID;
}
$cartLinesWithoutExcluded = count($cartLinesWithoutExcluded);
$totalCartItems = $cartLines - $cartLinesWithoutExcluded;
$discount = $maxCouponAmount / $totalCartItems;
}
} else {
$discount = 0.00;
}
return $discount;
}
}
// apply the coupon whether it is max discount or a product price adjustment
function apply_max_amount_or_product_price_adjustment(){
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
if ( !is_admin() && !wp_is_json_request() ) {
global $wp, $woocommerce;
$cartCoupons = WC()->cart->get_applied_coupons();
foreach ($cartCoupons as $key => $appliedCoupon) {
$coupon = new WC_Coupon($appliedCoupon);
$maxCouponAmount = get_post_meta( $coupon->get_id(), '_max_discount', true );
$excludedProducts = explode(",", get_post_meta( $coupon->get_id(), 'exclude_product_ids', true ));
$couponType = get_post_meta( $coupon->get_id(), 'discount_type', true );
// $fixedProductPrice = get_post_meta( $coupon->get_id(), '_adjust_price', true );
$couponAmount = WC()->cart->get_coupon_discount_amount( $appliedCoupon );
if (!empty($maxCouponAmount) && $couponType == 'percent' && ($couponAmount > $maxCouponAmount || $couponAmount == $maxCouponAmount)) {
add_filter( 'woocommerce_coupon_get_discount_amount', 'filter_woocommerce_coupon_get_discount_amount', 10, 5 );
}
if ($couponType == 'fixed_cart'){
$cart = WC()->cart->get_cart();
$couponProducts = explode(',',get_post_meta( $coupon->get_id(), 'product_ids', true ));
$fixedPricePerProduct = get_post_meta( $coupon->get_id(), '_price_per_product_amt', true );
foreach( $cart as $cart_item ) {
if (in_array($cart_item['data']->get_parent_id(), $couponProducts)) {
$cart_item['data']->set_price( $fixedPricePerProduct );
}
}
}
}
}
}
add_action('woocommerce_before_calculate_totals', 'apply_max_amount_or_product_price_adjustment', 10, 1);