Fix the child order upshifting when parent order is deleted (#38199)

This commit is contained in:
Vedanshu Jain 2023-05-15 16:03:35 +05:30 committed by GitHub
commit 2d6e433e05
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 88 additions and 16 deletions

View File

@ -0,0 +1,4 @@
Significance: patch
Type: fix
Fix: when order is deleted child orders should be deleted too, not set to parent id 0, unless the post type for the order is hierarchical

View File

@ -118,6 +118,13 @@ class OrdersTableDataStore extends \Abstract_WC_Order_Data_Store_CPT implements
*/
private $error_logger;
/**
* The instance of the LegacyProxy object to use.
*
* @var LegacyProxy
*/
private $legacy_proxy;
/**
* Initialize the object.
*
@ -131,6 +138,7 @@ class OrdersTableDataStore extends \Abstract_WC_Order_Data_Store_CPT implements
final public function init( OrdersTableDataStoreMeta $data_store_meta, DatabaseUtil $database_util, LegacyProxy $legacy_proxy ) {
$this->data_store_meta = $data_store_meta;
$this->database_util = $database_util;
$this->legacy_proxy = $legacy_proxy;
$this->error_logger = $legacy_proxy->call_function( 'wc_get_logger' );
$this->internal_meta_keys = $this->get_internal_meta_keys();
}
@ -1785,7 +1793,7 @@ FROM $order_meta_table
*/
do_action( 'woocommerce_before_delete_order', $order_id, $order );
$this->upshift_child_orders( $order );
$this->upshift_or_delete_child_orders( $order );
$this->delete_order_data_from_custom_order_tables( $order_id );
$this->delete_items( $order );
@ -1823,23 +1831,44 @@ FROM $order_meta_table
}
/**
* Helper method to set child orders to the parent order's parent.
* Set the parent id of child orders to the parent order's parent if the post type
* for the order is hierarchical, just delete the child orders otherwise.
*
* @param \WC_Abstract_Order $order Order object.
*
* @return void
*/
private function upshift_child_orders( $order ) {
private function upshift_or_delete_child_orders( $order ) {
global $wpdb;
$order_table = self::get_orders_table_name();
$order_parent = $order->get_parent_id();
$wpdb->update(
$order_table,
array( 'parent_order_id' => $order_parent ),
array( 'parent_order_id' => $order->get_id() ),
array( '%d' ),
array( '%d' )
);
$order_table = self::get_orders_table_name();
$order_parent_id = $order->get_parent_id();
if ( $this->legacy_proxy->call_function( 'is_post_type_hierarchical', $order->get_type() ) ) {
$wpdb->update(
$order_table,
array( 'parent_order_id' => $order_parent_id ),
array( 'parent_order_id' => $order->get_id() ),
array( '%d' ),
array( '%d' )
);
} else {
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
$child_order_ids = $wpdb->get_col(
$wpdb->prepare(
"SELECT id FROM $order_table WHERE parent_order_id=%d",
$order->get_id()
)
);
// phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
foreach ( $child_order_ids as $child_order_id ) {
$child_order = wc_get_order( $child_order_id );
if ( $child_order ) {
$child_order->delete( true );
}
}
}
}
/**

View File

@ -50,6 +50,7 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
* Initializes system under test.
*/
public function setUp(): void {
$this->reset_legacy_proxy_mocks();
$this->original_time_zone = wp_timezone_string();
//phpcs:ignore WordPress.DateTime.RestrictedFunctions.timezone_change_date_default_timezone_set -- We need to change the timezone to test the date sync fields.
update_option( 'timezone_string', 'Asia/Kolkata' );
@ -58,8 +59,10 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
$this->setup_cot();
$this->cot_state = OrderUtil::custom_orders_table_usage_is_enabled();
$this->toggle_cot( false );
$this->sut = wc_get_container()->get( OrdersTableDataStore::class );
$this->migrator = wc_get_container()->get( PostsToOrdersMigrationController::class );
$container = wc_get_container();
$container->reset_all_resolved();
$this->sut = $container->get( OrdersTableDataStore::class );
$this->migrator = $container->get( PostsToOrdersMigrationController::class );
$this->cpt_data_store = new WC_Order_Data_Store_CPT();
}
@ -2020,9 +2023,17 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
}
/**
* @testDox When parent order is deleted, child orders should be upshifted.
* @testDox When parent order is deleted, and the post order type is hierarchical, child orders should be upshifted.
*/
public function test_child_orders_are_promoted_when_parent_is_deleted() {
public function test_child_orders_are_promoted_when_parent_is_deleted_if_order_type_is_hierarchical() {
$this->register_legacy_proxy_function_mocks(
array(
'is_post_type_hierarchical' => function( $post_type ) {
return 'shop_order' === $post_type || is_post_type_hierarchical( $post_type );
},
)
);
$this->toggle_cot( true );
$order = new WC_Order();
$order->save();
@ -2038,6 +2049,34 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
$this->assertEquals( 0, $child_order->get_parent_id() );
}
/**
* @testDox When parent order is deleted, and the post order type is NOT hierarchical, child orders should be deleted.
*/
public function test_child_orders_are_promoted_when_parent_is_deleted_if_order_type_is_not_hierarchical() {
$this->register_legacy_proxy_function_mocks(
array(
'is_post_type_hierarchical' => function( $post_type ) {
return 'shop_order' === $post_type ? false : is_post_type_hierarchical( $post_type );
},
)
);
$this->toggle_cot( true );
$order = new WC_Order();
$order->save();
$child_order = new WC_Order();
$child_order->set_parent_id( $order->get_id() );
$child_order->save();
$this->assertEquals( $order->get_id(), $child_order->get_parent_id() );
$this->sut->delete( $order, array( 'force_delete' => true ) );
$child_order = wc_get_order( $child_order->get_id() );
$this->assertFalse( $child_order );
}
/**
* @testDox Make sure get_order return false when checking an order of different order types without warning.
*/