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

Commit

Permalink
Provide available shipping rates for addresses
Browse files Browse the repository at this point in the history
  • Loading branch information
pmclain committed Feb 4, 2019
1 parent 911a6e6 commit 4b84afb
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
use Magento\Framework\Api\ExtensibleDataObjectConverter;
use Magento\Quote\Api\Data\AddressInterface;
use Magento\Quote\Api\Data\CartInterface;
use Magento\Quote\Api\Data\ShippingMethodInterface;
use Magento\Quote\Model\Quote\Address as QuoteAddress;
use Magento\Quote\Model\Cart\ShippingMethodConverter;

/**
* Class AddressDataProvider
Expand All @@ -24,24 +26,33 @@ class AddressDataProvider
*/
private $dataObjectConverter;

/**
* @var ShippingMethodConverter
*/
private $shippingMethodConverter;

/**
* AddressDataProvider constructor.
*
* @param ExtensibleDataObjectConverter $dataObjectConverter
* @param ShippingMethodConverter $shippingMethodConverter
*/
public function __construct(
ExtensibleDataObjectConverter $dataObjectConverter
ExtensibleDataObjectConverter $dataObjectConverter,
ShippingMethodConverter $shippingMethodConverter
) {
$this->dataObjectConverter = $dataObjectConverter;
$this->shippingMethodConverter = $shippingMethodConverter;
}

/**
* Collect and return information about shipping and billing addresses
*
* @param CartInterface $cart
* @param bool $includeShippingMethods
* @return array
*/
public function getCartAddresses(CartInterface $cart): array
public function getCartAddresses(CartInterface $cart, $includeShippingMethods = false): array
{
$addressData = [];
$shippingAddress = $cart->getShippingAddress();
Expand All @@ -50,6 +61,12 @@ public function getCartAddresses(CartInterface $cart): array
if ($shippingAddress) {
$shippingData = $this->dataObjectConverter->toFlatArray($shippingAddress, [], AddressInterface::class);
$shippingData['address_type'] = 'SHIPPING';
if ($includeShippingMethods) {
$shippingData['available_shipping_methods'] = $this->extractAvailableShippingRateData(
$cart,
$shippingAddress
);
}
$addressData[] = array_merge($shippingData, $this->extractAddressData($shippingAddress));
}

Expand Down Expand Up @@ -84,11 +101,42 @@ private function extractAddressData(QuoteAddress $address): array
'code' => $address->getShippingMethod(),
'label' => $address->getShippingDescription(),
'free_shipping' => $address->getFreeShipping(),
'amount' => $address->getShippingAmount(),
'base_amount' => $address->getBaseShippingAmount(),
'amount_incl_tax' => $address->getShippingInclTax(),
'base_amount_incl_tax' => $address->getBaseShippingInclTax(),
],
'items_weight' => $address->getWeight(),
'customer_notes' => $address->getCustomerNotes()
'customer_notes' => $address->getCustomerNotes(),
'quote_id' => $address->getQuoteId(),
];

return $addressData;
}

private function extractAvailableShippingRateData(CartInterface $cart, QuoteAddress $address): array
{
$output = [];

// Allow shipping rates by setting country id for new addresses
if (!$address->getCountryId() && $address->getCountryCode()) {
$address->setCountryId($address->getCountryCode());
}

$address->setCollectShippingRates(true);
$address->collectShippingRates();

$shippingRates = $address->getGroupedAllShippingRates();
foreach ($shippingRates as $carrierRates) {
foreach ($carrierRates as $rate) {
$output[] = $this->dataObjectConverter->toFlatArray(
$this->shippingMethodConverter->modelToDataObject($rate, $cart->getQuoteCurrencyCode()),
[],
ShippingMethodInterface::class
);
}
}

return $output;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value

$cart = $value['model'];

return $this->addressDataProvider->getCartAddresses($cart);
return $this->addressDataProvider->getCartAddresses($cart, $this->includeShippingMethods($info));
}

private function includeShippingMethods(ResolveInfo $info): bool
{
return $info->getFieldSelection()['available_shipping_methods'] ?? false;
}
}
20 changes: 18 additions & 2 deletions app/code/Magento/QuoteGraphQl/etc/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ type CartAddress {
telephone: String
address_type: AdressTypeEnum
selected_shipping_method: CheckoutShippingMethod
available_shipping_methods: [CheckoutShippingMethod]
available_shipping_methods: [CheckoutAvailableShippingMethod]
items_weight: Float
customer_notes: String
cart_items: [CartItemQuantity]
Expand All @@ -138,7 +138,23 @@ type CheckoutShippingMethod {
label: String
free_shipping: Boolean!
error_message: String
# TODO: Add more complex structure for shipping rates
amount: Float!
base_amount: Float!
amount_incl_tax: Float!
base_amount_incl_tax: Float!
}

type CheckoutAvailableShippingMethod {
carrier_code: String!
carrier_title: String!
method_code: String!
method_title: String!
error_message: String
amount: Float!
base_amount: Float!
price_excl_tax: Float!
price_incl_tax: Float!
available: Boolean!
}

enum AdressTypeEnum {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,18 @@ public function testSetNewGuestShippingAddressOnCart()
city
postcode
telephone
available_shipping_methods {
amount
available
base_amount
carrier_code
carrier_title
error_message
method_code
method_title
price_excl_tax
price_incl_tax
}
}
}
}
Expand All @@ -99,6 +111,7 @@ public function testSetNewGuestShippingAddressOnCart()
self::assertArrayHasKey('addresses', $cartResponse);
$shippingAddressResponse = current($cartResponse['addresses']);
$this->assertNewShippingAddressFields($shippingAddressResponse);
$this->assertAvailableShippingRates($shippingAddressResponse);
}

/**
Expand Down Expand Up @@ -340,6 +353,18 @@ public function testSetNewRegisteredCustomerShippingAddressOnCart()
city
postcode
telephone
available_shipping_methods {
amount
available
base_amount
carrier_code
carrier_title
error_message
method_code
method_title
price_excl_tax
price_incl_tax
}
}
}
}
Expand All @@ -352,6 +377,7 @@ public function testSetNewRegisteredCustomerShippingAddressOnCart()
self::assertArrayHasKey('addresses', $cartResponse);
$shippingAddressResponse = current($cartResponse['addresses']);
$this->assertNewShippingAddressFields($shippingAddressResponse);
$this->assertAvailableShippingRates($shippingAddressResponse);
}

/**
Expand Down Expand Up @@ -398,6 +424,18 @@ public function testSetSavedRegisteredCustomerShippingAddressOnCart()
city
postcode
telephone
available_shipping_methods {
amount
available
base_amount
carrier_code
carrier_title
error_message
method_code
method_title
price_excl_tax
price_incl_tax
}
}
}
}
Expand All @@ -410,6 +448,7 @@ public function testSetSavedRegisteredCustomerShippingAddressOnCart()
self::assertArrayHasKey('addresses', $cartResponse);
$shippingAddressResponse = current($cartResponse['addresses']);
$this->assertSavedShippingAddressFields($shippingAddressResponse);
$this->assertAvailableShippingRates($shippingAddressResponse);
}

/**
Expand Down Expand Up @@ -452,6 +491,32 @@ private function assertSavedShippingAddressFields(array $shippingAddressResponse
$this->assertResponseFields($shippingAddressResponse, $assertionMap);
}

/**
* Verify the expected shipping method is available
*
* @param array $shippingAddressResponse
*/
private function assertAvailableShippingRates(array $shippingAddressResponse): void
{
$this->assertArrayHasKey('available_shipping_methods', $shippingAddressResponse);
$rate = current($shippingAddressResponse['available_shipping_methods']);

$assertionMap = [
['response_field' => 'amount', 'expected_value' => 5],
['response_field' => 'available', 'expected_value' => true],
['response_field' => 'base_amount', 'expected_value' => 5],
['response_field' => 'carrier_code', 'expected_value' => 'flatrate'],
['response_field' => 'carrier_title', 'expected_value' => 'Flat Rate'],
['response_field' => 'error_message', 'expected_value' => ''],
['response_field' => 'method_code', 'expected_value' => 'flatrate'],
['response_field' => 'method_title', 'expected_value' => 'Fixed'],
['response_field' => 'price_incl_tax', 'expected_value' => 5],
['response_field' => 'price_excl_tax', 'expected_value' => 5],
];

$this->assertResponseFields($rate, $assertionMap);
}

/**
* @param string $username
* @return array
Expand Down

0 comments on commit 4b84afb

Please sign in to comment.