I have got followed structure:
public class Proposal {
private final List<Product> products;
private final List<Customer> customers;
}
public class Customer {
private String id;
private String country;
}
public class Product {
private String customerId;
private String country;
private String type;
}
the requirements are: Don't check if the product type is "A" or "B" and for customer with id: 21. For any other products check if customerId match with id or if the customer country is set to null and the country on the product is set to 'US'
Based on that I prepared a rule but it does not work as it should:
//rule body
Proposal($products: products, $customers: customers)
$productsToChecks : Product(customerId != "21") && type not in ("A", "B") from $products
//first condition to check if there is any applicable case:
exist(Product(customerId != "21") && type not in ("A", "B") from $products) and
(
// check if there is a customer who can use this product
forall (
Product($customerId: customerId, $country: country) from $productsToChecks
Customer(id == $customerId || (country == null && $country == "US"))
)
)
Thank you for any help or advice
You have a syntax error in your
$productsToChecksdeclaration:Both of the attributes you're checking need to be inside of the
Product( ... )part like this:You repeat this error in other parts of the rule as well.
So your requirements are:
We can distill this to the following pseudo-code:
Given the 'OR' in the second part, this is two rules.
The first part we need to do is find the subset of products that we care about. You can do this in a number of ways --
collectoraccumulateare the two that immediately come to mind. Assuming that the requirements in your question are complete,collectis more appropriate here (and simpler).Now you can use that subset of products (which don't include the ones you need to ignore) to match your other criteria. As I mentioned, since those criteria are OR'd, they should be two distinct rules.
To cut down on the duplicate code, you can pull the common conditions into a single 'parent' rule and then use the
extendskeyword to create the two child rules with their distinct conditions.I designed these rules in this way under the assumption that you want to do some action against each of the products that meets your criteria. Based on this assumption, the right hand side will trigger for each product that matches the criteria of each rule (also note that since the two rules are not exclusive, products might trigger twice if the customerId matches and the country requirements are satisfied.)
However if all you want as the result is a list of all products that meets the criteria, you can again use a function to obtain that list of products. In this case, the
accumulatefunction more appropriate thancollect: