Skip to content

Commit

Permalink
GraphQL-37: [Cart Operations] Manage Cart Items
Browse files Browse the repository at this point in the history
-- Refactoring
  • Loading branch information
naydav committed Mar 6, 2019
1 parent c9d6491 commit 3522857
Show file tree
Hide file tree
Showing 6 changed files with 343 additions and 221 deletions.
110 changes: 77 additions & 33 deletions app/code/Magento/QuoteGraphQl/Model/Resolver/UpdateCartItems.php
Original file line number Diff line number Diff line change
@@ -1,74 +1,118 @@
<?php
declare(strict_types=1);
/**
* 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\GuestCartRepositoryInterface;
use Magento\QuoteGraphQl\Model\Cart\ExtractDataFromCart;
use Magento\Framework\Stdlib\ArrayManager;
use Magento\QuoteGraphQl\Model\Cart\UpdateCartItems as UpdateCartItemsService;
use Magento\Quote\Api\CartItemRepositoryInterface;
use Magento\Quote\Model\Quote;
use Magento\QuoteGraphQl\Model\Cart\GetCartForUser;

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

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

/**
* @var UpdateCartItemsService
*/
private $updateCartItems;

/**
* @param ExtractDataFromCart $extractDataFromCart
* @param ArrayManager $arrayManager
* @param UpdateCartItemsService $updateCartItems
* @param GetCartForUser $getCartForUser
* @param CartItemRepositoryInterface $cartItemRepository
*/
public function __construct(
ExtractDataFromCart $extractDataFromCart,
ArrayManager $arrayManager,
UpdateCartItemsService $updateCartItems
GetCartForUser $getCartForUser,
CartItemRepositoryInterface $cartItemRepository
) {
$this->extractDataFromCart = $extractDataFromCart;
$this->arrayManager = $arrayManager;
$this->updateCartItems = $updateCartItems;
$this->getCartForUser = $getCartForUser;
$this->cartItemRepository = $cartItemRepository;
}

/**
* @inheritdoc
*/
public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null)
{
$cartItems = $this->arrayManager->get('input/cart_items', $args);
$maskedCartId = $this->arrayManager->get('input/cart_id', $args);

if (!$maskedCartId) {
if (!isset($args['input']['cart_id']) || empty($args['input']['cart_id'])) {
throw new GraphQlInputException(__('Required parameter "cart_id" is missing'));
}
if (!$cartItems) {
throw new GraphQlInputException(__('Required parameter "cart_items " 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 {
$cart = $this->updateCartItems->update($maskedCartId, $cartItems);
$this->processCartItems($cart, $cartItems);
} catch (NoSuchEntityException $e) {
throw new GraphQlNoSuchEntityException(__($e->getMessage()));
throw new GraphQlNoSuchEntityException(__($e->getMessage()), $e);
} catch (LocalizedException $e) {
throw new GraphQlInputException(__($e->getMessage()), $e);
}

$cartData = $this->extractDataFromCart->execute($cart);
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'];

return ['cart' => array_merge(['cart_id' => $maskedCartId], $cartData)];
$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);
}
}
}
}
7 changes: 1 addition & 6 deletions app/code/Magento/QuoteGraphQl/etc/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,7 @@ input ApplyCouponToCartInput {

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

input UpdateCartItemInput {
item_id: String!
qty: Float!
cart_items: [CartItemQuantityInput!]!
}

input RemoveItemFromCartInput {
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
Loading

0 comments on commit 3522857

Please sign in to comment.