4

I have a problem with the end date of WooCommerce Subscriptions. I found that topic here Woocommerce Subscription change expiration date However, our case here is a little different but this topic was helpful.

We use the prorate (10th each month) setting in order to create the renewals order (each month) all at the same time. This is working fine. Also we use WooCommerce Membership in order taht customer can get access to specific memeber content. WooCommerce Subscription automatically set the end date based on the last payment date. We have a subscription variation product with different durations. (3, 6 and 12 month)

With that, we have the following problem: When a customer order today a subscription 04/03/2021 (d/m/y) then the system will create a subscription with the first payment of 10/03/2021. In that case, the end date would be at 10/06/2021. (10/03/2021 + 3 month) But we want, that the end date would be on the 04/06/2021 (startdate +3 month) instead 10/06/2021.

For that we trying to calc the subscription end date based on the startdate (order date) and the specific subscription variantion (3. 6 or 12 month).

Example:

  • 04/03/2021 (Order date & Initial Parent order created)
  • 10/03/2021 (Shipment 1)
  • 10/04/2021 (Shipment 2)
  • 10/05/2021 (Shipment 3)

=> End date should be 04/06/2021 instead of 10/06/2021

Other example:

  • 20/03/2021 (Order date & Initial Parent order created)
  • 10/04/2021 (Shipment 1)
  • 10/05/2021 (Shipment 2)
  • 10/06/2021 (Shipment 3)

=> End date should be 20/06/2021 instead of 10/07/2021

Current approach We try to work those action hook here: https://docs.woocommerce.com/document/subscriptions/develop/action-reference/

With this current state the end date is not changes. I'm now unsure what the problem is. I think I access the end date in the right way but it's not changed after a subscription creation.

add_action( 'woocommerce_checkout_subscription_created', 'recalc_subscription_end_date' );

function recalc_subscription_end_date ($order, $subscription) {
    if ( function_exists( 'wcs_order_contains_subscription' ) ) {
        if ( wcs_order_contains_subscription( $order->ID ) ) {
            
            // Set subscription end date based on subscription variation
            $end_date = date('Y-m-d H:i:s',strtotime("+12 months", strtotime($start_date)));

            $dates_to_update = array();
            $dates_to_update['end'] = $end_date;

            $subscription->update_dates($dates_to_update);

            $subscription->update_dates( array(
                'end' => $end_date,
            ) );

            $subscription->save();
        }
        $return;
    } 
}

UPDATE: With the new Info from @LoicTheAztec I get the following error in the log. Currently the +12 month calc is hardcoded for every variation. How do I have then to access the array for all 3 variations?

Our variation ID's: 11903 for 3 month, 11904 for 6 month, 11905 for 12 month,

[04-Mar-2021 16:43:10 UTC] PHP Fatal error:  Uncaught ArgumentCountError: Too few arguments to function recalc_subscription_end_date(), 1 passed in /home/testsystem/www/test887854.ch/cbctest/wp-includes/class-wp-hook.php on line 289 and exactly 2 expected in /home/testsystem/www/test887854.ch/cbctest/wp-content/plugins/code-snippets/php/snippet-ops.php(446) : eval()'d code:2
Stack trace:
#0 /home/testsystem/www/test887854.ch/cbctest/wp-includes/class-wp-hook.php(289): recalc_subscription_end_date(Object(WC_Subscription))
#1 /home/testsystem/www/test887854.ch/cbctest/wp-includes/class-wp-hook.php(311): WP_Hook->apply_filters(NULL, Array)
#2 /home/testsystem/www/test887854.ch/cbctest/wp-includes/plugin.php(478): WP_Hook->do_action(Array)
#3 /home/testsystem/www/test887854.ch/cbctest/wp-content/plugins/woocommerce-subscriptions/includes/class-wc-subscriptions-checkout.php(103): do_action('woocommerce_che...', Object(WC_Subscription), Object(Automattic\WooCommerce\Admin\Overrides\Order), Object(WC_Cart))
Nik7
  • 346
  • 2
  • 16
  • 1
    According to the documentation, the callback function for `woocommerce_checkout_subscription_created` takes three parameters, and the first one of those is a WC_Subscription instance. Yours takes just one, and appears to assume it was an order object? – CBroe Mar 04 '21 at 08:19
  • Seems that i miss that there. I updated the code and try it again. No change to the end date. It's the firsttime I work with WooCommerce subscription. So I do not have any experience how to access the date in the right way. – Nik7 Mar 04 '21 at 08:32

1 Answers1

3

Updated - The variable $start_date is not defined in your code and there are other mistakes.

Try the following (untested):

add_action( 'woocommerce_checkout_subscription_created', 'recalc_subscription_end_date' );
function recalc_subscription_end_date ($order, $subscription) {
    if ( function_exists( 'wcs_order_contains_subscription' ) && wcs_order_contains_subscription( $order ) ) {
        // The array of subscriptions dates
        $date_types = array('start', 'trial_end', 'next_payment', 'last_payment', 'end');
        $dates      = array(); // Initializing
        
        foreach( $suscription_date_types as $date_type ) {
            $dates[$date_type] = $subscription->get_date($date_type);
        }
        
        // Set subscription end date based on subscription variation
        $dates['end'] = date( 'Y-m-d H:i:s',strtotime( "+12 months", strtotime( $dates['start'] ) ) );

        $subscription->update_dates($dates);
        $subscription->save();
    } 
}

Code goes in functions.php file of the active child theme (or active theme). It could work.

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • Thanks. But It's not possible for me with that code to checkout the subscription product. I get a red noticed message with no message in it. And there is also no error message in debug mode. When I remove the code, then I can checkout without any problem. – Nik7 Mar 04 '21 at 16:16
  • Yes. I just updated the question with the error. – Nik7 Mar 04 '21 at 16:46
  • @Nik7 I removed `can_date_be_updated()` method… and make smaller changes. But I am not sure if it will work. – LoicTheAztec Mar 04 '21 at 20:28
  • Thanks. But the error still exists. Same error code and the checkout does not work. Even on a fresh installation with only Subscription plugin added. I do not understand why? We call the action after subscription creation, Why is a checkout not possible? – Nik7 Mar 04 '21 at 22:50
  • @Nik7 Sorry I really don't know for the moment… – LoicTheAztec Mar 04 '21 at 23:35
  • code might work if was `foreach( $date_types` NOT `foreach( $subscription_date_types` – CK MacLeod Dec 27 '21 at 18:33