Skip to content

Commit

Permalink
Fixed tests, decoupled logic for updating items
Browse files Browse the repository at this point in the history
  • Loading branch information
rogyar committed May 11, 2019
1 parent f81a633 commit 91251ea
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 46 deletions.
83 changes: 81 additions & 2 deletions app/code/Magento/QuoteGraphQl/Model/Cart/UpdateCartItem.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,48 @@
use Magento\Framework\DataObject;
use Magento\Framework\DataObjectFactory;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException;
use Magento\Quote\Api\CartItemRepositoryInterface;
use Magento\Quote\Api\CartRepositoryInterface;
use Magento\Quote\Model\Quote;
use Magento\Quote\Model\Quote\Item;

/**
* Update cart item
*
*/
class UpdateCartItem
{
/**
* @var CartRepositoryInterface
*/
private $quoteRepository;

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

/**
* @var DataObjectFactory
*/
private $dataObjectFactory;

/**
* @param DataObjectFactory $dataObjectFactory
* @param CartItemRepositoryInterface $cartItemRepository
* @param CartRepositoryInterface $quoteRepository
*/
public function __construct(
DataObjectFactory $dataObjectFactory
DataObjectFactory $dataObjectFactory,
CartItemRepositoryInterface $cartItemRepository,
CartRepositoryInterface $quoteRepository
) {
$this->dataObjectFactory = $dataObjectFactory;
$this->cartItemRepository = $cartItemRepository;
$this->quoteRepository = $quoteRepository;
}

/**
Expand All @@ -39,12 +60,20 @@ public function __construct(
* @param Quote $cart
* @param int $cartItemId
* @param float $qty
* @param null $customizableOptionsData
* @param array $customizableOptionsData
* @return void
* @throws GraphQlInputException
* @throws GraphQlNoSuchEntityException
* @throws NoSuchEntityException
*/
public function execute(Quote $cart, int $cartItemId, float $qty, array $customizableOptionsData): void
{
if (count($customizableOptionsData) === 0) { // Update only item's qty
$this->updateItemQty($cartItemId, $cart, $qty);

return;
}

$customizableOptions = [];
foreach ($customizableOptionsData as $customizableOption) {
$customizableOptions[$customizableOption['id']] = $customizableOption['value_string'];
Expand Down Expand Up @@ -77,6 +106,56 @@ public function execute(Quote $cart, int $cartItemId, float $qty, array $customi
['message' => $result->getMessage(true)]
));
}

$this->quoteRepository->save($cart);
}

/**
* Updates item qty for the specified cart
*
* @param int $itemId
* @param Quote $cart
* @param float $qty
* @throws GraphQlNoSuchEntityException
* @throws NoSuchEntityException
* @throws GraphQlNoSuchEntityException
*/
private function updateItemQty(int $itemId, Quote $cart, float $qty)
{
$cartItem = $cart->getItemById($itemId);
if ($cartItem === false) {
throw new GraphQlNoSuchEntityException(
__('Could not find cart item with id: %1.', $itemId)
);
}
$cartItem->setQty($qty);
$this->validateCartItem($cartItem);
$this->cartItemRepository->save($cartItem);
}

/**
* Validate cart item
*
* @param Item $cartItem
* @return void
* @throws GraphQlInputException
*/
private function validateCartItem(Item $cartItem): void
{
if ($cartItem->getHasError()) {
$errors = [];
foreach ($cartItem->getMessage(false) as $message) {
$errors[] = $message;
}
if (!empty($errors)) {
throw new GraphQlInputException(
__(
'Could not update the product with SKU %sku: %message',
['sku' => $cartItem->getSku(), 'message' => __(implode("\n", $errors))]
)
);
}
}
}

/**
Expand Down
45 changes: 4 additions & 41 deletions app/code/Magento/QuoteGraphQl/Model/Resolver/UpdateCartItems.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Quote\Api\CartItemRepositoryInterface;
use Magento\Quote\Api\CartRepositoryInterface;
use Magento\Quote\Model\Quote;
use Magento\QuoteGraphQl\Model\Cart\GetCartForUser;
use Magento\QuoteGraphQl\Model\Cart\UpdateCartItem;
Expand All @@ -25,11 +24,6 @@
*/
class UpdateCartItems implements ResolverInterface
{
/**
* @var CartRepositoryInterface
*/
private $quoteRepository;

/**
* @var UpdateCartItem
*/
Expand All @@ -49,18 +43,15 @@ class UpdateCartItems implements ResolverInterface
* @param GetCartForUser $getCartForUser
* @param CartItemRepositoryInterface $cartItemRepository
* @param UpdateCartItem $updateCartItem
* @param CartRepositoryInterface $quoteRepository
*/
public function __construct(
GetCartForUser $getCartForUser,
CartItemRepositoryInterface $cartItemRepository,
UpdateCartItem $updateCartItem,
CartRepositoryInterface $quoteRepository
UpdateCartItem $updateCartItem
) {
$this->getCartForUser = $getCartForUser;
$this->cartItemRepository = $cartItemRepository;
$this->updateCartItem = $updateCartItem;
$this->quoteRepository = $quoteRepository;
}

/**
Expand Down Expand Up @@ -112,46 +103,18 @@ private function processCartItems(Quote $cart, array $items): void
throw new GraphQlInputException(__('Required parameter "cart_item_id" for "cart_items" is missing.'));
}
$itemId = (int)$item['cart_item_id'];
$customizableOptions = $item['customizable_options'] ?? [];

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

if ($quantity <= 0.0) {
$this->cartItemRepository->deleteById((int)$cart->getId(), $itemId);
} else {
$customizableOptions = $item['customizable_options'] ?? null;

if ($customizableOptions === null) { // Update only item's qty
$this->updateItemQty($itemId, $cart, $quantity);
} else { // Update customizable options (and QTY if changed)
$this->updateCartItem->execute($cart, $itemId, $quantity, $customizableOptions);
$this->quoteRepository->save($cart);
}
$this->updateCartItem->execute($cart, $itemId, $quantity, $customizableOptions);
}
}
}

/**
* Updates item qty for the specified cart
*
* @param int $itemId
* @param Quote $cart
* @param float $qty
* @throws GraphQlNoSuchEntityException
* @throws NoSuchEntityException
* @throws GraphQlNoSuchEntityException
*/
private function updateItemQty(int $itemId, Quote $cart, float $qty)
{
$cartItem = $cart->getItemById($itemId);
if ($cartItem === false) {
throw new GraphQlNoSuchEntityException(
__('Could not find cart item with id: %1.', $itemId)
);
}
$cartItem->setQty($qty);
$this->cartItemRepository->save($cartItem);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ public function dataProviderUpdateWithMissedRequiredParameters(): array
],
'missed_cart_item_qty' => [
'cart_items: [{ cart_item_id: 1 }]',
'Field CartItemUpdateInput.quantity of required type Float! was not provided.'
'Required parameter "quantity" for "cart_items" is missing.'
],
];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,6 @@ public function testOptionsSetChangedOnChangeOneOption()
* @magentoApiDataFixture Magento/GraphQl/Catalog/_files/set_custom_options_simple_product.php
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php
* @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product_with_options.php
* @group recent
*/
public function testOptionSetPersistsOnExtraOptionWithIncorrectId()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ public function dataProviderUpdateWithMissedRequiredParameters(): array
],
'missed_cart_item_qty' => [
'cart_items: [{ cart_item_id: 1 }]',
'Field CartItemUpdateInput.quantity of required type Float! was not provided.'
'Required parameter "quantity" for "cart_items" is missing.'
],
];
}
Expand Down

0 comments on commit 91251ea

Please sign in to comment.