findLessonType($tenantId, (int) $payload['lesson_type_id']); $warnings = [ 'conflicts' => [], 'rest_period_warnings' => [], ]; $conflicts = $appointmentRepository->overlappingForInstructor( $tenantId, (int) $payload['instructor_id'], $payload['start_at'], $payload['end_at'], $appointmentId ); foreach ($conflicts as $conflict) { $warnings['conflicts'][] = [ 'type' => 'instructor_overlap', 'message' => 'Fahrlehrer ist in diesem Zeitraum bereits verplant.', 'appointment_id' => (int) $conflict['id'], ]; } if (!empty($payload['student_id'])) { $studentConflicts = $appointmentRepository->overlappingForStudent( $tenantId, (int) $payload['student_id'], $payload['start_at'], $payload['end_at'], $appointmentId ); foreach ($studentConflicts as $conflict) { $warnings['conflicts'][] = [ 'type' => 'student_overlap', 'message' => 'Fahrschueler ist in diesem Zeitraum bereits verplant.', 'appointment_id' => (int) $conflict['id'], ]; } } if ($lessonType !== null && (int) $lessonType['is_rest_relevant'] === 1) { $newStart = new DateTimeImmutable($payload['start_at']); $dayStart = $newStart->setTime(0, 0, 0); $dayEnd = $dayStart->modify('+1 day'); $hasLaterRelevantOnDay = $appointmentRepository->hasRestRelevantAfterStartOnDay( $tenantId, (int) $payload['instructor_id'], $dayStart->format(DATE_ATOM), $dayEnd->format(DATE_ATOM), $payload['start_at'] ); if ($hasLaterRelevantOnDay) { return $warnings; } $lastRelevant = $appointmentRepository->lastRestRelevantForInstructor( $tenantId, (int) $payload['instructor_id'], $payload['start_at'], $appointmentId ); if ($lastRelevant !== null) { $restEnds = (new DateTimeImmutable($lastRelevant['end_at']))->add(new DateInterval('PT11H')); if ($newStart < $restEnds) { $warnings['rest_period_warnings'][] = [ 'type' => 'rest_period', 'message' => 'Achtung: Dieser Termin liegt innerhalb der 11-Stunden-Ruhezeit.', 'rest_until' => $restEnds->format(DATE_ATOM), 'blocking_appointment_id' => (int) $lastRelevant['id'], ]; } } } return $warnings; } }