我在Optaweb(目前已停产)平台上工作,我有一个EmployeeAvailability
类,我可以定义startDateTime
和endDateTime
和状态(以下之一:UNAVAILABLE
,UNDESIRED
,DESIRED
)。然而,这些都是个别事件。我想要的是EmployeeAvailability
是一个循环的事件。我可以定义它的递归性(例如每周五),然后在计划班次时自动处理它。我该怎么做呢?我不是在寻找非常具体的说明,而是在更高层次上理解如何做到这一点。
现在,我试着通过在每个EmployeeAvailability
上设置一个标志isRecurring
来解决这个问题,然后当我计划下周时,我运行一个函数来复制所有EmployeeAvailability
与isRecurring == True
在过去的一周。这适用于每周循环,但它是一个相当手动的过程。
理想情况下,我希望:
- 能够定义任何复发模式(每周,每月,每天等)。也许我可以通过https://www.kanzaki.com/docs/ical/rrule.html 存储递归
- 数据库中没有单独的
EmployeeAvailability
对象,而是只有一个定义重复模式的对象。这个对象可以转换成单独的对象,当他们需要显示在前端或当他们需要解决由求解器?我不推荐这个:https://github.com/bmoeskau/Extensible/blob/master/recurrence-overview.md
一种方法是创建一个新类EmployeeAvailabilityPattern
,它有一个方法appliesToShift(Shift)
,如果Shift匹配可用性模式,该方法返回true,否则返回false。然后匹配EmployeeAvailabilityPattern
的约束看起来像这样:
private static BiConstraintStream<EmployeeAvailabilityPattern, Shift> getConstraintStreamWithAvailabilityPatternIntersections(
ConstraintFactory constraintFactory, EmployeeAvailabilityState employeeAvailabilityState) {
return constraintFactory.forEach(EmployeeAvailabilityPattern.class)
.filter(pattern -> pattern.getState() == employeeAvailabilityState)
.join(Shift.class,
equal(EmployeeAvailabilityPattern::getEmployee, Shift::getEmployee))
.filter((pattern, shift) -> pattern.appliesToShift(shift));
}
Constraint unavailablePatternEmployeeTimeSlot(ConstraintFactory constraintFactory) {
return getConstraintStreamWithAvailabilityPatternIntersections(constraintFactory, UNAVAILABLE)
.penalizeConfigurableLong(CONSTRAINT_UNAVAILABLE_TIME_SLOT_FOR_AN_EMPLOYEE,
((employeeAvailability, shift) -> shift.getLengthInMinutes()));
}