This repository has been archived by the owner on Dec 19, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 156
Mutations coupons #163
Merged
Merged
Mutations coupons #163
Changes from 12 commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
ced2301
Cart coupons prototype
rogyar 6abc7e5
Merge branch 'mutations-empty-cart' into mutations-coupons
rogyar b6eaa1f
Introduced service for checking cart mutations permissions
rogyar 1a077ac
Use corresponding service for converting masked id to int id
rogyar 9cb459e
Fixed typo for exception message
rogyar ba6dd12
Merge remote-tracking branch 'origin/2.3-develop' into mutations-coupons
02c2bc0
Merge branch '2.3-develop' into mutations-coupons
rogyar 7f1148f
Implementation improvements
rogyar b6365e1
Merge branch 'mutations-coupons' of github.com:magento/graphql-ce int…
rogyar 3007b3a
GraphQL-64: [Mutations] Cart Operations > Coupons
2a0a450
Merge remote-tracking branch 'origin/2.3-develop' into mutations-coupons
462601c
GraphQL-64: [Mutations] Cart Operations > Coupons
2f4767d
Fixed error messages assertions in api-functional tests
rogyar 343e463
Fixed coupon fixture
rogyar 46b40b4
Use another fixture for api-functional tests
rogyar fc12cb7
Mark test as incomplete because of random Bamboo fails
rogyar File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
67 changes: 67 additions & 0 deletions
67
app/code/Magento/QuoteGraphQl/Model/Authorization/IsCartMutationAllowedForCurrentUser.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
<?php | ||
/** | ||
* Copyright © Magento, Inc. All rights reserved. | ||
* See COPYING.txt for license details. | ||
*/ | ||
declare(strict_types=1); | ||
|
||
namespace Magento\QuoteGraphQl\Model\Authorization; | ||
|
||
use Magento\Authorization\Model\UserContextInterface; | ||
use Magento\Framework\Exception\NoSuchEntityException; | ||
use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; | ||
use Magento\Quote\Api\CartRepositoryInterface; | ||
|
||
/** | ||
* Service for checking that the shopping cart operations are allowed for current user | ||
*/ | ||
class IsCartMutationAllowedForCurrentUser | ||
{ | ||
/** | ||
* @var CartRepositoryInterface | ||
*/ | ||
private $cartRepository; | ||
|
||
/** | ||
* @var UserContextInterface | ||
*/ | ||
private $userContext; | ||
|
||
/** | ||
* @param UserContextInterface $userContext | ||
* @param CartRepositoryInterface $cartRepository | ||
*/ | ||
public function __construct( | ||
UserContextInterface $userContext, | ||
CartRepositoryInterface $cartRepository | ||
) { | ||
$this->userContext = $userContext; | ||
$this->cartRepository = $cartRepository; | ||
} | ||
|
||
/** | ||
* Check that the shopping cart operations are allowed for current user | ||
* | ||
* @param int $quoteId | ||
* @return bool | ||
* @throws GraphQlNoSuchEntityException | ||
*/ | ||
public function execute(int $quoteId): bool | ||
{ | ||
try { | ||
$quote = $this->cartRepository->get($quoteId); | ||
} catch (NoSuchEntityException $exception) { | ||
throw new GraphQlNoSuchEntityException(__($exception->getMessage())); | ||
} | ||
|
||
$customerId = $quote->getCustomerId(); | ||
|
||
/* Guest cart, allow operations */ | ||
if (!$customerId) { | ||
return true; | ||
} | ||
|
||
/* If the quote belongs to the current customer allow operations */ | ||
return $customerId == $this->userContext->getUserId(); | ||
} | ||
} |
110 changes: 110 additions & 0 deletions
110
app/code/Magento/QuoteGraphQl/Model/Resolver/Coupon/ApplyCouponToCart.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
<?php | ||
/** | ||
* Copyright © Magento, Inc. All rights reserved. | ||
* See COPYING.txt for license details. | ||
*/ | ||
declare(strict_types=1); | ||
|
||
namespace Magento\QuoteGraphQl\Model\Resolver\Coupon; | ||
|
||
use Magento\Framework\Exception\CouldNotSaveException; | ||
use Magento\Framework\Exception\NoSuchEntityException; | ||
use Magento\Framework\GraphQl\Config\Element\Field; | ||
use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; | ||
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\CouponManagementInterface; | ||
use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface; | ||
use Magento\QuoteGraphQl\Model\Authorization\IsCartMutationAllowedForCurrentUser; | ||
|
||
/** | ||
* @inheritdoc | ||
*/ | ||
class ApplyCouponToCart implements ResolverInterface | ||
{ | ||
/** | ||
* @var CouponManagementInterface | ||
*/ | ||
private $couponManagement; | ||
|
||
/** | ||
* @var MaskedQuoteIdToQuoteIdInterface | ||
*/ | ||
private $maskedQuoteIdToQuoteId; | ||
|
||
/** | ||
* @var IsCartMutationAllowedForCurrentUser | ||
*/ | ||
private $isCartMutationAllowedForCurrentUser; | ||
|
||
/** | ||
* @param CouponManagementInterface $couponManagement | ||
* @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToId | ||
* @param IsCartMutationAllowedForCurrentUser $isCartMutationAllowedForCurrentUser | ||
*/ | ||
public function __construct( | ||
CouponManagementInterface $couponManagement, | ||
MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToId, | ||
IsCartMutationAllowedForCurrentUser $isCartMutationAllowedForCurrentUser | ||
) { | ||
$this->couponManagement = $couponManagement; | ||
$this->maskedQuoteIdToQuoteId = $maskedQuoteIdToId; | ||
$this->isCartMutationAllowedForCurrentUser = $isCartMutationAllowedForCurrentUser; | ||
} | ||
|
||
/** | ||
* @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')); | ||
} | ||
$maskedCartId = $args['input']['cart_id']; | ||
|
||
if (!isset($args['input']['coupon_code'])) { | ||
throw new GraphQlInputException(__('Required parameter "coupon_code" is missing')); | ||
} | ||
$couponCode = $args['input']['coupon_code']; | ||
|
||
try { | ||
$cartId = $this->maskedQuoteIdToQuoteId->execute($maskedCartId); | ||
} catch (NoSuchEntityException $exception) { | ||
throw new GraphQlNoSuchEntityException( | ||
__('Could not find a cart with ID "%masked_cart_id"', ['masked_cart_id' => $maskedCartId]) | ||
); | ||
} | ||
|
||
if (false === $this->isCartMutationAllowedForCurrentUser->execute($cartId)) { | ||
throw new GraphQlAuthorizationException( | ||
__( | ||
'The current user cannot perform operations on cart "%masked_cart_id"', | ||
['masked_cart_id' => $maskedCartId] | ||
) | ||
); | ||
} | ||
|
||
/* Check current cart does not have coupon code applied */ | ||
$appliedCouponCode = $this->couponManagement->get($cartId); | ||
if (!empty($appliedCouponCode)) { | ||
throw new GraphQlInputException( | ||
__('A coupon is already applied to the cart. Please remove it to apply another') | ||
); | ||
} | ||
|
||
try { | ||
$this->couponManagement->set($cartId, $couponCode); | ||
} catch (NoSuchEntityException $exception) { | ||
throw new GraphQlNoSuchEntityException(__($exception->getMessage())); | ||
} catch (CouldNotSaveException $exception) { | ||
throw new GraphQlInputException(__($exception->getMessage())); | ||
} | ||
|
||
$data['cart']['applied_coupon'] = [ | ||
'code' => $couponCode, | ||
]; | ||
return $data; | ||
} | ||
} |
97 changes: 97 additions & 0 deletions
97
app/code/Magento/QuoteGraphQl/Model/Resolver/Coupon/RemoveCouponFromCart.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
<?php | ||
/** | ||
* Copyright © Magento, Inc. All rights reserved. | ||
* See COPYING.txt for license details. | ||
*/ | ||
declare(strict_types=1); | ||
|
||
namespace Magento\QuoteGraphQl\Model\Resolver\Coupon; | ||
|
||
use Magento\Framework\Exception\CouldNotDeleteException; | ||
use Magento\Framework\Exception\NoSuchEntityException; | ||
use Magento\Framework\GraphQl\Config\Element\Field; | ||
use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; | ||
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\CouponManagementInterface; | ||
use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface; | ||
use Magento\QuoteGraphQl\Model\Authorization\IsCartMutationAllowedForCurrentUser; | ||
|
||
/** | ||
* @inheritdoc | ||
*/ | ||
class RemoveCouponFromCart implements ResolverInterface | ||
{ | ||
/** | ||
* @var MaskedQuoteIdToQuoteIdInterface | ||
*/ | ||
private $maskedQuoteIdToId; | ||
|
||
/** | ||
* @var CouponManagementInterface | ||
*/ | ||
private $couponManagement; | ||
|
||
/** | ||
* @var IsCartMutationAllowedForCurrentUser | ||
*/ | ||
private $isCartMutationAllowedForCurrentUser; | ||
|
||
/** | ||
* @param CouponManagementInterface $couponManagement | ||
* @param IsCartMutationAllowedForCurrentUser $isCartMutationAllowedForCurrentUser | ||
* @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToId | ||
*/ | ||
public function __construct( | ||
CouponManagementInterface $couponManagement, | ||
IsCartMutationAllowedForCurrentUser $isCartMutationAllowedForCurrentUser, | ||
MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToId | ||
) { | ||
$this->couponManagement = $couponManagement; | ||
$this->isCartMutationAllowedForCurrentUser = $isCartMutationAllowedForCurrentUser; | ||
$this->maskedQuoteIdToId = $maskedQuoteIdToId; | ||
} | ||
|
||
/** | ||
* @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')); | ||
} | ||
$maskedCartId = $args['input']['cart_id']; | ||
|
||
try { | ||
$cartId = $this->maskedQuoteIdToId->execute($maskedCartId); | ||
} catch (NoSuchEntityException $exception) { | ||
throw new GraphQlNoSuchEntityException( | ||
__('Could not find a cart with ID "%masked_cart_id"', ['masked_cart_id' => $maskedCartId]) | ||
); | ||
} | ||
|
||
if (false === $this->isCartMutationAllowedForCurrentUser->execute($cartId)) { | ||
throw new GraphQlAuthorizationException( | ||
__( | ||
'The current user cannot perform operations on cart "%masked_cart_id"', | ||
['masked_cart_id' => $maskedCartId] | ||
) | ||
); | ||
} | ||
|
||
try { | ||
$this->couponManagement->remove($cartId); | ||
} catch (NoSuchEntityException $exception) { | ||
throw new GraphQlNoSuchEntityException(__($exception->getMessage())); | ||
} catch (CouldNotDeleteException $exception) { | ||
throw new GraphQlInputException(__($exception->getMessage())); | ||
} | ||
|
||
$data['cart']['applied_coupon'] = [ | ||
'code' => '', | ||
]; | ||
return $data; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,4 +3,35 @@ | |
|
||
type Mutation { | ||
createEmptyCart: String @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Cart\\CreateEmptyCart") @doc(description:"Creates empty shopping cart for guest or logged in user") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change description to Creates an empty shopping cart for a guest or a logged in user |
||
applyCouponToCart(input: ApplyCouponToCartInput): ApplyCouponToCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Coupon\\ApplyCouponToCart") | ||
removeCouponFromCart(input: RemoveCouponFromCartInput): RemoveCouponFromCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Coupon\\RemoveCouponFromCart") | ||
} | ||
|
||
input ApplyCouponToCartInput { | ||
cart_id: String! | ||
coupon_code: String! | ||
} | ||
|
||
type ApplyCouponToCartOutput { | ||
cart: Cart! | ||
} | ||
|
||
type Cart { | ||
applied_coupon: AppliedCoupon | ||
} | ||
|
||
type CartAddress { | ||
applied_coupon: AppliedCoupon | ||
} | ||
|
||
type AppliedCoupon { | ||
code: String! | ||
} | ||
|
||
input RemoveCouponFromCartInput { | ||
cart_id: String! | ||
} | ||
|
||
type RemoveCouponFromCartOutput { | ||
cart: Cart | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We must not display exception messages from
\Exception
to the clients, they may contain sensitive information. Please log the original exception message and display some generic one.Please make sure to fix similar issues across the PR if any.