I have a RuleSetting
class that is a problem fact
. It stores the type which can be Soft
, Medium
, and Hard
. Based on it the rule type will be changed.
I have implemented the constraint stream as follows:
Constraint daysCountMoreThanMaximumNumberOfDaysInContractPerWeek(ConstraintFactory
constraintFactory) {
return constraintFactory.forEach(RuleSetting.class)
.filter(ruleSetting -> ruleSetting.getRuleName().equals("E005")&& ruleSetting.getIsActive() == true)
.join(Shift.class)
.filter((ruleSetting, shift) -> shift.getEmployee().getContracts().getMaxDaysPerWeek() != null && shift.getEmployee().getContracts().getMaxDaysPerWeek() > 0)
.groupBy((ruleSetting, shift)->ruleSetting,
(ruleSetting, shift)->shift.getEmployee(),
(ruleSetting, shift)->shift.getWeekNo(),
ConstraintCollectors.countBi())
.filter((ruleSetting, employee, weekNo, noDays) -> noDays > employee.getContracts().getMaxDaysPerWeek())
.penalize(HardMediumSoftScore.ONE_SOFT
// This section is hardcoded to SOFT, I would like to make it dynamic.
// Like ruleSetting.getType().equals("Soft") ? HardMediumSoftScore.ONE_SOFT: HardMediumSoftScore.ONE_HARD
, (ruleSetting, employee, weekNo, noDays)->{
return (int)Math.abs(((double)ruleSetting.getWeight() * (double)noDays / (double) employee.getContracts().getMaxDaysPerWeek()));
})
.indictWith((ruleSetting, employee, weekNo, noDays) ->{
EmployeeScoreKeyItems res = new EmployeeScoreKeyItems(EmployeeScoreKeyItems.KeyType.BY_WEEK,
ruleSetting.getRuleName(),
employee.getEmployeeId(),
null, null, weekNo, null);
return List.of(res);
})
.asConstraint("Days Count More Than Maximum Number Of Days In Contract Per Week");
}
Please recommended the way of solution. I would prefer not to use the Configurable
option. But if there is no way, then may be I have to use that option.
This is exactly why @ConstraintConfiguration
, @ConstraintWeight
and penalizeConfigurable()
were created.
By using those, you won't even pay for the performance cost of the constraint streams of that constraint when the constraint weight is zero.