Skip to content

Commit 0dd949a

Browse files
author
Valeriy Naida
authored
ENGCOM-3495: GraphQl shipping address coverage #192
2 parents 928b13a + adeca0f commit 0dd949a

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)