Skip to content

Commit adeca0f

Browse files
ENGCOM-3495: GraphQl shipping address coverage #192
- Merge Pull Request magento/graphql-ce#192 from magento/graphql-ce:graph-ql-shipping-address-coverage - Merged commits: 1. e327bb6 2. ef8f126 3. a0bb0fc 4. c8dbdf4 5. bf0aaad 6. 0a6c0b5 7. 90831f5 8. 5d2b1c8 9. e1f09fb 10. 55b6f4e 11. 7c21b3b 12. 2644b54 13. c857857 14. 240cfb3 15. afd128e 16. d6f393a 17. 2b5c1aa 18. 313544e 19. 4694c06 20. c498773 21. 39225d4
2 parents 069d5cd + 39225d4 commit adeca0f

File tree

7 files changed

+721
-3
lines changed

7 files changed

+721
-3
lines changed
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
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\Cart;
9+
10+
use Magento\Customer\Api\Data\AddressInterface;
11+
use Magento\CustomerGraphQl\Model\Customer\CheckCustomerAccount;
12+
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
13+
use Magento\Framework\GraphQl\Query\Resolver\ContextInterface;
14+
use Magento\Quote\Api\Data\CartInterface;
15+
use Magento\Quote\Model\Quote\Address;
16+
use Magento\Quote\Model\ShippingAddressManagementInterface;
17+
use Magento\Customer\Api\AddressRepositoryInterface;
18+
19+
/**
20+
* Set single shipping address for a specified shopping cart
21+
*/
22+
class SetShippingAddressOnCart implements SetShippingAddressesOnCartInterface
23+
{
24+
/**
25+
* @var ShippingAddressManagementInterface
26+
*/
27+
private $shippingAddressManagement;
28+
29+
/**
30+
* @var AddressRepositoryInterface
31+
*/
32+
private $addressRepository;
33+
34+
/**
35+
* @var Address
36+
*/
37+
private $addressModel;
38+
39+
/**
40+
* @var CheckCustomerAccount
41+
*/
42+
private $checkCustomerAccount;
43+
44+
/**
45+
* @param ShippingAddressManagementInterface $shippingAddressManagement
46+
* @param AddressRepositoryInterface $addressRepository
47+
* @param Address $addressModel
48+
* @param CheckCustomerAccount $checkCustomerAccount
49+
*/
50+
public function __construct(
51+
ShippingAddressManagementInterface $shippingAddressManagement,
52+
AddressRepositoryInterface $addressRepository,
53+
Address $addressModel,
54+
CheckCustomerAccount $checkCustomerAccount
55+
) {
56+
$this->shippingAddressManagement = $shippingAddressManagement;
57+
$this->addressRepository = $addressRepository;
58+
$this->addressModel = $addressModel;
59+
$this->checkCustomerAccount = $checkCustomerAccount;
60+
}
61+
62+
/**
63+
* @inheritdoc
64+
*/
65+
public function execute(ContextInterface $context, CartInterface $cart, array $shippingAddresses): void
66+
{
67+
if (count($shippingAddresses) > 1) {
68+
throw new GraphQlInputException(
69+
__('You cannot specify multiple shipping addresses.')
70+
);
71+
}
72+
$shippingAddress = current($shippingAddresses);
73+
$customerAddressId = $shippingAddress['customer_address_id'] ?? null;
74+
$addressInput = $shippingAddress['address'] ?? null;
75+
76+
if (null === $customerAddressId && null === $addressInput) {
77+
throw new GraphQlInputException(
78+
__('The shipping address must contain either "customer_address_id" or "address".')
79+
);
80+
}
81+
if ($customerAddressId && $addressInput) {
82+
throw new GraphQlInputException(
83+
__('The shipping address cannot contain "customer_address_id" and "address" at the same time.')
84+
);
85+
}
86+
if (null === $customerAddressId) {
87+
$shippingAddress = $this->addressModel->addData($addressInput);
88+
} else {
89+
$this->checkCustomerAccount->execute($context->getUserId(), $context->getUserType());
90+
91+
/** @var AddressInterface $customerAddress */
92+
$customerAddress = $this->addressRepository->getById($customerAddressId);
93+
$shippingAddress = $this->addressModel->importCustomerAddressData($customerAddress);
94+
}
95+
96+
$this->shippingAddressManagement->assign($cart->getId(), $shippingAddress);
97+
}
98+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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\Cart;
9+
10+
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
11+
use Magento\Framework\GraphQl\Query\Resolver\ContextInterface;
12+
use Magento\Quote\Api\Data\CartInterface;
13+
14+
/**
15+
* Extension point for setting shipping addresses for a specified shopping cart
16+
*
17+
* All objects that are responsible for setting shipping addresses on a cart via GraphQl
18+
* should implement this interface.
19+
*/
20+
interface SetShippingAddressesOnCartInterface
21+
{
22+
/**
23+
* Set shipping addresses for a specified shopping cart
24+
*
25+
* @param ContextInterface $context
26+
* @param CartInterface $cart
27+
* @param array $shippingAddresses
28+
* @return void
29+
* @throws GraphQlInputException
30+
*/
31+
public function execute(ContextInterface $context, CartInterface $cart, array $shippingAddresses): void;
32+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
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;
9+
10+
use Magento\Framework\GraphQl\Config\Element\Field;
11+
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
12+
use Magento\Framework\GraphQl\Query\ResolverInterface;
13+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
14+
use Magento\Framework\Stdlib\ArrayManager;
15+
use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface;
16+
use Magento\Quote\Model\ShippingAddressManagementInterface;
17+
use Magento\QuoteGraphQl\Model\Cart\GetCartForUser;
18+
use Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCartInterface;
19+
20+
/**
21+
* Class SetShippingAddressesOnCart
22+
*
23+
* Mutation resolver for setting shipping addresses for shopping cart
24+
*/
25+
class SetShippingAddressesOnCart implements ResolverInterface
26+
{
27+
/**
28+
* @var MaskedQuoteIdToQuoteIdInterface
29+
*/
30+
private $maskedQuoteIdToQuoteId;
31+
32+
/**
33+
* @var ShippingAddressManagementInterface
34+
*/
35+
private $shippingAddressManagement;
36+
37+
/**
38+
* @var GetCartForUser
39+
*/
40+
private $getCartForUser;
41+
42+
/**
43+
* @var ArrayManager
44+
*/
45+
private $arrayManager;
46+
47+
/**
48+
* @var SetShippingAddressesOnCartInterface
49+
*/
50+
private $setShippingAddressesOnCart;
51+
52+
/**
53+
* @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId
54+
* @param ShippingAddressManagementInterface $shippingAddressManagement
55+
* @param GetCartForUser $getCartForUser
56+
* @param ArrayManager $arrayManager
57+
* @param SetShippingAddressesOnCartInterface $setShippingAddressesOnCart
58+
*/
59+
public function __construct(
60+
MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId,
61+
ShippingAddressManagementInterface $shippingAddressManagement,
62+
GetCartForUser $getCartForUser,
63+
ArrayManager $arrayManager,
64+
SetShippingAddressesOnCartInterface $setShippingAddressesOnCart
65+
) {
66+
$this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId;
67+
$this->shippingAddressManagement = $shippingAddressManagement;
68+
$this->getCartForUser = $getCartForUser;
69+
$this->arrayManager = $arrayManager;
70+
$this->setShippingAddressesOnCart = $setShippingAddressesOnCart;
71+
}
72+
73+
/**
74+
* @inheritdoc
75+
*/
76+
public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null)
77+
{
78+
$shippingAddresses = $this->arrayManager->get('input/shipping_addresses', $args);
79+
$maskedCartId = $this->arrayManager->get('input/cart_id', $args);
80+
81+
if (!$maskedCartId) {
82+
throw new GraphQlInputException(__('Required parameter "cart_id" is missing'));
83+
}
84+
if (!$shippingAddresses) {
85+
throw new GraphQlInputException(__('Required parameter "shipping_addresses" is missing'));
86+
}
87+
88+
$maskedCartId = $args['input']['cart_id'];
89+
$cart = $this->getCartForUser->execute($maskedCartId, $context->getUserId());
90+
91+
$this->setShippingAddressesOnCart->execute($context, $cart, $shippingAddresses);
92+
93+
return [
94+
'cart' => [
95+
'cart_id' => $maskedCartId,
96+
'model' => $cart,
97+
]
98+
];
99+
}
100+
}

app/code/Magento/QuoteGraphQl/composer.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
"magento/module-quote": "*",
99
"magento/module-checkout": "*",
1010
"magento/module-catalog": "*",
11-
"magento/module-store": "*"
11+
"magento/module-store": "*",
12+
"magento/module-customer": "*",
13+
"magento/module-customer-graph-ql": "*"
1214
},
1315
"suggest": {
1416
"magento/module-graph-ql": "*"
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
9+
<preference for="Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCartInterface"
10+
type="Magento\QuoteGraphQl\Model\Cart\SetShippingAddressOnCart" />
11+
</config>

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,23 @@ type Query {
66
}
77

88
type Mutation {
9-
createEmptyCart: String @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\CreateEmptyCart") @doc(description:"Creates empty shopping cart for guest or logged in user")
9+
createEmptyCart: String @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\CreateEmptyCart") @doc(description:"Creates an empty shopping cart for a guest or logged in user")
10+
applyCouponToCart(input: ApplyCouponToCartInput): ApplyCouponToCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Coupon\\ApplyCouponToCart")
11+
removeCouponFromCart(input: RemoveCouponFromCartInput): RemoveCouponFromCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Coupon\\RemoveCouponFromCart")
12+
setShippingAddressesOnCart(input: SetShippingAddressesOnCartInput): SetShippingAddressesOnCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\SetShippingAddressesOnCart")
1013
applyCouponToCart(input: ApplyCouponToCartInput): ApplyCouponToCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\ApplyCouponToCart")
1114
removeCouponFromCart(input: RemoveCouponFromCartInput): RemoveCouponFromCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\RemoveCouponFromCart")
12-
setShippingAddressesOnCart(input: SetShippingAddressesOnCartInput): SetShippingAddressesOnCartOutput
1315
setBillingAddressOnCart(input: SetBillingAddressOnCartInput): SetBillingAddressOnCartOutput
1416
setShippingMethodsOnCart(input: SetShippingMethodsOnCartInput): SetShippingMethodsOnCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\SetShippingMethodsOnCart")
1517
addSimpleProductsToCart(input: AddSimpleProductsToCartInput): AddSimpleProductsToCartOutput @resolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\AddSimpleProductsToCart")
1618
}
1719

1820
input SetShippingAddressesOnCartInput {
1921
cart_id: String!
22+
shipping_addresses: [ShippingAddressInput!]!
23+
}
24+
25+
input ShippingAddressInput {
2026
customer_address_id: Int # Can be provided in one-page checkout and is required for multi-shipping checkout
2127
address: CartAddressInput
2228
cart_items: [CartItemQuantityInput!]

0 commit comments

Comments
 (0)