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

Add minimum quantity and step so Cart Block and Store API. #5037

Closed
wants to merge 5 commits into from

Conversation

senadir
Copy link
Member

@senadir senadir commented Oct 28, 2021

This PR adds minimum and step concepts to Store API and Cart Block.

This functionality is still mainly plugin land, so we're not actually implementing a way for a merchant to setup a step or a minimum amount, but we're laying the foundation for plugins to use this, in Store API, via two new filters:

  • woocommerce_store_api_item_quantity_minimum
  • woocommerce_store_api_item_quantity_step

Following on the steps of woocommerce_store_api_product_quantity_limit.

The second addition is honoring those values in Cart Block. Cart Item quantity switcher now honors minimum and step values and would change according to them.

Based on 66b0534

Testing steps

  1. Smoke test adding items to cart and changing quantity, either via buttons or directly via the input.
  2. Keep you network tap open and make sure no extra requests are being made.
  3. Add this code, which would apply to your cart items:
add_filter(
	'woocommerce_store_api_item_quantity_minimum',
	function ( $value, $cart_item ) {
		return 6;
	},
	10,
	2
);

add_filter(
	'woocommerce_store_api_item_quantity_step',
	function ( $value, $cart_item ) {
		return 4;
	},
	10,
	2
);
  1. Substitute 6 and 4 with whatever value you want.
  2. Refresh your cart, change values, quantity should up and down by 4 (or whatever value you set for step).
  3. If the initial value isn't a multiplier of 4, after changing the quantity, your new quantity would be a multiplier of 4.
  4. Try to type a number inside the quantity selector, trying something that isn't a multiplier of 4 would change to the nearest one, for example, typing 14 would yield back 12.

Caveats:

  • I opted out for filters instead of a registration API. the surface area is very minimal (just a number).
  • I decided to keep this plugin land. This means there's no verification on Store API about minimum quantity and if it follows a step or not. We do have verification for maximum quantity, but that's because maximum quantity is a core feature, handled via sold individually and stock attributes.
  • @mikejolley and discussed not implementing the step part, and let plugins handle that on server side. This reduces the amount of logic we have, but I believe results in a subpar UI experience overall. I'd prefer, if we can, to handle that on our part.

Changelog

Store API and Cart block now support defining a quantity stepper and a minimum quantity.

@senadir senadir requested a review from mikejolley October 28, 2021 18:04
@senadir senadir self-assigned this Oct 28, 2021
@rubikuserbot rubikuserbot requested a review from a team October 28, 2021 18:04
@senadir senadir added category: extensibility Work involving adding or updating extensibility. Useful to combine with other scopes impacted. focus: rest api Work impacting REST api routes. type: enhancement The issue is a request for an enhancement. block: cart Issues related to the cart block. labels Oct 28, 2021
@github-actions
Copy link
Contributor

github-actions bot commented Oct 28, 2021

Size Change: +1.36 kB (0%)

Total Size: 820 kB

Filename Size Change
build/active-filters.js 7.05 kB +1 B (0%)
build/all-products-frontend.js 18.6 kB +8 B (0%)
build/all-products.js 34.4 kB -3 B (0%)
build/atomic-block-components/add-to-cart.js 6.42 kB -3 B (0%)
build/atomic-block-components/button.js 851 B +1 B (0%)
build/atomic-block-components/image-frontend.js 1.37 kB +1 B (0%)
build/atomic-block-components/image.js 1.05 kB +2 B (0%)
build/atomic-block-components/rating-frontend.js 551 B -1 B (0%)
build/atomic-block-components/stock-indicator-frontend.js 583 B -1 B (0%)
build/atomic-block-components/title.js 1.1 kB +1 B (0%)
build/attribute-filter.js 12.6 kB -1 B (0%)
build/cart-blocks/checkout-button-frontend.js 1.14 kB -2 B (0%)
build/cart-blocks/filled-cart-frontend.js 765 B -1 B (0%)
build/cart-blocks/items-frontend.js 299 B +1 B (0%)
build/cart-blocks/line-items-frontend.js 5.86 kB +732 B (+14%) ⚠️
build/cart-blocks/order-summary-frontend.js 8.98 kB -3 B (0%)
build/cart-blocks/totals-frontend.js 321 B +1 B (0%)
build/cart-frontend.js 45.6 kB +7 B (0%)
build/cart.js 44.5 kB +91 B (0%)
build/checkout-blocks/actions-frontend.js 1.44 kB +1 B (0%)
build/checkout-blocks/billing-address--checkout-blocks/shipping-address-frontend.js 4.24 kB +1 B (0%)
build/checkout-blocks/contact-information-frontend.js 2.95 kB -1 B (0%)
build/checkout-blocks/fields-frontend.js 344 B +1 B (0%)
build/checkout-blocks/order-note-frontend.js 1.13 kB -2 B (0%)
build/checkout-blocks/order-summary-frontend.js 11.4 kB -1 B (0%)
build/checkout-blocks/payment-frontend.js 7.41 kB -2 B (0%)
build/checkout-blocks/shipping-methods-frontend.js 4.81 kB -3 B (0%)
build/featured-product.js 9.91 kB +2 B (0%)
build/handpicked-products.js 7.32 kB -1 B (0%)
build/legacy-template.js 2.08 kB -1 B (0%)
build/mini-cart-contents.js 3.58 kB +1 B (0%)
build/price-filter.js 8.6 kB -2 B (0%)
build/product-best-sellers.js 7.51 kB -2 B (0%)
build/product-categories.js 3.47 kB -2 B (0%)
build/product-category.js 8.35 kB +3 B (0%)
build/product-new.js 7.66 kB +1 B (0%)
build/product-on-sale.js 8.05 kB -3 B (0%)
build/product-tag.js 7.76 kB -1 B (0%)
build/products-by-attribute.js 8.48 kB -1 B (0%)
build/reviews-by-category.js 11.8 kB -1 B (0%)
build/reviews-by-product.js 12.9 kB -1 B (0%)
build/single-product-frontend.js 22.1 kB +8 B (0%)
build/single-product.js 10.4 kB +4 B (0%)
build/stock-filter.js 6.82 kB -1 B (0%)
build/vendors--atomic-block-components/add-to-cart--cart-blocks/order-summary--checkout-blocks/billing-ad--c5eb4dcd-frontend.js 19 kB -2 B (0%)
build/wc-blocks-vendors.js 66.1 kB +537 B (+1%)
build/wc-blocks.js 2.96 kB -2 B (0%)
ℹ️ View Unchanged
Filename Size
build/active-filters-frontend.js 6.22 kB
build/all-reviews.js 8.35 kB
build/atomic-block-components/add-to-cart--atomic-block-components/button--atomic-block-components/image---a7e2bb9b.js 2.76 kB
build/atomic-block-components/add-to-cart--atomic-block-components/button.js 1.48 kB
build/atomic-block-components/add-to-cart-frontend.js 6.87 kB
build/atomic-block-components/button-frontend.js 1.48 kB
build/atomic-block-components/category-list-frontend.js 457 B
build/atomic-block-components/category-list.js 458 B
build/atomic-block-components/price-frontend.js 1.74 kB
build/atomic-block-components/price.js 1.69 kB
build/atomic-block-components/rating.js 553 B
build/atomic-block-components/sale-badge-frontend.js 625 B
build/atomic-block-components/sale-badge.js 621 B
build/atomic-block-components/sku-frontend.js 386 B
build/atomic-block-components/sku.js 385 B
build/atomic-block-components/stock-indicator.js 586 B
build/atomic-block-components/summary-frontend.js 872 B
build/atomic-block-components/summary.js 873 B
build/atomic-block-components/tag-list-frontend.js 458 B
build/atomic-block-components/tag-list.js 458 B
build/atomic-block-components/title-frontend.js 1.11 kB
build/attribute-filter-frontend.js 16.3 kB
build/blocks-checkout.js 17.6 kB
build/cart-blocks/accepted-payment-methods-frontend.js 1.15 kB
build/cart-blocks/empty-cart-frontend.js 345 B
build/cart-blocks/express-payment-frontend.js 4.86 kB
build/checkout-blocks/billing-address-frontend.js 884 B
build/checkout-blocks/express-payment-frontend.js 5.15 kB
build/checkout-blocks/shipping-address-frontend.js 971 B
build/checkout-blocks/terms-frontend.js 1.21 kB
build/checkout-blocks/totals-frontend.js 324 B
build/checkout-frontend.js 47.7 kB
build/checkout.js 47.1 kB
build/featured-category.js 8.55 kB
build/mini-cart-component-frontend.js 14.2 kB
build/mini-cart-frontend.js 1.76 kB
build/mini-cart.js 6.45 kB
build/price-filter-frontend.js 12.4 kB
build/price-format.js 1.18 kB
build/product-search.js 2.46 kB
build/product-top-rated.js 7.63 kB
build/reviews-frontend.js 7.25 kB
build/stock-filter-frontend.js 6.81 kB
build/vendors--atomic-block-components/add-to-cart-frontend.js 6.82 kB
build/vendors--atomic-block-components/price--cart-blocks/line-items--cart-blocks/order-summary--checkout--8a3571de-frontend.js 5.71 kB
build/vendors--cart-blocks/line-items--checkout-blocks/order-summary-frontend.js 3.14 kB
build/vendors--cart-blocks/order-summary--checkout-blocks/billing-address--checkout-blocks/order-summary---eb4d2cec-frontend.js 4.75 kB
build/wc-blocks-data.js 8.84 kB
build/wc-blocks-editor-style-rtl.css 4.4 kB
build/wc-blocks-editor-style.css 4.4 kB
build/wc-blocks-google-analytics.js 1.56 kB
build/wc-blocks-middleware.js 949 B
build/wc-blocks-registry.js 2.7 kB
build/wc-blocks-shared-context.js 1.51 kB
build/wc-blocks-shared-hocs.js 1.14 kB
build/wc-blocks-style-rtl.css 21.6 kB
build/wc-blocks-style.css 21.6 kB
build/wc-blocks-vendors-style-rtl.css 1.28 kB
build/wc-blocks-vendors-style.css 1.28 kB
build/wc-payment-method-bacs.js 820 B
build/wc-payment-method-cheque.js 816 B
build/wc-payment-method-cod.js 912 B
build/wc-payment-method-paypal.js 838 B
build/wc-payment-method-stripe.js 11.1 kB
build/wc-settings.js 2.6 kB

compressed-size-action

@ralucaStan ralucaStan removed the request for review from a team November 3, 2021 13:56
@manospsyx
Copy link

manospsyx commented Nov 23, 2021

Hey @senadir -- I have had a chance to quickly set up an example and do some tests.

One issue I noticed is that once I increase the cart item quantity to 2 or higher, I am no longer able to set it back to 1.

On another note, I tried to continue where we left things off in this PR and have the following to share:

  • The new API properties are a massive help from an integration perspective. I echo @mikejolley's feedback on the step property; my impression is that making the step property part of the API optimizes for providing a single extensibility point for those 3 related "properties". Whether we'd like to optimize for that is up for discussion.
  • These changes do not address the primary issue I attempted to tackle here and here, which is the failure to keep cart item quantities in sync.

Here's some code you can use to play around with this state-related problem:

add_action( 'woocommerce_after_cart_item_quantity_update', function( $cart_item_key, $quantity = 0 ) {

	if ( isset( WC()->cart->is_syncing ) && WC()->cart->is_syncing ) {
		return;
	}

	if ( ! empty( WC()->cart->cart_contents[ $cart_item_key ] ) ) {

		$cart_item = WC()->cart->cart_contents[ $cart_item_key ];

		if ( ! $quantity || $quantity < 0 ) {
			$quantity = 0;
		} else {
			$quantity = $cart_item[ 'quantity' ];
		}

		if ( in_array( $cart_item[ 'data' ]->get_name(), array( 'Hoodie', 'Belt' ) ) ) {

			foreach ( WC()->cart->cart_contents as $search_item_key => $search_item ) {

				if ( 'Belt' === $search_item[ 'data' ]->get_name() ) {

					if ( 'Hoodie' !== $cart_item[ 'data' ]->get_name() ) {
						continue;
					}

				} elseif ( 'Hoodie' === $search_item[ 'data' ]->get_name() ) {

					if ( 'Belt' !== $cart_item[ 'data' ]->get_name() ) {
						continue;
					}

				} else {
					continue;
				}

				WC()->cart->is_syncing = true;
				WC()->cart->set_quantity( $search_item_key, $quantity, false );
				WC()->cart->is_syncing = false;
			}

		}
	}
}, 10, 2 );

What this code does, in a nutshell: Whenever you change the quantity of an item called "Hoodie", it searches for an item called "Belt", and tries to keep the quantity of the latter in sync with the former. Here's how this works in the legacy cart:

Screen.Recording.2021-11-23.at.05.15.18.p.m.mp4

And here's what's happening in the block cart:

Screen.Recording.2021-11-23.at.05.17.51.p.m.mp4

Note that I need to refresh to get the qty of the "synced" item to update, although it's coming back just fine through the API.

I'm not sure if this needs to be addressed in this PR (probably not?) but it's still a roadblock, and one that we'll need to overcome to make the new Cart/Checkout Blocks compatible with Force Sells, Product Bundles, Composite Products, Mix and Match Products, and likely other extensions that rely on the woocommerce_after_cart_item_quantity_update filter to keep cart item quantities in sync.

@senadir senadir force-pushed the add/change-quantity-with-steps branch from 8169696 to f01c1c1 Compare November 24, 2021 10:34
@senadir
Copy link
Member Author

senadir commented Nov 24, 2021

One issue I noticed is that once I increase the cart item quantity to 2 or higher, I am no longer able to set it back to 1.

Yes, I noticed this as well, seems like a bug.

These changes do not address the primary issue I attempted to tackle here and here, which is the failure to keep cart item quantities in sync.

Keeping cart in sync is working, you can see the item subtotal changing, there's a small bug you can see there around reinitaiting state, that needs to be fixed, probably in a another PR.

@manospsyx
Copy link

that needs to be fixed, probably in a another PR

Yup, that's probably a separate issue -- definitely a blocking one for what we're trying to achieve! Will open a new issue with the description from the last comment. Thanks!!!

@mikejolley mikejolley self-assigned this Dec 15, 2021
@senadir
Copy link
Member Author

senadir commented Dec 17, 2021

Note that work on this was moved to #5406. I will be closing this in favor of that one.

@nielslange nielslange deleted the add/change-quantity-with-steps branch April 19, 2023 23:46
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
block: cart Issues related to the cart block. category: extensibility Work involving adding or updating extensibility. Useful to combine with other scopes impacted. focus: rest api Work impacting REST api routes. type: enhancement The issue is a request for an enhancement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants