Skip to content

Commit

Permalink
Merge branch '2.4-develop' of https://github.com/mage-os/mirror-magento2
Browse files Browse the repository at this point in the history
 into 2.4-develop
  • Loading branch information
mage-os-ci committed Nov 19, 2022
2 parents 110a1bb + 39f0be8 commit 20dc2c5
Show file tree
Hide file tree
Showing 9 changed files with 289 additions and 175 deletions.
89 changes: 16 additions & 73 deletions app/code/Magento/Quote/Model/Cart/AddProductsToCart.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@

namespace Magento\Quote\Model\Cart;

use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Quote\Api\CartRepositoryInterface;
use Magento\Quote\Model\Cart\BuyRequest\BuyRequestBuilder;
Expand All @@ -23,29 +21,6 @@
*/
class AddProductsToCart
{
/**#@+
* Error message codes
*/
private const ERROR_PRODUCT_NOT_FOUND = 'PRODUCT_NOT_FOUND';
private const ERROR_INSUFFICIENT_STOCK = 'INSUFFICIENT_STOCK';
private const ERROR_NOT_SALABLE = 'NOT_SALABLE';
private const ERROR_UNDEFINED = 'UNDEFINED';
/**#@-*/

/**
* List of error messages and codes.
*/
private const MESSAGE_CODES = [
'Could not find a product with SKU' => self::ERROR_PRODUCT_NOT_FOUND,
'The required options you selected are not available' => self::ERROR_NOT_SALABLE,
'Product that you are trying to add is not available.' => self::ERROR_NOT_SALABLE,
'This product is out of stock' => self::ERROR_INSUFFICIENT_STOCK,
'There are no source items' => self::ERROR_NOT_SALABLE,
'The fewest you may purchase is' => self::ERROR_INSUFFICIENT_STOCK,
'The most you may purchase is' => self::ERROR_INSUFFICIENT_STOCK,
'The requested qty is not available' => self::ERROR_INSUFFICIENT_STOCK,
];

/**
* @var CartRepositoryInterface
*/
Expand All @@ -67,25 +42,29 @@ class AddProductsToCart
private $productReader;

/**
* @param ProductRepositoryInterface $productRepository
* @var AddProductsToCartError
*/
private $error;

/**
* @param CartRepositoryInterface $cartRepository
* @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId
* @param BuyRequestBuilder $requestBuilder
* @param ProductReaderInterface|null $productReader
*
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
* @param ProductReaderInterface $productReader
* @param AddProductsToCartError $addProductsToCartError
*/
public function __construct(
ProductRepositoryInterface $productRepository,
CartRepositoryInterface $cartRepository,
MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId,
BuyRequestBuilder $requestBuilder,
ProductReaderInterface $productReader = null
ProductReaderInterface $productReader,
AddProductsToCartError $addProductsToCartError
) {
$this->cartRepository = $cartRepository;
$this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId;
$this->requestBuilder = $requestBuilder;
$this->productReader = $productReader ?: ObjectManager::getInstance()->get(ProductReaderInterface::class);
$this->productReader = $productReader;
$this->error = $addProductsToCartError;
}

/**
Expand All @@ -106,7 +85,7 @@ public function execute(string $maskedCartId, array $cartItems): AddProductsToCa

/** @var MessageInterface $error */
foreach ($errors as $error) {
$allErrors[] = $this->createError($error->getText());
$allErrors[] = $this->error->create($error->getText());
}
}

Expand Down Expand Up @@ -181,22 +160,22 @@ private function addItemToCart(Quote $cart, Data\CartItem $cartItem, int $cartIt
$result = null;

if ($cartItem->getQuantity() <= 0) {
$errors[] = $this->createError(
$errors[] = $this->error->create(
__('The product quantity should be greater than 0')->render(),
$cartItemPosition
);
} else {
$product = $this->productReader->getProductBySku($sku);
if (!$product || !$product->isSaleable() || !$product->isAvailable()) {
$errors[] = $this->createError(
$errors[] = $this->error->create(
__('Could not find a product with SKU "%sku"', ['sku' => $sku])->render(),
$cartItemPosition
);
} else {
try {
$result = $cart->addProduct($product, $this->requestBuilder->build($cartItem));
} catch (\Throwable $e) {
$errors[] = $this->createError(
$errors[] = $this->error->create(
__($e->getMessage())->render(),
$cartItemPosition
);
Expand All @@ -205,50 +184,14 @@ private function addItemToCart(Quote $cart, Data\CartItem $cartItem, int $cartIt

if (is_string($result)) {
foreach (array_unique(explode("\n", $result)) as $error) {
$errors[] = $this->createError(__($error)->render(), $cartItemPosition);
$errors[] = $this->error->create(__($error)->render(), $cartItemPosition);
}
}
}

return $errors;
}

/**
* Returns an error object
*
* @param string $message
* @param int $cartItemPosition
* @return Data\Error
*/
private function createError(string $message, int $cartItemPosition = 0): Data\Error
{
return new Data\Error(
$message,
$this->getErrorCode($message),
$cartItemPosition
);
}

/**
* Get message error code.
*
* TODO: introduce a separate class for getting error code from a message
*
* @param string $message
* @return string
*/
private function getErrorCode(string $message): string
{
foreach (self::MESSAGE_CODES as $codeMessage => $code) {
if (false !== stripos($message, $codeMessage)) {
return $code;
}
}

/* If no code was matched, return the default one */
return self::ERROR_UNDEFINED;
}

/**
* Creates a new output from existing errors
*
Expand Down
71 changes: 71 additions & 0 deletions app/code/Magento/Quote/Model/Cart/AddProductsToCartError.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\Quote\Model\Cart;

/**
* Create instances of errors on adding products to cart. Identify error code based on the message
*/
class AddProductsToCartError
{
/**#@+
* Error message codes
*/
private const ERROR_PRODUCT_NOT_FOUND = 'PRODUCT_NOT_FOUND';
private const ERROR_INSUFFICIENT_STOCK = 'INSUFFICIENT_STOCK';
private const ERROR_NOT_SALABLE = 'NOT_SALABLE';
private const ERROR_UNDEFINED = 'UNDEFINED';
/**#@-*/

/**
* List of error messages and codes.
*/
private const MESSAGE_CODES = [
'Could not find a product with SKU' => self::ERROR_PRODUCT_NOT_FOUND,
'The required options you selected are not available' => self::ERROR_NOT_SALABLE,
'Product that you are trying to add is not available.' => self::ERROR_NOT_SALABLE,
'This product is out of stock' => self::ERROR_INSUFFICIENT_STOCK,
'There are no source items' => self::ERROR_NOT_SALABLE,
'The fewest you may purchase is' => self::ERROR_INSUFFICIENT_STOCK,
'The most you may purchase is' => self::ERROR_INSUFFICIENT_STOCK,
'The requested qty is not available' => self::ERROR_INSUFFICIENT_STOCK,
];

/**
* Returns an error object
*
* @param string $message
* @param int $cartItemPosition
* @return Data\Error
*/
public function create(string $message, int $cartItemPosition = 0): Data\Error
{
return new Data\Error(
$message,
$this->getErrorCode($message),
$cartItemPosition
);
}

/**
* Get message error code.
*
* @param string $message
* @return string
*/
private function getErrorCode(string $message): string
{
foreach (self::MESSAGE_CODES as $codeMessage => $code) {
if (false !== stripos($message, $codeMessage)) {
return $code;
}
}

/* If no code was matched, return the default one */
return self::ERROR_UNDEFINED;
}
}
73 changes: 73 additions & 0 deletions app/code/Magento/QuoteGraphQl/Model/Cart/GetCartForCheckout.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?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\Exception\NoSuchEntityException;
use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException;
use Magento\Quote\Api\CartManagementInterface;
use Magento\Quote\Model\Quote;

/**
* Get cart
*/
class GetCartForCheckout
{
/**
* @var CheckCartCheckoutAllowance
*/
private CheckCartCheckoutAllowance $checkoutAllowance;

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

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

/**
* Gets the cart for the user validated and configured for guest checkout if applicable
*
* @param string $cartHash
* @param int|null $customerId
* @param int $storeId
* @return Quote
* @throws GraphQlAuthorizationException
* @throws GraphQlInputException
* @throws GraphQlNoSuchEntityException
*/
public function execute(string $cartHash, ?int $customerId, int $storeId): Quote
{
try {
$cart = $this->getCartForUser->execute($cartHash, $customerId, $storeId);
} catch (NoSuchEntityException $e) {
throw new GraphQlNoSuchEntityException(__($e->getMessage()), $e);
}
$this->checkoutAllowance->execute($cart);

if (null === $customerId || 0 === $customerId) {
if (!$cart->getCustomerEmail()) {
throw new GraphQlInputException(__("Guest email for cart is missing."));
}
$cart->setCheckoutMethod(CartManagementInterface::METHOD_GUEST);
}

return $cart;
}
}
Loading

0 comments on commit 20dc2c5

Please sign in to comment.