-
Notifications
You must be signed in to change notification settings - Fork 49
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
feat(wcs): add expired subscription cli tool #3593
Merged
chickenn00dle
merged 6 commits into
trunk
from
feat/add-subscriptions-expiration-cli-tool
Dec 9, 2024
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
558b8f5
feat(wcs): add expired subscription cli tool
chickenn00dle 60f5810
feat: add subscription ids handling
chickenn00dle 11c951f
fix: only expire failed retries
chickenn00dle 247838a
fix: update subscription end date
chickenn00dle e84ebeb
fix: save subscription update
chickenn00dle efdf5a7
fix: fix subscription update order
chickenn00dle File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
<?php | ||
/** | ||
* WooCommerce Subscriptions Integration CLI commands. | ||
* | ||
* @package Newspack | ||
*/ | ||
|
||
namespace Newspack\CLI; | ||
|
||
use WP_CLI; | ||
use Newspack\Woocommerce_Subscriptions as WooCommerce_Subscriptions_Integration; | ||
|
||
defined( 'ABSPATH' ) || exit; | ||
|
||
/** | ||
* WooCommerce Subscriptions Integration CLI commands. | ||
*/ | ||
class WooCommerce_Subscriptions { | ||
/** | ||
* Flag for live mode. | ||
* | ||
* @var bool | ||
*/ | ||
private static $live = false; | ||
|
||
/** | ||
* Flag for verbose output. | ||
* | ||
* @var bool | ||
*/ | ||
private static $verbose = false; | ||
|
||
/** | ||
* Subscription ids to process. | ||
* | ||
* @var bool|array | ||
*/ | ||
private static $ids = false; | ||
|
||
/** | ||
* Migrate status of on-hold WooCommerce subscriptions that have failed all payment retries to expired. | ||
* | ||
* ## OPTIONS | ||
* | ||
* [--live] | ||
* : Run the command in live mode, updating the subscriptions. | ||
* | ||
* [--verbose] | ||
* : Produce more output. | ||
* | ||
* [--ids] | ||
* : Comma-separated list of subscription IDs. If provided, only ubscriptions with these IDs will be processed. | ||
* | ||
* @param array $args Positional arguments. | ||
* @param array $assoc_args Assoc arguments. | ||
* | ||
* @return void | ||
*/ | ||
public function migrate_expired_subscriptions( $args, $assoc_args ) { | ||
WP_CLI::line( '' ); | ||
if ( ! WooCommerce_Subscriptions_Integration::is_enabled() ) { | ||
WP_CLI::error( 'WooCommerce Subscriptions Integration is not enabled.' ); | ||
WP_CLI::line( '' ); | ||
return; | ||
} | ||
self::$ids = isset( $assoc_args['ids'] ) ? explode( ',', $assoc_args['ids'] ) : false; | ||
self::$live = isset( $assoc_args['live'] ) ? true : false; | ||
self::$verbose = isset( $assoc_args['verbose'] ) ? true : false; | ||
$updated = 0; | ||
$page = 1; | ||
$per_page = 25; | ||
$subscriptions = self::get_subscriptions( $page ); | ||
if ( empty( $subscriptions ) ) { | ||
WP_CLI::success( 'No on-hold subscriptions to process.' ); | ||
WP_CLI::line( '' ); | ||
return; | ||
} | ||
WP_CLI::line( 'Processing subscriptions in ' . ( self::$live ? 'live' : 'dry run' ) . ' mode...' ); | ||
WP_CLI::line( '' ); | ||
while ( ! empty( $subscriptions ) ) { | ||
foreach ( $subscriptions as $subscription ) { | ||
$id = $subscription->get_id(); | ||
if ( self::$verbose ) { | ||
WP_CLI::line( 'Processing subscription ' . $id . '...' ); | ||
} | ||
// A pending retry indicates the subscription is awaiting payment retry. | ||
if ( $subscription->get_date( 'payment_retry' ) > 0 ) { | ||
if ( self::$verbose ) { | ||
WP_CLI::line( 'Subscription is awaiting payment retry. Moving to next subscription...' ); | ||
WP_CLI::line( '' ); | ||
} | ||
continue; | ||
} | ||
$renewal_order = $subscription->get_last_order( | ||
'all', | ||
[ 'renewal' ], | ||
[ | ||
'completed', | ||
'processing', | ||
'refunded', | ||
] | ||
); | ||
// No failed or pending renewal orders indicates the subscription was likely manually placed on hold. | ||
if ( empty( $renewal_order ) ) { | ||
if ( self::$verbose ) { | ||
WP_CLI::line( 'Subscription has no pending renewal orders. Moving to next subscription...' ); | ||
WP_CLI::line( '' ); | ||
} | ||
continue; | ||
} | ||
$last_retry = \WCS_Retry_Manager::store()->get_last_retry_for_order( wcs_get_objects_property( $renewal_order, 'id' ) ); | ||
// No retries indicates the subscription was likely manually placed on hold. | ||
if ( empty( $last_retry ) ) { | ||
if ( self::$verbose ) { | ||
WP_CLI::line( 'No retries scheduled. Moving to next subscription...' ); | ||
WP_CLI::line( '' ); | ||
} | ||
continue; | ||
} | ||
// A non failed status indicates the retry was either manually cancelled | ||
// or was successful at one point but likely placed on hold for some other reason. | ||
if ( 'failed' !== $last_retry->get_status() ) { | ||
if ( self::$verbose ) { | ||
WP_CLI::line( 'Last retry does not have a failed status. Moving to next subscription...' ); | ||
WP_CLI::line( '' ); | ||
} | ||
continue; | ||
} else { | ||
if ( self::$verbose ) { | ||
WP_CLI::line( 'Updating subscription status to expired...' ); | ||
} | ||
if ( self::$live ) { | ||
$subscription->update_status( 'expired', __( 'Subscription status updated by Newspack CLI command.', 'newspack-plugin' ) ); | ||
$subscription->set_end_date( $last_retry->get_date() ); | ||
$subscription->save(); | ||
} | ||
++$updated; | ||
} | ||
if ( self::$verbose ) { | ||
WP_CLI::line( 'Finished processing subscription ' . $id ); | ||
WP_CLI::line( '' ); | ||
} | ||
} | ||
$subscriptions = self::get_subscriptions( ++$page ); | ||
} | ||
WP_CLI::success( 'Finished processing subscriptions. ' . $updated . ' subscriptions updated.' ); | ||
if ( ! self::$live ) { | ||
WP_CLI::warning( 'Dry run. Use --live flag to process live subscriptions.' ); | ||
} | ||
WP_CLI::line( '' ); | ||
} | ||
|
||
/** | ||
* Get subscriptions to process. | ||
* | ||
* @param int $page Page number. | ||
* | ||
* @return array | ||
*/ | ||
private static function get_subscriptions( $page = 1 ) { | ||
$subscriptions = []; | ||
if ( false !== self::$ids ) { | ||
while ( ! empty( self::$ids ) ) { | ||
$id = array_shift( self::$ids ); | ||
if ( ! is_numeric( $id ) ) { | ||
continue; | ||
} | ||
$subscription = wcs_get_subscription( $id ); | ||
if ( $subscription ) { | ||
$subscriptions[] = $subscription; | ||
} | ||
} | ||
} else { | ||
$subscriptions = wcs_get_subscriptions( | ||
[ | ||
'paged' => $page, | ||
'subscriptions_per_page' => 25, | ||
'subscription_status' => 'on-hold', | ||
] | ||
); | ||
} | ||
return $subscriptions; | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's also add one of those Subscriptions Notes that show up in the subscription page?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In discussion with Tracy and Katie, it would be best if the subscription had the expiration date of the last failed payment rather than the expiration date of when the script was run.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The second argument to
$subscription->update_status
is added as a subscription note. Is this what you were referring to?Sure thing @claudiulodro! I updated to script to use the date of the last retry object. This should be the same as the last failed payment: b29bdd1
When testing though, since we are manually triggering the scheduled actions, this end date will be set as though the scheduled action was not triggered manually, using the expected end date for the retry. I think this should be fine since our publishers shouldn't be doing this, however let me know if we need to be more specific here.