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

Commit c62f3d2

Browse files
committed
Provide available shipping rates for addresses
1 parent 911a6e6 commit c62f3d2

File tree

4 files changed

+141
-6
lines changed

4 files changed

+141
-6
lines changed

app/code/Magento/QuoteGraphQl/Model/Cart/Address/AddressDataProvider.php

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@
77

88
namespace Magento\QuoteGraphQl\Model\Cart\Address;
99

10+
use Magento\Directory\Api\CountryInformationAcquirerInterface;
1011
use Magento\Framework\Api\ExtensibleDataObjectConverter;
1112
use Magento\Quote\Api\Data\AddressInterface;
1213
use Magento\Quote\Api\Data\CartInterface;
14+
use Magento\Quote\Api\Data\ShippingMethodInterface;
1315
use Magento\Quote\Model\Quote\Address as QuoteAddress;
16+
use Magento\Quote\Model\Cart\ShippingMethodConverter;
1417

1518
/**
1619
* Class AddressDataProvider
@@ -24,24 +27,33 @@ class AddressDataProvider
2427
*/
2528
private $dataObjectConverter;
2629

30+
/**
31+
* @var ShippingMethodConverter
32+
*/
33+
private $shippingMethodConverter;
34+
2735
/**
2836
* AddressDataProvider constructor.
2937
*
3038
* @param ExtensibleDataObjectConverter $dataObjectConverter
39+
* @param ShippingMethodConverter $shippingMethodConverter
3140
*/
3241
public function __construct(
33-
ExtensibleDataObjectConverter $dataObjectConverter
42+
ExtensibleDataObjectConverter $dataObjectConverter,
43+
ShippingMethodConverter $shippingMethodConverter
3444
) {
3545
$this->dataObjectConverter = $dataObjectConverter;
46+
$this->shippingMethodConverter = $shippingMethodConverter;
3647
}
3748

3849
/**
3950
* Collect and return information about shipping and billing addresses
4051
*
4152
* @param CartInterface $cart
53+
* @param bool $includeShippingMethods
4254
* @return array
4355
*/
44-
public function getCartAddresses(CartInterface $cart): array
56+
public function getCartAddresses(CartInterface $cart, $includeShippingMethods = false): array
4557
{
4658
$addressData = [];
4759
$shippingAddress = $cart->getShippingAddress();
@@ -50,6 +62,12 @@ public function getCartAddresses(CartInterface $cart): array
5062
if ($shippingAddress) {
5163
$shippingData = $this->dataObjectConverter->toFlatArray($shippingAddress, [], AddressInterface::class);
5264
$shippingData['address_type'] = 'SHIPPING';
65+
if ($includeShippingMethods) {
66+
$shippingData['available_shipping_methods'] = $this->extractAvailableShippingRateData(
67+
$cart,
68+
$shippingAddress
69+
);
70+
}
5371
$addressData[] = array_merge($shippingData, $this->extractAddressData($shippingAddress));
5472
}
5573

@@ -84,11 +102,42 @@ private function extractAddressData(QuoteAddress $address): array
84102
'code' => $address->getShippingMethod(),
85103
'label' => $address->getShippingDescription(),
86104
'free_shipping' => $address->getFreeShipping(),
105+
'amount' => $address->getShippingAmount(),
106+
'base_amount' => $address->getBaseShippingAmount(),
107+
'amount_incl_tax' => $address->getShippingInclTax(),
108+
'base_amount_incl_tax' => $address->getBaseShippingInclTax(),
87109
],
88110
'items_weight' => $address->getWeight(),
89-
'customer_notes' => $address->getCustomerNotes()
111+
'customer_notes' => $address->getCustomerNotes(),
112+
'quote_id' => $address->getQuoteId(),
90113
];
91114

92115
return $addressData;
93116
}
117+
118+
private function extractAvailableShippingRateData(CartInterface $cart, QuoteAddress $address): array
119+
{
120+
$output = [];
121+
122+
// Allow shipping rates by setting country id for new addresses
123+
if (!$address->getCountryId() && $address->getCountryCode()) {
124+
$address->setCountryId($address->getCountryCode());
125+
}
126+
127+
$address->setCollectShippingRates(true);
128+
$address->collectShippingRates();
129+
130+
$shippingRates = $address->getGroupedAllShippingRates();
131+
foreach ($shippingRates as $carrierRates) {
132+
foreach ($carrierRates as $rate) {
133+
$output[] = $this->dataObjectConverter->toFlatArray(
134+
$this->shippingMethodConverter->modelToDataObject($rate, $cart->getQuoteCurrencyCode()),
135+
[],
136+
ShippingMethodInterface::class
137+
);
138+
}
139+
}
140+
141+
return $output;
142+
}
94143
}

app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddresses.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value
4343

4444
$cart = $value['model'];
4545

46-
return $this->addressDataProvider->getCartAddresses($cart);
46+
return $this->addressDataProvider->getCartAddresses($cart, $this->includeShippingMethods($info));
47+
}
48+
49+
private function includeShippingMethods(ResolveInfo $info): bool
50+
{
51+
return $info->getFieldSelection()['available_shipping_methods'] ?? false;
4752
}
4853
}

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

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ type CartAddress {
112112
telephone: String
113113
address_type: AdressTypeEnum
114114
selected_shipping_method: CheckoutShippingMethod
115-
available_shipping_methods: [CheckoutShippingMethod]
115+
available_shipping_methods: [CheckoutAvailableShippingMethod]
116116
items_weight: Float
117117
customer_notes: String
118118
cart_items: [CartItemQuantity]
@@ -138,7 +138,23 @@ type CheckoutShippingMethod {
138138
label: String
139139
free_shipping: Boolean!
140140
error_message: String
141-
# TODO: Add more complex structure for shipping rates
141+
amount: Float!
142+
base_amount: Float!
143+
amount_incl_tax: Float!
144+
base_amount_incl_tax: Float!
145+
}
146+
147+
type CheckoutAvailableShippingMethod {
148+
carrier_code: String!
149+
carrier_title: String!
150+
method_code: String!
151+
method_title: String!
152+
error_message: String
153+
amount: Float!
154+
base_amount: Float!
155+
price_excl_tax: Float!
156+
price_incl_tax: Float!
157+
available: Boolean!
142158
}
143159

144160
enum AdressTypeEnum {

dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,18 @@ public function testSetNewGuestShippingAddressOnCart()
8787
city
8888
postcode
8989
telephone
90+
available_shipping_methods {
91+
amount
92+
available
93+
base_amount
94+
carrier_code
95+
carrier_title
96+
error_message
97+
method_code
98+
method_title
99+
price_excl_tax
100+
price_incl_tax
101+
}
90102
}
91103
}
92104
}
@@ -99,6 +111,7 @@ public function testSetNewGuestShippingAddressOnCart()
99111
self::assertArrayHasKey('addresses', $cartResponse);
100112
$shippingAddressResponse = current($cartResponse['addresses']);
101113
$this->assertNewShippingAddressFields($shippingAddressResponse);
114+
$this->assertAvailableShippingRates($shippingAddressResponse);
102115
}
103116

104117
/**
@@ -340,6 +353,18 @@ public function testSetNewRegisteredCustomerShippingAddressOnCart()
340353
city
341354
postcode
342355
telephone
356+
available_shipping_methods {
357+
amount
358+
available
359+
base_amount
360+
carrier_code
361+
carrier_title
362+
error_message
363+
method_code
364+
method_title
365+
price_excl_tax
366+
price_incl_tax
367+
}
343368
}
344369
}
345370
}
@@ -352,6 +377,7 @@ public function testSetNewRegisteredCustomerShippingAddressOnCart()
352377
self::assertArrayHasKey('addresses', $cartResponse);
353378
$shippingAddressResponse = current($cartResponse['addresses']);
354379
$this->assertNewShippingAddressFields($shippingAddressResponse);
380+
$this->assertAvailableShippingRates($shippingAddressResponse);
355381
}
356382

357383
/**
@@ -398,6 +424,18 @@ public function testSetSavedRegisteredCustomerShippingAddressOnCart()
398424
city
399425
postcode
400426
telephone
427+
available_shipping_methods {
428+
amount
429+
available
430+
base_amount
431+
carrier_code
432+
carrier_title
433+
error_message
434+
method_code
435+
method_title
436+
price_excl_tax
437+
price_incl_tax
438+
}
401439
}
402440
}
403441
}
@@ -410,6 +448,7 @@ public function testSetSavedRegisteredCustomerShippingAddressOnCart()
410448
self::assertArrayHasKey('addresses', $cartResponse);
411449
$shippingAddressResponse = current($cartResponse['addresses']);
412450
$this->assertSavedShippingAddressFields($shippingAddressResponse);
451+
$this->assertAvailableShippingRates($shippingAddressResponse);
413452
}
414453

415454
/**
@@ -452,6 +491,32 @@ private function assertSavedShippingAddressFields(array $shippingAddressResponse
452491
$this->assertResponseFields($shippingAddressResponse, $assertionMap);
453492
}
454493

494+
/**
495+
* Verify the expected shipping method is available
496+
*
497+
* @param array $shippingAddressResponse
498+
*/
499+
private function assertAvailableShippingRates(array $shippingAddressResponse): void
500+
{
501+
$this->assertArrayHasKey('available_shipping_methods', $shippingAddressResponse);
502+
$rate = current($shippingAddressResponse['available_shipping_methods']);
503+
504+
$assertionMap = [
505+
['response_field' => 'amount', 'expected_value' => 5],
506+
['response_field' => 'available', 'expected_value' => true],
507+
['response_field' => 'base_amount', 'expected_value' => 5],
508+
['response_field' => 'carrier_code', 'expected_value' => 'flatrate'],
509+
['response_field' => 'carrier_title', 'expected_value' => 'Flat Rate'],
510+
['response_field' => 'error_message', 'expected_value' => ''],
511+
['response_field' => 'method_code', 'expected_value' => 'flatrate'],
512+
['response_field' => 'method_title', 'expected_value' => 'Fixed'],
513+
['response_field' => 'price_incl_tax', 'expected_value' => 5],
514+
['response_field' => 'price_excl_tax', 'expected_value' => 5],
515+
];
516+
517+
$this->assertResponseFields($rate, $assertionMap);
518+
}
519+
455520
/**
456521
* @param string $username
457522
* @return array

0 commit comments

Comments
 (0)