Skip to content
This repository has been archived by the owner on Dec 19, 2019. It is now read-only.

[Cart Operations] Update Cart Items Mutation #377

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
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()));
} 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 @@ -241,6 +247,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