WooCommerce Subscriptions missing "Completed" status

397 views Asked by At

this is my first question here, I can not find a solution for this:

We are running am e-learning platform along with the e-commerce system for selling the courses, which can be purchased by two ways, the full price or a monthly subscription, all of this mounted with WordPress (Sensei + WooCommerce - Subscriptions addon installed - )

WoordPress Ver.: 4.5.2

WooCommerce Ver.: 2.5.5

Subscription Ver.: 2.1.2

In order to let the user enter the course we need to check if that user have an active/completed subscription or a completed order.

First problem, subscriptions does not have a completed status, instead the system mark them as cancelled, I understand that a complete subscription is one in which all payments have been completed, so this function is totally useless:

wcs_user_has_subscription( $user_id, $product_id, 'cancelled' )

Because a cancelled subscription may have missing payments.

So I created this function:

foreach ( wcs_get_users_subscriptions( $user_id ) as $subscription ) {
    $sub_wc = new WC_Subscription( $subscription->id );

    // Only for testing, we only need the first product.
    $product = reset( $sub_wc->get_items() );

    $done_payments  = $sub_wc->get_completed_payment_count();
    $total_payments = WC_Subscriptions_Product::get_length( $item['product_id'] );

    if( ( $total_payments == $done_payments ) || $sub_wc->post_status == 'wc-active' ) {
        $result = true;
    }
}

And if that functions returns false (I have summarized, omitting the return) we need to check for completed orders, but not related with a subscription because each subscription can have more than one order (parent, renewal, etc), so this function is useless:

wc_customer_bought_product( $current_user->user_email, $current_user->ID, $product_id )

And you might ask, why? That functions works fine if you are not working with subscriptions, remember that a cancelled subscription can have 2 completed orders, and this function will return true because it does not matter if the order is related to a subscription.

So for this case I created this function:

$user_completed_orders = get_posts( array(
    'numberposts' => -1,
    'meta_key'    => '_customer_user',
    'meta_value'  => $user->ID,
    'post_type'   => 'shop_order',
    'post_status' => 'wc-completed'
) );

foreach ( $completed_orders as $completed_order ) {
    $order_wc = new WC_Order( $completed_order->ID );

    // We only want orders not related with any subscriptions
    if( !wcs_order_contains_subscription( $order_wc ) ) {

        // Check if the user purchased the product
        // Only for testing, we only need the first product.
        $product = reset( $order_wc->get_items() );
        if( $product['product_id'] == $product_id ) {
            $result = true;
        }
    }
}

All this causes the load to increase, and we go from about 6-7 seconds of load to 14, I know it is not much, but it pisses me off that there are no defined functions for this.

Do you think there is a better approach for this particular case?

Improve the code above?

Maybe I'm missing an official function/method?

Thanks community, sorry for the long post and for any spelling mistakes that may have. Have a good day.

0

There are 0 answers