diff --git a/plugins/woocommerce-blocks/assets/js/base/components/address-form/index.js b/plugins/woocommerce-blocks/assets/js/base/components/address-form/index.js
index 44482b4b403..875de012fa1 100644
--- a/plugins/woocommerce-blocks/assets/js/base/components/address-form/index.js
+++ b/plugins/woocommerce-blocks/assets/js/base/components/address-form/index.js
@@ -66,6 +66,8 @@ const AddressForm = ( {
...values,
country: newValue,
state: '',
+ city: '',
+ postcode: '',
} )
}
required={ field.required }
diff --git a/plugins/woocommerce-blocks/assets/js/base/hooks/cart/use-store-cart.js b/plugins/woocommerce-blocks/assets/js/base/hooks/cart/use-store-cart.js
index c27286fe9a5..251585c03eb 100644
--- a/plugins/woocommerce-blocks/assets/js/base/hooks/cart/use-store-cart.js
+++ b/plugins/woocommerce-blocks/assets/js/base/hooks/cart/use-store-cart.js
@@ -14,7 +14,6 @@ import { previewCart } from '@woocommerce/resource-previews';
*/
const defaultCartData = {
cartCoupons: [],
- shippingRates: [],
cartItems: [],
cartItemsCount: 0,
cartItemsWeight: 0,
@@ -22,6 +21,18 @@ const defaultCartData = {
cartTotals: {},
cartIsLoading: true,
cartErrors: [],
+ shippingAddress: {
+ first_name: '',
+ last_name: '',
+ company: '',
+ address_1: '',
+ address_2: '',
+ city: '',
+ state: '',
+ postcode: '',
+ country: '',
+ },
+ shippingRates: [],
};
/**
@@ -43,7 +54,7 @@ export const useStoreCart = ( options = { shouldSelect: true } ) => {
const results = useSelect(
( select ) => {
if ( ! shouldSelect ) {
- return null;
+ return defaultCartData;
}
if ( isEditor ) {
@@ -70,6 +81,7 @@ export const useStoreCart = ( options = { shouldSelect: true } ) => {
return {
cartCoupons: cartData.coupons,
shippingRates: cartData.shippingRates,
+ shippingAddress: cartData.shippingAddress,
cartItems: cartData.items,
cartItemsCount: cartData.itemsCount,
cartItemsWeight: cartData.itemsWeight,
@@ -81,8 +93,5 @@ export const useStoreCart = ( options = { shouldSelect: true } ) => {
},
[ shouldSelect ]
);
- if ( results === null ) {
- return defaultCartData;
- }
return results;
};
diff --git a/plugins/woocommerce-blocks/assets/js/base/hooks/payment-methods/use-payment-method-interface.js b/plugins/woocommerce-blocks/assets/js/base/hooks/payment-methods/use-payment-method-interface.js
index 1e3b3b7c345..ef4ceaa5aed 100644
--- a/plugins/woocommerce-blocks/assets/js/base/hooks/payment-methods/use-payment-method-interface.js
+++ b/plugins/woocommerce-blocks/assets/js/base/hooks/payment-methods/use-payment-method-interface.js
@@ -169,9 +169,6 @@ export const usePaymentMethodInterface = () => {
orderLoading,
cartTotal: currentCartTotal.current,
currency: getCurrencyFromPriceResponse( cartTotals ),
- // @todo need to pass along the default country set for the site
- // if it's available.
- country: '',
cartTotalItems: currentCartTotals.current,
displayPricesIncludingTax: DISPLAY_CART_PRICES_INCLUDING_TAX,
appliedCoupons,
diff --git a/plugins/woocommerce-blocks/assets/js/base/hooks/shipping/index.js b/plugins/woocommerce-blocks/assets/js/base/hooks/shipping/index.js
index c3f8b53b5dd..8bff3df9835 100644
--- a/plugins/woocommerce-blocks/assets/js/base/hooks/shipping/index.js
+++ b/plugins/woocommerce-blocks/assets/js/base/hooks/shipping/index.js
@@ -1,2 +1,3 @@
export * from './use-select-shipping-rate';
export * from './use-shipping-rates';
+export * from './use-shipping-address';
diff --git a/plugins/woocommerce-blocks/assets/js/base/hooks/shipping/use-shipping-address.js b/plugins/woocommerce-blocks/assets/js/base/hooks/shipping/use-shipping-address.js
new file mode 100644
index 00000000000..e95b6420a3d
--- /dev/null
+++ b/plugins/woocommerce-blocks/assets/js/base/hooks/shipping/use-shipping-address.js
@@ -0,0 +1,39 @@
+/**
+ * External dependencies
+ */
+import { useDispatch } from '@wordpress/data';
+import { useEffect, useState } from '@wordpress/element';
+import isShallowEqual from '@wordpress/is-shallow-equal';
+import { useDebounce } from 'use-debounce';
+import { CART_STORE_KEY as storeKey } from '@woocommerce/block-data';
+
+/**
+ * Internal dependencies
+ */
+import { useStoreCart } from '../cart/use-store-cart';
+import { pluckAddress } from '../../utils';
+
+const shouldUpdateStore = ( oldAddress, newAddress ) =>
+ ! isShallowEqual( pluckAddress( oldAddress ), pluckAddress( newAddress ) );
+
+export const useShippingAddress = () => {
+ const { shippingAddress: initialAddress } = useStoreCart();
+ const [ shippingAddress, setShippingAddress ] = useState( initialAddress );
+ const [ debouncedShippingAddress ] = useDebounce( shippingAddress, 400 );
+ const { updateShippingAddress } = useDispatch( storeKey );
+
+ // Note, we're intentionally not using initialAddress as a dependency here
+ // so that the stale (previous) value is being used for comparison.
+ useEffect( () => {
+ if (
+ debouncedShippingAddress.country &&
+ shouldUpdateStore( initialAddress, debouncedShippingAddress )
+ ) {
+ updateShippingAddress( debouncedShippingAddress );
+ }
+ }, [ debouncedShippingAddress ] );
+ return {
+ shippingAddress,
+ setShippingAddress,
+ };
+};
diff --git a/plugins/woocommerce-blocks/assets/js/base/hooks/shipping/use-shipping-rates.js b/plugins/woocommerce-blocks/assets/js/base/hooks/shipping/use-shipping-rates.js
index dd48e116881..d37fcfac10b 100644
--- a/plugins/woocommerce-blocks/assets/js/base/hooks/shipping/use-shipping-rates.js
+++ b/plugins/woocommerce-blocks/assets/js/base/hooks/shipping/use-shipping-rates.js
@@ -1,24 +1,19 @@
/**
* External dependencies
*/
-import { useSelect, useDispatch } from '@wordpress/data';
-import { useReducer, useEffect } from '@wordpress/element';
-import isShallowEqual from '@wordpress/is-shallow-equal';
-import { useDebounce } from 'use-debounce';
+import { useSelect } from '@wordpress/data';
import { CART_STORE_KEY as storeKey } from '@woocommerce/block-data';
/**
* Internal dependencies
*/
import { useStoreCart } from '../cart/use-store-cart';
-import { pluckAddress } from '../../utils';
+import { useShippingAddress } from '../shipping/use-shipping-address';
/**
* This is a custom hook that is wired up to the `wc/store/cart/shipping-rates` route.
* Given a a set of default fields keys, this will handle shipping form state and load
* new rates when certain fields change.
*
- * @param {Array} addressFieldsKeys an array containing default fields keys.
- *
* @return {Object} This hook will return an object with three properties:
* - {Boolean} shippingRatesLoading A boolean indicating whether the shipping
* rates are still loading or not.
@@ -27,39 +22,13 @@ import { pluckAddress } from '../../utils';
* - {Object} shippingAddress An object containing shipping address.
* - {Object} shippingAddress True when address data exists.
*/
-export const useShippingRates = ( addressFieldsKeys ) => {
+export const useShippingRates = () => {
const { cartErrors, shippingRates } = useStoreCart();
- const initialAddress = shippingRates[ 0 ]?.destination || {};
- addressFieldsKeys.forEach( ( key ) => {
- initialAddress[ key ] = initialAddress[ key ] || '';
- } );
- const shippingAddressReducer = ( state, address ) => ( {
- ...state,
- ...address,
- } );
- const [ shippingAddress, setShippingAddress ] = useReducer(
- shippingAddressReducer,
- initialAddress
- );
- const [ debouncedShippingAddress ] = useDebounce( shippingAddress, 400 );
+ const { shippingAddress, setShippingAddress } = useShippingAddress();
const shippingRatesLoading = useSelect(
( select ) => select( storeKey ).areShippingRatesLoading(),
[]
);
- const { updateShippingAddress } = useDispatch( storeKey );
-
- useEffect( () => {
- if (
- ! isShallowEqual(
- pluckAddress( debouncedShippingAddress ),
- pluckAddress( initialAddress )
- ) &&
- debouncedShippingAddress.country
- ) {
- updateShippingAddress( debouncedShippingAddress );
- }
- }, [ debouncedShippingAddress ] );
-
return {
shippingRates,
shippingAddress,
diff --git a/plugins/woocommerce-blocks/assets/js/base/hooks/test/use-shipping-rates.js b/plugins/woocommerce-blocks/assets/js/base/hooks/test/use-shipping-rates.js
index a8dfb74be68..81739796e02 100644
--- a/plugins/woocommerce-blocks/assets/js/base/hooks/test/use-shipping-rates.js
+++ b/plugins/woocommerce-blocks/assets/js/base/hooks/test/use-shipping-rates.js
@@ -38,9 +38,8 @@ describe( 'useShippingRates', () => {
);
- const defaultFieldsConfig = [ 'country', 'state', 'city', 'postcode' ];
const getTestComponent = () => () => {
- const items = useShippingRates( defaultFieldsConfig );
+ const items = useShippingRates();
return
;
};
@@ -50,6 +49,12 @@ describe( 'useShippingRates', () => {
itemsCount: 123,
itemsWeight: 123,
needsShipping: false,
+ shippingAddress: {
+ country: '',
+ state: '',
+ city: '',
+ postcode: '',
+ },
shippingRates: [
{
shippingRates: [ { foo: 'bar' } ],
@@ -94,9 +99,7 @@ describe( 'useShippingRates', () => {
} );
const { shippingAddress } = getProps( renderer );
- expect( shippingAddress ).toStrictEqual(
- mockCartData.shippingRates[ 0 ].destination
- );
+ expect( shippingAddress ).toStrictEqual( mockCartData.shippingAddress );
// rerender
act( () => {
renderer.update( getWrappedComponents( TestComponent ) );
diff --git a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/checkout/block.js b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/checkout/block.js
index 2e8cc5bed01..e35906239a1 100644
--- a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/checkout/block.js
+++ b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/checkout/block.js
@@ -89,7 +89,7 @@ const Block = ( {
shippingRatesLoading,
shippingAddress: shippingFields,
setShippingAddress: setShippingFields,
- } = useShippingRates( Object.keys( addressFields ) );
+ } = useShippingRates();
return (
diff --git a/plugins/woocommerce-blocks/assets/js/data/cart/reducers.js b/plugins/woocommerce-blocks/assets/js/data/cart/reducers.js
index 99bf4467ed6..4beb1e81fb9 100644
--- a/plugins/woocommerce-blocks/assets/js/data/cart/reducers.js
+++ b/plugins/woocommerce-blocks/assets/js/data/cart/reducers.js
@@ -47,6 +47,17 @@ const reducer = (
cartData: {
coupons: [],
shippingRates: [],
+ shippingAddress: {
+ first_name: '',
+ last_name: '',
+ company: '',
+ address_1: '',
+ address_2: '',
+ city: '',
+ state: '',
+ postcode: '',
+ country: '',
+ },
items: [],
itemsCount: 0,
itemsWeight: 0,
diff --git a/plugins/woocommerce-blocks/assets/js/type-defs/cart.js b/plugins/woocommerce-blocks/assets/js/type-defs/cart.js
index 179bec97afd..63d65327fa2 100644
--- a/plugins/woocommerce-blocks/assets/js/type-defs/cart.js
+++ b/plugins/woocommerce-blocks/assets/js/type-defs/cart.js
@@ -179,13 +179,17 @@
/**
* @typedef {Object} CartData
*
- * @property {Array} coupons Coupons applied to cart.
- * @property {Array} shippingRates array of selected shipping rates
- * @property {Array} items Items in the cart.
- * @property {number} itemsCount Number of items in the cart.
- * @property {number} itemsWeight Weight of items in the cart.
- * @property {boolean} needsShipping True if the cart needs shipping.
- * @property {CartTotals} totals Cart total amounts.
+ * @property {Array} coupons Coupons applied to cart.
+ * @property {Array} shippingRates Array of selected shipping
+ * rates.
+ * @property {CartShippingAddress} shippingAddress Shipping address for the
+ * cart.
+ * @property {Array} items Items in the cart.
+ * @property {number} itemsCount Number of items in the cart.
+ * @property {number} itemsWeight Weight of items in the cart.
+ * @property {boolean} needsShipping True if the cart needs
+ * shipping.
+ * @property {CartTotals} totals Cart total amounts.
*/
/**
diff --git a/plugins/woocommerce-blocks/assets/js/type-defs/hooks.js b/plugins/woocommerce-blocks/assets/js/type-defs/hooks.js
index 4d40e78688b..ff6b92dcab3 100644
--- a/plugins/woocommerce-blocks/assets/js/type-defs/hooks.js
+++ b/plugins/woocommerce-blocks/assets/js/type-defs/hooks.js
@@ -1,19 +1,32 @@
/**
* @typedef {import('./cart').CartData} CartData
+ * @typedef {import('./cart').CartBillingAddress} CartBillingAddress
+ * @typedef {import('./cart').CartShippingAddress} CartShippingAddress
*/
/**
* @typedef {Object} StoreCart
*
- * @property {Array} cartCoupons An array of coupons applied to the cart.
- * @property {Array} shippingRates array of selected shipping rates
- * @property {Array} cartItems An array of items in the cart.
- * @property {number} cartItemsCount The number of items in the cart.
- * @property {number} cartItemsWeight The weight of all items in the cart.
- * @property {boolean} cartNeedsShipping True when the cart will require shipping.
- * @property {Object} cartTotals Cart and line total amounts.
- * @property {boolean} cartIsLoading True when cart data is being loaded.
- * @property {Array} cartErrors An array of errors thrown by the cart.
+ * @property {Array} cartCoupons An array of coupons applied
+ * to the cart.
+ * @property {Array} shippingRates array of selected shipping
+ * rates
+ * @property {CartShippingAddress} shippingAddress Shipping address for the
+ * cart.
+ * @property {Array} cartItems An array of items in the
+ * cart.
+ * @property {number} cartItemsCount The number of items in the
+ * cart.
+ * @property {number} cartItemsWeight The weight of all items in
+ * the cart.
+ * @property {boolean} cartNeedsShipping True when the cart will
+ * require shipping.
+ * @property {Object} cartTotals Cart and line total
+ * amounts.
+ * @property {boolean} cartIsLoading True when cart data is
+ * being loaded.
+ * @property {Array} cartErrors An array of errors thrown
+ * by the cart.
*/
/**
diff --git a/plugins/woocommerce-blocks/assets/js/type-defs/registered-payment-method-props.js b/plugins/woocommerce-blocks/assets/js/type-defs/registered-payment-method-props.js
index bdaa836d4d1..6302158c3ca 100644
--- a/plugins/woocommerce-blocks/assets/js/type-defs/registered-payment-method-props.js
+++ b/plugins/woocommerce-blocks/assets/js/type-defs/registered-payment-method-props.js
@@ -130,10 +130,6 @@
* @property {CartTotalItem} cartTotal The total item for
* the cart.
* @property {SiteCurrency} currency Currency object.
- * @property {string} country ISO country code
- * for the default
- * country for the
- * site.
* @property {CartTotalItem[]} cartTotalItems The various subtotal
* amounts.
* @property {boolean} displayPricesIncludingTax True means that the
diff --git a/plugins/woocommerce-blocks/package-lock.json b/plugins/woocommerce-blocks/package-lock.json
index 71e0559f748..cc7157945c9 100644
--- a/plugins/woocommerce-blocks/package-lock.json
+++ b/plugins/woocommerce-blocks/package-lock.json
@@ -28612,7 +28612,7 @@
}
},
"woocommerce": {
- "version": "git+https://github.com/woocommerce/woocommerce.git#fb1001b14a90b3020ca8000e424c955845142f5c",
+ "version": "git+https://github.com/woocommerce/woocommerce.git#6f2b232fc7fa53417691a742a419147bb0134a5c",
"from": "git+https://github.com/woocommerce/woocommerce.git",
"dev": true,
"requires": {
diff --git a/plugins/woocommerce-blocks/src/RestApi/StoreApi/Schemas/CartSchema.php b/plugins/woocommerce-blocks/src/RestApi/StoreApi/Schemas/CartSchema.php
index 9b3950688b8..d70758dcc2f 100644
--- a/plugins/woocommerce-blocks/src/RestApi/StoreApi/Schemas/CartSchema.php
+++ b/plugins/woocommerce-blocks/src/RestApi/StoreApi/Schemas/CartSchema.php
@@ -31,7 +31,7 @@ class CartSchema extends AbstractSchema {
*/
public function get_properties() {
return [
- 'coupons' => [
+ 'coupons' => [
'description' => __( 'List of applied cart coupons.', 'woo-gutenberg-products-block' ),
'type' => 'array',
'context' => [ 'view', 'edit' ],
@@ -41,7 +41,7 @@ class CartSchema extends AbstractSchema {
'properties' => $this->force_schema_readonly( ( new CartCouponSchema() )->get_properties() ),
],
],
- 'shipping_rates' => [
+ 'shipping_rates' => [
'description' => __( 'List of available shipping rates for the cart.', 'woo-gutenberg-products-block' ),
'type' => 'array',
'context' => [ 'view', 'edit' ],
@@ -51,7 +51,17 @@ class CartSchema extends AbstractSchema {
'properties' => $this->force_schema_readonly( ( new CartShippingRateSchema() )->get_properties() ),
],
],
- 'items' => [
+ 'shipping_address' => [
+ 'description' => __( 'Current set shipping address for the customer.', 'woo-gutenberg-products-block' ),
+ 'type' => 'object',
+ 'context' => [ 'view', 'edit' ],
+ 'readonly' => true,
+ 'items' => [
+ 'type' => 'object',
+ 'properties' => $this->force_schema_readonly( ( new ShippingAddressSchema() )->get_properties() ),
+ ],
+ ],
+ 'items' => [
'description' => __( 'List of cart items.', 'woo-gutenberg-products-block' ),
'type' => 'array',
'context' => [ 'view', 'edit' ],
@@ -61,25 +71,25 @@ class CartSchema extends AbstractSchema {
'properties' => $this->force_schema_readonly( ( new CartItemSchema() )->get_properties() ),
],
],
- 'items_count' => [
+ 'items_count' => [
'description' => __( 'Number of items in the cart.', 'woo-gutenberg-products-block' ),
'type' => 'integer',
'context' => [ 'view', 'edit' ],
'readonly' => true,
],
- 'items_weight' => [
+ 'items_weight' => [
'description' => __( 'Total weight (in grams) of all products in the cart.', 'woo-gutenberg-products-block' ),
'type' => 'number',
'context' => [ 'view', 'edit' ],
'readonly' => true,
],
- 'needs_shipping' => [
+ 'needs_shipping' => [
'description' => __( 'True if the cart needs shipping. False for carts with only digital goods or stores with no shipping methods set-up.', 'woo-gutenberg-products-block' ),
'type' => 'boolean',
'context' => [ 'view', 'edit' ],
'readonly' => true,
],
- 'totals' => [
+ 'totals' => [
'description' => __( 'Cart total amounts provided using the smallest unit of the currency.', 'woo-gutenberg-products-block' ),
'type' => 'object',
'context' => [ 'view', 'edit' ],
@@ -183,20 +193,22 @@ class CartSchema extends AbstractSchema {
* @return array
*/
public function get_item_response( $cart ) {
- $controller = new CartController();
- $cart_coupon_schema = new CartCouponSchema();
- $cart_item_schema = new CartItemSchema();
- $shipping_rate_schema = new CartShippingRateSchema();
- $context = 'edit';
+ $controller = new CartController();
+ $cart_coupon_schema = new CartCouponSchema();
+ $cart_item_schema = new CartItemSchema();
+ $shipping_rate_schema = new CartShippingRateSchema();
+ $shipping_address_schema = ( new ShippingAddressSchema() )->get_item_response( WC()->customer );
+ $context = 'edit';
return [
- 'coupons' => array_values( array_map( [ $cart_coupon_schema, 'get_item_response' ], array_filter( $cart->get_applied_coupons() ) ) ),
- 'shipping_rates' => array_values( array_map( [ $shipping_rate_schema, 'get_item_response' ], $controller->get_shipping_packages() ) ),
- 'items' => array_values( array_map( [ $cart_item_schema, 'get_item_response' ], array_filter( $cart->get_cart() ) ) ),
- 'items_count' => $cart->get_cart_contents_count(),
- 'items_weight' => wc_get_weight( $cart->get_cart_contents_weight(), 'g' ),
- 'needs_shipping' => $cart->needs_shipping(),
- 'totals' => (object) array_merge(
+ 'coupons' => array_values( array_map( [ $cart_coupon_schema, 'get_item_response' ], array_filter( $cart->get_applied_coupons() ) ) ),
+ 'shipping_rates' => array_values( array_map( [ $shipping_rate_schema, 'get_item_response' ], $controller->get_shipping_packages() ) ),
+ 'shipping_address' => $shipping_address_schema,
+ 'items' => array_values( array_map( [ $cart_item_schema, 'get_item_response' ], array_filter( $cart->get_cart() ) ) ),
+ 'items_count' => $cart->get_cart_contents_count(),
+ 'items_weight' => wc_get_weight( $cart->get_cart_contents_weight(), 'g' ),
+ 'needs_shipping' => $cart->needs_shipping(),
+ 'totals' => (object) array_merge(
$this->get_store_currency_response(),
[
'total_items' => $this->prepare_money_response( $cart->get_subtotal(), wc_get_price_decimals() ),
diff --git a/plugins/woocommerce-blocks/src/RestApi/StoreApi/Schemas/OrderSchema.php b/plugins/woocommerce-blocks/src/RestApi/StoreApi/Schemas/OrderSchema.php
index 9ab2813a221..a4f3a641459 100644
--- a/plugins/woocommerce-blocks/src/RestApi/StoreApi/Schemas/OrderSchema.php
+++ b/plugins/woocommerce-blocks/src/RestApi/StoreApi/Schemas/OrderSchema.php
@@ -219,53 +219,7 @@ class OrderSchema extends AbstractSchema {
'description' => __( 'Shipping address.', 'woo-gutenberg-products-block' ),
'type' => 'object',
'context' => [ 'view', 'edit' ],
- 'properties' => [
- 'first_name' => [
- 'description' => __( 'First name', 'woo-gutenberg-products-block' ),
- 'type' => 'string',
- 'context' => [ 'view', 'edit' ],
- ],
- 'last_name' => [
- 'description' => __( 'Last name', 'woo-gutenberg-products-block' ),
- 'type' => 'string',
- 'context' => [ 'view', 'edit' ],
- ],
- 'company' => [
- 'description' => __( 'Company', 'woo-gutenberg-products-block' ),
- 'type' => 'string',
- 'context' => [ 'view', 'edit' ],
- ],
- 'address_1' => [
- 'description' => __( 'Address', 'woo-gutenberg-products-block' ),
- 'type' => 'string',
- 'context' => [ 'view', 'edit' ],
- ],
- 'address_2' => [
- 'description' => __( 'Apartment, suite, etc.', 'woo-gutenberg-products-block' ),
- 'type' => 'string',
- 'context' => [ 'view', 'edit' ],
- ],
- 'city' => [
- 'description' => __( 'City', 'woo-gutenberg-products-block' ),
- 'type' => 'string',
- 'context' => [ 'view', 'edit' ],
- ],
- 'state' => [
- 'description' => __( 'State/County code, or name of the state, county, province, or district.', 'woo-gutenberg-products-block' ),
- 'type' => 'string',
- 'context' => [ 'view', 'edit' ],
- ],
- 'postcode' => [
- 'description' => __( 'Postal code', 'woo-gutenberg-products-block' ),
- 'type' => 'string',
- 'context' => [ 'view', 'edit' ],
- ],
- 'country' => [
- 'description' => __( 'Country/Region code in ISO 3166-1 alpha-2 format.', 'woo-gutenberg-products-block' ),
- 'type' => 'string',
- 'context' => [ 'view', 'edit' ],
- ],
- ],
+ 'properties' => $this->force_schema_readonly( ( new ShippingAddressSchema() )->get_properties() ),
],
'coupons' => [
'description' => __( 'List of applied coupons.', 'woo-gutenberg-products-block' ),
@@ -422,19 +376,7 @@ class OrderSchema extends AbstractSchema {
'phone' => $order->get_billing_phone(),
]
),
- 'shipping_address' => (object) $this->prepare_html_response(
- [
- 'first_name' => $order->get_shipping_first_name(),
- 'last_name' => $order->get_shipping_last_name(),
- 'company' => $order->get_shipping_company(),
- 'address_1' => $order->get_shipping_address_1(),
- 'address_2' => $order->get_shipping_address_2(),
- 'city' => $order->get_shipping_city(),
- 'state' => $order->get_shipping_state(),
- 'postcode' => $order->get_shipping_postcode(),
- 'country' => $order->get_shipping_country(),
- ]
- ),
+ 'shipping_address' => ( new ShippingAddressSchema() )->get_item_response( $order ),
'coupons' => array_values( array_map( [ $order_coupon_schema, 'get_item_response' ], $order->get_items( 'coupon' ) ) ),
'items' => array_values( array_map( [ $order_item_schema, 'get_item_response' ], $order->get_items( 'line_item' ) ) ),
'totals' => (object) array_merge(
diff --git a/plugins/woocommerce-blocks/src/RestApi/StoreApi/Schemas/ShippingAddressSchema.php b/plugins/woocommerce-blocks/src/RestApi/StoreApi/Schemas/ShippingAddressSchema.php
new file mode 100644
index 00000000000..2b1dfb6e4fc
--- /dev/null
+++ b/plugins/woocommerce-blocks/src/RestApi/StoreApi/Schemas/ShippingAddressSchema.php
@@ -0,0 +1,120 @@
+ [
+ 'description' => __( 'First name', 'woo-gutenberg-products-block' ),
+ 'type' => 'string',
+ 'context' => [ 'view', 'edit' ],
+ ],
+ 'last_name' => [
+ 'description' => __( 'Last name', 'woo-gutenberg-products-block' ),
+ 'type' => 'string',
+ 'context' => [ 'view', 'edit' ],
+ ],
+ 'company' => [
+ 'description' => __( 'Company', 'woo-gutenberg-products-block' ),
+ 'type' => 'string',
+ 'context' => [ 'view', 'edit' ],
+ ],
+ 'address_1' => [
+ 'description' => __( 'Address', 'woo-gutenberg-products-block' ),
+ 'type' => 'string',
+ 'context' => [ 'view', 'edit' ],
+ ],
+ 'address_2' => [
+ 'description' => __( 'Apartment, suite, etc.', 'woo-gutenberg-products-block' ),
+ 'type' => 'string',
+ 'context' => [ 'view', 'edit' ],
+ ],
+ 'city' => [
+ 'description' => __( 'City', 'woo-gutenberg-products-block' ),
+ 'type' => 'string',
+ 'context' => [ 'view', 'edit' ],
+ ],
+ 'state' => [
+ 'description' => __( 'State/County code, or name of the state, county, province, or district.', 'woo-gutenberg-products-block' ),
+ 'type' => 'string',
+ 'context' => [ 'view', 'edit' ],
+ ],
+ 'postcode' => [
+ 'description' => __( 'Postal code', 'woo-gutenberg-products-block' ),
+ 'type' => 'string',
+ 'context' => [ 'view', 'edit' ],
+ ],
+ 'country' => [
+ 'description' => __( 'Country/Region code in ISO 3166-1 alpha-2 format.', 'woo-gutenberg-products-block' ),
+ 'type' => 'string',
+ 'context' => [ 'view', 'edit' ],
+ ],
+ ];
+ }
+
+ /**
+ * Convert a term object into an object suitable for the response.
+ *
+ * @param \WC_Order|\WC_Customer $address An object with shipping address.
+ *
+ * @throws RouteException When the invalid object types are provided.
+ * @return stdClass
+ */
+ public function get_item_response( $address ) {
+ if ( ( $address instanceof \WC_Customer || $address instanceof \WC_Order ) ) {
+ return (object) $this->prepare_html_response(
+ [
+ 'first_name' => $address->get_shipping_first_name(),
+ 'last_name' => $address->get_shipping_last_name(),
+ 'company' => $address->get_shipping_company(),
+ 'address_1' => $address->get_shipping_address_1(),
+ 'address_2' => $address->get_shipping_address_2(),
+ 'city' => $address->get_shipping_city(),
+ 'state' => $address->get_shipping_state(),
+ 'postcode' => $address->get_shipping_postcode(),
+ 'country' => $address->get_shipping_country(),
+ ]
+ );
+ }
+ throw new RouteException(
+ 'invalid_object_type',
+ sprintf(
+ /* translators: Placeholders are class and method names */
+ __( '%1$s requires an instance of %2$s or %3$s for the address', 'woo-gutenberg-products-block' ),
+ 'ShippingAddress::get_item_response',
+ 'WC_Customer',
+ 'WC_Order'
+ ),
+ 500
+ );
+ }
+}