Skip to content
This repository was archived by the owner on Dec 19, 2019. It is now read-only.

Commit dc5b402

Browse files
author
Valeriy Naida
authored
ENGCOM-3007: Mutations coupons #163
2 parents 43dca41 + ff84a75 commit dc5b402

File tree

7 files changed

+559
-16
lines changed

7 files changed

+559
-16
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\QuoteGraphQl\Model\Authorization;
9+
10+
use Magento\Authorization\Model\UserContextInterface;
11+
use Magento\Framework\Exception\NoSuchEntityException;
12+
use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException;
13+
use Magento\Quote\Api\CartRepositoryInterface;
14+
15+
/**
16+
* Service for checking that the shopping cart operations are allowed for current user
17+
*/
18+
class IsCartMutationAllowedForCurrentUser
19+
{
20+
/**
21+
* @var CartRepositoryInterface
22+
*/
23+
private $cartRepository;
24+
25+
/**
26+
* @var UserContextInterface
27+
*/
28+
private $userContext;
29+
30+
/**
31+
* @param UserContextInterface $userContext
32+
* @param CartRepositoryInterface $cartRepository
33+
*/
34+
public function __construct(
35+
UserContextInterface $userContext,
36+
CartRepositoryInterface $cartRepository
37+
) {
38+
$this->userContext = $userContext;
39+
$this->cartRepository = $cartRepository;
40+
}
41+
42+
/**
43+
* Check that the shopping cart operations are allowed for current user
44+
*
45+
* @param int $quoteId
46+
* @return bool
47+
* @throws GraphQlNoSuchEntityException
48+
*/
49+
public function execute(int $quoteId): bool
50+
{
51+
try {
52+
$quote = $this->cartRepository->get($quoteId);
53+
} catch (NoSuchEntityException $exception) {
54+
throw new GraphQlNoSuchEntityException(__($exception->getMessage()));
55+
}
56+
57+
$customerId = $quote->getCustomerId();
58+
59+
/* Guest cart, allow operations */
60+
if (!$customerId) {
61+
return true;
62+
}
63+
64+
/* If the quote belongs to the current customer allow operations */
65+
return $customerId == $this->userContext->getUserId();
66+
}
67+
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\QuoteGraphQl\Model\Resolver\Coupon;
9+
10+
use Magento\Framework\Exception\CouldNotSaveException;
11+
use Magento\Framework\Exception\NoSuchEntityException;
12+
use Magento\Framework\GraphQl\Config\Element\Field;
13+
use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException;
14+
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
15+
use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException;
16+
use Magento\Framework\GraphQl\Query\ResolverInterface;
17+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
18+
use Magento\Quote\Api\CouponManagementInterface;
19+
use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface;
20+
use Magento\QuoteGraphQl\Model\Authorization\IsCartMutationAllowedForCurrentUser;
21+
22+
/**
23+
* @inheritdoc
24+
*/
25+
class ApplyCouponToCart implements ResolverInterface
26+
{
27+
/**
28+
* @var CouponManagementInterface
29+
*/
30+
private $couponManagement;
31+
32+
/**
33+
* @var MaskedQuoteIdToQuoteIdInterface
34+
*/
35+
private $maskedQuoteIdToQuoteId;
36+
37+
/**
38+
* @var IsCartMutationAllowedForCurrentUser
39+
*/
40+
private $isCartMutationAllowedForCurrentUser;
41+
42+
/**
43+
* @param CouponManagementInterface $couponManagement
44+
* @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToId
45+
* @param IsCartMutationAllowedForCurrentUser $isCartMutationAllowedForCurrentUser
46+
*/
47+
public function __construct(
48+
CouponManagementInterface $couponManagement,
49+
MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToId,
50+
IsCartMutationAllowedForCurrentUser $isCartMutationAllowedForCurrentUser
51+
) {
52+
$this->couponManagement = $couponManagement;
53+
$this->maskedQuoteIdToQuoteId = $maskedQuoteIdToId;
54+
$this->isCartMutationAllowedForCurrentUser = $isCartMutationAllowedForCurrentUser;
55+
}
56+
57+
/**
58+
* @inheritdoc
59+
*/
60+
public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null)
61+
{
62+
if (!isset($args['input']['cart_id'])) {
63+
throw new GraphQlInputException(__('Required parameter "cart_id" is missing'));
64+
}
65+
$maskedCartId = $args['input']['cart_id'];
66+
67+
if (!isset($args['input']['coupon_code'])) {
68+
throw new GraphQlInputException(__('Required parameter "coupon_code" is missing'));
69+
}
70+
$couponCode = $args['input']['coupon_code'];
71+
72+
try {
73+
$cartId = $this->maskedQuoteIdToQuoteId->execute($maskedCartId);
74+
} catch (NoSuchEntityException $exception) {
75+
throw new GraphQlNoSuchEntityException(
76+
__('Could not find a cart with ID "%masked_cart_id"', ['masked_cart_id' => $maskedCartId])
77+
);
78+
}
79+
80+
if (false === $this->isCartMutationAllowedForCurrentUser->execute($cartId)) {
81+
throw new GraphQlAuthorizationException(
82+
__(
83+
'The current user cannot perform operations on cart "%masked_cart_id"',
84+
['masked_cart_id' => $maskedCartId]
85+
)
86+
);
87+
}
88+
89+
/* Check current cart does not have coupon code applied */
90+
$appliedCouponCode = $this->couponManagement->get($cartId);
91+
if (!empty($appliedCouponCode)) {
92+
throw new GraphQlInputException(
93+
__('A coupon is already applied to the cart. Please remove it to apply another')
94+
);
95+
}
96+
97+
try {
98+
$this->couponManagement->set($cartId, $couponCode);
99+
} catch (NoSuchEntityException $exception) {
100+
throw new GraphQlNoSuchEntityException(__($exception->getMessage()));
101+
} catch (CouldNotSaveException $exception) {
102+
throw new GraphQlInputException(__($exception->getMessage()));
103+
}
104+
105+
$data['cart']['applied_coupon'] = [
106+
'code' => $couponCode,
107+
];
108+
return $data;
109+
}
110+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\QuoteGraphQl\Model\Resolver\Coupon;
9+
10+
use Magento\Framework\Exception\CouldNotDeleteException;
11+
use Magento\Framework\Exception\NoSuchEntityException;
12+
use Magento\Framework\GraphQl\Config\Element\Field;
13+
use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException;
14+
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
15+
use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException;
16+
use Magento\Framework\GraphQl\Query\ResolverInterface;
17+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
18+
use Magento\Quote\Api\CouponManagementInterface;
19+
use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface;
20+
use Magento\QuoteGraphQl\Model\Authorization\IsCartMutationAllowedForCurrentUser;
21+
22+
/**
23+
* @inheritdoc
24+
*/
25+
class RemoveCouponFromCart implements ResolverInterface
26+
{
27+
/**
28+
* @var MaskedQuoteIdToQuoteIdInterface
29+
*/
30+
private $maskedQuoteIdToId;
31+
32+
/**
33+
* @var CouponManagementInterface
34+
*/
35+
private $couponManagement;
36+
37+
/**
38+
* @var IsCartMutationAllowedForCurrentUser
39+
*/
40+
private $isCartMutationAllowedForCurrentUser;
41+
42+
/**
43+
* @param CouponManagementInterface $couponManagement
44+
* @param IsCartMutationAllowedForCurrentUser $isCartMutationAllowedForCurrentUser
45+
* @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToId
46+
*/
47+
public function __construct(
48+
CouponManagementInterface $couponManagement,
49+
IsCartMutationAllowedForCurrentUser $isCartMutationAllowedForCurrentUser,
50+
MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToId
51+
) {
52+
$this->couponManagement = $couponManagement;
53+
$this->isCartMutationAllowedForCurrentUser = $isCartMutationAllowedForCurrentUser;
54+
$this->maskedQuoteIdToId = $maskedQuoteIdToId;
55+
}
56+
57+
/**
58+
* @inheritdoc
59+
*/
60+
public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null)
61+
{
62+
if (!isset($args['input']['cart_id'])) {
63+
throw new GraphQlInputException(__('Required parameter "cart_id" is missing'));
64+
}
65+
$maskedCartId = $args['input']['cart_id'];
66+
67+
try {
68+
$cartId = $this->maskedQuoteIdToId->execute($maskedCartId);
69+
} catch (NoSuchEntityException $exception) {
70+
throw new GraphQlNoSuchEntityException(
71+
__('Could not find a cart with ID "%masked_cart_id"', ['masked_cart_id' => $maskedCartId])
72+
);
73+
}
74+
75+
if (false === $this->isCartMutationAllowedForCurrentUser->execute($cartId)) {
76+
throw new GraphQlAuthorizationException(
77+
__(
78+
'The current user cannot perform operations on cart "%masked_cart_id"',
79+
['masked_cart_id' => $maskedCartId]
80+
)
81+
);
82+
}
83+
84+
try {
85+
$this->couponManagement->remove($cartId);
86+
} catch (NoSuchEntityException $exception) {
87+
throw new GraphQlNoSuchEntityException(__($exception->getMessage()));
88+
} catch (CouldNotDeleteException $exception) {
89+
throw new GraphQlInputException(__($exception->getMessage()));
90+
}
91+
92+
$data['cart']['applied_coupon'] = [
93+
'code' => '',
94+
];
95+
return $data;
96+
}
97+
}

app/code/Magento/QuoteGraphQl/etc/schema.graphqls

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,35 @@
33

44
type Mutation {
55
createEmptyCart: String @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Cart\\CreateEmptyCart") @doc(description:"Creates empty shopping cart for guest or logged in user")
6+
applyCouponToCart(input: ApplyCouponToCartInput): ApplyCouponToCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Coupon\\ApplyCouponToCart")
7+
removeCouponFromCart(input: RemoveCouponFromCartInput): RemoveCouponFromCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Coupon\\RemoveCouponFromCart")
68
}
9+
10+
input ApplyCouponToCartInput {
11+
cart_id: String!
12+
coupon_code: String!
13+
}
14+
15+
type ApplyCouponToCartOutput {
16+
cart: Cart!
17+
}
18+
19+
type Cart {
20+
applied_coupon: AppliedCoupon
21+
}
22+
23+
type CartAddress {
24+
applied_coupon: AppliedCoupon
25+
}
26+
27+
type AppliedCoupon {
28+
code: String!
29+
}
30+
31+
input RemoveCouponFromCartInput {
32+
cart_id: String!
33+
}
34+
35+
type RemoveCouponFromCartOutput {
36+
cart: Cart
37+
}

0 commit comments

Comments
 (0)