Skip to content

Commit

Permalink
Merge branch 'trunk' into issue/wcs-4535
Browse files Browse the repository at this point in the history
  • Loading branch information
james-allan authored Sep 19, 2023
2 parents 84f4aae + c212aa3 commit 8797c58
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 82 deletions.
4 changes: 2 additions & 2 deletions assets/src/js/filters/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* External dependencies
*/
import { __, sprintf } from '@wordpress/i18n';
import { __experimentalRegisterCheckoutFilters } from '@woocommerce/blocks-checkout';
import { registerCheckoutFilters } from '@woocommerce/blocks-checkout';

/**
* Internal dependencies
Expand All @@ -25,7 +25,7 @@ import {
* If an error is thrown, it would be visible for store managers only.
*/
export const registerFilters = () => {
__experimentalRegisterCheckoutFilters( 'woocommerce-subscriptions', {
registerCheckoutFilters( 'woocommerce-subscriptions', {
// subscriptions data here comes from register_endpoint_data /cart registration.
totalLabel: ( label, { subscriptions } ) => {
if ( 0 < subscriptions?.length ) {
Expand Down
4 changes: 3 additions & 1 deletion changelog.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
*** WooCommerce Subscriptions Core Changelog ***

= 6.3.0 - 2023-xx-xx =
= 6.3.0 - xxxx-xx-xx =
* Fix - When HPOS is enabled, make the orders_by_type_query filter box work in the WooCommerce orders screen.
* Fix - Resolved an issue that caused paying for failed/pending parent orders that include Product Add-ons to not calculate the correct total.
* Add - Introduce the "Subscription Relationship" column under the Orders list admin page when HPOS is enabled.

= 6.2.0 - 2023-08-10 =
* Add - Introduce an updated empty state screen for the WooCommerce > Subscriptions list table.
Expand Down
252 changes: 173 additions & 79 deletions includes/class-wc-subscriptions-order.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ public static function init() {
add_filter( 'manage_edit-shop_order_columns', __CLASS__ . '::add_contains_subscription_column' );
add_action( 'manage_shop_order_posts_custom_column', __CLASS__ . '::add_contains_subscription_column_content', 10, 1 );

// HPOS - Add column that indicates whether an order is parent or renewal for a subscription.
add_filter( 'woocommerce_shop_order_list_table_columns', __CLASS__ . '::add_contains_subscription_column' );
add_action( 'woocommerce_shop_order_list_table_custom_column', __CLASS__ . '::add_contains_subscription_column_content_orders_table', 10, 2 );

// Record initial payment against the subscription & set start date based on that payment
add_action( 'woocommerce_order_status_changed', __CLASS__ . '::maybe_record_subscription_payment', 9, 3 );

Expand All @@ -44,8 +48,13 @@ public static function init() {
// Add dropdown to admin orders screen to filter on order type
add_action( 'restrict_manage_posts', __CLASS__ . '::restrict_manage_subscriptions', 50 );

// For HPOS - Add dropdown to admin orders screen to filter on order type.
add_action( 'woocommerce_order_list_table_restrict_manage_orders', __CLASS__ . '::restrict_manage_subscriptions_hpos' );

// Add filter to queries on admin orders screen to filter on order type. To avoid WC overriding our query args, we need to hook on after them on 10.
add_filter( 'request', __CLASS__ . '::orders_by_type_query', 11 );
// HPOS - Add filter to queries on admin orders screen to filter on order type. Only triggered for the shop_order order type.
add_filter( 'woocommerce_shop_order_list_table_prepare_items_query_args', __CLASS__ . '::maybe_modify_orders_by_type_query_from_request', 11 );

// Don't display migrated order item meta on the Edit Order screen
add_filter( 'woocommerce_hidden_order_itemmeta', __CLASS__ . '::hide_order_itemmeta' );
Expand Down Expand Up @@ -411,26 +420,36 @@ public static function add_contains_subscription_column( $columns ) {
}

/**
* Add column content to the WooCommerce -> Orders admin screen to indicate whether an
* order is a parent of a subscription, a renewal order for a subscription, or a
* regular order.
*
* @param string $column The string of the current column
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.1
* Add column content to the WooCommerce -> Orders admin screen to indicate whether an
* order is a parent of a subscription, a renewal order for a subscription, or a regular order.
*
* @see add_contains_subscription_column_content_orders_table For when HPOS is enabled.
*
* @param string $column The string of the current column
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.1
*/
public static function add_contains_subscription_column_content( $column ) {
global $post;

if ( 'subscription_relationship' == $column ) {
if ( wcs_order_contains_subscription( $post->ID, 'renewal' ) ) {
echo '<span class="subscription_renewal_order tips" data-tip="' . esc_attr__( 'Renewal Order', 'woocommerce-subscriptions' ) . '"></span>';
} elseif ( wcs_order_contains_subscription( $post->ID, 'resubscribe' ) ) {
echo '<span class="subscription_resubscribe_order tips" data-tip="' . esc_attr__( 'Resubscribe Order', 'woocommerce-subscriptions' ) . '"></span>';
} elseif ( wcs_order_contains_subscription( $post->ID, 'parent' ) ) {
echo '<span class="subscription_parent_order tips" data-tip="' . esc_attr__( 'Parent Order', 'woocommerce-subscriptions' ) . '"></span>';
} else {
echo '<span class="normal_order">&ndash;</span>';
}
if ( 'subscription_relationship' === $column ) {
self::render_contains_subscription_column_content( $post->ID );
}
}

/**
* Add column content to the WooCommerce -> Orders admin screen to indicate whether an
* order is a parent of a subscription, a renewal order for a subscription, or a regular order.
*
* @see add_contains_subscription_column_content For when HPOS is disabled.
*
* @since 6.3.0
*
* @param string $column_name Identifier for the custom column.
* @param WC_Order $order Current WooCommerce order object.
*/
public static function add_contains_subscription_column_content_orders_table( string $column_name, WC_Order $order ) {
if ( 'subscription_relationship' === $column_name ) {
self::render_contains_subscription_column_content( $order->get_id() );
}
}

Expand Down Expand Up @@ -708,33 +727,26 @@ public static function add_sub_info_email( $order, $is_admin_email, $plaintext =
public static function restrict_manage_subscriptions() {
global $typenow;

if ( 'shop_order' != $typenow ) {
if ( 'shop_order' !== $typenow ) {
return;
}?>
<select name='shop_order_subtype' id='dropdown_shop_order_subtype'>
<option value=""><?php esc_html_e( 'All orders types', 'woocommerce-subscriptions' ); ?></option>
<?php
$order_types = apply_filters( 'woocommerce_subscriptions_order_type_dropdown', array(
'original' => _x( 'Original', 'An order type', 'woocommerce-subscriptions' ),
'parent' => _x( 'Subscription Parent', 'An order type', 'woocommerce-subscriptions' ),
'renewal' => _x( 'Subscription Renewal', 'An order type', 'woocommerce-subscriptions' ),
'resubscribe' => _x( 'Subscription Resubscribe', 'An order type', 'woocommerce-subscriptions' ),
'switch' => _x( 'Subscription Switch', 'An order type', 'woocommerce-subscriptions' ),
'regular' => _x( 'Non-subscription', 'An order type', 'woocommerce-subscriptions' ),
) );
}

foreach ( $order_types as $order_type_key => $order_type_description ) {
echo '<option value="' . esc_attr( $order_type_key ) . '"';
self::render_restrict_manage_subscriptions_dropdown();
}

if ( isset( $_GET['shop_order_subtype'] ) && $_GET['shop_order_subtype'] ) {
selected( $order_type_key, $_GET['shop_order_subtype'] );
}
/**
* When HPOS is active, adds admin dropdown for order types to Woocommerce -> Orders screen
*
* @since 6.3.0
*
* @param string $order_type The order type.
*/
public static function restrict_manage_subscriptions_hpos( string $order_type ) {
if ( 'shop_order' !== $order_type ) {
return;
}

echo '>' . esc_html( $order_type_description ) . '</option>';
}
?>
</select>
<?php
self::render_restrict_manage_subscriptions_dropdown();
}

/**
Expand All @@ -746,62 +758,84 @@ public static function restrict_manage_subscriptions() {
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.5
*/
public static function orders_by_type_query( $vars ) {
global $typenow, $wpdb;
global $typenow;

if ( 'shop_order' == $typenow && ! empty( $_GET['shop_order_subtype'] ) ) {
if ( 'shop_order' === $typenow ) {
return self::maybe_modify_orders_by_type_query_from_request( $vars );
}

if ( 'original' == $_GET['shop_order_subtype'] || 'regular' == $_GET['shop_order_subtype'] ) {
return $vars;
}

$vars['meta_query']['relation'] = 'AND';
/**
* Filters the arguments to be pased to `wc_get_orders()` under the Woocommerce -> Orders screen.
*
* @since 6.3.0
*
* @param array $order_query_args Arguments to be passed to `wc_get_orders()`.
*
* @return array
*/
public static function maybe_modify_orders_by_type_query_from_request( array $order_query_args ): array {
// The order subtype selected by the user in the dropdown.
$selected_shop_order_subtype = isset( $_GET['shop_order_subtype'] ) ? wc_clean( wp_unslash( $_GET['shop_order_subtype'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended

$vars['meta_query'][] = array(
'key' => '_subscription_renewal',
'compare' => 'NOT EXISTS',
);
// Don't modify the query args if no order subtype was selected.
if ( empty( $selected_shop_order_subtype ) ) {
return $order_query_args;
}

$vars['meta_query'][] = array(
'key' => '_subscription_switch',
'compare' => 'NOT EXISTS',
);
if ( 'original' === $selected_shop_order_subtype || 'regular' === $selected_shop_order_subtype ) {

} elseif ( 'parent' == $_GET['shop_order_subtype'] ) {
$order_query_args['meta_query']['relation'] = 'AND';

$vars['post__in'] = wcs_get_subscription_orders();
$order_query_args['meta_query'][] = array(
'key' => '_subscription_renewal',
'compare' => 'NOT EXISTS',
);

} else {
$order_query_args['meta_query'][] = array(
'key' => '_subscription_switch',
'compare' => 'NOT EXISTS',
);

switch ( $_GET['shop_order_subtype'] ) {
case 'renewal':
$meta_key = '_subscription_renewal';
break;
case 'resubscribe':
$meta_key = '_subscription_resubscribe';
break;
case 'switch':
$meta_key = '_subscription_switch';
break;
default:
$meta_key = '';
break;
}
} elseif ( 'parent' === $selected_shop_order_subtype ) {

$meta_key = apply_filters( 'woocommerce_subscriptions_admin_order_type_filter_meta_key', $meta_key, $_GET['shop_order_subtype'] );
$order_query_args['post__in'] = wcs_get_subscription_orders();

if ( ! empty( $meta_key ) ) {
$vars['meta_query'][] = array(
'key' => $meta_key,
'compare' => 'EXISTS',
);
}
} else {

switch ( $selected_shop_order_subtype ) {
case 'renewal':
$meta_key = '_subscription_renewal';
break;
case 'resubscribe':
$meta_key = '_subscription_resubscribe';
break;
case 'switch':
$meta_key = '_subscription_switch';
break;
default:
$meta_key = '';
break;
}

// Also exclude parent orders from non-subscription query
if ( 'regular' == $_GET['shop_order_subtype'] ) {
$vars['post__not_in'] = wcs_get_subscription_orders();
$meta_key = apply_filters( 'woocommerce_subscriptions_admin_order_type_filter_meta_key', $meta_key, $selected_shop_order_subtype );

if ( ! empty( $meta_key ) ) {
$order_query_args['meta_query'][] = array(
'key' => $meta_key,
'compare' => 'EXISTS',
);
}
}

return $vars;
// Also exclude parent orders from non-subscription query
if ( 'regular' === $selected_shop_order_subtype ) {
$order_query_args['post__not_in'] = wcs_get_subscription_orders();
}

return $order_query_args;
}

/**
Expand Down Expand Up @@ -2280,4 +2314,64 @@ public static function get_meta( $order, $meta_key, $default = 0 ) {

return $meta_value;
}

/**
* Prints the HTML for the admin dropdown for order types to Woocommerce -> Orders screen.
*
* @since 6.3.0
*/
private static function render_restrict_manage_subscriptions_dropdown() {
$order_types = apply_filters(
'woocommerce_subscriptions_order_type_dropdown',
array(
'original' => _x( 'Original', 'An order type', 'woocommerce-subscriptions' ),
'parent' => _x( 'Subscription Parent', 'An order type', 'woocommerce-subscriptions' ),
'renewal' => _x( 'Subscription Renewal', 'An order type', 'woocommerce-subscriptions' ),
'resubscribe' => _x( 'Subscription Resubscribe', 'An order type', 'woocommerce-subscriptions' ),
'switch' => _x( 'Subscription Switch', 'An order type', 'woocommerce-subscriptions' ),
'regular' => _x( 'Non-subscription', 'An order type', 'woocommerce-subscriptions' ),
)
);

// phpcs:ignore WordPress.Security.NonceVerification.Recommended
$selected_shop_order_subtype = isset( $_GET['shop_order_subtype'] ) ? wc_clean( wp_unslash( $_GET['shop_order_subtype'] ) ) : '';

?>
<select name='shop_order_subtype' id='dropdown_shop_order_subtype'>
<option value=""><?php esc_html_e( 'All orders types', 'woocommerce-subscriptions' ); ?></option>

<?php foreach ( $order_types as $order_type_key => $order_type_description ) : ?>
<option
value="<?php echo esc_attr( $order_type_key ); ?>"
<?php selected( $selected_shop_order_subtype, $order_type_key ); ?>
>
<?php echo esc_html( $order_type_description ); ?>
</option>
<?php endforeach; ?>

</select>
<?php
}

/**
* Renders the contents of the "contains_subscription" column.
*
* This column indicates whether an order is a parent of a subscription,
* a renewal order for a subscription, or a regular order.
*
* @since 6.3.0
*
* @param integer $order_id The ID of the order in the current row.
*/
private static function render_contains_subscription_column_content( int $order_id ) {
if ( wcs_order_contains_subscription( $order_id, 'renewal' ) ) {
echo '<span class="subscription_renewal_order tips" data-tip="' . esc_attr__( 'Renewal Order', 'woocommerce-subscriptions' ) . '"></span>';
} elseif ( wcs_order_contains_subscription( $order_id, 'resubscribe' ) ) {
echo '<span class="subscription_resubscribe_order tips" data-tip="' . esc_attr__( 'Resubscribe Order', 'woocommerce-subscriptions' ) . '"></span>';
} elseif ( wcs_order_contains_subscription( $order_id, 'parent' ) ) {
echo '<span class="subscription_parent_order tips" data-tip="' . esc_attr__( 'Parent Order', 'woocommerce-subscriptions' ) . '"></span>';
} else {
echo '<span class="normal_order">&ndash;</span>';
}
}
}

0 comments on commit 8797c58

Please sign in to comment.