Make rule on drolls to check subdata - drools

I have a package. Package includes a list of items. Item has a list of fields. I need to check if specific fields are set to correct value for all items in a package:
rule "Slapper"
dialect "mvel"
when
itm : item( ) from pkg.items
List( size() == itm.size() ) from collect (
field( fieldId == "111" , value == "1" ) from itm.fields
field( fieldId == "222" , value == "2" ) from itm.fields
) from itm
then
...
end
how I can get collection filtered by subfields?

Need to use accumulate function:
List( size == pkg.items.size() ) from accumulate (
$a: itemData( $field1: fields, $field2: fields ) from pkg.items
and
fieldData( fieldId == "111" , value == "1" ) from $field1
and
fieldData( fieldId == "222" , value == "2" ) from $field2;
collectList( $a )
)

Related

Convert date in jsonb (Postgres)

I have jsonb column data =
"{"history": [{"endDate": "30.06.2015", "classname": "Class A", "startDate": "2010-04-01", "numberAction": "0016", "positionName": "Teacher"},
{"endDate": "31.06.2010", "classname": "Class A", "startDate": "2005-08-10", "numberAction": "0015", "positionName": "Student"},
{"endDate": "2005.08.09", "classname": "Class B", "startDate": "2005-02-21", "numberAction": "0014", "positionName": " Student "}]}"
As you can see, the dates of the "endDate" in the array are not correct. Please tell me how they can be converted to the format YYYY-MM-DD?
My idle attempt:
UPDATE table
SET data = jsonb_set(data, '{endDate}', to_date('{endDate}', 'YYYY-MM-DD'), false)
WHERE id = 'UUID';
Answer =
update table
set data = data - 'history' ||
jsonb_build_object
( 'history'
, ( select jsonb_agg
( case when aa.value ->> 'endDate' like '%.%' then
aa.value - 'endDate' || jsonb_build_object
( 'endDate'
, to_date(aa.value ->> 'endDate','dd.mm.yyyy')
)
else
aa.value
end
)
from jsonb_array_elements(data -> 'history') as aa
)
)
WHERE uuid = 'UUID'
and exists ( select *
from jsonb_array_elements(data -> 'history') as aa
where aa.value ->> 'endDate' like '%.%'
);

drools not exists in collection

I need to fire a rule if a collection does not have a specific object.
AuditAssignment is available as problem fact.
AuditAssignment has a property "requiredSkill"
Audit Assignment has a property "auditor"
Auditor object has a list of "qualifications" which is a collection of "requiredSkill "
Now , I need to check , if the qualifications of the auditor in the auditassignment object has the requiredSkill
Below is sample rule which I tried but does not work .
rule "checkIfAuditSkillIsMatching"
when
$auditAssignment : AuditAssignment( $neededSkill : requiredSkill.getSkillCode())
$auditor : Auditor( $auditorSkills : qualifications)
not exists ( Skill ( skillCode == $neededSkill ) from $auditorSkills )
then
System.out.println( " **** " + $neededSkill);
scoreHolder.addHardConstraintMatch(kcontext, -1 );
end
I have tried the below one as well
rule "checkIfAuditSkillIsMatching"
when
$validAuditorCount : Number ( intValue < 1 ) from accumulate (
$auditor : Auditor( $auditorSkills: qualifications )
and exists AuditAssignment( auditor == $auditor ,
$auditorSkills.contains(requiredSkill) ) ,
count($auditor)
)
then
scoreHolder.addHardConstraintMatch(kcontext, -1 );
end
Here it is advisable to use a property method of Collection to obtain the logical value you need.
rule "checkIfAuditSkillIsMatching"
when
$auditAssignment: AuditAssignment( $neededSkill: requiredSkill.getSkillCode() )
$auditor: Auditor( $auditorSkills: qualifications,
! $auditorSkills.contains( $neededSkill ) )
then
//...no suitably qualified auditor
end
The below configuration worked
rule "checkIfAuditSkillIsMatching"
when
$auditAssignment : AuditAssignment( $neededSkill : requiredSkill ,
$assignedAuditor : auditor )
$auditor : Auditor( this == $assignedAuditor , !qualifications.contains($neededSkill) )
then
scoreHolder.addHardConstraintMatch(kcontext, -1 );
end

Using OR in the WHEN conditions in DROOLS

I have a problem with a rule in Drools.
In a drl file i have a rule:
rule ""
when
$g: class1( $tm: list1 )
$p: class2() from $tm
$ph: class3(isEnd==false, $s: steps) from $p.list2
$st: Step(isEnd==false ) from $s
then
----
end
I want a OR with the 3th and 4th conditions.
How can i do it?
Try this - I haven't tested it:
rule "xxx"
when
$g: class1( $tm: list1 )
$p: class2() from $tm
( class3(isEnd==false ) from $p.list2
or
( $ph: class3(isEnd==true ) from $p.list2
and
Step(isEnd==false ) from $ph.getSteps() )
)
then
----
end

Crystal Reports Multiple if conditions in Record Selection

I want to create a report and filter it by two parameters as below;
Parameter values are;
Call_type = "All" , "Sale" , "Buy"
and
Call_status = "All" , "Sold" , "Pending" , "None" , "Closed"
I have used below formula;
(
if {?type} <> "All" then
{cars_call_log.type} = {?type}
else
true;
);
(
if {?status} <> "All" then
{cars_call_log.status} = {?status}
else
true;
);
But it will work only for first If condition. It doesn't work for both conditions.
I want to make it like, Filter by first parameter then (filtered records)--> filter by second parameter.
The proper, record-selection-formula syntax for your needs:
(
if {?type} <> "All" then
{cars_call_log.type} = {?type}
else
true
)
AND
(
if {?status} <> "All" then
{cars_call_log.status} = {?status}
else
true
)

Selecting a set of three distinct objects

Drools Planner used this to select two distinct objects, ensuring that a rule did not fire twice for a given pair of objects. If o1 and o2 made a match, it fired only once, not twice for (o1,o2) and (o2,01).
when
$stp1 : SubjectTeacherPeriod( $slno : slNo,
$id : id,
$period_day_order : period.dayOrder
)
$stp2 : SubjectTeacherPeriod( slNo > $slno,
id == $id,
period.dayOrder == $period_day_order
)
How do I select a set of three distinct objects? What is a good selection criteria for that?
Same approach should work:
$f1 : SomeFact( ... )
$f2 : SomeFact( id > $f1.id, ... )
$f3 : SomeFact( id > $f2.id, ... )