Как назначить сотрудников с множественной доступностью в списке сотрудников Opta Planner?
У меня есть список из 10 сотрудников и 10 смен в приложении для составления списка сотрудников Opta-web, из этих десяти сотрудников у двоих есть две возможности: одна соответствует времени смены, а другая нет.
Мое предположение заключалось в том, что следует назначить всех десяти сотрудников, поскольку есть по крайней мере один доступный срок, соответствующий времени смены. Но это не назначение этих двух сотрудников с несколькими доступностями.
вот мой файл правил
// ############################################################################
// Hard constraints
// ############################################################################
rule "Unavailable time slot for an employee"
when
$availability: EmployeeAvailability(
$e : employee,
$employeeName : employee.getName(),
$startDateTime : startDateTime,
$endDateTime : endDateTime)
Shift(employee == $e,
!DateTimeUtils.doTimeslotsMatch($startDateTime,$endDateTime, startDateTime, endDateTime, $employeeName))
then
scoreHolder.penalize(kcontext, 100);
end
rule "No overlapping shifts"
when
$s : Shift(employee != null, $e : employee, $firstStartDateTime: startDateTime, $firstEndDateTime : endDateTime)
$s2: Shift(employee == $e, this != $s,
DateTimeUtils.doTimeslotsMatch($firstStartDateTime,$firstEndDateTime, startDateTime, endDateTime, $e.getName()))
then
scoreHolder.penalize(kcontext, $s2.getLengthInMinutes());
end
// ############################################################################
// Medium constraints
// ############################################################################
rule "Assign every shift"
when
Shift(employee == null)
then
scoreHolder.penalize(kcontext);
end
// ############################################################################
// Soft constraints
// ############################################################################
rule "Desired time slot for an employee"
when
$availability: EmployeeAvailability(
$e : employee,
$employeeName : employee.getName(),
$startDateTime : startDateTime,
$endDateTime : endDateTime)
Shift(employee == $e,
DateTimeUtils.doTimeslotsMatch($startDateTime,$endDateTime, startDateTime, endDateTime, $employeeName))
then
scoreHolder.reward(kcontext, 100);
end
вот метод doTimeslotsMatch, добавленный для случая точного совпадения
// added method for exact match case
public static boolean doTimeslotsMatch(OffsetDateTime empStart, OffsetDateTime empEnd, OffsetDateTime shiftStart,
OffsetDateTime shiftEnd, String empName) {
if ((empStart.getDayOfMonth() == shiftStart.getDayOfMonth()) &&
empEnd.getDayOfMonth() == shiftEnd.getDayOfMonth()) {
if ((empStart.isBefore(shiftStart) || empStart.isEqual(shiftStart)) &&
(empEnd.isAfter(shiftEnd) || empEnd.isEqual(shiftEnd))) {
log.debug("emp {} startTime {} endTime {} match with shift: startTime {} endTime {}", empName, empStart, empEnd, shiftStart, shiftEnd);
return true;
}
}
log.debug("emp {} , emp: startTime {} endTime {} not match with shift: startTime {} endTime {}", empName, empStart, empEnd, shiftStart, shiftEnd);
return false;
}