I'm trying to add a new rule to the employee rostering example in optaplanner business central. A rule to check that if a shift is assigned to an employee outside of his schedule then lowers the hard constraint score holder.
package employeerostering.employeerostering;
rule "ShiftHoursWithinEmployeeSchedule"
dialect "mvel"
when
$shiftAssignment : ShiftAssignment( $employee : employee != null, $shiftEndDateTime : shift.timeslot.endTime, $shiftStartDate : shift.timeslot.startTime)
not Schedule ( day == $shiftEndDateTime.dayOfWeek.getValue() && (startTime > $shiftStartDateTime || endTime < $shiftEndDateTime) ) from $employee.schedules
then
scoreHolder.addHardConstraintMatch(kcontext, -1);
end
I'm new into DRL, i want to modify the second rule so it loops over all schedules of the $employee and checks if there isnt a single one that fulfills the condition.
I think you just need to flip the relational operators because you want to penalize a situation when there is no schedule such that the shift fits into the schedule:
not Schedule ( day == $shiftEndDateTime.dayOfWeek.getValue() && (
startTime < $shiftStartDateTime &&
endTime > $shiftEndDateTime)
) from $employee.schedules
Not sure what is the type of Schedule.startTime
. If it's a day time offset (e.g. 8:00) then you probably can't compare it to Timeslot.startTime
which is probably an absolute time amount (date + time).
I would recommend to reuse Timeslot
type in Schedule
instead of defining the schedule as day + time. Then you should be able to write:
rule "ShiftHoursWithinEmployeeSchedule"
dialect "mvel"
when
$shiftAssignment : ShiftAssignment( $employee : employee != null, $shiftEndDateTime : shift.timeslot.endTime, $shiftStartDate : shift.timeslot.startTime)
not Schedule ( timeslot.startTime > $shiftStartDateTime && timeslot.endTime < $shiftEndDateTime ) from $employee.schedules
then
scoreHolder.addHardConstraintMatch(kcontext, -1);
end