IBM WCS comes with default set up for Buy X1 , Get Y free promotion type. One can add multiple catalog entries within X which WCS translate is as Buy out of ( X1 , X2 , X3 , .... Xn ) and Get Y free through MultiSKUFilter specified within respective xsl file as
<Filter impl="com.ibm.commerce.marketing.promotion.condition.MultiSKUFilter">
MultiSKUFilter takes the Include and Exclude list as input and evaluate whether the promotion should be activated or not. In this case with multiple included entries , it treats the logic as OR instead of AND.
If you want that promotion should be activated only in case all the speified included items are in cart ( or Buy X and Y , Get Z free ). Make the following change either in the promotion xml ( for particular promotion) or make the change in the promotion type xsl.
<xsl:for-each select="PromotionData/Elements/PurchaseCondition/IncludeCatalogEntryIdentifier">
<Filter impl="com.ibm.commerce.marketing.promotion.condition.MultiSKUFilter">
<IncludeCatEntryKey>
<xsl:call-template name="CatalogEntryKeyTemplate">
<xsl:with-param name="dn" select="Data/DN" />
<xsl:with-param name="sku" select="Data/SKU" />
</xsl:call-template>
</IncludeCatEntryKey>
</Filter>
</xsl:for-each>
i.e <xsl:for each> tag outside filter.
The output of this change will be that different SKU's will come with individual filter tags and hence MultiSKUFilter will be called for individual item in the include list and hence promotion will only be activated if all included items will be added to cart.
Related Post -
Steps to create a custom promotion type.