Implementation Lifecycle: Personas
Commerce SFDX Environment Setup
Implement Custom Self-Registration for a B2B Store
Commerce LWR Storefront Performance Best Practices
Image Optimization Best Practices
Custom Rules for Product Readiness
Merchandisers can run Product Readiness on their catalogs to ensure that all products in a catalog are storefront ready. By default, Product Readiness uses a rule set that contains criteria based on SKUs, images, categories, and descriptions. If the default Product Readiness rule set doesn’t fit your organization’s needs, create a custom rule set to determine what criteria a product must fit to be considered ready.
Use an APEX class to create a rule set, and then activate the Readiness.ProductEvaluator. After the rule set is enabled, an admin must rebuild the index.
A custom rule can’t be added to the default rule set. If a custom rule set is enabled, it replaces the default rule set.
ProductScore records are associated with productIds as a measure of Product Readiness. If there are no score details returned for a given product, the score record is deleted. This rule allows for obsolete product scores to be deleted if the rules no longer return scores for these cases.
1public class ProductReadinessDescriptionEvaluator implements Readiness.ProductEvaluator {
2
3 // return true for the rule to run
4 public boolean isActive() {
5 return true;
6 }
7
8 // return a list of Readiness.ProductScoreDetail which will become the product readiness score
9 public List<Readiness.ProductScoreDetail> evaluateReadiness(Readiness.ProductEvaluationContext productContext) {
10 // example implmentation which checks for a description and a price
11 Set<ID> productIds = productContext.ProductIds;
12 List<Readiness.ProductScoreDetail> scores = new List<Readiness.ProductScoreDetail>();
13
14 List<Product2> products = [SELECT
15 id, description
16 FROM Product2
17 WHERE
18 id IN : productIds];
19
20 for (Product2 product : products) {
21 scores.add(new Readiness.ProductScoreDetail(
22 product.Id,
23 'Description Length',
24 String.isBlank(product.description) ? 0 : 100,
25 'Product does not have a Description.'));
26
27 List<PricebookEntry> entries = [SELECT id FROM PricebookEntry WHERE Product2Id = :product.Id];
28 Integer pricebookScore = (entries.size() == 0) ? 0 : 100;
29 scores.add(new Readiness.ProductScoreDetail(
30 product.Id,
31 'Price',
32 pricebookScore,
33 'Product must have a price.'));
34 }
35
36 return scores;
37 }
38}