Skip to content

Commit

Permalink
Merge pull request #104 from kidunot89/feature/order-item-mutations
Browse files Browse the repository at this point in the history
deleteOrderItems mutation
  • Loading branch information
kidunot89 authored Jul 10, 2019
2 parents 61a72a7 + d6ef041 commit 5c53b2e
Show file tree
Hide file tree
Showing 6 changed files with 322 additions and 0 deletions.
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

0 comments on commit 5c53b2e

Please sign in to comment.