Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Sync shipping address with billing address when shipping address fields are disabled #3358

Merged
merged 47 commits into from
Nov 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
f8e44ee
Correct docblock description
mikejolley Nov 3, 2020
22daa88
Sync shipping address changes with billing data
mikejolley Nov 3, 2020
172a4a9
Update inline documentation
mikejolley Nov 3, 2020
4f74cdf
Revert address sync because it fails when shipping is disabled explic…
mikejolley Nov 3, 2020
fdeff73
Avoid loading shipping address from customer is shipping is disabled
mikejolley Nov 3, 2020
3f0ff9c
Rather than update order from the wc/store/checkout request, update t…
mikejolley Nov 3, 2020
a6f842a
Add action that combines billing and shipping updates
mikejolley Nov 3, 2020
3897fc2
Add route for updating billing and shipping address
mikejolley Nov 3, 2020
037cfce
Sync billing data to server on change
mikejolley Nov 3, 2020
46c8f92
Shared constants for billing data
mikejolley Nov 4, 2020
b4b013d
Skip address update if missing country
mikejolley Nov 4, 2020
87792db
Allow null values to skip formatting
mikejolley Nov 4, 2020
1f52a28
Add billing to cart schema
mikejolley Nov 4, 2020
8478dd0
Removed unwanted hooks from previous commit
mikejolley Nov 4, 2020
63ec657
Decoding is handled in useStoreCart
mikejolley Nov 4, 2020
f2f50d7
Remove hook
mikejolley Nov 4, 2020
e6c8fa0
Make shipping context hold state
mikejolley Nov 4, 2020
62ca606
Make billing context hold state
mikejolley Nov 4, 2020
400563f
Add address processors
mikejolley Nov 4, 2020
7714032
Cart does not have billing
mikejolley Nov 4, 2020
e30221d
Update tests, remove some unrelated changes affecting the diff
mikejolley Nov 4, 2020
648a47f
Revert "Update inline documentation"
mikejolley Nov 4, 2020
e4bb1bd
Make shippingRatesAreResolving conditonal based on API request
mikejolley Nov 4, 2020
10343fb
Shared address processor in cart and checkout
mikejolley Nov 5, 2020
243f5be
Rename REST endpoint
mikejolley Nov 5, 2020
16dd0db
CustomerDataProvider and hook
mikejolley Nov 9, 2020
a266038
Update shipping address type defs
mikejolley Nov 10, 2020
4075001
Rename customer address endpoint, and remove update-shipping
mikejolley Nov 10, 2020
0dc0f67
Update tests
mikejolley Nov 10, 2020
d474b76
Fix tests by restoring country validation
mikejolley Nov 10, 2020
5726da3
typo
mikejolley Nov 10, 2020
d71bfa9
Update assets/js/base/hooks/cart/use-store-cart.js
mikejolley Nov 13, 2020
960736e
Simplify debounce and request handling
mikejolley Nov 13, 2020
116a187
Remove state from address sync
mikejolley Nov 13, 2020
4b9e174
Rename shipping rates loading to customer data loading
mikejolley Nov 13, 2020
6330152
Sync based on useStoreCart data
mikejolley Nov 13, 2020
480ce56
Made cart API less strict on addresses
mikejolley Nov 13, 2020
1d6dc48
Fix useCheckoutAddress sync
mikejolley Nov 13, 2020
19fdd9e
Add note on currentShippingAsBilling
mikejolley Nov 17, 2020
a79ecf0
Use incoming isCart
mikejolley Nov 17, 2020
b815624
Add more detailed inline comment for shippingAsBilling toggle event
mikejolley Nov 17, 2020
5769913
Combine customer billing and shipping ref
mikejolley Nov 17, 2020
0d38e0f
Update address docblock
mikejolley Nov 17, 2020
138b265
Error handling in pluckAddress
mikejolley Nov 17, 2020
057ceb1
Fix cart response after rebase
mikejolley Nov 17, 2020
dd5724a
Update customer tests
mikejolley Nov 17, 2020
6804cc0
Update src/StoreApi/Routes/CartUpdateCustomer.php
mikejolley Nov 20, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 0 additions & 50 deletions assets/js/base/context/cart-checkout/billing/constants.js

This file was deleted.

51 changes: 0 additions & 51 deletions assets/js/base/context/cart-checkout/billing/index.js

This file was deleted.

6 changes: 3 additions & 3 deletions assets/js/base/context/cart-checkout/checkout/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/
import { PaymentMethodDataProvider } from '../payment-methods';
import { ShippingDataProvider } from '../shipping';
import { BillingDataProvider } from '../billing';
import { CustomerDataProvider } from '../customer';
import { CheckoutStateProvider } from '../checkout-state';
import CheckoutProcessor from './processor';

Expand All @@ -27,14 +27,14 @@ export const CheckoutProvider = ( {
} ) => {
return (
<CheckoutStateProvider redirectUrl={ redirectUrl } isCart={ isCart }>
<BillingDataProvider>
<CustomerDataProvider>
<ShippingDataProvider>
<PaymentMethodDataProvider>
{ children }
<CheckoutProcessor />
</PaymentMethodDataProvider>
</ShippingDataProvider>
</BillingDataProvider>
</CustomerDataProvider>
</CheckoutStateProvider>
);
};
32 changes: 5 additions & 27 deletions assets/js/base/context/cart-checkout/checkout/processor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import triggerFetch from '@wordpress/api-fetch';
import {
useCheckoutContext,
useShippingDataContext,
useBillingDataContext,
useCustomerDataContext,
usePaymentMethodDataContext,
useValidationContext,
} from '@woocommerce/base-context';
Expand All @@ -20,31 +20,9 @@ import {
import { useStoreCart, useStoreNotices } from '@woocommerce/base-hooks';

/**
* @typedef {import('@woocommerce/type-defs/payments').PaymentDataItem} PaymentDataItem
* Internal dependencies
*/

/**
* Utility function for preparing payment data for the request.
*
* @param {Object} paymentData Arbitrary payment data provided by the payment method.
* @param {boolean} shouldSave Whether to save the payment method info to user account.
* @param {Object} activePaymentMethod The current active payment method.
*
* @return {PaymentDataItem[]} Returns the payment data as an array of
* PaymentDataItem objects.
*/
const preparePaymentData = ( paymentData, shouldSave, activePaymentMethod ) => {
mikejolley marked this conversation as resolved.
Show resolved Hide resolved
const apiData = Object.keys( paymentData ).map( ( property ) => {
const value = paymentData[ property ];
return { key: property, value };
}, [] );
const savePaymentMethodKey = `wc-${ activePaymentMethod }-new-payment-method`;
apiData.push( {
key: savePaymentMethodKey,
value: shouldSave,
} );
return apiData;
};
import { preparePaymentData } from './utils';

/**
* CheckoutProcessor component.
Expand All @@ -66,8 +44,8 @@ const CheckoutProcessor = () => {
shouldCreateAccount,
} = useCheckoutContext();
const { hasValidationErrors } = useValidationContext();
const { shippingAddress, shippingErrorStatus } = useShippingDataContext();
const { billingData } = useBillingDataContext();
const { shippingErrorStatus } = useShippingDataContext();
const { billingData, shippingAddress } = useCustomerDataContext();
mikejolley marked this conversation as resolved.
Show resolved Hide resolved
const { cartNeedsPayment, receiveCart } = useStoreCart();
const {
activePaymentMethod,
Expand Down
30 changes: 30 additions & 0 deletions assets/js/base/context/cart-checkout/checkout/processor/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* @typedef {import('@woocommerce/type-defs/payments').PaymentDataItem} PaymentDataItem
*/

/**
* Utility function for preparing payment data for the request.
*
* @param {Object} paymentData Arbitrary payment data provided by the payment method.
* @param {boolean} shouldSave Whether to save the payment method info to user account.
* @param {Object} activePaymentMethod The current active payment method.
Comment on lines +8 to +10
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally we'd have paymentData and activePaymentMethod defined as typedefs so we are explicit about what is passed through here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this is unrelated to this PR I won't add it here, but I did notice this already has a todo: @todo do typedefs for the payment event state. in payment-methods/constants.js

*
* @return {PaymentDataItem[]} Returns the payment data as an array of
* PaymentDataItem objects.
*/
export const preparePaymentData = (
paymentData,
shouldSave,
activePaymentMethod
) => {
const apiData = Object.keys( paymentData ).map( ( property ) => {
const value = paymentData[ property ];
return { key: property, value };
}, [] );
const savePaymentMethodKey = `wc-${ activePaymentMethod }-new-payment-method`;
apiData.push( {
key: savePaymentMethodKey,
value: shouldSave,
} );
return apiData;
};
91 changes: 91 additions & 0 deletions assets/js/base/context/cart-checkout/customer/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/**
* External dependencies
*/
import { createContext, useContext } from '@wordpress/element';
import { useCustomerData } from '@woocommerce/base-hooks';

/**
* @typedef {import('@woocommerce/type-defs/contexts').CustomerDataContext} CustomerDataContext
* @typedef {import('@woocommerce/type-defs/billing').BillingData} BillingData
* @typedef {import('@woocommerce/type-defs/shipping').ShippingAddress} ShippingAddress
*/

/**
* @type {BillingData}
*/
const defaultBillingData = {
first_name: '',
last_name: '',
company: '',
address_1: '',
address_2: '',
city: '',
state: '',
postcode: '',
country: '',
email: '',
phone: '',
};

/**
* @type {ShippingAddress}
*/
export const defaultShippingAddress = {
first_name: '',
last_name: '',
company: '',
address_1: '',
address_2: '',
city: '',
state: '',
postcode: '',
country: '',
};

/**
* Creates CustomerDataContext
*/
const CustomerDataContext = createContext( {
billingData: defaultBillingData,
shippingAddress: defaultShippingAddress,
setBillingData: () => null,
setShippingAddress: () => null,
} );

/**
* @return {CustomerDataContext} Returns data and functions related to customer billing and shipping addresses.
*/
export const useCustomerDataContext = () => {
return useContext( CustomerDataContext );
};

/**
* Customer Data context provider.
*
* @param {Object} props Incoming props for the provider.
* @param {Object} props.children The children being wrapped.
*/
export const CustomerDataProvider = ( { children } ) => {
const {
billingData,
shippingAddress,
setBillingData,
setShippingAddress,
} = useCustomerData();

/**
* @type {CustomerDataContext}
*/
const contextValue = {
billingData,
shippingAddress,
setBillingData,
setShippingAddress,
};

return (
<CustomerDataContext.Provider value={ contextValue }>
{ children }
</CustomerDataContext.Provider>
);
};
2 changes: 1 addition & 1 deletion assets/js/base/context/cart-checkout/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export * from './payment-methods';
export * from './shipping';
export * from './billing';
export * from './customer';
export * from './checkout';
export * from './cart';
export { useCheckoutContext } from './checkout-state';
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@
*/
import { ACTION_TYPES } from './constants';

/**
* @typedef {import('@woocommerce/type-defs/cart').CartBillingData} CartBillingData
*/

const {
ERROR,
FAILED,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import {
usePaymentMethods,
useExpressPaymentMethods,
} from './use-payment-method-registration';
import { useBillingDataContext } from '../billing';
import { useCustomerDataContext } from '../customer';
import { useCheckoutContext } from '../checkout-state';
import { useShippingDataContext } from '../shipping';
import {
Expand Down Expand Up @@ -116,7 +116,7 @@ const getCustomerPaymentMethods = ( availablePaymentMethods = [] ) => {
* provider.
*/
export const PaymentMethodDataProvider = ( { children } ) => {
const { setBillingData } = useBillingDataContext();
const { setBillingData } = useCustomerDataContext();
const {
isProcessing: checkoutIsProcessing,
isIdle: checkoutIsIdle,
Expand Down
4 changes: 2 additions & 2 deletions assets/js/base/context/cart-checkout/shipping/constants.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* @typedef {import('@woocommerce/type-defs/contexts').ShippingErrorTypes} ShippingErrorTypes
* @typedef {import('@woocommerce/type-defs/cart').CartShippingAddress} CartShippingAddress
* @typedef {import('@woocommerce/type-defs/shipping').ShippingAddress} ShippingAddress
* @typedef {import('@woocommerce/type-defs/contexts').ShippingDataContext} ShippingDataContext
*/

Expand All @@ -20,7 +20,7 @@ export const shippingErrorCodes = {
};

/**
* @type {CartShippingAddress}
* @type {ShippingAddress}
*/
export const DEFAULT_SHIPPING_ADDRESS = {
first_name: '',
Expand Down
11 changes: 5 additions & 6 deletions assets/js/base/context/cart-checkout/shipping/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,11 @@ import {
useMemo,
useRef,
} from '@wordpress/element';
import { useStoreCart, useSelectShippingRate } from '@woocommerce/base-hooks';
import {
useShippingAddress,
useStoreCart,
useSelectShippingRate,
} from '@woocommerce/base-hooks';
import { useCheckoutContext } from '@woocommerce/base-context';
useCheckoutContext,
useCustomerDataContext,
} from '@woocommerce/base-context';

/**
* Internal dependencies
Expand Down Expand Up @@ -83,6 +82,7 @@ const hasInvalidShippingAddress = ( errors ) => {
*/
export const ShippingDataProvider = ( { children } ) => {
const { dispatchActions } = useCheckoutContext();
const { shippingAddress, setShippingAddress } = useCustomerDataContext();
const {
cartNeedsShipping: needsShipping,
cartHasCalculatedShipping: hasCalculatedShipping,
Expand All @@ -95,7 +95,6 @@ export const ShippingDataProvider = ( { children } ) => {
NONE
);
const [ observers, subscriber ] = useReducer( emitReducer, {} );
const { shippingAddress, setShippingAddress } = useShippingAddress();
const currentObservers = useRef( observers );
const {
selectShippingRate: setSelectedRates,
Expand Down
Loading