feat : ajout des suspensions et des jours de présence
Some checks failed
Auto Tag Develop / tag (push) Has been cancelled
Some checks failed
Auto Tag Develop / tag (push) Has been cancelled
This commit is contained in:
77
src/Service/Leave/SuspensionDaysCalculator.php
Normal file
77
src/Service/Leave/SuspensionDaysCalculator.php
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Service\Leave;
|
||||
|
||||
use App\Entity\ContractSuspension;
|
||||
use DateTimeImmutable;
|
||||
|
||||
final class SuspensionDaysCalculator
|
||||
{
|
||||
/**
|
||||
* Count calendar days suspended within a month window [monthStart, monthEnd].
|
||||
*
|
||||
* @param list<ContractSuspension> $suspensions
|
||||
*/
|
||||
public function countSuspendedDaysInMonth(
|
||||
DateTimeImmutable $monthStart,
|
||||
DateTimeImmutable $monthEnd,
|
||||
array $suspensions
|
||||
): int {
|
||||
$total = 0;
|
||||
|
||||
foreach ($suspensions as $suspension) {
|
||||
$sStart = $suspension->getStartDate();
|
||||
$sEnd = $suspension->getEndDate() ?? $monthEnd;
|
||||
|
||||
$overlapStart = $sStart > $monthStart ? $sStart : $monthStart;
|
||||
$overlapEnd = $sEnd < $monthEnd ? $sEnd : $monthEnd;
|
||||
|
||||
if ($overlapStart > $overlapEnd) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$total += ((int) $overlapEnd->diff($overlapStart)->format('%a')) + 1;
|
||||
}
|
||||
|
||||
return $total;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count business days (Mon-Fri, excl. public holidays) suspended within a period.
|
||||
*
|
||||
* @param list<ContractSuspension> $suspensions
|
||||
* @param array<string, string> $publicHolidays map of Y-m-d => label
|
||||
*/
|
||||
public function countSuspendedBusinessDays(
|
||||
DateTimeImmutable $periodStart,
|
||||
DateTimeImmutable $periodEnd,
|
||||
array $suspensions,
|
||||
array $publicHolidays
|
||||
): int {
|
||||
$total = 0;
|
||||
|
||||
foreach ($suspensions as $suspension) {
|
||||
$sStart = $suspension->getStartDate();
|
||||
$sEnd = $suspension->getEndDate() ?? $periodEnd;
|
||||
|
||||
$overlapStart = $sStart > $periodStart ? $sStart : $periodStart;
|
||||
$overlapEnd = $sEnd < $periodEnd ? $sEnd : $periodEnd;
|
||||
|
||||
if ($overlapStart > $overlapEnd) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for ($cursor = $overlapStart; $cursor <= $overlapEnd; $cursor = $cursor->modify('+1 day')) {
|
||||
$weekDay = (int) $cursor->format('N');
|
||||
$dayKey = $cursor->format('Y-m-d');
|
||||
if ($weekDay <= 5 && !isset($publicHolidays[$dayKey])) {
|
||||
++$total;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $total;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user