From a6b8e0e542b1e1c8e74437212a63ca44ebee1c17 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 3 Jul 2023 10:10:18 +0100 Subject: [PATCH] Hide "collection from" text when a location has an incomplete address. (https://github.com/woocommerce/woocommerce-blocks/pull/9808) * Hide "collection from" text when a location has an incomplete address. * Fix display on confirmation page * has_valid_pickup_location helper * Missing isset * Update test * Fix pickup text assertion --------- Co-authored-by: Niels Lange --- .../cart-checkout/pickup-location/index.tsx | 14 +---- .../pickup-location/test/index.tsx | 8 +-- .../src/Shipping/PickupLocation.php | 58 ++++++++++++++++++- .../src/Shipping/ShippingController.php | 6 +- 4 files changed, 69 insertions(+), 17 deletions(-) diff --git a/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/pickup-location/index.tsx b/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/pickup-location/index.tsx index a213f795f71..40423ece0cd 100644 --- a/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/pickup-location/index.tsx +++ b/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/pickup-location/index.tsx @@ -10,7 +10,7 @@ import { isPackageRateCollectable } from '@woocommerce/base-utils'; * Shows a formatted pickup location. */ const PickupLocation = (): JSX.Element | null => { - const { pickupAddress, pickupMethod } = useSelect( ( select ) => { + const { pickupAddress } = useSelect( ( select ) => { const cartShippingRates = select( 'wc/store/cart' ).getShippingRates(); const flattenedRates = cartShippingRates.flatMap( @@ -36,7 +36,6 @@ const PickupLocation = (): JSX.Element | null => { const selectedRatePickupAddress = selectedRateMetaData.value; return { pickupAddress: selectedRatePickupAddress, - pickupMethod: selectedCollectableRate.name, }; } } @@ -44,20 +43,15 @@ const PickupLocation = (): JSX.Element | null => { if ( isObject( selectedCollectableRate ) ) { return { pickupAddress: undefined, - pickupMethod: selectedCollectableRate.name, }; } return { pickupAddress: undefined, - pickupMethod: undefined, }; } ); // If the method does not contain an address, or the method supporting collection was not found, return early. - if ( - typeof pickupAddress === 'undefined' && - typeof pickupMethod === 'undefined' - ) { + if ( typeof pickupAddress === 'undefined' ) { return null; } @@ -67,9 +61,7 @@ const PickupLocation = (): JSX.Element | null => { { sprintf( /* translators: %s: shipping method name, e.g. "Amazon Locker" */ __( 'Collection from %s', 'woo-gutenberg-products-block' ), - typeof pickupAddress === 'undefined' - ? pickupMethod - : pickupAddress + pickupAddress ) + ' ' } ); diff --git a/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/pickup-location/test/index.tsx b/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/pickup-location/test/index.tsx index 603bb951931..31f81fa80ac 100644 --- a/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/pickup-location/test/index.tsx +++ b/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/pickup-location/test/index.tsx @@ -26,7 +26,7 @@ jest.mock( '@woocommerce/settings', () => { }; } ); describe( 'PickupLocation', () => { - it( `renders an address if one is set in the method's metadata`, async () => { + it( `renders an address if one is set in the methods metadata`, async () => { dispatch( CHECKOUT_STORE_KEY ).setPrefersCollection( true ); // Deselect the default selected rate and select pickup_location:1 rate. @@ -54,7 +54,7 @@ describe( 'PickupLocation', () => { ) ).toBeInTheDocument(); } ); - it( 'renders the method name if address is not in metadata', async () => { + it( 'renders no address if one is not set in the methods metadata', async () => { dispatch( CHECKOUT_STORE_KEY ).setPrefersCollection( true ); // Deselect the default selected rate and select pickup_location:1 rate. @@ -87,7 +87,7 @@ describe( 'PickupLocation', () => { render( ); expect( - screen.getByText( /Collection from Local pickup/ ) - ).toBeInTheDocument(); + screen.queryByText( /Collection from / ) + ).not.toBeInTheDocument(); } ); } ); diff --git a/plugins/woocommerce-blocks/src/Shipping/PickupLocation.php b/plugins/woocommerce-blocks/src/Shipping/PickupLocation.php index 4e0872d219e..f7373e4a6c1 100644 --- a/plugins/woocommerce-blocks/src/Shipping/PickupLocation.php +++ b/plugins/woocommerce-blocks/src/Shipping/PickupLocation.php @@ -8,6 +8,20 @@ use WC_Shipping_Method; */ class PickupLocation extends WC_Shipping_Method { + /** + * Pickup locations. + * + * @var array + */ + protected $pickup_locations = []; + + /** + * Cost + * + * @var string + */ + protected $cost = ''; + /** * Constructor. */ @@ -31,6 +45,48 @@ class PickupLocation extends WC_Shipping_Method { add_filter( 'woocommerce_attribute_label', array( $this, 'translate_meta_data' ), 10, 3 ); } + /** + * Checks if a given address is complete. + * + * @param array $address Address. + * @return bool + */ + protected function has_valid_pickup_location( $address ) { + // Normalize address. + $address_fields = wp_parse_args( + (array) $address, + array( + 'city' => '', + 'postcode' => '', + 'state' => '', + 'country' => '', + ) + ); + + // Country is always required. + if ( empty( $address_fields['country'] ) ) { + return false; + } + + // If all fields are provided, we can skip further checks. + if ( ! empty( $address_fields['city'] ) && ! empty( $address_fields['postcode'] ) && ! empty( $address_fields['state'] ) ) { + return true; + } + + // Check validity based on requirements for the country. + $country_address_fields = wc()->countries->get_address_fields( $address_fields['country'], 'shipping_' ); + + foreach ( $country_address_fields as $field_name => $field ) { + $key = str_replace( 'shipping_', '', $field_name ); + + if ( isset( $address_fields[ $key ] ) && true === $field['required'] && empty( $address_fields[ $key ] ) ) { + return false; + } + } + + return true; + } + /** * Calculate shipping. * @@ -51,7 +107,7 @@ class PickupLocation extends WC_Shipping_Method { 'cost' => $this->cost, 'meta_data' => array( 'pickup_location' => wp_kses_post( $location['name'] ), - 'pickup_address' => wc()->countries->get_formatted_address( $location['address'], ', ' ), + 'pickup_address' => $this->has_valid_pickup_location( $location['address'] ) ? wc()->countries->get_formatted_address( $location['address'], ', ' ) : '', 'pickup_details' => wp_kses_post( $location['details'] ), ), ) diff --git a/plugins/woocommerce-blocks/src/Shipping/ShippingController.php b/plugins/woocommerce-blocks/src/Shipping/ShippingController.php index aee1e9edf82..78d534bdf6a 100644 --- a/plugins/woocommerce-blocks/src/Shipping/ShippingController.php +++ b/plugins/woocommerce-blocks/src/Shipping/ShippingController.php @@ -135,9 +135,13 @@ class ShippingController { $location = $shipping_method->get_meta( 'pickup_location' ); $address = $shipping_method->get_meta( 'pickup_address' ); + if ( ! $address ) { + return $return; + } + return sprintf( // Translators: %s location name. - __( 'Pickup from %s:', 'woo-gutenberg-products-block' ), + __( 'Collection from %s:', 'woo-gutenberg-products-block' ), $location ) . '
' . str_replace( ',', ',
', $address ) . '

' . $details; }