From a966648a7e3e1865c74d34ed43b95e879820e689 Mon Sep 17 00:00:00 2001 From: dipatrik10 Date: Tue, 2 Jun 2026 00:24:57 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A1=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB=20=D0=BE?= =?UTF-8?q?=D0=B1=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA=D1=83=20=D0=BD=D0=B0?= =?UTF-8?q?=20=D0=92=D0=95=20=D0=BA=D0=BE=D0=BD=D1=84=D0=BB=D0=B8=D0=BA?= =?UTF-8?q?=D1=82=D0=BD=D1=8B=D1=85=20=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ScheduleRuleAdminController.java | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/backend/src/main/java/com/magistr/app/controller/ScheduleRuleAdminController.java b/backend/src/main/java/com/magistr/app/controller/ScheduleRuleAdminController.java index b0624b4..e00dddd 100644 --- a/backend/src/main/java/com/magistr/app/controller/ScheduleRuleAdminController.java +++ b/backend/src/main/java/com/magistr/app/controller/ScheduleRuleAdminController.java @@ -6,6 +6,7 @@ import com.magistr.app.dto.ScheduleRuleSlotDto; import com.magistr.app.model.*; import com.magistr.app.repository.*; import com.magistr.app.service.ScheduleGeneratorService; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; @@ -81,6 +82,13 @@ public class ScheduleRuleAdminController { try { ScheduleRule rule = new ScheduleRule(); applyRule(rule, request); + ScheduleRule conflictRule = findConflictingRule(request, rule.getSlots(), null); + if (conflictRule != null) { + return ResponseEntity.status(HttpStatus.CONFLICT).body(Map.of( + "message", "Невозможно сохранить правило: слот занят", + "conflictRule", toDto(conflictRule) + )); + } ScheduleRule saved = scheduleRuleRepository.save(rule); scheduleGeneratorService.clearCache(); return ResponseEntity.ok(toDto(saved)); @@ -104,6 +112,13 @@ public class ScheduleRuleAdminController { try { applyRule(rule, request); + ScheduleRule conflictRule = findConflictingRule(request, rule.getSlots(), rule.getId()); + if (conflictRule != null) { + return ResponseEntity.status(HttpStatus.CONFLICT).body(Map.of( + "message", "Невозможно сохранить правило: слот занят", + "conflictRule", toDto(conflictRule) + )); + } ScheduleRule saved = scheduleRuleRepository.save(rule); scheduleGeneratorService.clearCache(); return ResponseEntity.ok(toDto(saved)); @@ -181,6 +196,37 @@ public class ScheduleRuleAdminController { rule.getSlots().addAll(slots); } + private ScheduleRule findConflictingRule(ScheduleRuleDto request, Collection newSlots, Long excludeRuleId) { + return scheduleRuleRepository.findAllWithDetails().stream() + .filter(rule -> !Objects.equals(rule.getId(), excludeRuleId)) + .filter(rule -> rule.getSemester() != null && Objects.equals(rule.getSemester().getId(), request.semesterId())) + .filter(rule -> hasSlotConflict(newSlots, rule.getSlots())) + .min(Comparator.comparing(ScheduleRule::getId)) + .orElse(null); + } + + private boolean hasSlotConflict(Collection newSlots, Collection existingSlots) { + for (ScheduleRuleSlot newSlot : newSlots) { + for (ScheduleRuleSlot existingSlot : existingSlots) { + if (sameTimeSlot(newSlot, existingSlot) && sameTeacherOrClassroom(newSlot, existingSlot)) { + return true; + } + } + } + return false; + } + + private boolean sameTimeSlot(ScheduleRuleSlot first, ScheduleRuleSlot second) { + return Objects.equals(first.getDayOfWeek(), second.getDayOfWeek()) + && Objects.equals(first.getParity(), second.getParity()) + && Objects.equals(first.getTimeSlot().getId(), second.getTimeSlot().getId()); + } + + private boolean sameTeacherOrClassroom(ScheduleRuleSlot first, ScheduleRuleSlot second) { + return Objects.equals(first.getTeacher().getId(), second.getTeacher().getId()) + || Objects.equals(first.getClassroom().getId(), second.getClassroom().getId()); + } + private ScheduleRuleSlot buildSlot(ScheduleRule rule, ScheduleRuleSlotDto slotDto) { if (slotDto.dayOfWeek() == null || slotDto.dayOfWeek() < 1 || slotDto.dayOfWeek() > 7) { throw new IllegalArgumentException("День недели должен быть от 1 до 7");