1
votes

I am using WooCommerce subscriptions plugin in WooCommerce. I am trying to write a function to perform a 10% discount on normal products when one of the following conditions are met:

  1. The User Has an Active Subscription
  2. The User has a Subscription Product in his cart
function vip_discount() {

    $woocommerce = WC();
    $items = $woocommerce->cart->get_cart();
    $vip_product_id = get_subscription_product_id();
    $is_vip_in_cart = is_in_cart($vip_product_id);
    $vip_product_price = 0;

    foreach ($items as $item) {
        if( $item['variation_id'] === get_subscription_variation_id('monthly') || $item['variation_id'] === get_subscription_variation_id('quarterly') || $item['variation_id'] === get_subscription_variation_id('annually') ) {
            $vip_product_price = $item['line_total'];
        }
    }

    if ( wcs_user_has_subscription( '', '', 'active' ) || $is_vip_in_cart ) {
        // Make sure that the calculation is a negative number at the end ALWAYS!
        $discount = -( 10 / 100 ) * ( $woocommerce->cart->get_displayed_subtotal() - $vip_product_price);
        print_r($discount);
        $woocommerce->cart->add_fee( 'VIP Discount', $discount );
    }
}
add_action( 'woocommerce_cart_calculate_fees', 'vip_discount' );

The problem is that this hook is for some reason run twice. Also it's not applying the correct fee. It's supposed to subtract the recurring items total from the negatively applied fee, instead the fee is ending up as the subscription (recurring) product price itself.

Any supplementary information or help is appreciated.

1

1 Answers

0
votes

First if you use $woocommerce, you need first global $woocommerce;. Is better to use WC() as is the actual way for the same thing.

With woocommerce_cart_calculate_fees action hook there is a missing argument $cart (the WC_Cart object) in your hooked function.

The function get_subscription_product_id() doesn't exits, so it might be a custom function… I have replace it by something else.

You should need to use cart_contents_total instead of the displayed subtotal, as this hook runs before totals calculations.

Try this revisited similar code instead:

add_action( 'woocommerce_cart_calculate_fees', 'vip_discount', 10, 1 );
function vip_discount( $cart ) {
    if ( is_admin() && ! defined('DOING_AJAX') ) return; // Exit

    // Here the rate percentage of 10% to be applied
    $rate = .10;

    // Initializing variables
    $vip_price = $discount = 0;
    $subscription_in_cart = false;

    // Loop through the cart items
    foreach ($cart->get_cart() as $cart_item) {
        if( $cart_item['variation_id'] === get_subscription_variation_id('monthly') || $cart_item['variation_id'] === get_subscription_variation_id('quarterly') || $cart_item['variation_id'] === get_subscription_variation_id('annually') ) {
            $vip_price += $cart_item['line_total'];
        }

        // Get an instance of the parent product object (if not parent the product object)
        $product = wc_get_product( $cart_item['product_id']);

        // Check for simple or variable "subscription" products
        if( $product->is_type('subscription') || $product->is_type('variable-subscription') ){
            $subscription_in_cart = true;
        }
    }

    // If customer has an active subscription or a product subscription in cart
    if ( wcs_user_has_subscription( '', '', 'active' ) || $subscription_in_cart ) {

        // The discount calculation
        $discount = ( $cart->cart_contents_total - $vip_product_price ) * $rate;

        if( $discount > 0 ){
            // Add a negative fee (a discount)
            $cart->add_fee( __("VIP Discount"), -$discount ); // not taxable here
        }
    }
}

This code goes in function.php file of your active child theme (or theme) or also in any plugin file.

This should works.