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

Update canMakePayment to receive cart as argument and make it react to changes in billingData. #4776

Merged
merged 6 commits into from
Sep 23, 2021

Conversation

ralucaStan
Copy link
Contributor

@ralucaStan ralucaStan commented Sep 17, 2021

This PR

Fixes:
#4670
#4766

A new ticket has been created for deprecating cart-derived values from the canMakePayment argument #4809

How to test the changes in this Pull Request:

  1. Go to assets/js/base/context/providers/cart-checkout/payment-methods/use-payment-method-registration.ts and edit for the purpose of testing only:
  • add registerPaymentMethodExtensionCallbacks to the existing import from '@woocommerce/blocks-registry'
  • register a callback for COD at the top of the file, after the imports
registerPaymentMethodExtensionCallbacks( 'woocommerce-marketplace-extension', {
	cod: ( arg ) => {
		console.log( 'checking COD' );
		return arg.billingData.first_name === 'Alexandra';
	},
} );
  1. Make the console visible
  2. Go to Checkout block and notice that COD payment method is missing and that an initial check was made COD (see console.log())
  3. Deselect Use same address for billing and write "Alexandra" for First Name in the Billing Address section. Cash on Delivery option should be available as a payment method.
  4. Notice that the check for COD is done only after the user finished typing

Changelog

Update canMakePayment to receive cart as argument and make it react to changes in billingData. Improve the performance of calculating canMakePayment after changes in the Checkout block.

@ralucaStan ralucaStan requested a review from a team as a code owner September 17, 2021 17:01
@ralucaStan ralucaStan marked this pull request as draft September 17, 2021 17:01
@github-actions
Copy link
Contributor

github-actions bot commented Sep 17, 2021

Size Change: +1.37 kB (0%)

Total Size: 1.25 MB

Filename Size Change
build/active-filters-frontend.js 8.34 kB -40 B (0%)
build/active-filters.js 8.01 kB -2 B (0%)
build/all-products-frontend.js 23.1 kB -4 B (0%)
build/all-products.js 37 kB -28 B (0%)
build/all-reviews.js 9.56 kB -72 B (-1%)
build/atomic-block-components/add-to-cart--atomic-block-components/button--atomic-block-components/image---a7e2bb9b.js 2.66 kB +1 B (0%)
build/atomic-block-components/add-to-cart--atomic-block-components/button.js 1.81 kB -1 B (0%)
build/atomic-block-components/add-to-cart--atomic-block-components/image--atomic-block-components/title.js 332 B -1 B (0%)
build/atomic-block-components/add-to-cart-frontend.js 8.38 kB +6 B (0%)
build/atomic-block-components/add-to-cart.js 7.72 kB -1 B (0%)
build/atomic-block-components/button-frontend.js 1.74 kB +3 B (0%)
build/atomic-block-components/button.js 875 B -2 B (0%)
build/atomic-block-components/category-list-frontend.js 472 B +1 B (0%)
build/atomic-block-components/image-frontend.js 1.88 kB -4 B (0%)
build/atomic-block-components/image.js 1.35 kB -2 B (0%)
build/atomic-block-components/price-frontend.js 2.13 kB +39 B (+2%)
build/atomic-block-components/price.js 2.11 kB +7 B (0%)
build/atomic-block-components/rating-frontend.js 563 B +1 B (0%)
build/atomic-block-components/sale-badge.js 869 B +1 B (0%)
build/atomic-block-components/sku.js 393 B -2 B (-1%)
build/atomic-block-components/stock-indicator.js 611 B -1 B (0%)
build/atomic-block-components/summary-frontend.js 906 B +1 B (0%)
build/atomic-block-components/tag-list-frontend.js 468 B -1 B (0%)
build/atomic-block-components/tag-list.js 471 B -1 B (0%)
build/atomic-block-components/title-frontend.js 1.47 kB +29 B (+2%)
build/atomic-block-components/title.js 1.29 kB -3 B (0%)
build/attribute-filter-frontend.js 18.8 kB -31 B (0%)
build/attribute-filter.js 12.2 kB +19 B (0%)
build/blocks-checkout.js 21 kB +53 B (0%)
build/cart-frontend.js 91.3 kB +100 B (0%)
build/cart-i2-frontend.js 91.1 kB +82 B (0%)
build/cart-i2.js 47.7 kB +1.43 kB (+3%)
build/cart.js 46.6 kB +54 B (0%)
build/checkout-blocks/billing-address--checkout-blocks/shipping-address-frontend.js 5.09 kB +65 B (+1%)
build/checkout-blocks/express-payment--checkout-blocks/payment-frontend.js 4.83 kB +1 B (0%)
build/checkout-blocks/express-payment-frontend.js 1.83 kB -5 B (0%)
build/checkout-blocks/fields-frontend.js 290 B -1 B (0%)
build/checkout-blocks/order-note-frontend.js 1.56 kB +3 B (0%)
build/checkout-blocks/order-summary-frontend.js 12.7 kB +74 B (+1%)
build/checkout-blocks/payment-frontend.js 4.51 kB -1 B (0%)
build/checkout-blocks/shipping-address-frontend.js 1.62 kB +1 B (0%)
build/checkout-blocks/shipping-methods-frontend.js 5.54 kB +3 B (0%)
build/checkout-blocks/terms-frontend.js 1.64 kB -4 B (0%)
build/checkout-blocks/totals-frontend.js 270 B -1 B (0%)
build/checkout-frontend.js 54.3 kB +68 B (0%)
build/checkout.js 52.5 kB +59 B (0%)
build/featured-category.js 7.73 kB -65 B (-1%)
build/featured-product.js 9.41 kB -80 B (-1%)
build/handpicked-products.js 6.27 kB -65 B (-1%)
build/mini-cart-component-frontend.js 36.6 kB +18 B (0%)
build/mini-cart-frontend.js 2.35 kB +2 B (0%)
build/price-filter-frontend.js 14.4 kB -94 B (-1%)
build/price-filter.js 9.63 kB -66 B (-1%)
build/product-best-sellers.js 6.61 kB -67 B (-1%)
build/product-categories.js 3.38 kB +1 B (0%)
build/product-category.js 7.49 kB -64 B (-1%)
build/product-new.js 6.77 kB -74 B (-1%)
build/product-on-sale.js 7.13 kB -64 B (-1%)
build/product-search.js 2.66 kB +2 B (0%)
build/product-tag.js 6.58 kB -71 B (-1%)
build/product-top-rated.js 6.73 kB -73 B (-1%)
build/products-by-attribute.js 7.7 kB -72 B (-1%)
build/reviews-by-category.js 11.5 kB -79 B (-1%)
build/reviews-by-product.js 13 kB -59 B (0%)
build/reviews-frontend.js 8.97 kB -26 B (0%)
build/single-product-frontend.js 26.2 kB -4 B (0%)
build/single-product.js 9.76 kB -17 B (0%)
build/stock-filter-frontend.js 8.77 kB -31 B (0%)
build/stock-filter.js 7.81 kB +3 B (0%)
build/vendors--atomic-block-components/add-to-cart--checkout-blocks/billing-address--checkout-blocks/orde--63cde524-frontend.js 16.2 kB +3 B (0%)
build/vendors--atomic-block-components/add-to-cart-frontend.js 4.77 kB -1 B (0%)
build/vendors--checkout-blocks/billing-address--checkout-blocks/order-summary--checkout-blocks/shipping-address-frontend.js 5.02 kB +3 B (0%)
build/wc-blocks-data.js 11.3 kB +182 B (+2%)
build/wc-blocks-editor-style-rtl.css 15.6 kB +76 B (0%)
build/wc-blocks-editor-style.css 15.6 kB +77 B (0%)
build/wc-blocks-registry.js 3.71 kB -23 B (-1%)
build/wc-blocks-shared-context.js 1.54 kB +1 B (0%)
build/wc-blocks-style-rtl.css 20.1 kB +25 B (0%)
build/wc-blocks-style.css 20.1 kB +25 B (0%)
build/wc-blocks-vendors.js 254 kB +154 B (0%)
ℹ️ View Unchanged
Filename Size
build/atomic-block-components/category-list.js 476 B
build/atomic-block-components/rating.js 566 B
build/atomic-block-components/sale-badge-frontend.js 862 B
build/atomic-block-components/sku-frontend.js 391 B
build/atomic-block-components/stock-indicator-frontend.js 613 B
build/atomic-block-components/summary.js 911 B
build/checkout-blocks/actions-frontend.js 1.47 kB
build/checkout-blocks/billing-address-frontend.js 1.14 kB
build/checkout-blocks/contact-information-frontend.js 3.88 kB
build/checkout-blocks/sample-frontend.js 249 B
build/mini-cart.js 2.34 kB
build/price-format.js 1.37 kB
build/vendors--atomic-block-components/price--checkout-blocks/order-summary--checkout-blocks/shipping-methods-frontend.js 5.71 kB
build/vendors--checkout-blocks/order-summary-frontend.js 3.11 kB
build/wc-blocks-google-analytics.js 1.98 kB
build/wc-blocks-middleware.js 1.47 kB
build/wc-blocks-shared-hocs.js 1.75 kB
build/wc-blocks-vendors-style-rtl.css 1.37 kB
build/wc-blocks-vendors-style.css 1.37 kB
build/wc-blocks.js 3.5 kB
build/wc-payment-method-bacs.js 806 B
build/wc-payment-method-cheque.js 806 B
build/wc-payment-method-cod.js 898 B
build/wc-payment-method-paypal.js 839 B
build/wc-payment-method-stripe.js 12.2 kB
build/wc-settings.js 2.91 kB

compressed-size-action

@ralucaStan ralucaStan removed the request for review from a team September 20, 2021 14:14
The initial approach was to debounce billingData and use this value as a dependency for the useEffect that runs refreshCanMakePayments.
But because the depencies array can always change we decided to debounce the callback instead, ensuring this way that callback is not called multiple times: for example when typing a field in the billing address. Debounced was chosen instead of throttle because we want to call refreshCanMakePayments once the change event has stopped, with the final value.
@ralucaStan ralucaStan changed the title Add cartCoupons to canMakePayment argument Add cart to canMakePayment argument an debounce refreshCanMakePayment Sep 22, 2021
@ralucaStan ralucaStan changed the title Add cart to canMakePayment argument an debounce refreshCanMakePayment Update canMakePayment to receive cart as argument and make it react to changes in billingData. Sep 22, 2021
@ralucaStan ralucaStan requested review from senadir and removed request for mikejolley September 22, 2021 11:23
@ralucaStan ralucaStan marked this pull request as ready for review September 22, 2021 11:23
@ralucaStan
Copy link
Contributor Author

@senadir the PR is ready for review.

@ralucaStan ralucaStan added status: needs review type: enhancement The issue is a request for an enhancement. block: checkout Issues related to the checkout block. and removed needs feedback labels Sep 22, 2021
Copy link
Member

@senadir senadir left a comment

Choose a reason for hiding this comment

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

This checks out, thank you for working on this Raluca!

I left a small comment around spreading cart and some left over code.

The changelog entry also seems to be not part of the quote? you might want to remove the empty line to ensure it's included.

@@ -68,6 +67,7 @@ const usePaymentMethodRegistration = (

useEffect( () => {
canPayArgument.current = {
cart,
Copy link
Member

Choose a reason for hiding this comment

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

How about spreading cart here, which would include cartTotals, cartNeedsShipping, paymentRequirements, and also add the rest of items at the same level?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I would advise against it, as cart has a lot of keys, and that would make the signature really confusing. After deprecating the keys you mentioned it would just be cart and billingData and that makes it easier to understand where the data comes from.

Copy link
Member

Choose a reason for hiding this comment

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

Wouldn't having cart as is just complicated one step further? so instead of arg.cartTotals you need arg.cart.cartTotals especially seeing that canPayArgument is made of cart related fields only.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's also made of billingData and shipping data from the CustomerDataContext

Copy link
Member

Choose a reason for hiding this comment

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

Those are also present in Cart, shipping data is shippingAddress and billing data is billingAddress.

The only difference here is that billingAddress reflects what's currently in state, and what's in Cart reflects what comes from the server, so this might not always be in sync. billingData can still replace billingAddress from cart.

This is not a huge point to block the PR on as moving the other direction (spreading) is easier than reversing.

:shipit:

Copy link
Contributor Author

@ralucaStan ralucaStan Sep 23, 2021

Choose a reason for hiding this comment

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

The data is indeed out of sync. This would be an issue for extensions that need to make calculations on the current billingData or shippingData.

This is not a huge point to block the PR on as moving the other direction (spreading) is easier than reversing.
👍

Comment on lines +70 to +84
beforeEach( async () => {
fetchMock.mockResponse( ( req ) => {
if ( req.url.match( /wc\/store\/cart/ ) ) {
return Promise.resolve( JSON.stringify( previewCart ) );
}
return Promise.resolve( '' );
} );
// need to clear the store resolution state between tests.
await dispatch( storeKey ).invalidateResolutionForStore();
await dispatch( storeKey ).receiveCart( defaultCartState.cartData );
} );

afterEach( () => {
fetchMock.resetMocks();
} );
Copy link
Member

Choose a reason for hiding this comment

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

Why was this added?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

a call was being made by useStoreCart and it needed to be mocked. I improved to mock to make it clearer.

@@ -87,11 +87,13 @@ A callback to determine whether the payment method should be available as an opt

```
canMakePayment( {
cart: Cart,
cartCoupons: CartCoupons,
Copy link
Member

Choose a reason for hiding this comment

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

cartCoupons is no longer exposed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Really good catch

@@ -27,6 +28,8 @@ export interface Supports extends SupportsConfiguration {
}

export interface CanMakePaymentArgument {
cart: Cart;
cartCoupons: CartResponseCoupons;
Copy link
Member

Choose a reason for hiding this comment

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

Also here.

@ralucaStan ralucaStan requested a review from senadir September 23, 2021 14:30
@ralucaStan
Copy link
Contributor Author

Please take another look, I've addressed your requests

@senadir senadir merged commit 2752e1a into trunk Sep 23, 2021
@senadir senadir deleted the add/4670-coupon-data-canMakePayment branch September 23, 2021 15:27
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
block: checkout Issues related to the checkout block. type: enhancement The issue is a request for an enhancement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

canMakePayment isn’t tracking billingData changes
2 participants