If the declared type of productId and getProductId() is String, it should be
compared to a string literal. (A conversion might be made, but don't rely on
that.)
You cannot access components of a global in RHS code using the simplified
notation (not unless you use "mvel" - but don't do that.) Here, all
accesses
should be written the usual Java way, with getter and setter calls.
The problem you have with modify(ci) is a bug (fixed for 5.3.0). As a
workaround,use
modify( (CartItem)ci ){ ... }
-W
2011/9/9 Sandeep Bandela <gibsosmat(a)gmail.com>
some more info for the modify() problem, the CartItem is an interface
and
the implementation is CartItemImpl. if this info leads to some clues.
On Fri, Sep 9, 2011 at 1:28 PM, Sandeep Bandela <gibsosmat(a)gmail.com>wrote:
> Hi here is the same thing converted to mvl
>
> // this Bundler.java has integer member that keeps incrementing
> global Bundler bundler
>
>
> rule "Apply 10% discount if you purchase 2 items"
> when
> $s1 : CartItem( *productId == 219759*, processed == false)
> $s2 : CartItem( this != $s1, productId == $s1.productId, processed
> == false)
>
> $m : RuleMessage()
> then
> $m.addMessage("Found item1: " + $s1.getName() + " id:
> "+$s1.getId());
> $m.addMessage("Found item2: " + $s2.getName() + " id:
> "+$s2.getId());
> modify($s1){
> setProcessed(true),
> setPromoItemDiscount($s1.getPrice() * 0.1),
> setPromoId("1"),
> setBundleId(bundler.getId()),
> setAggrigatorId(1)
> };
> modify($s2){
> setProcessed(true),
> setPromoItemDiscount($s2.getPrice() * 0.1),
> setPromoId("1"),
> setBundleId(bundler.getId()),
> setAggrigatorId(1)
> };
> $m.addMessage("bundled ["+*bundler.getId()*+"]
> "+$s1.getId()+","+$s2.getId());
> bundler.increment();
> end
>
> the above rule dosent fire, but if I change the highlighter to
> getProductId() == 219759, or use productId == "219759", may be this is
some
> edge case but it took long time for me to figure it out productId is String.
> now consider the *bundler.getId()*, if I use *bundler.id* I get
> compilation error.
>
> Rule Compilation error : [Rule name='Apply 10% discount if you purchase 2
> items']
>
>
com/example/promotions/promotionEngine/Rule_Apply_10__discount_if_you_purchase_2_items_0.java
> (23:1592) : The field Bundler.id is not visible
> 2011-09-09 13:18:39,863 INFO [STDOUT] - 2011-09-09 13:18:39,863 INFO
> [PromotionsManager] - ksession initialized
> 2011-09-09 13:18:39,863 INFO [STDOUT] - 2011-09-09 13:18:39,863 INFO
> [PromotionsManager] - Exploding items and inserting cart
> 2011-09-09 13:18:39,864 INFO [STDOUT] - 2011-09-09 13:18:39,863 ERROR
> [CheckOutBasedUtilities] - Failed to apply promo offers
> java.lang.RuntimeException: Unexpected global [bundler]
> at
> org.drools.common.AbstractWorkingMemory.setGlobal(AbstractWorkingMemory.java:613)
> at
>
org.drools.impl.StatefulKnowledgeSessionImpl.setGlobal(StatefulKnowledgeSessionImpl.java:332)
> at
>
com.example.promotions.promotionEngine.PromotionsManager.applyOffers(PromotionsManager.java:154)
> at
>
com.example.promotions.promotionEngine.PromotionsManager.shuffleForOffers(PromotionsManager.java:61)`
>
> lastly my actual problem that I am looking for a solution lets say we have
> "Buy X items of A and get Y Items of B". X=5 & Y=4 from the original
problem
> I want to template the rule and load the values of X,A,Y,B from database or
> excel etc. if I use modify the error is as follows
>
> *my rule*
>
>
>
> rule "Buy X units of Product A and Get Y units of Product B Free"
> when
> $itemsX : ArrayList( size == 2 ) from collect( CartItem(
> getProductId() == 24257, !isProcessed()))
> $itemsY : ArrayList( size == 1) from collect(CartItem(
> getProductId() == 24260, !isProcessed()))
> $m : RuleMessage()
> then
> for(Object item : $itemsX){
> CartItem ci = (CartItem) item;
> $m.addMessage( ci.getId()+")Found item:
"+ci.getItemId()+"
> name: "+ci.getName());
> modify(ci){
> setProcessed(true),
> setPromoItemDiscount(0),
>
> setPromoId("2"),
> setBundleId(bundler.getId()),
> setAggrigatorId(1)
> };
> }
> for(Object item : $itemsY){
> CartItem ci = (CartItem) item;
> $m.addMessage( ci.getId()+")Found item:
"+ci.getItemId()+"
> name: "+ci.getName());
> modify(ci){
> setProcessed(true),
> setPromoItemDiscount(ci.getPrice()),
> setPromoId("2"),
> setBundleId(bundler.getId()),
> setAggrigatorId(2)
> };
> }
> bundler.increment();
> end
>
> Rule Compilation error : [Rule name='Buy X units of Product A and Get Y
> units of Product B Free']
>
>
com/example/promotions/promotionEngine/Rule_Buy_X_units_of_Product_A_and_Get_Y_units_of_Product_B_Free_0.java
> (11:1236) : The method setProcessed(boolean) is undefined for the type
> Object
>
>
com/example/promotions/promotionEngine/Rule_Buy_X_units_of_Product_A_and_Get_Y_units_of_Product_B_Free_0.java
> (12:1265) : The method setPromoItemDiscount(int) is undefined for the type
> Object
>
>
com/example/promotions/promotionEngine/Rule_Buy_X_units_of_Product_A_and_Get_Y_units_of_Product_B_Free_0.java
> (13:1299) : The method setPromoId(String) is undefined for the type Object
>
>
com/example/promotions/promotionEngine/Rule_Buy_X_units_of_Product_A_and_Get_Y_units_of_Product_B_Free_0.java
> (14:1325) : The method setBundleId(Integer) is undefined for the type Object
>
>
com/example/promotions/promotionEngine/Rule_Buy_X_units_of_Product_A_and_Get_Y_units_of_Product_B_Free_0.java
> (15:1364) : The method setAggrigatorId(int) is undefined for the type Object
>
>
com/example/promotions/promotionEngine/Rule_Buy_X_units_of_Product_A_and_Get_Y_units_of_Product_B_Free_0.java
> (22:1702) : The method setProcessed(boolean) is undefined for the type
> Object
>
>
com/example/promotions/promotionEngine/Rule_Buy_X_units_of_Product_A_and_Get_Y_units_of_Product_B_Free_0.java
> (23:1731) : The method setPromoItemDiscount(Double) is undefined for the
> type Object
>
>
com/example/promotions/promotionEngine/Rule_Buy_X_units_of_Product_A_and_Get_Y_units_of_Product_B_Free_0.java
> (24:1777) : The method setPromoId(String) is undefined for the type Object
>
>
com/example/promotions/promotionEngine/Rule_Buy_X_units_of_Product_A_and_Get_Y_units_of_Product_B_Free_0.java
> (25:1803) : The method setBundleId(Integer) is undefined for the type Object
>
>
com/example/promotions/promotionEngine/Rule_Buy_X_units_of_Product_A_and_Get_Y_units_of_Product_B_Free_0.java
> (26:1842) : The method setAggrigatorId(int) is undefined for the type Object
>
> Rule Compilation error : [Rule name='Apply 10% discount if you purchase 2
> items']
>
>
com/example/promotions/promotionEngine/Rule_Apply_10__discount_if_you_purchase_2_items_0.java
> (23:1592) : The field Bundler.id is not visible
>
>
>
> On Fri, Sep 9, 2011 at 12:40 PM, Sandeep Bandela <gibsosmat(a)gmail.com>wrote:
>
>> Hi Wolfgang,
>> This is what I did initially but for product > 2 I didnt find a generic
>> way to do this. following is my first rule. I didnt use field names because
>> it was giving error that member is not accessible. I will attach the errors
>> of each case in a few mins.
>>
>> rule "Apply 10% discount if you purchase 2 items"
>> dialect "java"
>> when
>> $s1 : CartItem( getProductId() == 236061, !isProcessed())
>> $s2 : CartItem( getProductId() == 236061, getId() != $s1.getId(),
>> !isProcessed())
>> $m : RuleMessage()
>> then
>> $m.addMessage("Found item1: " + $s1.getName() + " id:
>> "+$s1.getId());
>> $m.addMessage("Found item2: " + $s2.getName() + " id:
>> "+$s2.getId());
>> modify($s1){
>> setProcessed(true),
>> setPromoItemDiscount($s1.getPrice() * 0.1),
>> setPromoId("1"),
>> setBundleId(bundler.getId()),
>> setAggrigatorId(1)
>> };
>> modify($s2){
>> setProcessed(true),
>> setPromoItemDiscount($s2.getPrice() * 0.1),
>> setPromoId("1"),
>> setBundleId(bundler.getId()),
>> setAggrigatorId(1)
>> };
>> bundler.increment();
>> end
>>
>>
>> 2011/9/9 Wolfgang Laun <wolfgang.laun(a)gmail.com>
>>
>>> Your rule exhibits procedural thinking. (For an aspiring rule programmer
>>> his is typical teething troubles.)
>>>
>>> There's no need to collect all A's and B's in order to determine
their
>>> number being greater than one or two - this is achieved automatically by a
>>> simple triple match rule. Consider
>>>
>>> rule "2A - 1B"
>>> when
>>> $a1: CartItem( productId == "A", processed == false )
>>> $a2: CartItem( this != $a1, productId == "A", processed == false
)
>>> $b: CartItem( productId == "B", processed == false )
>>> then
>>> modify( $a1 ){...}
>>> modify( $a2 ){...}
>>> modify( $b ){...}
>>> end
>>>
>>> Note:
>>>
>>> - The modify is essential. (When you say "doesn't work",
always
>>> provide details.)
>>> - Use the field name rather than the getter call - it improves
>>> readability.
>>> - I'm not sure whether 5.2.0 final handles boolean fields correctly
>>> - IIRC, there were some issues. It's possible that CartItem(...,
!processed)
>>> works.
>>>
>>> -W
>>>
>>> 2011/9/8 Sandeep Bandela <gibsosmat(a)gmail.com>
>>>
>>>> Hi,
>>>> I am new to rules engine, after going through the examples shipped
>>>> (shopping.drl, petstore.drl)
>>>> I am trying to implement promotional discounting using drools 5.2.0
>>>> final, stateful session. assume cart has all the items that customer
wants
>>>> to buy,
>>>> I am trying to bundle them together with the existing offers
>>>>
>>>> rule "Buy X units of Product A and Get Y units of Product B
Free"
>>>> dialect "java"
>>>> when
>>>> $itemsA : ArrayList( size >= 2) from collect( CartItem(
>>>> getProductId() == "A", !isProcessed()))
>>>> $itemsB : ArrayList( size >= 1) from collect( CartItem(
>>>> getProductId() == "B", !isProcessed()))
>>>> then
>>>> // current scenario buy 2*A and get 1*B
>>>> int x = 2;
>>>> int y = 1;
>>>> for(int i=0 ; i < x ; i++){
>>>> CartItem $ci = (CartItem) $itemsA.get(i);
>>>> // modify($ci){setProcessed(true) ... } dosent work
>>>> $ci.setProcessed(true);
>>>> $ci.setItemDiscount(0.0);
>>>> $ci.setBundleId(bundler.getId());
>>>> }
>>>>
>>>> for(int i=0 ; i < y ; i++){
>>>> CartItem $ci = (CartItem) $itemsB.get(i);
>>>> $ci.setProcessed(true);
>>>> $ci.setItemDiscount($ci.getPrice());
>>>> $ci.setBundleId(bundler.getId());
>>>> }
>>>> // global counter to identify bundled items
>>>> bundler.increment();
>>>> end
>>>>
>>>> the above rule calculates only for 1 set of offer i.e first 2*A &
1*B
>>>> are considered, rest in the cart are not bundled.
>>>> if customer buys 4*A + 2*B it dosent consider it. am I missing
>>>> anything? is this the right way to do it?
>>>> any feedback is appreciated.
>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Regards,
>>>> Sandeep Bandela.
>>>>
>>>>
>>>> _______________________________________________
>>>> rules-users mailing list
>>>> rules-users(a)lists.jboss.org
>>>>
https://lists.jboss.org/mailman/listinfo/rules-users
>>>>
>>>>
>>>
>>> _______________________________________________
>>> rules-users mailing list
>>> rules-users(a)lists.jboss.org
>>>
https://lists.jboss.org/mailman/listinfo/rules-users
>>>
>>>
>>
>>
>> --
>> Regards,
>> Sandeep Bandela.
>>
>>
>
>
> --
> Regards,
> Sandeep Bandela.
>
>
--
Regards,
Sandeep Bandela.
_______________________________________________
rules-users mailing list
rules-users(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users