Skip to content

Commit

Permalink
Update cart items with customizable options
Browse files Browse the repository at this point in the history
  • Loading branch information
rogyar committed Apr 24, 2019
1 parent 18dc53f commit 0e8cf92
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 12 deletions.
98 changes: 98 additions & 0 deletions app/code/Magento/QuoteGraphQl/Model/Cart/UpdateCartItem.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\QuoteGraphQl\Model\Cart;

use Magento\Framework\DataObject;
use Magento\Framework\DataObjectFactory;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Quote\Model\Quote;

/**
* Update cart item
*
*/
class UpdateCartItem
{
/**
* @var DataObjectFactory
*/
private $dataObjectFactory;

/**
* @param DataObjectFactory $dataObjectFactory
*/
public function __construct(
DataObjectFactory $dataObjectFactory
) {
$this->dataObjectFactory = $dataObjectFactory;
}

/**
* Update cart item
*
* @param Quote $cart
* @param int $cartItemId
* @param float $qty
* @param null $customizableOptionsData
* @return void
* @throws GraphQlInputException
*/
public function execute(Quote $cart, int $cartItemId, float $qty, array $customizableOptionsData): void
{
$customizableOptions = [];
foreach ($customizableOptionsData as $customizableOption) {
$customizableOptions[$customizableOption['id']] = $customizableOption['value'];
}

try {
$result = $cart->updateItem(
$cartItemId,
$this->createBuyRequest($qty, $customizableOptions)
);
} catch (LocalizedException $e) {
throw new GraphQlInputException(
__(
'Could not update cart item: %message',
['message' => $e->getMessage()]
)
);
}

if (is_string($result)) {
throw new GraphQlInputException(__(
'Could not update cart item: %message',
['message' => $result]
));
}

if ($result->getHasError()) {
throw new GraphQlInputException(__(
'Could not update cart item: %message',
['message' => $result->getMessage()]
));
}
}

/**
* Format GraphQl input data to a shape that buy request has
*
* @param float $qty
* @param array $customOptions
* @return DataObject
*/
private function createBuyRequest(float $qty, array $customOptions): DataObject
{
return $this->dataObjectFactory->create([
'data' => [
'qty' => $qty,
'options' => $customOptions,
],
]);
}
}
61 changes: 50 additions & 11 deletions app/code/Magento/QuoteGraphQl/Model/Resolver/UpdateCartItems.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,26 @@
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;

/**
* @inheritdoc
*/
class UpdateCartItems implements ResolverInterface
{
/**
* @var CartRepositoryInterface
*/
private $quoteRepository;

/**
* @var UpdateCartItem
*/
private $updateCartItem;

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

/**
Expand Down Expand Up @@ -93,26 +111,47 @@ private function processCartItems(Quote $cart, array $items): void
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'];
$itemId = (int)$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);
$customizableOptions = $item['customizable_options'] ?? null;

if ($customizableOptions === null) { // Update only item's qty
$this->updateItemQty($itemId, $cart, $qty);
} else { // Update customizable options (and QTY if changed)
$this->updateCartItem->execute($cart, $itemId, $qty, $customizableOptions);
$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->cartItemRepository->save($cartItem);
}
}
3 changes: 2 additions & 1 deletion app/code/Magento/QuoteGraphQl/etc/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ input UpdateCartItemsInput {

input CartItemQuantityInput {
cart_item_id: Int!
quantity: Float!
quantity: Float
customizable_options: [CustomizableOptionInput!]
}

input RemoveItemFromCartInput {
Expand Down

0 comments on commit 0e8cf92

Please sign in to comment.