feat : notification de fin de contrat (veille ouvrée du dernier jour) #35
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Service\Notification;
|
||||
|
||||
use App\Service\PublicHolidayServiceInterface;
|
||||
use DateTimeImmutable;
|
||||
use Throwable;
|
||||
|
||||
final readonly class WorkingDayCalculator
|
||||
{
|
||||
public function __construct(
|
||||
private PublicHolidayServiceInterface $holidays,
|
||||
) {}
|
||||
|
||||
public function isWorkingDay(DateTimeImmutable $date): bool
|
||||
{
|
||||
$dayOfWeek = (int) $date->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')]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Tests\Service\Notification;
|
||||
|
||||
use App\Service\Notification\WorkingDayCalculator;
|
||||
use App\Service\PublicHolidayServiceInterface;
|
||||
use DateTimeImmutable;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class WorkingDayCalculatorTest extends TestCase
|
||||
{
|
||||
public function testWeekdayIsWorkingDay(): void
|
||||
{
|
||||
// Mardi 08/07/2025
|
||||
self::assertTrue($this->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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user