some renaming of variables
All checks were successful
Build, test and publish / verify (push) Successful in 5m55s
All checks were successful
Build, test and publish / verify (push) Successful in 5m55s
This commit is contained in:
@@ -14,7 +14,7 @@ public final class ScheduleRules {
|
||||
public static List<String> violations(final SchedulingInput input, final List<List<Long>> parts) {
|
||||
final List<String> errors = new ArrayList<>();
|
||||
if (input.dayParts() == 0 || input.preferredDayParts() < 1 || input.preferredDayParts() > input.dayParts()) {
|
||||
errors.add("Configure dayparts and x between 1 and the number of dayparts.");
|
||||
errors.add("Configure dayparts and preferredDayParts between 1 and the number of dayparts.");
|
||||
}
|
||||
if (parts == null || parts.size() != input.dayParts() || parts.stream().anyMatch(java.util.Objects::isNull)) {
|
||||
errors.add("Assignments must contain one list for every daypart.");
|
||||
@@ -86,7 +86,7 @@ public final class ScheduleRules {
|
||||
|
||||
private static void attendance(
|
||||
final SchedulingInput input, final List<List<Long>> parts, final List<String> errors) {
|
||||
final Set<Long> exempt = new HashSet<>(input.coachIds());
|
||||
final Set<Long> exempt = new HashSet<>(input.coachDancerIds());
|
||||
input.groups().stream()
|
||||
.filter(GroupRequirement::showcase)
|
||||
.forEach((final GroupRequirement g) -> exempt.addAll(g.dancerIds()));
|
||||
@@ -96,7 +96,8 @@ public final class ScheduleRules {
|
||||
}
|
||||
attendance.forEach((final Long dancer, final Set<Integer> dayparts) -> {
|
||||
if (!exempt.contains(dancer) && dayparts.size() > input.preferredDayParts()) {
|
||||
errors.add("Dancer " + dancer + " exceeds x=" + input.preferredDayParts() + " dayparts.");
|
||||
errors.add(
|
||||
"Dancer " + dancer + " exceeds preferredDayParts=" + input.preferredDayParts() + " dayparts.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,16 +3,21 @@ package nl.agilecc.agiledancers.model.scheduling;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Immutable solver snapshot.
|
||||
*
|
||||
* @param coachDancerIds dancer registration IDs linked to coaches, used for participation exemptions
|
||||
*/
|
||||
public record SchedulingInput(
|
||||
long showId,
|
||||
long revision,
|
||||
int dayParts,
|
||||
List<GroupRequirement> groups,
|
||||
int preferredDayParts,
|
||||
Set<Long> coachIds) {
|
||||
Set<Long> coachDancerIds) {
|
||||
public SchedulingInput {
|
||||
groups = List.copyOf(groups);
|
||||
coachIds = Set.copyOf(coachIds);
|
||||
coachDancerIds = Set.copyOf(coachDancerIds);
|
||||
}
|
||||
|
||||
public SchedulingInput(
|
||||
|
||||
@@ -26,7 +26,7 @@ public final class SchedulingInputs {
|
||||
}
|
||||
|
||||
public static SchedulingInput of(final DanceSchool school, final Show show, final long revision) {
|
||||
final int x = preferred(show);
|
||||
final int preferredDayParts = preferred(show);
|
||||
final LocalDate date = show.getDayParts().stream()
|
||||
.map(DayPart::getDate)
|
||||
.min(LocalDate::compareTo)
|
||||
@@ -40,7 +40,8 @@ public final class SchedulingInputs {
|
||||
.filter(java.util.Objects::nonNull)
|
||||
.map(Dancer::getId)
|
||||
.collect(Collectors.toSet());
|
||||
return new SchedulingInput(show.getId(), revision, show.getDayParts().size(), groups, x, coaches);
|
||||
return new SchedulingInput(
|
||||
show.getId(), revision, show.getDayParts().size(), groups, preferredDayParts, coaches);
|
||||
}
|
||||
|
||||
private static GroupRequirement requirement(final DanceGroup group, final Show show, final LocalDate date) {
|
||||
|
||||
@@ -60,7 +60,8 @@ public class SchoolManagementService {
|
||||
"Scheduling requires at least one school group and one daypart.");
|
||||
}
|
||||
if (SchedulingInputs.preferred(show) > show.getDayParts().size()) {
|
||||
throw new ManagementException(ManagementExceptionKind.INVALID_INPUT, "Correct x before scheduling.");
|
||||
throw new ManagementException(
|
||||
ManagementExceptionKind.INVALID_INPUT, "Correct preferredDayParts before scheduling.");
|
||||
}
|
||||
running.add(showId);
|
||||
return SchedulingInputs.of(school(schoolId), show, revisions.getOrDefault(showId, 0L));
|
||||
|
||||
@@ -21,25 +21,26 @@ public class ShowSchedules {
|
||||
this.schools = schools;
|
||||
}
|
||||
|
||||
/** Retains assignments by date/type; removing dayparts may retain an invalid x in the draft. */
|
||||
/** Retains assignments by date/type; removing dayparts may retain an invalid preferredDayParts in the draft. */
|
||||
public Show configure(final long schoolId, final Long showId, final Show settings) {
|
||||
synchronized (schools) {
|
||||
ShowConfiguration.validateParts(settings.getDayParts());
|
||||
final Show existing = showId == null ? null : schools.show(schoolId, showId);
|
||||
final int x = settings.getPreferredDayParts() == null
|
||||
final int preferredDayParts = settings.getPreferredDayParts() == null
|
||||
? (existing == null
|
||||
? (settings.getDayParts().size() == 1 ? 1 : 2)
|
||||
: SchedulingInputs.preferred(existing))
|
||||
: settings.getPreferredDayParts();
|
||||
validateX(x, existing, settings.getDayParts().size());
|
||||
validatePreferredDayParts(
|
||||
preferredDayParts, existing, settings.getDayParts().size());
|
||||
final Show show = existing == null
|
||||
? schools.createShow(schoolId, settings.getName(), settings.getDayParts(), null)
|
||||
: existing;
|
||||
final boolean changed = x != SchedulingInputs.preferred(show)
|
||||
final boolean changed = preferredDayParts != SchedulingInputs.preferred(show)
|
||||
|| !keys(show.getDayParts()).equals(keys(settings.getDayParts()));
|
||||
show.setDayParts(ShowConfiguration.retainAssignments(show, settings.getDayParts()));
|
||||
show.setName(settings.getName());
|
||||
show.setPreferredDayParts(x);
|
||||
show.setPreferredDayParts(preferredDayParts);
|
||||
if (changed) {
|
||||
schools.touch(show);
|
||||
}
|
||||
@@ -53,13 +54,16 @@ public class ShowSchedules {
|
||||
.toList();
|
||||
}
|
||||
|
||||
private static void validateX(final int x, final Show existing, final int parts) {
|
||||
if (x < 1
|
||||
|| x > 6
|
||||
|| (parts > 0 && x > parts && (existing == null || x != SchedulingInputs.preferred(existing)))) {
|
||||
private static void validatePreferredDayParts(final int preferredDayParts, final Show existing, final int parts) {
|
||||
if (preferredDayParts < 1
|
||||
|| preferredDayParts > 6
|
||||
|| (parts > 0
|
||||
&& preferredDayParts > parts
|
||||
&& (existing == null || preferredDayParts != SchedulingInputs.preferred(existing)))) {
|
||||
throw new ManagementException(
|
||||
ManagementExceptionKind.INVALID_INPUT,
|
||||
"x must be between 1 and the number of dayparts. Retained x must be corrected before scheduling.");
|
||||
"preferredDayParts must be between 1 and the number of dayparts. Retained preferredDayParts must"
|
||||
+ " be corrected before scheduling.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -205,8 +205,9 @@ public record SchoolSnapshot(
|
||||
.build());
|
||||
}
|
||||
ShowConfiguration.validateParts(parts);
|
||||
final int x = show.preferredDayParts() == null ? (parts.size() == 1 ? 1 : 2) : show.preferredDayParts();
|
||||
check(x >= 1 && x <= 6, "x moet tussen 1 en 6 liggen");
|
||||
final int preferredDayParts =
|
||||
show.preferredDayParts() == null ? (parts.size() == 1 ? 1 : 2) : show.preferredDayParts();
|
||||
check(preferredDayParts >= 1 && preferredDayParts <= 6, "preferredDayParts moet tussen 1 en 6 liggen");
|
||||
final Show entity = Show.builder()
|
||||
.name(show.name())
|
||||
.dayParts(parts)
|
||||
@@ -214,7 +215,7 @@ public record SchoolSnapshot(
|
||||
show.appearances() == null
|
||||
? ShowConfiguration.defaults(parts.size())
|
||||
: Map.copyOf(show.appearances()))
|
||||
.preferredDayParts(x)
|
||||
.preferredDayParts(preferredDayParts)
|
||||
.finalized(false)
|
||||
.build();
|
||||
entity.setId((long) showIds.size());
|
||||
|
||||
@@ -24,7 +24,7 @@ public final class SchedulingObjectives {
|
||||
input.groups().stream()
|
||||
.filter(GroupRequirement::showcase)
|
||||
.forEach((final GroupRequirement g) -> showcases.addAll(g.dancerIds()));
|
||||
dancers.removeAll(input.coachIds());
|
||||
dancers.removeAll(input.coachDancerIds());
|
||||
final LinearExprBuilder penalty = LinearExpr.newBuilder();
|
||||
for (final long dancer : dancers) {
|
||||
final IntVar[] parts = dancerParts(model, input, vars, dancer);
|
||||
|
||||
@@ -40,11 +40,11 @@ class S18LifecycleTest {
|
||||
.toList();
|
||||
}
|
||||
|
||||
private Show settings(final int n, final Integer x) {
|
||||
private Show settings(final int n, final Integer preferredDayParts) {
|
||||
return Show.builder()
|
||||
.name("Show")
|
||||
.dayParts(parts(n))
|
||||
.preferredDayParts(x)
|
||||
.preferredDayParts(preferredDayParts)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user