1

I have a restaurant app and have a rule where a 20% discount needs to be offered for every 2nd ice-cream.

So,

  • If bill has 2 icecreams, 20% discount on the 2nd icecream
  • If bill has 3 icecreams, still 20% discount on the 2nd icecream
  • If bill has 4 icecreams, 20% discount on the 2nd and 4th icecreams

I have a collection called $bill.items which contains each individual item in the bill.

How can I write this rule in Drools given that there seems to be no way to access the index of an element in a collection.

arahant
  • 2,203
  • 7
  • 38
  • 62

1 Answers1

2

Just collect them up and apply the discounts on the right-hand-side:

rule "Discount multiple ice creams"
when
    $bill : Bill()
    $iceCreams : ArrayList( size > 1 ) from $bill.items
then
    for (int i = 0; i < $iceCreams.size(); i++) {
        if (i % 2 == 0) {
            // Apply a discount
        }
    }
end

Or if each bill item is available in working memory, the following can be used on the LHS to collect them:

$iceCreams : ArrayList( size > 1 )
             from collect( BillItem(type == "Ice Cream") )

You may need to re-sort the list you have collected, based on each item's index within the bill.

Although, does the order of the items on a single bill really matter? The order in which items are entered on a bill is a rather unusual basis for a discount. As a customer buying 2 ice creams of differing price, I would ask for the cheapest item first because I will get a bigger discount on the second ice cream added to my bill. Hence why such discounts are usually applied to the N cheapest items. i.e. If 4 ice creams are purchased, then the 2 cheapest are discounted. Also, are ice creams different prices? If each ice cream is the same price, then all you really need to know is how many need to be discounted.

Steve
  • 9,270
  • 5
  • 47
  • 61
  • The Collection `$bill.items` is already avaiable. So you can the right hand side without any additions/changes on the left hand side. What you have there doesn't fit the question. (Agreed on the lack of precision in the question.) – laune Jul 30 '14 at 09:43
  • Thanks. I was actually trying to use the for loop on the LHS to collect every second icecream, but the for loop on the LHS was not working. I guess I have a long way to go before I understand Drools (and rule engines in general). As far as the issue about order of the items is concerned, the question I asked was explicitly simplified to leave out such details. – arahant Jul 30 '14 at 09:59
  • Tweaked as per @laune's comment that I can assume that the items are already available and don't need to `collect` them. – Steve Jul 30 '14 at 10:16