Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cache subscription last order date #819

Open
wants to merge 13 commits into
base: trunk
Choose a base branch
from
1 change: 1 addition & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* Fix - Ensure the order_awaiting_payment session arg is restored when loading a renewal cart from the session to prevent duplicate orders.
* Fix - Ensure custom placeholders (time_until_renewal, customers_first_name) are included in customer notification email previews.
* Fix - Correctly load product names with HTML on the cart and checkout shipping rates.
* Fix - Improve performance of the subscription listing page.
* Dev - Fix Node version mismatch between package.json and .nvmrc (both are now set to v16.17.1).

= 8.0.1 - 2025-02-13 =
Expand Down
22 changes: 19 additions & 3 deletions includes/admin/class-wcs-admin-post-types.php
Original file line number Diff line number Diff line change
Expand Up @@ -684,9 +684,25 @@ public function render_shop_subscription_columns( $column, $subscription = null
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.3.0
*/
public static function get_date_column_content( $subscription, $column ) {
$date_type_map = array( 'last_payment_date' => 'last_order_date_created' );
$date_type = array_key_exists( $column, $date_type_map ) ? $date_type_map[ $column ] : $column;
$date_timestamp = $subscription->get_time( $date_type );
$date_type_map = array( 'last_payment_date' => 'last_order_date_created' );
$date_type = array_key_exists( $column, $date_type_map ) ? $date_type_map[ $column ] : $column;

if ( 'last_payment_date' === $column ) {
// Get last order date created from subscription metadata if it exists.
$last_order_date_created = $subscription->get_last_order_date_created();

if ( ! empty( $last_order_date_created ) ) {
$date_timestamp = $last_order_date_created;
} else {
// If not exists, get the last order date created from the orders and update the metadata.
$date_timestamp = $subscription->get_time( $date_type );

$subscription->set_last_order_date_created( $date_timestamp );
$subscription->save();
}
} else {
$date_timestamp = $subscription->get_time( $date_type );
}

if ( 0 === $date_timestamp ) {
return '-';
Expand Down
17 changes: 17 additions & 0 deletions includes/class-wc-subscription.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class WC_Subscription extends WC_Order {
'requires_manual_renewal' => true,
'cancelled_email_sent' => false,
'trial_period' => '',
'last_order_date_created' => null,

// Extra data that requires manual getting/setting because we don't define getters/setters for it
'schedule_trial_end' => null,
Expand Down Expand Up @@ -908,6 +909,15 @@ public function get_cancelled_email_sent( $context = 'view' ) {
return $this->get_prop( 'cancelled_email_sent', $context );
}

/**
* The subscription last order created date.
*
* @return string
*/
public function get_last_order_date_created( $context = 'view' ) {
return $this->get_prop( 'last_order_date_created', $context );
}

/*** Setters *****************************************************/

/**
Expand Down Expand Up @@ -1092,6 +1102,13 @@ public function set_cancelled_email_sent( $value ) {
$this->set_prop( 'cancelled_email_sent', $value );
}

/**
* Set the subscription last order created date.
*/
public function set_last_order_date_created( $value ) {
$this->set_prop( 'last_order_date_created', $value );
}

/*** Date methods *****************************************************/

/**
Expand Down
1 change: 1 addition & 0 deletions includes/class-wc-subscriptions-data-copier.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class WC_Subscriptions_Data_Copier {
'_suspension_count',
'_requires_manual_renewal',
'_cancelled_email_sent',
'_last_order_date_created',
'_trial_period',
'_created_via',
'_order_stock_reduced',
Expand Down
24 changes: 24 additions & 0 deletions includes/class-wc-subscriptions-order.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ public static function init() {
add_filter( 'woocommerce_order_query_args', array( __CLASS__, 'map_order_query_args_for_subscriptions' ) );

add_filter( 'woocommerce_orders_table_query_clauses', [ __CLASS__, 'filter_orders_query_by_parent_orders' ], 10, 2 );

add_action( 'woocommerce_before_delete_order', __CLASS__ . '::delete_order_update_subscription_last_order_date_created', 10, 2 );
}

/*
Expand Down Expand Up @@ -2396,6 +2398,28 @@ public static function get_meta( $order, $meta_key, $default = 0 ) {
return $meta_value;
}

/**
* Update subscription cached last_order_date_created metadata when deleting a child order.
*
* @param int $id The deleted order ID.
* @param WC_Order $order The deleted order object.
*/
public static function delete_order_update_subscription_last_order_date_created( $id, $order ) {
if ( $order->get_created_via() !== 'subscription' ) {
return;
}

$subscription_ids = wcs_get_subscription_ids_for_order( $order );

foreach ( $subscription_ids as $subscription_id ) {
$subscription = wcs_get_subscription( $subscription_id );
$last_order_date_created = $subscription->get_time( 'last_order_date_created' );

$subscription->set_last_order_date_created( $last_order_date_created );
$subscription->save();
}
}

/**
* Prints the HTML for the admin dropdown for order types to Woocommerce -> Orders screen.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class WCS_Orders_Table_Subscription_Data_Store extends \Automattic\WooCommerce\I
'_cancelled_email_sent' => 'cancelled_email_sent',
'_requires_manual_renewal' => 'requires_manual_renewal',
'_trial_period' => 'trial_period',
'_last_order_date_created' => 'last_order_date_created',

'_schedule_trial_end' => 'schedule_trial_end',
'_schedule_next_payment' => 'schedule_next_payment',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class WCS_Subscription_Data_Store_CPT extends WC_Order_Data_Store_CPT implements
'_cancelled_email_sent' => 'cancelled_email_sent',
'_requires_manual_renewal' => 'requires_manual_renewal',
'_trial_period' => 'trial_period',
'_last_order_date_created' => 'last_order_date_created',

'_schedule_trial_end' => 'schedule_trial_end',
'_schedule_next_payment' => 'schedule_next_payment',
Expand Down
3 changes: 3 additions & 0 deletions includes/wcs-order-functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,9 @@ function wcs_create_order_from_subscription( $subscription, $type ) {
throw new Exception( sprintf( __( 'There was an error fetching the new order (%1$s) for subscription %2$d.', 'woocommerce-subscriptions' ), $type, $subscription->get_id() ) );
}

$subscription->set_last_order_date_created( $new_order->get_date_created()->getTimestamp() );
$subscription->save();

/**
* Filters the new order created from the subscription.
*
Expand Down