Reputation: 45
I have 1 subscription with 3 variations. I'm trying to force the first renewal date depending on the variation ID that was purchased.
Variation 1 (876) set to renew every day - I want first re-bill date to be 11/15/2020 12:00AM Variation 2 (877) set to renew every 2 days - I want first re-bill date to be 2/15/2021 12:00AM Variation 3 (878) set to renew every 3 days - I want first re-bill date to be 8/15/2021 12:00AM
I thought the below code worked. After the order is created the next bill date DOES show one of the above dates, but it must not be registering with WooCommerce or something, because the renewals are triggering regardless of the above dates.
For my test, I create an order for Variation 1, the next payment date is showing 11/15/2020, but it's renewing the next day.
Hoping to get some insight from someone smarter than me. Again, the sub's next bill date is showing the above dates, but renewals are still happening early/before the above dates.
function nextpaymentdatechange( $order_id ){
$order = wc_get_order( $order_id );
$items = $order->get_items();
foreach ( $items as $item_id => $item ) {
$product_id = $item->get_variation_id() ? $item->get_variation_id() : $item->get_product_id();
if ( $product_id === 876 ) {
$subid = $order_id + 1;
$nextdate = get_post_meta( $subid, '_schedule_next_payment', true );
$new_date = date( 'Y-m-d H:i:s', strtotime( '2020-11-15 07:00:00', strtotime( $nextdate )) );
update_post_meta( $subid , '_schedule_next_payment', $new_date);
}
else{ if ( $product_id === 877 ) {
$subid = $order_id + 1;
$nextdate = get_post_meta( $subid, '_schedule_next_payment', true );
$new_date = date( 'Y-m-d H:i:s', strtotime( '2021-02-15 07:00:00', strtotime( $nextdate )) );
update_post_meta( $subid , '_schedule_next_payment', $new_date);
}
else{
if ( $product_id === 878 ) {
$subid = $order_id + 1;
$nextdate = get_post_meta( $subid, '_schedule_next_payment', true );
$new_date = date( 'Y-m-d H:i:s', strtotime( '2021-08-03 07:00:00', strtotime( $nextdate )) );
update_post_meta( $subid , '_schedule_next_payment', $new_date);
}
}
}
}
} ```
Upvotes: 0
Views: 3340
Reputation: 31
if i understand, this :
function nextpaymentdatechange( $order_id ){
// YOUR SETTINGS: Set in this array your desired dates (value(s)) by product Id (key)
$dates_for_product = array(
588 => array(
'end' => '2020-12-05 07:00:00',
),
);
// The date types for subscriptions
$suscription_date_types = array('start', 'trial_end', 'next_payment', 'last_payment', 'end');
Set automaticaly a end date 05 of december for my product 588 (it's a simple subscription)?
Upvotes: 0
Reputation: 253784
To make that work you need first to get WC_Subscription
Objects from the order using:
$subscriptions = wcs_get_subscriptions_for_order( $order_id );
that gives an array of the WC_Subscription Object(s) for the Order, from an order Id.
Now you can use the WC_Subscription
method update_dates($dates)
, that requires to set an array of all dates types from a subscription that are 'start'
, 'trial_end'
, 'next_payment'
, 'last_payment'
and 'end'
.
To get a specific date from a subscription, we use WC_Subscription
method get_date($date_type)
.
Additionally I use WC_Subscription
method can_date_be_updated($date_type)
, to check if a date type can be updated.
I am not sure about which ones dates require to be updated as they are likely related.
You can try the following that should update the related(s) subscription(s) dates from an order, based on your code (the code doesn't throw errors).
I thin that you need to change 'next_payment'
, 'last_payment'
and 'end'
dates.
Using the methods update_dates() and save() at the end of the code, allows to change dates, save all required data to database refreshing cached data.
The function code:
function nextpaymentdatechange( $order_id ){
// YOUR SETTINGS: Set in this array your desired dates (value(s)) by product Id (key)
$dates_for_product = array(
876 => array(
'next_payment' => '2020-11-15 07:00:00',
'last_payment' => '2020-11-16 07:00:00',
),
877 => array(
'next_payment' => '2021-02-15 07:00:00',
'last_payment' => '2021-02-16 07:00:00',
),
878 => array(
'next_payment' => '2021-08-03 07:00:00',
'last_payment' => '2021-08-04 07:00:00',
),
);
// The date types for subscriptions
$suscription_date_types = array('start', 'trial_end', 'next_payment', 'last_payment', 'end');
// Get the subscriptions from the current order Id
$subscriptions = wcs_get_subscriptions_for_order( $order_id );
// Loop through subscriptions
foreach ( $subscriptions as $subscription_id => $subscription ) {
// Loop through items in this subscription
foreach ( $subscription->get_items() as $item_id => $item ) {
$product = $item->get_product();
// Loop through defined products dates
foreach( $dates_for_product as $product_id => $new_dates ) {
// If current subscription product id matches
if ( $product->get_id() == $product_id ) {
$current_product_id = $product_id; // Set current product id
break; // Stop the current loop
}
}
if ( isset($current_product_id) ) {
break; // Stop the current loop
}
}
// Updating subscription dates
if ( isset($current_product_id) ) {
$updated_dates = array(); // Initializing
// Loop through subscription date types
foreach( $suscription_date_types as $date_type ) {
$date = $subscription->get_date($date_type);
// For 'next_payment' and 'last_payment' dates
if( isset($new_dates[$date_type]) && $subscription->can_date_be_updated($date_type) ) {
$updated_dates[$date_type] = $new_dates[$date_type];
}
// For 'end' date
elseif ( $date_type === 'end' && $subscription->can_date_be_updated($date_type) ) {
$updated_dates[$date_type] = $new_dates['last_payment']; // ??? Or may be instead: $date; … (or simply: 0;)
}
// Other dates
else {
$updated_dates[$date_type] = $date;
}
}
// Update subscription date, save to database and refresh cached data
$subscription->update_dates($updated_dates);
$subscription->save();
}
}
}
Code goes in functions.php file of your active child theme (or active theme). It should works.
Upvotes: 2