diff --git a/backend/src/Scolarite/Application/Command/UpdateRecurringSlot/UpdateRecurringSlotHandler.php b/backend/src/Scolarite/Application/Command/UpdateRecurringSlot/UpdateRecurringSlotHandler.php index 8af3366..5252660 100644 --- a/backend/src/Scolarite/Application/Command/UpdateRecurringSlot/UpdateRecurringSlotHandler.php +++ b/backend/src/Scolarite/Application/Command/UpdateRecurringSlot/UpdateRecurringSlotHandler.php @@ -117,7 +117,12 @@ final readonly class UpdateRecurringSlotHandler $slot->terminerRecurrenceLe($dayBefore, $now); $this->slotRepository->save($slot); - // Create new slot starting from the occurrence date + // Use the Monday of the occurrence week as recurrenceStart so the new slot + // is visible in the current week even when moved to an earlier day-of-week. + $dayN = (int) $occurrenceDate->format('N'); + $weekMonday = $occurrenceDate->modify('-' . ($dayN - 1) . ' days'); + + // Create new slot starting from the Monday of the occurrence week $newSlot = ScheduleSlot::creer( tenantId: $tenantId, classId: ClassId::fromString($command->classId), @@ -128,7 +133,7 @@ final readonly class UpdateRecurringSlotHandler room: $command->room, isRecurring: true, now: $now, - recurrenceStart: $occurrenceDate, + recurrenceStart: $weekMonday, recurrenceEnd: $originalRecurrenceEnd, ); diff --git a/backend/tests/Unit/Scolarite/Application/Command/UpdateRecurringSlot/UpdateRecurringSlotHandlerTest.php b/backend/tests/Unit/Scolarite/Application/Command/UpdateRecurringSlot/UpdateRecurringSlotHandlerTest.php index 45d6a91..a0f56e5 100644 --- a/backend/tests/Unit/Scolarite/Application/Command/UpdateRecurringSlot/UpdateRecurringSlotHandlerTest.php +++ b/backend/tests/Unit/Scolarite/Application/Command/UpdateRecurringSlot/UpdateRecurringSlotHandlerTest.php @@ -119,6 +119,41 @@ final class UpdateRecurringSlotHandlerTest extends TestCase self::assertTrue($result['newSlot']->teacherId->equals(UserId::fromString(self::NEW_TEACHER_ID))); } + #[Test] + public function allFutureCrossDayMoveSetsRecurrenceStartToWeekMonday(): void + { + // Wednesday slot — moving it to Monday + $slot = $this->createAndSaveSlot( + dayOfWeek: DayOfWeek::WEDNESDAY, + recurrenceStart: new DateTimeImmutable('2026-09-01'), + recurrenceEnd: new DateTimeImmutable('2027-07-04'), + ); + + $command = new UpdateRecurringSlotCommand( + tenantId: self::TENANT_ID, + slotId: (string) $slot->id, + occurrenceDate: '2026-10-14', // Wednesday + scope: 'all_future', + classId: self::CLASS_ID, + subjectId: self::SUBJECT_ID, + teacherId: self::TEACHER_ID, + dayOfWeek: DayOfWeek::MONDAY->value, + startTime: '08:00', + endTime: '09:00', + room: null, + updatedBy: self::UPDATER_ID, + ); + + $result = ($this->handler)($command); + + $newSlot = $result['newSlot']; + self::assertNotNull($newSlot); + self::assertSame(DayOfWeek::MONDAY, $newSlot->dayOfWeek); + // recurrenceStart must be the Monday of the occurrence week (2026-10-12), + // not the occurrence date (2026-10-14), so the slot is visible this week + self::assertSame('2026-10-12', $newSlot->recurrenceStart->format('Y-m-d')); + } + #[Test] public function allFutureWithNoOriginalEndUsesNullForNewSlotEnd(): void { @@ -149,6 +184,7 @@ final class UpdateRecurringSlotHandlerTest extends TestCase } private function createAndSaveSlot( + DayOfWeek $dayOfWeek = DayOfWeek::MONDAY, ?DateTimeImmutable $recurrenceStart = null, ?DateTimeImmutable $recurrenceEnd = null, ): ScheduleSlot { @@ -157,7 +193,7 @@ final class UpdateRecurringSlotHandlerTest extends TestCase classId: ClassId::fromString(self::CLASS_ID), subjectId: SubjectId::fromString(self::SUBJECT_ID), teacherId: UserId::fromString(self::TEACHER_ID), - dayOfWeek: DayOfWeek::MONDAY, + dayOfWeek: $dayOfWeek, timeSlot: new TimeSlot('08:00', '09:00'), room: null, isRecurring: true,