diff --git a/src/Service/Notification/WorkingDayCalculator.php b/src/Service/Notification/WorkingDayCalculator.php new file mode 100644 index 0000000..314546f --- /dev/null +++ b/src/Service/Notification/WorkingDayCalculator.php @@ -0,0 +1,47 @@ +format('N'); // 1 (lundi) .. 7 (dimanche) + if ($dayOfWeek >= 6) { + return false; + } + + return !$this->isPublicHoliday($date); + } + + public function nextWorkingDay(DateTimeImmutable $date): DateTimeImmutable + { + $candidate = $date->modify('+1 day')->setTime(0, 0, 0); + while (!$this->isWorkingDay($candidate)) { + $candidate = $candidate->modify('+1 day'); + } + + return $candidate; + } + + private function isPublicHoliday(DateTimeImmutable $date): bool + { + try { + $holidays = $this->holidays->getHolidaysDayByYears('metropole', $date->format('Y')); + } catch (Throwable) { + return false; + } + + return isset($holidays[$date->format('Y-m-d')]); + } +} diff --git a/tests/Service/Notification/WorkingDayCalculatorTest.php b/tests/Service/Notification/WorkingDayCalculatorTest.php new file mode 100644 index 0000000..5d98dba --- /dev/null +++ b/tests/Service/Notification/WorkingDayCalculatorTest.php @@ -0,0 +1,62 @@ +calculator()->isWorkingDay(new DateTimeImmutable('2025-07-08'))); + } + + public function testSaturdayAndSundayAreNotWorkingDays(): void + { + self::assertFalse($this->calculator()->isWorkingDay(new DateTimeImmutable('2025-07-12'))); // samedi + self::assertFalse($this->calculator()->isWorkingDay(new DateTimeImmutable('2025-07-13'))); // dimanche + } + + public function testPublicHolidayIsNotWorkingDay(): void + { + self::assertFalse($this->calculator()->isWorkingDay(new DateTimeImmutable('2025-07-14'))); // lundi férié + } + + public function testNextWorkingDayFromWeekdayIsTomorrow(): void + { + // Mardi 08/07 -> Mercredi 09/07 + self::assertSame( + '2025-07-09', + $this->calculator()->nextWorkingDay(new DateTimeImmutable('2025-07-08'))->format('Y-m-d') + ); + } + + public function testNextWorkingDayFromFridaySkipsWeekend(): void + { + // Vendredi 11/07 -> lundi 14/07 est férié -> mardi 15/07 + self::assertSame( + '2025-07-15', + $this->calculator()->nextWorkingDay(new DateTimeImmutable('2025-07-11'))->format('Y-m-d') + ); + } + + private function calculator(): WorkingDayCalculator + { + $holidays = $this->createStub(PublicHolidayServiceInterface::class); + $holidays->method('getHolidaysDayByYears')->willReturn([ + // Lundi 14/07/2025 férié + '2025-07-14' => 'Fête nationale', + ]); + + return new WorkingDayCalculator($holidays); + } +}