Skip to content

Commit d6ef041

Browse files
committed
"deleteOrderItems" implemented and tested.
1 parent 6e28061 commit d6ef041

File tree

6 files changed

+318
-0
lines changed

6 files changed

+318
-0
lines changed

includes/class-actions.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
use WPGraphQL\Extensions\WooCommerce\Mutation\Order_Create;
7878
use WPGraphQL\Extensions\WooCommerce\Mutation\Order_Update;
7979
use WPGraphQL\Extensions\WooCommerce\Mutation\Order_Delete;
80+
use WPGraphQL\Extensions\WooCommerce\Mutation\Order_Delete_Items;
8081
use WPGraphQL\Extensions\WooCommerce\Mutation\Checkout;
8182

8283
/**
@@ -176,6 +177,7 @@ public static function graphql_register_types() {
176177
Order_Create::register_mutation();
177178
Order_Update::register_mutation();
178179
Order_Delete::register_mutation();
180+
Order_Delete_Items::register_mutation();
179181
Checkout::register_mutation();
180182
}
181183
}
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
<?php
2+
/**
3+
* Mutation - deleteOrderItems
4+
*
5+
* Registers mutation for delete an items from an order.
6+
*
7+
* @package WPGraphQL\Extensions\WooCommerce\Mutation
8+
* @since 0.2.0
9+
*/
10+
11+
namespace WPGraphQL\Extensions\WooCommerce\Mutation;
12+
13+
use GraphQL\Error\UserError;
14+
use GraphQL\Type\Definition\ResolveInfo;
15+
use GraphQLRelay\Relay;
16+
use WPGraphQL\AppContext;
17+
use WPGraphQL\Extensions\WooCommerce\Data\Mutation\Order_Mutation;
18+
use WPGraphQL\Extensions\WooCommerce\Model\Order;
19+
20+
/**
21+
* Class Order_Delete_Items
22+
*/
23+
class Order_Delete_Items {
24+
/**
25+
* Registers mutation
26+
*/
27+
public static function register_mutation() {
28+
register_graphql_mutation(
29+
'deleteOrderItems',
30+
array(
31+
'inputFields' => self::get_input_fields(),
32+
'outputFields' => self::get_output_fields(),
33+
'mutateAndGetPayload' => self::mutate_and_get_payload(),
34+
)
35+
);
36+
}
37+
38+
/**
39+
* Defines the mutation input field configuration
40+
*
41+
* @return array
42+
*/
43+
public static function get_input_fields() {
44+
$input_fields = array_merge(
45+
array(
46+
'id' => array(
47+
'type' => 'ID',
48+
'description' => __( 'Order global ID', 'wp-graphql-woocommerce' ),
49+
),
50+
'orderId' => array(
51+
'type' => 'Int',
52+
'description' => __( 'Order WP ID', 'wp-graphql-woocommerce' ),
53+
),
54+
'itemIds' => array(
55+
'type' => array( 'list_of' => 'Int' ),
56+
'description' => __( 'ID Order items being deleted', 'wp-graphql-woocommerce' ),
57+
),
58+
)
59+
);
60+
61+
return $input_fields;
62+
}
63+
64+
/**
65+
* Defines the mutation output field configuration
66+
*
67+
* @return array
68+
*/
69+
public static function get_output_fields() {
70+
return array(
71+
'order' => array(
72+
'type' => 'Order',
73+
'resolve' => function( $payload ) {
74+
return $payload['order'];
75+
},
76+
),
77+
);
78+
}
79+
80+
/**
81+
* Defines the mutation data modification closure.
82+
*
83+
* @return callable
84+
*/
85+
public static function mutate_and_get_payload() {
86+
return function( $input, AppContext $context, ResolveInfo $info ) {
87+
if ( Order_Mutation::authorized( 'delete', $input, $context, $info ) ) {
88+
throw new UserError( __( 'User does not have the capabilities necessary to delete an order.', 'wp-graphql-woocommerce' ) );
89+
}
90+
91+
// Retrieve order ID.
92+
$order_id = null;
93+
if ( ! empty( $input['id'] ) ) {
94+
$id_components = Relay::fromGlobalId( $input['id'] );
95+
if ( empty( $id_components['id'] ) || empty( $id_components['type'] ) ) {
96+
throw new UserError( __( 'The "id" provided is invalid', 'wp-graphql-woocommerce' ) );
97+
}
98+
$order_id = absint( $id_components['id'] );
99+
} elseif ( ! empty( $input['orderId'] ) ) {
100+
$order_id = absint( $input['orderId'] );
101+
} else {
102+
throw new UserError( __( 'No order ID provided.', 'wp-graphql-woocommerce' ) );
103+
}
104+
105+
// Confirm item IDs.
106+
if ( empty( $input['itemIds'] ) ) {
107+
throw new UserError( __( 'No item IDs provided.', 'wp-graphql-woocommerce' ) );
108+
} elseif ( ! is_array( $input['itemIds'] ) ) {
109+
throw new UserError( __( 'The "itemIds" provided is invalid', 'wp-graphql-woocommerce' ) );
110+
}
111+
$ids = $input['itemIds'];
112+
113+
// Get Order model instance for output.
114+
$order = new Order( $order_id );
115+
116+
// Cache items to prevent null value errors.
117+
// @codingStandardsIgnoreStart
118+
$order->downloadableItems;
119+
$order->get_items();
120+
$order->get_items( 'fee' );
121+
$order->get_items( 'shipping' );
122+
$order->get_items( 'tax' );
123+
$order->get_items( 'coupon' );
124+
// @codingStandardsIgnoreEnd.
125+
126+
// Get working order model.
127+
$working_order = new Order( $order_id );
128+
129+
/**
130+
* Action called before order is deleted.
131+
*
132+
* @param WC_Order $order WC_Order instance.
133+
* @param array $input Input data describing order.
134+
* @param AppContext $context Request AppContext instance.
135+
* @param ResolveInfo $info Request ResolveInfo instance.
136+
*/
137+
do_action( 'woocommerce_graphql_before_order_items_delete', $ids, $working_order, $input, $context, $info );
138+
139+
// Delete order.
140+
$errors = '';
141+
foreach ( $ids as $id ) {
142+
$working_order->remove_item( $id );
143+
}
144+
$working_order->save();
145+
146+
/**
147+
* Action called before order is deleted.
148+
*
149+
* @param WC_Order $order WC_Order instance.
150+
* @param array $input Input data describing order
151+
* @param AppContext $context Request AppContext instance.
152+
* @param ResolveInfo $info Request ResolveInfo instance.
153+
*/
154+
do_action( 'woocommerce_graphql_after_order_delete', $ids, $working_order, $input, $context, $info );
155+
156+
return array( 'order' => $order );
157+
};
158+
}
159+
}

includes/mutation/class-order-update-items.php

Whitespace-only changes.

tests/wpunit/OrderMutationsTest.php

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -922,4 +922,159 @@ public function testDeleteOrderMutation() {
922922
$this->assertEquals( $initial_response['data']['createOrder'], $actual['data']['deleteOrder'] );
923923
$this->assertFalse( \WC_Order_Factory::get_order( $order->get_id() ) );
924924
}
925+
926+
public function testDeleteOrderItemsMutation() {
927+
// Create products and coupons to be used in order creation.
928+
$variable = $this->variation->create( $this->product->create_variable() );
929+
$product_ids = array(
930+
$this->product->create_simple(),
931+
$this->product->create_simple(),
932+
$variable['product'],
933+
);
934+
$coupon = new WC_Coupon(
935+
$this->coupon->create( array( 'product_ids' => $product_ids ) )
936+
);
937+
938+
// Create initial order input.
939+
$initial_input = array(
940+
'clientMutationId' => 'someId',
941+
'customerId' => $this->customer,
942+
'customerNote' => 'Customer test note',
943+
'coupons' => array(
944+
$coupon->get_code(),
945+
),
946+
'paymentMethod' => 'bacs',
947+
'paymentMethodTitle' => 'Direct Bank Transfer',
948+
'billing' => array(
949+
'firstName' => 'May',
950+
'lastName' => 'Parker',
951+
'address1' => '20 Ingram St',
952+
'city' => 'New York City',
953+
'state' => 'NY',
954+
'postcode' => '12345',
955+
'country' => 'US',
956+
'email' => '[email protected]',
957+
'phone' => '555-555-1234',
958+
),
959+
'shipping' => array(
960+
'firstName' => 'May',
961+
'lastName' => 'Parker',
962+
'address1' => '20 Ingram St',
963+
'city' => 'New York City',
964+
'state' => 'NY',
965+
'postcode' => '12345',
966+
'country' => 'US',
967+
),
968+
'lineItems' => array(
969+
array(
970+
'productId' => $product_ids[0],
971+
'quantity' => 5,
972+
'metaData' => array(
973+
array(
974+
'key' => 'test_product_key',
975+
'value' => 'test product value',
976+
),
977+
),
978+
),
979+
array(
980+
'productId' => $product_ids[1],
981+
'quantity' => 2,
982+
),
983+
array(
984+
'productId' => $product_ids[2],
985+
'quantity' => 6,
986+
'variationId' => $variable['variations'][0]
987+
),
988+
),
989+
'shippingLines' => array(
990+
array(
991+
'methodId' => 'flat_rate_shipping',
992+
'methodTitle' => 'Flat Rate shipping',
993+
'total' => '10',
994+
),
995+
),
996+
'feeLines' => array(
997+
array(
998+
'name' => 'Some Fee',
999+
'taxStatus' => 'TAXABLE',
1000+
'total' => '100',
1001+
'taxClass' => 'STANDARD',
1002+
),
1003+
),
1004+
'metaData' => array(
1005+
array(
1006+
'key' => 'test_key',
1007+
'value' => 'test value',
1008+
),
1009+
),
1010+
'isPaid' => false,
1011+
);
1012+
1013+
// Create order to delete.
1014+
wp_set_current_user( $this->shop_manager );
1015+
$initial_response = $this->orderMutation( $initial_input );
1016+
1017+
// use --debug flag to view.
1018+
codecept_debug( $initial_response );
1019+
1020+
// Clear loader cache.
1021+
$this->getModule('\Helper\Wpunit')->clear_loader_cache( 'wc_post_crud' );
1022+
1023+
// Retrieve order and items
1024+
$order_id = $initial_response['data']['createOrder']['order']['orderId'];
1025+
$order = \WC_Order_Factory::get_order( $order_id );
1026+
$line_items = $order->get_items();
1027+
$shipping_lines = $order->get_items( 'shipping' );
1028+
$fee_lines = $order->get_items( 'fee' );
1029+
$coupon_lines = $order->get_items( 'coupon' );
1030+
$tax_lines = $order->get_items( 'tax' );
1031+
1032+
// Create DeleteOrderInput.
1033+
$deleted_items_input = array(
1034+
'clientMutationId' => 'someId',
1035+
'orderId' => $order->get_id(),
1036+
'itemIds' => array(
1037+
current( $line_items )->get_id(),
1038+
current( $coupon_lines )->get_id(),
1039+
),
1040+
);
1041+
1042+
/**
1043+
* Assertion One
1044+
*
1045+
* User without necessary capabilities cannot delete order an order.
1046+
*/
1047+
wp_set_current_user( $this->customer );
1048+
$actual = $this->orderMutation(
1049+
$deleted_items_input,
1050+
'deleteOrderItems',
1051+
'DeleteOrderItemsInput'
1052+
);
1053+
1054+
// use --debug flag to view.
1055+
codecept_debug( $actual );
1056+
1057+
$this->assertArrayHasKey('errors', $actual );
1058+
1059+
/**
1060+
* Assertion Two
1061+
*
1062+
* Test mutation and input.
1063+
*/
1064+
wp_set_current_user( $this->shop_manager );
1065+
$actual = $this->orderMutation(
1066+
$deleted_items_input,
1067+
'deleteOrderItems',
1068+
'DeleteOrderItemsInput'
1069+
);
1070+
1071+
// use --debug flag to view.
1072+
codecept_debug( $actual );
1073+
1074+
$this->assertArrayHasKey( 'data', $actual );
1075+
$this->assertArrayHasKey( 'deleteOrderItems', $actual['data'] );
1076+
$this->assertEquals( $initial_response['data']['createOrder'], $actual['data']['deleteOrderItems'] );
1077+
$this->assertFalse( \WC_Order_Factory::get_order_item( current( $line_items ) ) );
1078+
$this->assertFalse( \WC_Order_Factory::get_order_item( current( $coupon_lines ) ) );
1079+
}
9251080
}

vendor/composer/autoload_classmap.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
'WPGraphQL\\Extensions\\WooCommerce\\Mutation\\Customer_Update' => $baseDir . '/includes/mutation/class-customer-update.php',
6868
'WPGraphQL\\Extensions\\WooCommerce\\Mutation\\Order_Create' => $baseDir . '/includes/mutation/class-order-create.php',
6969
'WPGraphQL\\Extensions\\WooCommerce\\Mutation\\Order_Delete' => $baseDir . '/includes/mutation/class-order-delete.php',
70+
'WPGraphQL\\Extensions\\WooCommerce\\Mutation\\Order_Delete_Items' => $baseDir . '/includes/mutation/class-order-delete-items.php',
7071
'WPGraphQL\\Extensions\\WooCommerce\\Mutation\\Order_Update' => $baseDir . '/includes/mutation/class-order-update.php',
7172
'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPEnum\\Backorders' => $baseDir . '/includes/type/enum/class-backorders.php',
7273
'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPEnum\\Catalog_Visibility' => $baseDir . '/includes/type/enum/class-catalog-visibility.php',

vendor/composer/autoload_static.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ class ComposerStaticInitee0d17af17b841ed3a93c4a0e5cc5e5f
8282
'WPGraphQL\\Extensions\\WooCommerce\\Mutation\\Customer_Update' => __DIR__ . '/../..' . '/includes/mutation/class-customer-update.php',
8383
'WPGraphQL\\Extensions\\WooCommerce\\Mutation\\Order_Create' => __DIR__ . '/../..' . '/includes/mutation/class-order-create.php',
8484
'WPGraphQL\\Extensions\\WooCommerce\\Mutation\\Order_Delete' => __DIR__ . '/../..' . '/includes/mutation/class-order-delete.php',
85+
'WPGraphQL\\Extensions\\WooCommerce\\Mutation\\Order_Delete_Items' => __DIR__ . '/../..' . '/includes/mutation/class-order-delete-items.php',
8586
'WPGraphQL\\Extensions\\WooCommerce\\Mutation\\Order_Update' => __DIR__ . '/../..' . '/includes/mutation/class-order-update.php',
8687
'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPEnum\\Backorders' => __DIR__ . '/../..' . '/includes/type/enum/class-backorders.php',
8788
'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPEnum\\Catalog_Visibility' => __DIR__ . '/../..' . '/includes/type/enum/class-catalog-visibility.php',

0 commit comments

Comments
 (0)