some renaming of variables
All checks were successful
Build, test and publish / verify (push) Successful in 5m55s

This commit is contained in:
2026-11-03 12:58:15 +01:00
parent a7f7730ea0
commit 3a5203eb47
17 changed files with 98 additions and 54 deletions

View File

@@ -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.");
}
});
}

View File

@@ -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(

View File

@@ -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) {

View File

@@ -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));

View File

@@ -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.");
}
}

View File

@@ -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());

View File

@@ -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);

View File

@@ -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();
}