Skip to content
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

deleteOrderItems mutation #104

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions includes/class-actions.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
use WPGraphQL\Extensions\WooCommerce\Mutation\Order_Create;
use WPGraphQL\Extensions\WooCommerce\Mutation\Order_Update;
use WPGraphQL\Extensions\WooCommerce\Mutation\Order_Delete;
use WPGraphQL\Extensions\WooCommerce\Mutation\Order_Delete_Items;
use WPGraphQL\Extensions\WooCommerce\Mutation\Checkout;

/**
Expand Down Expand Up @@ -176,6 +177,7 @@ public static function graphql_register_types() {
Order_Create::register_mutation();
Order_Update::register_mutation();
Order_Delete::register_mutation();
Order_Delete_Items::register_mutation();
Checkout::register_mutation();
}
}
159 changes: 159 additions & 0 deletions includes/mutation/class-order-delete-items.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
<?php
/**
* Mutation - deleteOrderItems
*
* Registers mutation for delete an items from an order.
*
* @package WPGraphQL\Extensions\WooCommerce\Mutation
* @since 0.2.0
*/

namespace WPGraphQL\Extensions\WooCommerce\Mutation;

use GraphQL\Error\UserError;
use GraphQL\Type\Definition\ResolveInfo;
use GraphQLRelay\Relay;
use WPGraphQL\AppContext;
use WPGraphQL\Extensions\WooCommerce\Data\Mutation\Order_Mutation;
use WPGraphQL\Extensions\WooCommerce\Model\Order;

/**
* Class Order_Delete_Items
*/
class Order_Delete_Items {
/**
* Registers mutation
*/
public static function register_mutation() {
register_graphql_mutation(
'deleteOrderItems',
array(
'inputFields' => self::get_input_fields(),
'outputFields' => self::get_output_fields(),
'mutateAndGetPayload' => self::mutate_and_get_payload(),
)
);
}

/**
* Defines the mutation input field configuration
*
* @return array
*/
public static function get_input_fields() {
$input_fields = array_merge(
array(
'id' => array(
'type' => 'ID',
'description' => __( 'Order global ID', 'wp-graphql-woocommerce' ),
),
'orderId' => array(
'type' => 'Int',
'description' => __( 'Order WP ID', 'wp-graphql-woocommerce' ),
),
'itemIds' => array(
'type' => array( 'list_of' => 'Int' ),
'description' => __( 'ID Order items being deleted', 'wp-graphql-woocommerce' ),
),
)
);

return $input_fields;
}

/**
* Defines the mutation output field configuration
*
* @return array
*/
public static function get_output_fields() {
return array(
'order' => array(
'type' => 'Order',
'resolve' => function( $payload ) {
return $payload['order'];
},
),
);
}

/**
* Defines the mutation data modification closure.
*
* @return callable
*/
public static function mutate_and_get_payload() {
return function( $input, AppContext $context, ResolveInfo $info ) {
if ( Order_Mutation::authorized( 'delete', $input, $context, $info ) ) {
throw new UserError( __( 'User does not have the capabilities necessary to delete an order.', 'wp-graphql-woocommerce' ) );
}

// Retrieve order ID.
$order_id = null;
if ( ! empty( $input['id'] ) ) {
$id_components = Relay::fromGlobalId( $input['id'] );
if ( empty( $id_components['id'] ) || empty( $id_components['type'] ) ) {
throw new UserError( __( 'The "id" provided is invalid', 'wp-graphql-woocommerce' ) );
}
$order_id = absint( $id_components['id'] );
} elseif ( ! empty( $input['orderId'] ) ) {
$order_id = absint( $input['orderId'] );
} else {
throw new UserError( __( 'No order ID provided.', 'wp-graphql-woocommerce' ) );
}

// Confirm item IDs.
if ( empty( $input['itemIds'] ) ) {
throw new UserError( __( 'No item IDs provided.', 'wp-graphql-woocommerce' ) );
} elseif ( ! is_array( $input['itemIds'] ) ) {
throw new UserError( __( 'The "itemIds" provided is invalid', 'wp-graphql-woocommerce' ) );
}
$ids = $input['itemIds'];

// Get Order model instance for output.
$order = new Order( $order_id );

// Cache items to prevent null value errors.
// @codingStandardsIgnoreStart
$order->downloadableItems;
$order->get_items();
$order->get_items( 'fee' );
$order->get_items( 'shipping' );
$order->get_items( 'tax' );
$order->get_items( 'coupon' );
// @codingStandardsIgnoreEnd.

// Get working order model.
$working_order = new Order( $order_id );

/**
* Action called before order is deleted.
*
* @param WC_Order $order WC_Order instance.
* @param array $input Input data describing order.
* @param AppContext $context Request AppContext instance.
* @param ResolveInfo $info Request ResolveInfo instance.
*/
do_action( 'woocommerce_graphql_before_order_items_delete', $ids, $working_order, $input, $context, $info );

// Delete order.
$errors = '';
foreach ( $ids as $id ) {
$working_order->remove_item( $id );
}
$working_order->save();

/**
* Action called before order is deleted.
*
* @param WC_Order $order WC_Order instance.
* @param array $input Input data describing order
* @param AppContext $context Request AppContext instance.
* @param ResolveInfo $info Request ResolveInfo instance.
*/
do_action( 'woocommerce_graphql_after_order_delete', $ids, $working_order, $input, $context, $info );

return array( 'order' => $order );
};
}
}
4 changes: 4 additions & 0 deletions includes/type/input/class-fee-line-input.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ public static function register() {
'type' => 'String',
'description' => __( 'Fee name.', 'wp-graphql-woocommerce' ),
),
'amount' => array(
'type' => 'String',
'description' => __( 'Fee amount.', 'wp-graphql-woocommerce' ),
),
'taxClass' => array(
'type' => 'TaxClassEnum',
'description' => __( 'Tax class of fee.', 'wp-graphql-woocommerce' ),
Expand Down
155 changes: 155 additions & 0 deletions tests/wpunit/OrderMutationsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -922,4 +922,159 @@ public function testDeleteOrderMutation() {
$this->assertEquals( $initial_response['data']['createOrder'], $actual['data']['deleteOrder'] );
$this->assertFalse( \WC_Order_Factory::get_order( $order->get_id() ) );
}

public function testDeleteOrderItemsMutation() {
// Create products and coupons to be used in order creation.
$variable = $this->variation->create( $this->product->create_variable() );
$product_ids = array(
$this->product->create_simple(),
$this->product->create_simple(),
$variable['product'],
);
$coupon = new WC_Coupon(
$this->coupon->create( array( 'product_ids' => $product_ids ) )
);

// Create initial order input.
$initial_input = array(
'clientMutationId' => 'someId',
'customerId' => $this->customer,
'customerNote' => 'Customer test note',
'coupons' => array(
$coupon->get_code(),
),
'paymentMethod' => 'bacs',
'paymentMethodTitle' => 'Direct Bank Transfer',
'billing' => array(
'firstName' => 'May',
'lastName' => 'Parker',
'address1' => '20 Ingram St',
'city' => 'New York City',
'state' => 'NY',
'postcode' => '12345',
'country' => 'US',
'email' => 'superfreak500@gmail.com',
'phone' => '555-555-1234',
),
'shipping' => array(
'firstName' => 'May',
'lastName' => 'Parker',
'address1' => '20 Ingram St',
'city' => 'New York City',
'state' => 'NY',
'postcode' => '12345',
'country' => 'US',
),
'lineItems' => array(
array(
'productId' => $product_ids[0],
'quantity' => 5,
'metaData' => array(
array(
'key' => 'test_product_key',
'value' => 'test product value',
),
),
),
array(
'productId' => $product_ids[1],
'quantity' => 2,
),
array(
'productId' => $product_ids[2],
'quantity' => 6,
'variationId' => $variable['variations'][0]
),
),
'shippingLines' => array(
array(
'methodId' => 'flat_rate_shipping',
'methodTitle' => 'Flat Rate shipping',
'total' => '10',
),
),
'feeLines' => array(
array(
'name' => 'Some Fee',
'taxStatus' => 'TAXABLE',
'total' => '100',
'taxClass' => 'STANDARD',
),
),
'metaData' => array(
array(
'key' => 'test_key',
'value' => 'test value',
),
),
'isPaid' => false,
);

// Create order to delete.
wp_set_current_user( $this->shop_manager );
$initial_response = $this->orderMutation( $initial_input );

// use --debug flag to view.
codecept_debug( $initial_response );

// Clear loader cache.
$this->getModule('\Helper\Wpunit')->clear_loader_cache( 'wc_post_crud' );

// Retrieve order and items
$order_id = $initial_response['data']['createOrder']['order']['orderId'];
$order = \WC_Order_Factory::get_order( $order_id );
$line_items = $order->get_items();
$shipping_lines = $order->get_items( 'shipping' );
$fee_lines = $order->get_items( 'fee' );
$coupon_lines = $order->get_items( 'coupon' );
$tax_lines = $order->get_items( 'tax' );

// Create DeleteOrderInput.
$deleted_items_input = array(
'clientMutationId' => 'someId',
'orderId' => $order->get_id(),
'itemIds' => array(
current( $line_items )->get_id(),
current( $coupon_lines )->get_id(),
),
);

/**
* Assertion One
*
* User without necessary capabilities cannot delete order an order.
*/
wp_set_current_user( $this->customer );
$actual = $this->orderMutation(
$deleted_items_input,
'deleteOrderItems',
'DeleteOrderItemsInput'
);

// use --debug flag to view.
codecept_debug( $actual );

$this->assertArrayHasKey('errors', $actual );

/**
* Assertion Two
*
* Test mutation and input.
*/
wp_set_current_user( $this->shop_manager );
$actual = $this->orderMutation(
$deleted_items_input,
'deleteOrderItems',
'DeleteOrderItemsInput'
);

// use --debug flag to view.
codecept_debug( $actual );

$this->assertArrayHasKey( 'data', $actual );
$this->assertArrayHasKey( 'deleteOrderItems', $actual['data'] );
$this->assertEquals( $initial_response['data']['createOrder'], $actual['data']['deleteOrderItems'] );
$this->assertFalse( \WC_Order_Factory::get_order_item( current( $line_items ) ) );
$this->assertFalse( \WC_Order_Factory::get_order_item( current( $coupon_lines ) ) );
}
}
1 change: 1 addition & 0 deletions vendor/composer/autoload_classmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
'WPGraphQL\\Extensions\\WooCommerce\\Mutation\\Customer_Update' => $baseDir . '/includes/mutation/class-customer-update.php',
'WPGraphQL\\Extensions\\WooCommerce\\Mutation\\Order_Create' => $baseDir . '/includes/mutation/class-order-create.php',
'WPGraphQL\\Extensions\\WooCommerce\\Mutation\\Order_Delete' => $baseDir . '/includes/mutation/class-order-delete.php',
'WPGraphQL\\Extensions\\WooCommerce\\Mutation\\Order_Delete_Items' => $baseDir . '/includes/mutation/class-order-delete-items.php',
'WPGraphQL\\Extensions\\WooCommerce\\Mutation\\Order_Update' => $baseDir . '/includes/mutation/class-order-update.php',
'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPEnum\\Backorders' => $baseDir . '/includes/type/enum/class-backorders.php',
'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPEnum\\Catalog_Visibility' => $baseDir . '/includes/type/enum/class-catalog-visibility.php',
Expand Down
1 change: 1 addition & 0 deletions vendor/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class ComposerStaticInitee0d17af17b841ed3a93c4a0e5cc5e5f
'WPGraphQL\\Extensions\\WooCommerce\\Mutation\\Customer_Update' => __DIR__ . '/../..' . '/includes/mutation/class-customer-update.php',
'WPGraphQL\\Extensions\\WooCommerce\\Mutation\\Order_Create' => __DIR__ . '/../..' . '/includes/mutation/class-order-create.php',
'WPGraphQL\\Extensions\\WooCommerce\\Mutation\\Order_Delete' => __DIR__ . '/../..' . '/includes/mutation/class-order-delete.php',
'WPGraphQL\\Extensions\\WooCommerce\\Mutation\\Order_Delete_Items' => __DIR__ . '/../..' . '/includes/mutation/class-order-delete-items.php',
'WPGraphQL\\Extensions\\WooCommerce\\Mutation\\Order_Update' => __DIR__ . '/../..' . '/includes/mutation/class-order-update.php',
'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPEnum\\Backorders' => __DIR__ . '/../..' . '/includes/type/enum/class-backorders.php',
'WPGraphQL\\Extensions\\WooCommerce\\Type\\WPEnum\\Catalog_Visibility' => __DIR__ . '/../..' . '/includes/type/enum/class-catalog-visibility.php',
Expand Down