Skip to content
This repository was archived by the owner on May 21, 2025. It is now read-only.

Fix status update for wrong renewal orders #625

Merged
merged 17 commits into from
Jun 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
*** WooCommerce Subscriptions Core Changelog ***

= 7.3.0 - 2024-xx-xx =
* Fix - Fixed an issue with subscriptions containing multiple renewal orders to mark a random item as processing, instead of the last order.

= 7.2.0 - 2024-06-13 =
* Fix - label improvement on my subscription page template.
* Fix - Regenerate subscriptions related order caches (renewal, resubscribe, switch) if it's stored as an invalid value to prevent fatal errors.
Expand Down
3 changes: 2 additions & 1 deletion includes/class-wc-subscriptions-renewal-order.php
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ public static function maybe_record_subscription_payment( $order_id, $orders_old
$is_failed_renewal_order = 'failed' === $orders_old_status || wc_string_to_bool( $order->get_meta( WC_Subscription::RENEWAL_FAILED_META_KEY, true ) );
$is_failed_renewal_order = apply_filters( 'woocommerce_subscriptions_is_failed_renewal_order', $is_failed_renewal_order, $order_id, $orders_old_status );

if ( $order_needed_payment ) {
// Subscription will be activated only if this is the last renewal order of the subscription.
if ( $order_needed_payment && wcs_is_order_last_renewal_of_subscription( $order, $subscription ) ) {
$subscription->payment_complete();
$was_activated = true;
}
Expand Down
45 changes: 41 additions & 4 deletions includes/wcs-renewal-functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,18 @@ function wcs_order_contains_renewal( $order ) {
return apply_filters( 'woocommerce_subscriptions_is_renewal_order', $is_renewal, $order );
}

/**
* Determines if a given order is the subscription's latest renewal order.
*
* @param $order WC_Order The order object.
* @param $subscription WC_Subscription The subscription object.
* @return bool Whether the order is the latest renewal order of the provided subscription.
*/
function wcs_is_order_last_renewal_of_subscription( $order, $subscription ) {
$last_renewal_order = wcs_get_last_renewal_order( $subscription );
return $last_renewal_order && $last_renewal_order->get_id() === $order->get_id();
}

/**
* Checks the cart to see if it contains a subscription product renewal.
*
Expand Down Expand Up @@ -128,10 +140,7 @@ function wcs_get_subscriptions_for_renewal_order( $order ) {
*/
function wcs_get_last_non_early_renewal_order( $subscription ) {
$last_non_early_renewal = false;
$renewal_orders = $subscription->get_related_orders( 'all', 'renewal' );

// We need the orders sorted by the date they were created, with the newest first.
wcs_sort_objects( $renewal_orders, 'date_created', 'descending' );
$renewal_orders = wcs_get_renewal_orders_sorted_by( $subscription, 'date_created' );

foreach ( $renewal_orders as $renewal_order ) {
if ( ! wcs_order_contains_early_renewal( $renewal_order ) ) {
Expand All @@ -143,6 +152,34 @@ function wcs_get_last_non_early_renewal_order( $subscription ) {
return $last_non_early_renewal;
}

/**
* Get the last renewal order (early renewals included).
*
* @param WC_Subscription $subscription The subscription object.
* @return WC_Order|bool The last non-early renewal order, otherwise false.
*/
function wcs_get_last_renewal_order( $subscription ) {
$renewal_orders = wcs_get_renewal_orders_sorted_by( $subscription, 'date_created' );
return $renewal_orders ? reset( $renewal_orders ) : false;
}

/**
* Gets the renewal orders for a subscription, sorted by the specified property.
*
* @param WC_Subscription $subscription The subscription object.
* @param string $sort_by The subscription property to sort by.
* @param string $order Optional. The sort order to sort by. Default is 'descending'.
*
* @return WC_Order[] The subscriptions renewal orders sorted.
*/
function wcs_get_renewal_orders_sorted_by( $subscription, $sort_by, $order = 'descending' ) {
$renewal_orders = $subscription->get_related_orders( 'all', 'renewal' );

wcs_sort_objects( $renewal_orders, $sort_by, $order );

return $renewal_orders;
}

/**
* Checks if manual renewals are required - automatic renewals are disabled.
*
Expand Down
Loading