Skip to content

Commit

Permalink
ENGCOM-4453: [Cart Operations] Update Cart Items Mutation #377
Browse files Browse the repository at this point in the history
  • Loading branch information
naydav authored Mar 6, 2019
2 parents c427332 + 8d900eb commit 441e923
Show file tree
Hide file tree
Showing 10 changed files with 862 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,12 @@ public function __construct(
*/
public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null)
{
if (!isset($args['input']['cart_id'])) {
if (!isset($args['input']['cart_id']) || empty($args['input']['cart_id'])) {
throw new GraphQlInputException(__('Required parameter "cart_id" is missing'));
}
$maskedCartId = $args['input']['cart_id'];

if (!isset($args['input']['coupon_code'])) {
if (!isset($args['input']['coupon_code']) || empty($args['input']['coupon_code'])) {
throw new GraphQlInputException(__('Required parameter "coupon_code" is missing'));
}
$couponCode = $args['input']['coupon_code'];
Expand Down
2 changes: 1 addition & 1 deletion app/code/Magento/QuoteGraphQl/Model/Resolver/Cart.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public function __construct(
*/
public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null)
{
if (!isset($args['cart_id'])) {
if (!isset($args['cart_id']) || empty($args['cart_id'])) {
throw new GraphQlInputException(__('Required parameter "cart_id" is missing'));
}
$maskedCartId = $args['cart_id'];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public function __construct(
*/
public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null)
{
if (!isset($args['input']['cart_id'])) {
if (!isset($args['input']['cart_id']) || empty($args['input']['cart_id'])) {
throw new GraphQlInputException(__('Required parameter "cart_id" is missing'));
}
$maskedCartId = $args['input']['cart_id'];
Expand Down
28 changes: 14 additions & 14 deletions app/code/Magento/QuoteGraphQl/Model/Resolver/RemoveItemFromCart.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Quote\Api\GuestCartItemRepositoryInterface;
use Magento\Quote\Api\CartItemRepositoryInterface;
use Magento\QuoteGraphQl\Model\Cart\GetCartForUser;

/**
Expand All @@ -23,46 +23,46 @@
class RemoveItemFromCart implements ResolverInterface
{
/**
* @var GuestCartItemRepositoryInterface
* @var GetCartForUser
*/
private $guestCartItemRepository;
private $getCartForUser;

/**
* @var GetCartForUser
* @var CartItemRepositoryInterface
*/
private $getCartForUser;
private $cartItemRepository;

/**
* @param GuestCartItemRepositoryInterface $guestCartItemRepository
* @param GetCartForUser $getCartForUser
* @param CartItemRepositoryInterface $cartItemRepository
*/
public function __construct(
GuestCartItemRepositoryInterface $guestCartItemRepository,
GetCartForUser $getCartForUser
GetCartForUser $getCartForUser,
CartItemRepositoryInterface $cartItemRepository
) {
$this->guestCartItemRepository = $guestCartItemRepository;
$this->getCartForUser = $getCartForUser;
$this->cartItemRepository = $cartItemRepository;
}

/**
* @inheritdoc
*/
public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null)
{
if (!isset($args['input']['cart_id'])) {
throw new GraphQlInputException(__('Required parameter "cart_id" is missing'));
if (!isset($args['input']['cart_id']) || empty($args['input']['cart_id'])) {
throw new GraphQlInputException(__('Required parameter "cart_id" is missing.'));
}
$maskedCartId = $args['input']['cart_id'];

if (!isset($args['input']['cart_item_id'])) {
throw new GraphQlInputException(__('Required parameter "cart_item_id" is missing'));
if (!isset($args['input']['cart_item_id']) || empty($args['input']['cart_item_id'])) {
throw new GraphQlInputException(__('Required parameter "cart_item_id" is missing.'));
}
$itemId = $args['input']['cart_item_id'];

$cart = $this->getCartForUser->execute($maskedCartId, $context->getUserId());

try {
$this->guestCartItemRepository->deleteById($maskedCartId, $itemId);
$this->cartItemRepository->deleteById((int)$cart->getId(), $itemId);
} catch (NoSuchEntityException $e) {
throw new GraphQlNoSuchEntityException(__($e->getMessage()), $e);
} catch (LocalizedException $e) {
Expand Down
118 changes: 118 additions & 0 deletions app/code/Magento/QuoteGraphQl/Model/Resolver/UpdateCartItems.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\QuoteGraphQl\Model\Resolver;

use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Quote\Api\CartItemRepositoryInterface;
use Magento\Quote\Model\Quote;
use Magento\QuoteGraphQl\Model\Cart\GetCartForUser;

/**
* @inheritdoc
*/
class UpdateCartItems implements ResolverInterface
{
/**
* @var GetCartForUser
*/
private $getCartForUser;

/**
* @var CartItemRepositoryInterface
*/
private $cartItemRepository;

/**
* @param GetCartForUser $getCartForUser
* @param CartItemRepositoryInterface $cartItemRepository
*/
public function __construct(
GetCartForUser $getCartForUser,
CartItemRepositoryInterface $cartItemRepository
) {
$this->getCartForUser = $getCartForUser;
$this->cartItemRepository = $cartItemRepository;
}

/**
* @inheritdoc
*/
public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null)
{
if (!isset($args['input']['cart_id']) || empty($args['input']['cart_id'])) {
throw new GraphQlInputException(__('Required parameter "cart_id" is missing.'));
}
$maskedCartId = $args['input']['cart_id'];

if (!isset($args['input']['cart_items']) || empty($args['input']['cart_items'])
|| !is_array($args['input']['cart_items'])
) {
throw new GraphQlInputException(__('Required parameter "cart_items" is missing.'));
}
$cartItems = $args['input']['cart_items'];

$cart = $this->getCartForUser->execute($maskedCartId, $context->getUserId());

try {
$this->processCartItems($cart, $cartItems);
} catch (NoSuchEntityException $e) {
throw new GraphQlNoSuchEntityException(__($e->getMessage()), $e);
} catch (LocalizedException $e) {
throw new GraphQlInputException(__($e->getMessage()), $e);
}

return [
'cart' => [
'model' => $cart,
],
];
}

/**
* Process cart items
*
* @param Quote $cart
* @param array $items
* @throws GraphQlInputException
* @throws LocalizedException
*/
private function processCartItems(Quote $cart, array $items): void
{
foreach ($items as $item) {
if (!isset($item['cart_item_id']) || empty($item['cart_item_id'])) {
throw new GraphQlInputException(__('Required parameter "cart_item_id" for "cart_items" is missing.'));
}
$itemId = $item['cart_item_id'];

if (!isset($item['quantity'])) {
throw new GraphQlInputException(__('Required parameter "quantity" for "cart_items" is missing.'));
}
$qty = (float)$item['quantity'];

$cartItem = $cart->getItemById($itemId);
if ($cartItem === false) {
throw new GraphQlNoSuchEntityException(
__('Could not find cart item with id: %1.', $item['cart_item_id'])
);
}

if ($qty <= 0.0) {
$this->cartItemRepository->deleteById((int)$cart->getId(), $itemId);
} else {
$cartItem->setQty($qty);
$this->cartItemRepository->save($cartItem);
}
}
}
}
10 changes: 10 additions & 0 deletions app/code/Magento/QuoteGraphQl/etc/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ type Mutation {
addVirtualProductsToCart(input: AddVirtualProductsToCartInput): AddVirtualProductsToCartOutput @resolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\AddSimpleProductsToCart")
applyCouponToCart(input: ApplyCouponToCartInput): ApplyCouponToCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\ApplyCouponToCart")
removeCouponFromCart(input: RemoveCouponFromCartInput): RemoveCouponFromCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\RemoveCouponFromCart")
updateCartItems(input: UpdateCartItemsInput): UpdateCartItemsOutput @resolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\UpdateCartItems")
removeItemFromCart(input: RemoveItemFromCartInput): RemoveItemFromCartOutput @resolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\RemoveItemFromCart")
setShippingAddressesOnCart(input: SetShippingAddressesOnCartInput): SetShippingAddressesOnCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\SetShippingAddressesOnCart")
setBillingAddressOnCart(input: SetBillingAddressOnCartInput): SetBillingAddressOnCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\SetBillingAddressOnCart")
Expand Down Expand Up @@ -53,6 +54,11 @@ input ApplyCouponToCartInput {
coupon_code: String!
}

input UpdateCartItemsInput {
cart_id: String!
cart_items: [CartItemQuantityInput!]!
}

input RemoveItemFromCartInput {
cart_id: String!
cart_item_id: Int!
Expand Down Expand Up @@ -230,6 +236,10 @@ type AddVirtualProductsToCartOutput {
cart: Cart!
}

type UpdateCartItemsOutput {
cart: Cart!
}

type RemoveItemFromCartOutput {
cart: Cart!
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,20 +75,24 @@ public function testRemoveItemFromCart()

/**
* @magentoApiDataFixture Magento/Customer/_files/customer.php
* @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php
* @expectedException \Exception
* @expectedExceptionMessage Could not find a cart with ID "non_existent_masked_id"
*/
public function testRemoveItemFromNonExistentCart()
{
$query = $this->prepareMutationQuery('non_existent_masked_id', 1);
$quote = $this->quoteFactory->create();
$this->quoteResource->load($quote, 'test_order_1', 'reserved_order_id');
$itemId = (int)$quote->getItemByProduct($this->productRepository->get('simple'))->getId();

$query = $this->prepareMutationQuery('non_existent_masked_id', $itemId);
$this->graphQlQuery($query, [], '', $this->getHeaderMap());
}

/**
* @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php
*/
public function testRemoveNotExistentItem()
public function testRemoveNonExistentItem()
{
$quote = $this->quoteFactory->create();
$this->quoteResource->load($quote, 'test_order_1', 'reserved_order_id');
Expand Down Expand Up @@ -183,6 +187,50 @@ public function testRemoveItemFromAnotherCustomerCart()
$this->graphQlQuery($query, [], '', $this->getHeaderMap());
}

/**
* @magentoApiDataFixture Magento/Customer/_files/customer.php
* @param string $input
* @param string $message
* @dataProvider dataProviderUpdateWithMissedRequiredParameters
*/
public function testUpdateWithMissedItemRequiredParameters(string $input, string $message)
{
$query = <<<QUERY
mutation {
removeItemFromCart(
input: {
{$input}
}
) {
cart {
items {
qty
}
}
}
}
QUERY;
$this->expectExceptionMessage($message);
$this->graphQlQuery($query, [], '', $this->getHeaderMap());
}

/**
* @return array
*/
public function dataProviderUpdateWithMissedRequiredParameters(): array
{
return [
'missed_cart_id' => [
'cart_item_id: 1',
'Required parameter "cart_id" is missing.'
],
'missed_cart_item_id' => [
'cart_id: "test"',
'Required parameter "cart_item_id" is missing.'
],
];
}

/**
* @param string $maskedQuoteId
* @param int $itemId
Expand Down
Loading

1 comment on commit 441e923

@amolsarva
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesnt seem to be the most elegant solution.

Please sign in to comment.