Skip to content

fix: switcher respects commercetools inventory settings#245

Open
Riraseth wants to merge 3 commits into
mainfrom
54-quantity-switcher
Open

fix: switcher respects commercetools inventory settings#245
Riraseth wants to merge 3 commits into
mainfrom
54-quantity-switcher

Conversation

@Riraseth

@Riraseth Riraseth commented Jun 2, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

@Riraseth Riraseth requested a review from a team June 2, 2026 14:35
Comment thread integrations/commercetools-api/src/services/cart.service.ts Outdated
Comment thread integrations/commercetools-api/src/services/cart.service.ts Outdated
}
stateRef.current.expectedServerQuantity = newQuantity
const clampedQuantity =
max !== undefined ? Math.min(newQuantity, max) : newQuantity

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

max !== undefined ? Math.min(v, max) : v is repeated at lines 62–63, 116–117, and 129. Maybe would be good to extract it as shared function to change it once later if clamping policy changes?

const validatedCart = CartApiResponseSchema.parse(responseBody)
const mappedCart = mapCartToResponse(validatedCart, currentLanguage)
return CartResponseSchema.parse(mappedCart)
const enrichedCart = await this.enrichWithInventory(mappedCart)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

processCartResponse always awaits enrichWithInventory, so every cart op pays for an inventory query even though maxQuantity is only read by the quantity switcher on /cart (checkout uses CartItemCompact with preview={true}, which shows static text and never touches it). So getActiveCart on page loads and the address/shipping mutations each fire a wasted inventory().get(), and a quantity change becomes three serialized round-trips (getCartVersion GET → cart POST → inventory GET).

Could we only enrich where the switcher consumes it? getCart + the line-item mutations (addToCart/updateCartItem/removeCartItem) need it since their responses land in the shared ['cart'] cache and re-render the switcher. setBillingAddress/setShippingAddress/setShippingMethod/getActiveCart can skip it — the switcher is hidden in checkout and useCart has staleTime: 0, so /cart refetches an enriched getCart on return. createCart is a no-op anyway.


return {
...item,
maxQuantity: Math.max(item.quantity, availableQuantity),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

When current cart quantity already exceeds availability, max snaps up to the cart quantity, so the field stops meaning "available stock."

}
}

private buildInventoryWhereClause(skus: string[]): string {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

buildInventoryWhereClause + escapeWhereStringValue re-implement the field in ("a","b") predicate that already exists at integrations/commercetools-api/src/helpers/fetch-projections.ts:25:

const wherePredicate = `id in (${ids.map((id) => `"${id}"`).join(',')})`

Failure scenario: three independent in (...) builders now exist (this one, fetch-projections.ts:25, wishlist.ts:42) and only the new one escapes quotes/backslashes. A SKU/id containing " breaks the others but works here. The fix exists but isn't reachable from the other call sites. Extract a shared buildInClause(field, values) (with escaping) into src/helpers/ and call it from all three.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants