From 2c626fe854c825bde40588dee816ad26aff2876a Mon Sep 17 00:00:00 2001 From: "Jorge A. Torres" Date: Mon, 10 Apr 2023 14:11:08 -0500 Subject: [PATCH 1/7] Add auto-draft to orders list table --- .../woocommerce/src/Internal/Admin/Orders/ListTable.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/plugins/woocommerce/src/Internal/Admin/Orders/ListTable.php b/plugins/woocommerce/src/Internal/Admin/Orders/ListTable.php index 02745c54589..c105b4e4ce1 100644 --- a/plugins/woocommerce/src/Internal/Admin/Orders/ListTable.php +++ b/plugins/woocommerce/src/Internal/Admin/Orders/ListTable.php @@ -471,7 +471,7 @@ class ListTable extends WP_List_Table { $view_counts[ $slug ] = $total_in_status; } - if ( ( get_post_status_object( $slug ) )->show_in_admin_all_list ) { + if ( ( get_post_status_object( $slug ) )->show_in_admin_all_list && 'auto-draft' !== $slug ) { $all_count += $total_in_status; } } @@ -550,8 +550,9 @@ class ListTable extends WP_List_Table { array_merge( wc_get_order_statuses(), array( - 'trash' => ( get_post_status_object( 'trash' ) )->label, - 'draft' => ( get_post_status_object( 'draft' ) )->label, + 'trash' => ( get_post_status_object( 'trash' ) )->label, + 'draft' => ( get_post_status_object( 'draft' ) )->label, + 'auto-draft' => ( get_post_status_object( 'auto-draft' ) )->label, ) ), array_flip( get_post_stati( array( 'show_in_admin_status_list' => true ) ) ) @@ -916,7 +917,7 @@ class ListTable extends WP_List_Table { } // Gracefully handle legacy statuses. - if ( in_array( $order->get_status(), array( 'trash', 'draft' ), true ) ) { + if ( in_array( $order->get_status(), array( 'trash', 'draft', 'auto-draft' ), true ) ) { $status_name = ( get_post_status_object( $order->get_status() ) )->label; } else { $status_name = wc_get_order_status_name( $order->get_status() ); From 9d60bf90ed4277238b9049765bee41c3817a4af2 Mon Sep 17 00:00:00 2001 From: "Jorge A. Torres" Date: Mon, 10 Apr 2023 14:13:00 -0500 Subject: [PATCH 2/7] =?UTF-8?q?Create=20orders=20as=20=E2=80=98auto-draft?= =?UTF-8?q?=E2=80=99=20instead=20of=20=E2=80=98pending=E2=80=99=20in=20the?= =?UTF-8?q?=20admin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/Internal/Admin/Orders/PageController.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/plugins/woocommerce/src/Internal/Admin/Orders/PageController.php b/plugins/woocommerce/src/Internal/Admin/Orders/PageController.php index b2e93628844..7f6109a2dbd 100644 --- a/plugins/woocommerce/src/Internal/Admin/Orders/PageController.php +++ b/plugins/woocommerce/src/Internal/Admin/Orders/PageController.php @@ -286,9 +286,14 @@ class PageController { $this->order = new $order_class_name(); $this->order->set_object_read( false ); - $this->order->set_status( 'pending' ); + $this->order->set_status( 'auto-draft' ); $this->order->save(); + // Schedule auto-draft cleanup. We re-use the WP event here on purpose. + if ( ! wp_next_scheduled( 'wp_scheduled_auto_draft_delete' ) ) { + wp_schedule_event( time(), 'daily', 'wp_scheduled_auto_draft_delete' ); + } + $theorder = $this->order; } From dec3dda375788048fcddf5c66b318eb150e71d9d Mon Sep 17 00:00:00 2001 From: "Jorge A. Torres" Date: Mon, 10 Apr 2023 14:13:12 -0500 Subject: [PATCH 3/7] Periodically delete auto-draft orders older than a week --- .../DataStores/Orders/DataSynchronizer.php | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/plugins/woocommerce/src/Internal/DataStores/Orders/DataSynchronizer.php b/plugins/woocommerce/src/Internal/DataStores/Orders/DataSynchronizer.php index 193009492ec..d407ef946d4 100644 --- a/plugins/woocommerce/src/Internal/DataStores/Orders/DataSynchronizer.php +++ b/plugins/woocommerce/src/Internal/DataStores/Orders/DataSynchronizer.php @@ -79,6 +79,8 @@ class DataSynchronizer implements BatchProcessorInterface { self::add_action( 'deleted_post', array( $this, 'handle_deleted_post' ), 10, 2 ); self::add_action( 'woocommerce_new_order', array( $this, 'handle_updated_order' ), 100 ); self::add_action( 'woocommerce_update_order', array( $this, 'handle_updated_order' ), 100 ); + self::add_action( 'wp_scheduled_auto_draft_delete', array( $this, 'delete_auto_draft_orders' ) ); + self::add_filter( 'woocommerce_feature_description_tip', array( $this, 'handle_feature_description_tip' ), 10, 3 ); } @@ -467,6 +469,45 @@ ORDER BY orders.id ASC } } + /** + * Handles deletion of auto-draft orders in sync with WP's own auto-draft deletion. + * + * @since 7.7.0 + * + * @return void + */ + private function delete_auto_draft_orders() { + if ( ! $this->custom_orders_table_is_authoritative() ) { + return; + } + + // Fetch auto-draft orders older than 1 week. + $to_delete = wc_get_orders( + array( + 'date_query' => array( + array( + 'column' => 'date_created', + 'before' => '-1 week', + ), + ), + 'orderby' => 'date', + 'order' => 'ASC', + 'status' => 'auto-draft', + ) + ); + + foreach ( $to_delete as $order ) { + $order->delete( true ); + } + + /** + * Fires after schedueld deletion of auto-draft orders has been completed. + * + * @since 7.7.0 + */ + do_action( 'woocommerce_scheduled_auto_draft_delete' ); + } + /** * Handle the 'woocommerce_feature_description_tip' filter. * From 4873f7c2c5457e16df8a78f3cf181527d662a202 Mon Sep 17 00:00:00 2001 From: "Jorge A. Torres" Date: Mon, 10 Apr 2023 14:13:22 -0500 Subject: [PATCH 4/7] Test auto-draft deletion --- .../Orders/DataSynchronizerTests.php | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/plugins/woocommerce/tests/php/src/Internal/DataStores/Orders/DataSynchronizerTests.php b/plugins/woocommerce/tests/php/src/Internal/DataStores/Orders/DataSynchronizerTests.php index 6d1ac547a35..9fc3fe77805 100644 --- a/plugins/woocommerce/tests/php/src/Internal/DataStores/Orders/DataSynchronizerTests.php +++ b/plugins/woocommerce/tests/php/src/Internal/DataStores/Orders/DataSynchronizerTests.php @@ -28,6 +28,7 @@ class DataSynchronizerTests extends WC_Unit_Test_Case { remove_filter( 'query', array( $this, '_drop_temporary_tables' ) ); OrderHelper::delete_order_custom_tables(); // We need this since non-temporary tables won't drop automatically. OrderHelper::create_order_custom_table_if_not_exist(); + OrderHelper::toggle_cot( false ); $this->sut = wc_get_container()->get( DataSynchronizer::class ); $features_controller = wc_get_container()->get( Featurescontroller::class ); $features_controller->change_feature_enable( 'custom_order_tables', true ); @@ -311,4 +312,43 @@ class DataSynchronizerTests extends WC_Unit_Test_Case { $this->assertEquals( $order2->get_id(), $orders_to_migrate[0] ); $this->assertEquals( $max_id + 1, $orders_to_migrate[1] ); } + + /** + * Tests that auto-draft orders older than 1 week are automatically deleted when WP does the same for posts. + * + * @return void + */ + public function test_auto_draft_deletion(): void { + OrderHelper::toggle_cot( true ); + + $order1 = new \WC_Order(); + $order1->set_status( 'auto-draft' ); + $order1->set_date_created( strtotime( '-10 days' ) ); + $order1->save(); + + $order2 = new \WC_Order(); + $order2->set_status( 'auto-draft' ); + $order2->save(); + + $order3 = new \WC_Order(); + $order3->set_status( 'processing' ); + $order3->save(); + + // Run WP's auto-draft delete. + do_action( 'wp_scheduled_auto_draft_delete' ); // phpcs:ignore WooCommerce.Commenting.CommentHooks.HookCommentWrongStyle + + $orders = wc_get_orders( + array( + 'status' => 'all', + 'limit' => -1, + 'return' => 'ids', + ) + ); + + // Confirm that only $order1 is deleted when the action runs but the other orders remain intact. + $this->assertContains( $order2->get_id(), $orders ); + $this->assertContains( $order3->get_id(), $orders ); + $this->assertNotContains( $order1->get_id(), $orders ); + } + } From 4e16e6117b317b0cff484a025a01abe2775a565a Mon Sep 17 00:00:00 2001 From: "Jorge A. Torres" Date: Mon, 10 Apr 2023 14:13:28 -0500 Subject: [PATCH 5/7] Add changelog --- plugins/woocommerce/changelog/fix-36749 | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 plugins/woocommerce/changelog/fix-36749 diff --git a/plugins/woocommerce/changelog/fix-36749 b/plugins/woocommerce/changelog/fix-36749 new file mode 100644 index 00000000000..3dbb28e7f2b --- /dev/null +++ b/plugins/woocommerce/changelog/fix-36749 @@ -0,0 +1,4 @@ +Significance: patch +Type: add + +Create orders as 'auto-draft' by default in admin. From 18d00cadd0e0c851d5a41ec54a76b8f7b5b5647a Mon Sep 17 00:00:00 2001 From: "Jorge A. Torres" Date: Mon, 10 Apr 2023 15:11:03 -0500 Subject: [PATCH 6/7] =?UTF-8?q?Consider=20=E2=80=98auto-draft=E2=80=99=20t?= =?UTF-8?q?he=20same=20as=20=E2=80=98pending=E2=80=99=20for=20orders?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This for backwards compat with CPT --- plugins/woocommerce/includes/abstracts/abstract-wc-order.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/woocommerce/includes/abstracts/abstract-wc-order.php b/plugins/woocommerce/includes/abstracts/abstract-wc-order.php index 717800b4c4c..e4afa9c5be7 100644 --- a/plugins/woocommerce/includes/abstracts/abstract-wc-order.php +++ b/plugins/woocommerce/includes/abstracts/abstract-wc-order.php @@ -638,7 +638,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order { } // If the old status is set but unknown (e.g. draft) assume its pending for action usage. - if ( $old_status && ! in_array( 'wc-' . $old_status, $this->get_valid_statuses(), true ) && ! in_array( $old_status, $status_exceptions, true ) ) { + if ( $old_status && ( ( ! in_array( 'wc-' . $old_status, $this->get_valid_statuses(), true ) && ! in_array( $old_status, $status_exceptions, true ) ) || 'auto-draft' === $old_status ) ) { $old_status = 'pending'; } } From 3c27123aa2cf83c8d579846e5ebd3bb733c368aa Mon Sep 17 00:00:00 2001 From: "Jorge A. Torres" Date: Tue, 2 May 2023 17:11:36 -0300 Subject: [PATCH 7/7] Make changes per review --- plugins/woocommerce/includes/abstracts/abstract-wc-order.php | 2 +- .../src/Internal/DataStores/Orders/DataSynchronizer.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/woocommerce/includes/abstracts/abstract-wc-order.php b/plugins/woocommerce/includes/abstracts/abstract-wc-order.php index e4afa9c5be7..2bcad8535db 100644 --- a/plugins/woocommerce/includes/abstracts/abstract-wc-order.php +++ b/plugins/woocommerce/includes/abstracts/abstract-wc-order.php @@ -638,7 +638,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order { } // If the old status is set but unknown (e.g. draft) assume its pending for action usage. - if ( $old_status && ( ( ! in_array( 'wc-' . $old_status, $this->get_valid_statuses(), true ) && ! in_array( $old_status, $status_exceptions, true ) ) || 'auto-draft' === $old_status ) ) { + if ( $old_status && ( 'auto-draft' === $old_status || ( ! in_array( 'wc-' . $old_status, $this->get_valid_statuses(), true ) && ! in_array( $old_status, $status_exceptions, true ) ) ) ) { $old_status = 'pending'; } } diff --git a/plugins/woocommerce/src/Internal/DataStores/Orders/DataSynchronizer.php b/plugins/woocommerce/src/Internal/DataStores/Orders/DataSynchronizer.php index d407ef946d4..c85dd0f78c8 100644 --- a/plugins/woocommerce/src/Internal/DataStores/Orders/DataSynchronizer.php +++ b/plugins/woocommerce/src/Internal/DataStores/Orders/DataSynchronizer.php @@ -79,7 +79,7 @@ class DataSynchronizer implements BatchProcessorInterface { self::add_action( 'deleted_post', array( $this, 'handle_deleted_post' ), 10, 2 ); self::add_action( 'woocommerce_new_order', array( $this, 'handle_updated_order' ), 100 ); self::add_action( 'woocommerce_update_order', array( $this, 'handle_updated_order' ), 100 ); - self::add_action( 'wp_scheduled_auto_draft_delete', array( $this, 'delete_auto_draft_orders' ) ); + self::add_action( 'wp_scheduled_auto_draft_delete', array( $this, 'delete_auto_draft_orders' ), 9 ); self::add_filter( 'woocommerce_feature_description_tip', array( $this, 'handle_feature_description_tip' ), 10, 3 ); }