diff --git a/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/form/form.tsx b/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/form/form.tsx index 5e01a7f5203..de21f2075e5 100644 --- a/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/form/form.tsx +++ b/plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/form/form.tsx @@ -1,7 +1,6 @@ /** * External dependencies */ -import { isPostcode } from '@woocommerce/blocks-checkout'; import { ValidatedTextInput, type ValidatedTextInputHandle, @@ -164,22 +163,12 @@ const Form = < T extends AddressFormValues | ContactFormValues >( { { ...fieldProps } value={ values.country } onChange={ ( newCountry ) => { - const newValues = { + onChange( { ...values, country: newCountry, state: '', - }; - // Country will impact postcode too. Do we need to clear it? - if ( - values.postcode && - ! isPostcode( { - postcode: values.postcode, - country: newCountry, - } ) - ) { - newValues.postcode = ''; - } - onChange( newValues ); + postcode: '', + } ); } } /> ); diff --git a/plugins/woocommerce-blocks/assets/js/data/cart/push-changes.ts b/plugins/woocommerce-blocks/assets/js/data/cart/push-changes.ts index 5fe134551db..67b51a5ed08 100644 --- a/plugins/woocommerce-blocks/assets/js/data/cart/push-changes.ts +++ b/plugins/woocommerce-blocks/assets/js/data/cart/push-changes.ts @@ -68,6 +68,40 @@ const updateDirtyProps = () => { // Update local cache of customer data so the next time this runs, it can compare against the latest data. localState.customerData = newCustomerData; + + const dirtyShippingAddress = localState.dirtyProps.shippingAddress; + const dirtyBillingAddress = localState.dirtyProps.billingAddress; + + const customerShippingAddress = localState.customerData.shippingAddress; + const customerBillingAddress = localState.customerData.billingAddress; + + // Check if country is changing without state + const shippingCountryChanged = dirtyShippingAddress.includes( 'country' ); + const billingCountryChanged = dirtyBillingAddress.includes( 'country' ); + const shippingStateChanged = dirtyShippingAddress.includes( 'state' ); + const billingStateChanged = dirtyBillingAddress.includes( 'state' ); + const shippingPostcodeChanged = dirtyShippingAddress.includes( 'postcode' ); + const billingPostcodeChanged = dirtyBillingAddress.includes( 'postcode' ); + + if ( shippingCountryChanged && ! shippingPostcodeChanged ) { + dirtyShippingAddress.push( 'postcode' ); + customerShippingAddress.postcode = ''; + } + + if ( billingCountryChanged && ! billingPostcodeChanged ) { + dirtyBillingAddress.push( 'postcode' ); + customerBillingAddress.postcode = ''; + } + + if ( shippingCountryChanged && ! shippingStateChanged ) { + dirtyShippingAddress.push( 'state' ); + customerShippingAddress.state = ''; + } + + if ( billingCountryChanged && ! billingStateChanged ) { + dirtyBillingAddress.push( 'state' ); + customerBillingAddress.state = ''; + } }; /** diff --git a/plugins/woocommerce/changelog/47369-fix-state-flickring-when-switching-countries b/plugins/woocommerce/changelog/47369-fix-state-flickring-when-switching-countries new file mode 100644 index 00000000000..ad2d29c6319 --- /dev/null +++ b/plugins/woocommerce/changelog/47369-fix-state-flickring-when-switching-countries @@ -0,0 +1,4 @@ +Significance: patch +Type: fix + +Correctly clear out state and postcode when switching countries. \ No newline at end of file diff --git a/plugins/woocommerce/src/StoreApi/Routes/V1/CartUpdateCustomer.php b/plugins/woocommerce/src/StoreApi/Routes/V1/CartUpdateCustomer.php index ed3f6a66e8e..86fa79596d0 100644 --- a/plugins/woocommerce/src/StoreApi/Routes/V1/CartUpdateCustomer.php +++ b/plugins/woocommerce/src/StoreApi/Routes/V1/CartUpdateCustomer.php @@ -240,21 +240,8 @@ class CartUpdateCustomer extends AbstractCartRoute { * @return array */ protected function get_customer_billing_address( \WC_Customer $customer ) { - $validation_util = new ValidationUtils(); - $billing_country = $customer->get_billing_country(); - $billing_state = $customer->get_billing_state(); - $additional_fields = $this->additional_fields_controller->get_all_fields_from_object( $customer, 'billing' ); - /** - * There's a bug in WooCommerce core in which not having a state ("") would result in us validating against the store's state. - * This resets the state to an empty string if it doesn't match the country. - * - * @todo Removing this handling once we fix the issue with the state value always being the store one. - */ - if ( ! $validation_util->validate_state( $billing_state, $billing_country ) ) { - $billing_state = ''; - } return array_merge( [ 'first_name' => $customer->get_billing_first_name(), @@ -263,9 +250,9 @@ class CartUpdateCustomer extends AbstractCartRoute { 'address_1' => $customer->get_billing_address_1(), 'address_2' => $customer->get_billing_address_2(), 'city' => $customer->get_billing_city(), - 'state' => $billing_state, + 'state' => $customer->get_billing_state(), 'postcode' => $customer->get_billing_postcode(), - 'country' => $billing_country, + 'country' => $customer->get_billing_country(), 'phone' => $customer->get_billing_phone(), 'email' => $customer->get_billing_email(), ], diff --git a/plugins/woocommerce/src/StoreApi/Schemas/V1/AbstractAddressSchema.php b/plugins/woocommerce/src/StoreApi/Schemas/V1/AbstractAddressSchema.php index 91370c57b54..077492f1de5 100644 --- a/plugins/woocommerce/src/StoreApi/Schemas/V1/AbstractAddressSchema.php +++ b/plugins/woocommerce/src/StoreApi/Schemas/V1/AbstractAddressSchema.php @@ -123,7 +123,7 @@ abstract class AbstractAddressSchema extends AbstractSchema { $address = array_intersect_key( $address, $field_schema ); $address = array_reduce( array_keys( $address ), - function( $carry, $key ) use ( $address, $validation_util, $field_schema ) { + function ( $carry, $key ) use ( $address, $validation_util, $field_schema ) { switch ( $key ) { case 'country': $carry[ $key ] = wc_strtoupper( sanitize_text_field( wp_unslash( $address[ $key ] ) ) ); @@ -281,7 +281,7 @@ abstract class AbstractAddressSchema extends AbstractSchema { $address_fields = array_filter( $fields, - function( $key ) use ( $additional_fields_keys ) { + function ( $key ) use ( $additional_fields_keys ) { return in_array( $key, $additional_fields_keys, true ); }, ARRAY_FILTER_USE_KEY @@ -298,7 +298,7 @@ abstract class AbstractAddressSchema extends AbstractSchema { if ( 'select' === $field['type'] ) { $field_schema['enum'] = array_map( - function( $option ) { + function ( $option ) { return $option['value']; }, $field['options']