2016-10-20 66 views
0

我是Drools的新手。想问一个关于条件元素的问题。我有一些类,下面的UML图显示了这些对象之间的关系: UML diagramforall总是评估为真[Drools 6.3 final]

一个订单有一个客户并有一个订单行列表。 每个订单行链接到一个项目。坦率地说,这是一本关于Drools的书的示例代码。

Iwant火以下规则时的订单的客户是银类别和订单的所有项目都在高范围(成本高),以建立订单的折扣。这里是规则:

rule "Silver Customers + High Range Order - 10% Discount -1" 
when 

    $o: Order($lines : orderLines.size >= 2, $customer: customer, discount == null) 
    $c: Customer(category == Category.SILVER, this == $customer) 
    forall(OrderLine(this memberOf $lines, $item : item) 
      Item(this == $item, category == Item.Category.HIGH_RANGE) 
    ) 
then 
    $o.setDiscount(new Discount(10.0)); 
    update($o); 
end 

的问题是规则始终闪光,甚至当我试图插入一个为了在低范围内5个项目。

在调试信息我发现的第一个项目的类别是LOW_RANGE但规则仍解雇:

==>[BeforeActivationFiredEvent: getActivation()=[[ Silver Customers + High Range Order - 10% Discount active=false ] [ null 
[fact 0:1:1561745898:141057847:1:DEFAULT:NON_TRAIT:org.drools.devguide.eshop.model.Customer:Customer [id = null, age=null, email=null, name=null, category = SILVER]] 
[fact 0:12:1971991758:-345298280:12:DEFAULT:NON_TRAIT:org.drools.devguide.eshop.model.Order:Order [ id = null, customer=Customer [id = null, age=null, email=null, name=null, category = SILVER], date=Fri Oct 21 11:11:38 CST 2016, lines=[OrderLine [item=Item{id=1, name=A, cost=80.0, salePrice=800.0, category=LOW_RANGE}, quantity=1], OrderLine [item=Item{id=1, name=B, cost=800.0, salePrice=850.0, category=HIGH_RANGE}, quantity=2], OrderLine [item=Item{id=1, name=C, cost=800.0, salePrice=850.0, category=HIGH_RANGE}, quantity=3], OrderLine [item=Item{id=1, name=D, cost=800.0, salePrice=850.0, category=HIGH_RANGE}, quantity=4], OrderLine [item=Item{id=1, name=E, cost=800.0, salePrice=850.0, category=HIGH_RANGE}, quantity=5]], state=PENDING, discount=null]] ] ], getKnowledgeRuntime()=KieSession[0]] 
------------------- 
rule triggered:Silver Customers + High Range Order - 10% Discount 
==>[AfterActivationFiredEvent: getActivation()=[[ Silver Customers + High Range Order - 10% Discount active=false ] [ null 
[fact 0:1:1561745898:141057847:1:DEFAULT:NON_TRAIT:org.drools.devguide.eshop.model.Customer:Customer [id = null, age=null, email=null, name=null, category = SILVER]] 
[fact 0:12:1971991758:-345298280:18:DEFAULT:NON_TRAIT:org.drools.devguide.eshop.model.Order:Order [ id = null, customer=Customer [id = null, age=null, email=null, name=null, category = SILVER], date=Fri Oct 21 11:11:38 CST 2016, lines=[OrderLine [item=Item{id=1, name=A, cost=80.0, salePrice=800.0, category=LOW_RANGE}, quantity=1], OrderLine [item=Item{id=1, name=B, cost=800.0, salePrice=850.0, category=HIGH_RANGE}, quantity=2], OrderLine [item=Item{id=1, name=C, cost=800.0, salePrice=850.0, category=HIGH_RANGE}, quantity=3], OrderLine [item=Item{id=1, name=D, cost=800.0, salePrice=850.0, category=HIGH_RANGE}, quantity=4], OrderLine [item=Item{id=1, name=E, cost=800.0, salePrice=850.0, category=HIGH_RANGE}, quantity=5]], state=PENDING, discount=10.0 % ]] ] ], getKnowledgeRuntime()=KieSession[0]] 

我已经阅读了问题的答案:forall always evaluates to be true [Drools]。我尝试了解决方案,但我得到了另一个错误的结果,下面的规则永远不会触发,即使我用所有高范围项目的订单:

rule "Silver Customers + High Range Order - 10% Discount" 
when 

    $o: Order($lines : orderLines.size >= 2, discount == null) 
    $c: Customer(category == Category.SILVER) from $o.customer 
    forall(OrderLine() from $o.orderLines 
      OrderLine(item.category == Item.Category.HIGH_RANGE) 
    ) 
then 
    $o.setDiscount(new Discount(10.0)); 
    update($o); 
end 

的单元测试代码如下:

@Test 
public void highRangeOrderDiscountTest() { 
    KieSession kSession = createDefaultSession(); 

    Order o = ModelFactory.getOrderWithFiveHighRangeItems(); 

    kSession.insert(o.getCustomer()); 
    kSession.insert(o.getOrderLines().get(0)); 
    kSession.insert(o.getOrderLines().get(1)); 
    kSession.insert(o.getOrderLines().get(2)); 
    kSession.insert(o.getOrderLines().get(3)); 
    kSession.insert(o.getOrderLines().get(4)); 
    kSession.insert(o.getOrderLines().get(0).getItem()); 
    kSession.insert(o.getOrderLines().get(1).getItem()); 
    kSession.insert(o.getOrderLines().get(2).getItem()); 
    kSession.insert(o.getOrderLines().get(3).getItem()); 
    kSession.insert(o.getOrderLines().get(4).getItem()); 
    kSession.insert(o); 

    int fired = kSession.fireAllRules(); 

    // We have 5 Items that are categorized -> 5 rules were fired 
    // We have 1 Customer that needs to be categorized -> 1 rule fired 
    // We have just one order with all HIGH RAnge items -> 1 rule fired 
    // One Coupon is created for the SILVER Customer -> 1 rule fired 
    assertThat(8, is(fired)); 
    assertThat(o.getCustomer().getCategory(), is(Customer.Category.SILVER)); 
    assertThat(o.getDiscount(), not(nullValue())); 
    assertThat(o.getDiscount().getPercentage(), is(10.0)); 


} 
} 

你能告诉我原因或告诉我正确的用法?非常感谢。

回答

0

这建立了一组OrderLine-s,然后确定所有都属于高范围项目。 (注:未经测试)

rule "Silver Customers + High Range Order - 10% Discount" 
when 
    $c: Customer(category == Category.SILVER) 
    $o: Order($lines : orderLines.size >= 2, customer == $c, 
       discount == null) 
    forall(OrderLine($item : item) from $lines 
      Item(this == $item, category == Item.Category.HIGH_RANGE)) 
then 
    modify($o){ setDiscount(new Discount(10.0)) } 
end 

所有Customer和Item对象必须作为事实插入; OrderLine-s也是合理的。

+0

感谢您的回答。我试过你的解决方案仍然解雇了低范围物品的规则。 – bigMichael2017