Skip to content

Add support for Rule Based Promotions for Choice of Bonus Products - #3418

Merged
sf-shikhar-prasoon merged 31 commits into
developfrom
feature/bonus-products-rule-based-v3
Oct 25, 2025
Merged

Add support for Rule Based Promotions for Choice of Bonus Products#3418
sf-shikhar-prasoon merged 31 commits into
developfrom
feature/bonus-products-rule-based-v3

Conversation

@sf-shikhar-prasoon

@sf-shikhar-prasoon sf-shikhar-prasoon commented Oct 23, 2025

Copy link
Copy Markdown
Contributor

Description

Add support for Rule Base Promotions to Choice of Bonus Products.

Last release we added support for Choice of Bonus Products where the shopper is presented a set of choices to select bonus products from.

Currently only list based promotions are supported. After merging this PR, rule based promotions will be supported.

Currently, merchants have to explicitly list the products that are offered as choices. After merging this PR, merchants can configure rules that will search for all products that satisfy the promotion rule and create the list to be presented to the shopper.

demo-.rule.based.mov

Types of Changes

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Documentation update
  • Breaking change (could cause existing functionality to not work as expected)
  • Other changes (non-breaking changes that does not fit any of the above)

Breaking changes include:

  • Removing a public function or component or prop
  • Adding a required argument to a function
  • Changing the data type of a function parameter or return value
  • Adding a new peer dependency to package.json

Changes

Features:

  • New Hook: useRuleBasedBonusProducts - Fetches bonus products using ShopperSearch productSearch endpoint with promotionId
  • Detection Logic: isRuleBasedPromotion() - Identifies rule-based vs list-based promotions (empty bonusProducts array indicator)
  • Enhanced Discovery: Updated discovery.js to handle both promotion types via ruleBasedProductsMap parameter
  • Business Logic: New utilities in business-logic.js for rule-based promotion detection

Affected Components:

  • app/hooks/use-rule-based-bonus-products.js (NEW - 50 lines)
  • app/utils/bonus-product/discovery.js (+81 lines)
  • app/utils/bonus-product/business-logic.js (+42 lines)
  • app/hooks/use-derived-product.js (updated integration)

How to Test-Drive This PR

  • MRT Env . Qualifying product: Search for "25493613M"
  • To test locally, run the app locally
  • Go to product 25493613M Long Center Seam Skirt
  • Add it to cart and click on "Select Bonus Products"
  • Verify that you see a list of bonus products that matches the promotion (shown below)
  • You can also setup more rule based promotions and test them
    The promotion:
Screenshot 2025-10-23 at 10 13 56 AM

Checklists

General

  • Changes are covered by test cases
  • CHANGELOG.md updated with a short description of changes (not required for documentation updates)

Accessibility Compliance

You must check off all items in one of the follow two lists:

  • There are no changes to UI

or...

Localization

  • Changes include a UI text update in the Retail React App (which requires translation)

update feature branch `bonus-products-rule-based-v3` with develop branch
update feature branch `bonus-products-rule-based-v3` with develop branch
update feature branch `bonus-products-rule-based-v3` with develop branch
* 1. use search endpoint

* 2 add rule based detection

* 3. update discovery logic

* add tests, update bundle size limit, update changelog
…gic (#3408)

* 1. use search endpoint

* 2 add rule based detection

* 3. update discovery logic

* cleanup. remove unused code

* add tests, update bundle size limit, update changelog
@sf-shikhar-prasoon
sf-shikhar-prasoon requested a review from a team October 23, 2025 09:26
@cc-prodsec

cc-prodsec commented Oct 23, 2025

Copy link
Copy Markdown
Collaborator

Snyk checks have passed. No issues have been found so far.

Status Scanner Critical High Medium Low Total (0)
Licenses 0 0 0 0 0 issues
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

Update feature branch with latest from develop branch
@sf-shikhar-prasoon
sf-shikhar-prasoon marked this pull request as ready for review October 23, 2025 14:20
@sf-shikhar-prasoon
sf-shikhar-prasoon requested a review from a team as a code owner October 23, 2025 14:20
Comment thread packages/template-retail-react-app/CHANGELOG.md Outdated
Comment thread packages/template-retail-react-app/app/utils/bonus-product/hooks.js Outdated
@sf-shikhar-prasoon sf-shikhar-prasoon changed the title merge feature/bonus-products-rule-based-v3 into develop Add support for Rule Based Promotions for Choice of Bonus Products Oct 23, 2025
Comment thread packages/template-retail-react-app/app/hooks/use-rule-based-bonus-products.js Outdated
Comment thread packages/template-retail-react-app/app/hooks/use-rule-based-bonus-products.js Outdated
Comment thread packages/template-retail-react-app/app/utils/bonus-product/calculations.js Outdated
enabled: ruleBasedPromotions.length > 0,
limit: 50
}
)

@sf-deepali-bharmal sf-deepali-bharmal Oct 23, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why are we not creating a list of rule based promotionIds ?
And call search API for all promotionIds instead of one at a time ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

According to @sf-shikhar-prasoon This PR only supports 1 rule based promotion per product. Mentioned the same in changeLog

Comment thread packages/template-retail-react-app/app/hooks/use-rule-based-bonus-products.js Outdated
Comment thread packages/template-retail-react-app/app/utils/bonus-product/hooks.js Outdated
@vmarta

vmarta commented Oct 24, 2025

Copy link
Copy Markdown
Contributor

Is this a bug? This video shows how it's possible a product that does not have bonus products could still be associated with bonus products.

Arc.2025-10-23.at.19.09.24.mp4
Arc 2025-10-23 at 19 14 03

@vmarta

vmarta commented Oct 24, 2025

Copy link
Copy Markdown
Contributor

Now that we have modal for choosing the bonus products, let's make sure that its UX is the same/similar to the other modal for editing the cart item.

For bonus products, the content shifts around each time we select a different size, for example. Compare that with how the UX feels like for editing the cart item. Yes, selecting a different size triggers a fetch, but is there a way to keep the content feels more stable?

Arc.2025-10-23.at.19.16.31.mp4

sf-shikhar-prasoon and others added 16 commits October 24, 2025 00:31
…1/ruleBasedBugs/main

Resolved conflict in use-rule-based-bonus-products.js by keeping Commerce SDK implementation (useProductSearch) which includes pmpt=bonus parameter.

Merged changes:
- Hybrid proxy support for local development
- Order details multiship and BOPIS support
- Bonus product calculations improvements
- Various CHANGELOG updates
…9980361/ruleBasedBugs/main

PR comments for #3418 (PR for merging feature branch bonus-products-rule-based-v3 into develop)
This PR enhances the existing rule-based bonus product promotions feature by adding proper variant eligibility checking. Previously, rule-based promotions could not accurately determine which specific product variants qualified for a promotion. This enhancement introduces a qualifying products lookup system that uses the product search API to fetch and validate eligible variants, ensuring that only products that truly qualify can trigger bonus product selection UI and functionality.

Key Changes:

1. New Hook: useRuleBasedQualifyingProducts
   - Added to app/hooks/use-rule-based-bonus-products.js
   - Fetches qualifying products for rule-based promotions using productSearch API
   - Uses refinement parameters: pmid=${promotionId} and pmpt=qualifying
   - Returns a Set of qualifying product IDs for efficient lookup
   - Supports variant eligibility checking by examining both variant and master product IDs

2. Enhanced Promotion Eligibility Logic
   - Updated getPromotionIdsForProduct() in app/utils/bonus-product/common.js
   - Distinguishes between list-based and rule-based promotions
   - Added fallback logic to check master product IDs when variants don't directly qualify
   - Filters promotion IDs to only return those the product actually qualifies for

3. Qualifying Products Map Integration
   - Added ruleBasedQualifyingProductsMap parameter throughout the bonus product utility chain
   - Updated useBasketProductsWithPromotions() hook to fetch and return qualifying products map
   - Propagated the map through all relevant functions and components

4. Updated Function Signatures
   - isAutomaticPromotion()
   - shouldShowBonusProductSelection()
   - getBonusProductsForSpecificCartItem()
   - getBonusProductsInCartForProduct()
   - getAvailableBonusItemsForProduct()
   - getRemainingAvailableBonusProductsForProduct()

5. Component Updates
   - Cart Page: Destructures and passes ruleBasedQualifyingProductsMap
   - Add to Cart Modal: Uses qualifying products map for eligibility checks
   - Cart Product List: Accepts and forwards ruleBasedQualifyingProductsMap prop

6. Comprehensive Test Updates
   - Updated all test files to distinguish list-based vs rule-based promotions
   - Added new test cases for rule-based promotion eligibility scenarios
   - Enhanced test coverage across all bonus product utility test files

Backward Compatibility:
- All changes are backward compatible with existing list-based promotions
- Default parameter values ensure functions work without the new map
- Existing tests updated to explicitly mark promotions as list-based
…#3431)

* fix: prevent promotion flash by keeping previous data during variant changes

- Add keepPreviousData option parameter to useProductViewModal hook
- Pass keepPreviousData: true in BonusProductViewModal to maintain UI stability
- Prevents promotion message from clearing while fetching new variant data

* chore: trigger CI

* remove those stable references

* revert last changes
…0037720

Rule-Based Bonus Product Promotions Enhancement
* Fixed duplicating bonus products in the UI

* Fixed issue with list based not rendering properly

* Update cart-product-list-with-grouped-bonus-products.jsx

Signed-off-by: Daniel Diaz <38542490+ddiazccrz@users.noreply.github.com>

* Fixed lint errors

---------

Signed-off-by: Daniel Diaz <38542490+ddiazccrz@users.noreply.github.com>

@ddiazccrz ddiazccrz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I am approving this with the understanding that there are a few minor existing bugs (there with bonus products before this rule based bonus products) that will be fixed after. @sf-shikhar-prasoon lets make sure we make work items to address the lower priority issues.

@sf-deepali-bharmal sf-deepali-bharmal left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I am approving the PR but please test this feature branch thoroughly, preferably maintain a doc with tested scenario's.
Mix of rule based, list based, multiple rules or list based promo's in cart etc end to end.

enabled: ruleBasedPromotions.length > 0,
limit: 50
}
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

According to @sf-shikhar-prasoon This PR only supports 1 rule based promotion per product. Mentioned the same in changeLog


// Count selected items for this promotion (all bonus items with this promotion's bonusDiscountLineItemIds)
const promotionBonusLineItemIds = promotionBonusItems.map((item) => item.id).filter(Boolean)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This file can be reverted.

@sf-shikhar-prasoon
sf-shikhar-prasoon merged commit 31d17a2 into develop Oct 25, 2025
42 checks passed
@sf-shikhar-prasoon
sf-shikhar-prasoon deleted the feature/bonus-products-rule-based-v3 branch October 25, 2025 02:10
shethj pushed a commit that referenced this pull request Oct 31, 2025
…3418)

* @W-18957985- Product Search Integration & Rule-Based Detection (#3396)

* 1. use search endpoint

* 2 add rule based detection

* 3. update discovery logic

* add tests, update bundle size limit, update changelog

* @W-19980361 Rule based bonus products- Work Item 2- update display logic (#3408)

* 1. use search endpoint

* 2 add rule based detection

* 3. update discovery logic

* cleanup. remove unused code

* add tests, update bundle size limit, update changelog

* fix header counts

* fix flasing, re-rendering

* pr comments + lint

* @W-19980361 fix 2 bugs- selection count & flashing due to re-renders (#3421)

* fix header counts

* fix flasing, re-rendering

* pr comments + lint

* add param &refine=pmpt=bonus for promotion type

* pr comments

* use commerce sdk

* add const- limit=50  |  replace harded Search Param values

* remove function breakdown change

* update changelog

* refactor. re-use

* fix: prevent promotion message flashing when changing product variant… (#3428)

* fix tests

* Rule-Based Bonus Product Promotions Enhancement

This PR enhances the existing rule-based bonus product promotions feature by adding proper variant eligibility checking. Previously, rule-based promotions could not accurately determine which specific product variants qualified for a promotion. This enhancement introduces a qualifying products lookup system that uses the product search API to fetch and validate eligible variants, ensuring that only products that truly qualify can trigger bonus product selection UI and functionality.

Key Changes:

1. New Hook: useRuleBasedQualifyingProducts
   - Added to app/hooks/use-rule-based-bonus-products.js
   - Fetches qualifying products for rule-based promotions using productSearch API
   - Uses refinement parameters: pmid=${promotionId} and pmpt=qualifying
   - Returns a Set of qualifying product IDs for efficient lookup
   - Supports variant eligibility checking by examining both variant and master product IDs

2. Enhanced Promotion Eligibility Logic
   - Updated getPromotionIdsForProduct() in app/utils/bonus-product/common.js
   - Distinguishes between list-based and rule-based promotions
   - Added fallback logic to check master product IDs when variants don't directly qualify
   - Filters promotion IDs to only return those the product actually qualifies for

3. Qualifying Products Map Integration
   - Added ruleBasedQualifyingProductsMap parameter throughout the bonus product utility chain
   - Updated useBasketProductsWithPromotions() hook to fetch and return qualifying products map
   - Propagated the map through all relevant functions and components

4. Updated Function Signatures
   - isAutomaticPromotion()
   - shouldShowBonusProductSelection()
   - getBonusProductsForSpecificCartItem()
   - getBonusProductsInCartForProduct()
   - getAvailableBonusItemsForProduct()
   - getRemainingAvailableBonusProductsForProduct()

5. Component Updates
   - Cart Page: Destructures and passes ruleBasedQualifyingProductsMap
   - Add to Cart Modal: Uses qualifying products map for eligibility checks
   - Cart Product List: Accepts and forwards ruleBasedQualifyingProductsMap prop

6. Comprehensive Test Updates
   - Updated all test files to distinguish list-based vs rule-based promotions
   - Added new test cases for rule-based promotion eligibility scenarios
   - Enhanced test coverage across all bonus product utility test files

Backward Compatibility:
- All changes are backward compatible with existing list-based promotions
- Default parameter values ensure functions work without the new map
- Existing tests updated to explicitly mark promotions as list-based

* fix: prevent promotion message flashing when changing product variant (#3431)

* fix: prevent promotion flash by keeping previous data during variant changes

- Add keepPreviousData option parameter to useProductViewModal hook
- Pass keepPreviousData: true in BonusProductViewModal to maintain UI stability
- Prevents promotion message from clearing while fetching new variant data

* chore: trigger CI

* remove those stable references

* revert last changes

* bundle size limit update

* @W-20037720: Not allow duplicate items to appear in the cart (#3433)

* Fixed duplicating bonus products in the UI

* Fixed issue with list based not rendering properly

* Update cart-product-list-with-grouped-bonus-products.jsx

Signed-off-by: Daniel Diaz <38542490+ddiazccrz@users.noreply.github.com>

* Fixed lint errors

---------

Signed-off-by: Daniel Diaz <38542490+ddiazccrz@users.noreply.github.com>

---------

Signed-off-by: Daniel Diaz <38542490+ddiazccrz@users.noreply.github.com>
Co-authored-by: sf-xingquan-jin <xingquan.jin@salesforce.com>
Co-authored-by: cboscenco <cboscenco@salesforce.com>
Co-authored-by: Daniel Diaz <38542490+ddiazccrz@users.noreply.github.com>
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.

10 participants