Demandware中如何从BonusDiscountLineItem的bonusProducts过滤缺货商品?
过滤BonusDiscountLineItem.bonusProducts中的缺货商品方案
嘿,这个需求我之前在Demandware(现在的Salesforce Commerce Cloud)项目里刚好处理过,完全有可行的方案来过滤掉BonusDiscountLineItem.bonusProducts里的缺货商品!下面给你分享几个实用的方法:
方法1:服务器端脚本直接过滤(最常用)
默认情况下bonusProducts确实会返回全量赠品,包括缺货的。你可以在获取到这个列表后,手动通过脚本过滤掉库存不足的商品。核心是检查每个商品的库存记录,判断是否处于可售状态。
举个JavaScript脚本的例子:
// 获取当前促销线项的原始赠品列表 var bonusLineItem = pdict.CurrentBonusDiscountLineItem; var originalBonusProducts = bonusLineItem ? bonusLineItem.bonusProducts : []; // 过滤出有库存的商品(这里的判断逻辑可以根据你的业务规则调整) var filteredProducts = originalBonusProducts.filter(function(product) { var inventoryRecord = product.getInventoryRecord(); // 示例:判断可用库存(ATS)大于0,或者库存状态为'in_stock' return inventoryRecord && inventoryRecord.ATS && inventoryRecord.ATS.value > 0; });
你可以把这段逻辑放在ISML模板、控制器脚本或者自定义模块里,在展示赠品或者处理促销逻辑时调用。
方法2:扩展全局可用的过滤方法
如果需要在多个地方复用这个过滤逻辑,建议封装成一个自定义模块,这样整个系统都能调用统一的过滤规则,避免重复代码。
比如创建一个自定义脚本模块BonusProductFilter.js:
/** * 过滤赠品列表中的缺货商品 * @param {dw.order.BonusDiscountLineItem} bonusLineItem - 促销线项 * @returns {Array<dw.catalog.Product>} 过滤后的赠品列表 */ function getFilteredBonusProducts(bonusLineItem) { if (!bonusLineItem || !bonusLineItem.bonusProducts || bonusLineItem.bonusProducts.length === 0) { return []; } return bonusLineItem.bonusProducts.filter(function(product) { var invRecord = product.getInventoryRecord(); // 这里可以根据业务需求调整,比如支持预购的话可以放宽条件 return invRecord && invRecord.getAvailabilityStatus() === 'in_stock'; }); } exports.getFilteredBonusProducts = getFilteredBonusProducts;
然后在需要的地方导入并使用:
var BonusProductFilter = require('~/cartridge/scripts/util/BonusProductFilter'); var filteredProducts = BonusProductFilter.getFilteredBonusProducts(pdict.CurrentBonusDiscountLineItem);
方法3:OCAPI响应扩展过滤
如果是通过OCAPI对外提供数据,可以在OCAPI的扩展脚本中,对返回的bonus_products字段进行转换过滤。比如在OCAPI的response_transform脚本里,添加过滤逻辑,确保返回给前端的赠品列表已经去掉了缺货商品。
注意事项
- 库存判断规则要匹配业务:不同业务对“缺货”的定义可能不同,有的是ATS为0,有的是库存状态为
out_of_stock,还有的要考虑预购/预订的情况,记得调整判断条件。 - 多库存节点场景:如果你的店铺用了多库存节点,要确保检查的是对应分配节点的库存状态,而不是全局库存。
- 性能优化:如果赠品列表很大,过滤时尽量减少不必要的库存查询,可以考虑提前缓存库存状态,避免重复调用
getInventoryRecord()影响性能。
内容的提问来源于stack exchange,提问作者Aravind
相关产品推荐
相关产品推荐

