Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8563ddb08c | ||
| 353d4d9d2b | |||
|
|
8745e5e425 | ||
| 4d8c850a77 | |||
| 1974ace1f2 |
@@ -1,2 +1,2 @@
|
||||
parameters:
|
||||
app.version: '0.1.48'
|
||||
app.version: '0.1.50'
|
||||
|
||||
@@ -212,12 +212,14 @@ Tous les filtres checkbox sont cochés par défaut à l'ouverture du drawer.
|
||||
- en cours d'acquisition jours: `25/12 = 2,08` jours/mois
|
||||
- en cours d'acquisition samedis: `5/12 = 0,42` samedi/mois (non detaille en UI)
|
||||
- en cas de début/fin en cours de mois, l'acquisition est proratisée au nombre de jours calendaires couverts dans le mois
|
||||
- en cas de suspension en cours de mois, l'acquisition est proratisée en jours ouvrés (lun-ven hors fériés) travaillés / 22 (standard mensuel)
|
||||
- samedis acquis affiches: uniquement `opening_saturdays` (report N-1)
|
||||
- contrat `4h`:
|
||||
- acquis annuel CP: `10`
|
||||
- acquis annuel samedi: `0`
|
||||
- en cours d'acquisition: `0.83` jour/mois
|
||||
- en cas de début/fin en cours de mois, l'acquisition est proratisée au nombre de jours calendaires couverts dans le mois
|
||||
- en cas de suspension en cours de mois, l'acquisition est proratisée en jours ouvrés (lun-ven hors fériés) travaillés / 22
|
||||
- contrat `FORFAIT`:
|
||||
- base annuelle: `jours ouvrés de l'exercice (lundi-vendredi, hors jours fériés métropole) - 218`
|
||||
- prorata: en cas de démarrage/fin de contrat en cours d'année civile, le calcul ne couvre que l'intervalle actif du contrat dans l'année
|
||||
|
||||
@@ -1045,7 +1045,7 @@ export const useHoursPage = () => {
|
||||
isSubmitting.value = true
|
||||
try {
|
||||
const entries = employees.value
|
||||
.filter((employee) => hasContractAtSelectedDate(employee.id))
|
||||
.filter((employee) => hasContractAtSelectedDate(employee.id) && !isRowLocked(employee.id))
|
||||
.map((employee) => {
|
||||
const employeeId = employee.id
|
||||
const row = rows.value[employeeId] ?? emptyRow()
|
||||
|
||||
@@ -278,10 +278,11 @@ final readonly class LeaveBalanceComputationService
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
$periodStart = $this->normalizeDate($periodStart);
|
||||
$periodEnd = $this->normalizeDate($periodEnd);
|
||||
$coveredMonths = 0.0;
|
||||
$cursor = $periodStart->modify('first day of this month')->setTime(0, 0);
|
||||
$periodStart = $this->normalizeDate($periodStart);
|
||||
$periodEnd = $this->normalizeDate($periodEnd);
|
||||
$publicHolidays = [] !== $suspensions ? $this->buildPublicHolidayMap($periodStart, $periodEnd) : [];
|
||||
$coveredMonths = 0.0;
|
||||
$cursor = $periodStart->modify('first day of this month')->setTime(0, 0);
|
||||
while ($cursor <= $periodEnd) {
|
||||
$monthStart = $cursor > $periodStart ? $cursor : $periodStart;
|
||||
$monthEnd = $cursor->modify('last day of this month')->setTime(0, 0);
|
||||
@@ -289,11 +290,19 @@ final readonly class LeaveBalanceComputationService
|
||||
$monthEnd = $periodEnd;
|
||||
}
|
||||
|
||||
$coveredDays = ((int) $monthEnd->diff($monthStart)->format('%a')) + 1;
|
||||
if ([] !== $suspensions) {
|
||||
$suspendedDays = $this->suspensionDaysCalculator->countSuspendedDaysInMonth($monthStart, $monthEnd, $suspensions);
|
||||
$coveredDays = max(0, $coveredDays - $suspendedDays);
|
||||
if ($suspendedDays > 0) {
|
||||
$businessDays = $this->countBusinessDaysInRange($monthStart, $monthEnd, $publicHolidays);
|
||||
$suspendedBusinessDays = $this->suspensionDaysCalculator->countSuspendedBusinessDays($monthStart, $monthEnd, $suspensions, $publicHolidays);
|
||||
$coveredMonths += max(0, $businessDays - $suspendedBusinessDays) / 22.0;
|
||||
$cursor = $cursor->modify('first day of next month');
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$coveredDays = ((int) $monthEnd->diff($monthStart)->format('%a')) + 1;
|
||||
$daysInMonth = (int) $cursor->format('t');
|
||||
$coveredMonths += $coveredDays / $daysInMonth;
|
||||
|
||||
@@ -317,8 +326,15 @@ final readonly class LeaveBalanceComputationService
|
||||
|
||||
private function countBusinessDays(DateTimeImmutable $from, DateTimeImmutable $to): int
|
||||
{
|
||||
$publicHolidays = $this->buildPublicHolidayMap($from, $to);
|
||||
$count = 0;
|
||||
return $this->countBusinessDaysInRange($from, $to, $this->buildPublicHolidayMap($from, $to));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, string> $publicHolidays pre-built map
|
||||
*/
|
||||
private function countBusinessDaysInRange(DateTimeImmutable $from, DateTimeImmutable $to, array $publicHolidays): int
|
||||
{
|
||||
$count = 0;
|
||||
for ($cursor = $from; $cursor <= $to; $cursor = $cursor->modify('+1 day')) {
|
||||
$weekDay = (int) $cursor->format('N');
|
||||
$dayKey = $cursor->format('Y-m-d');
|
||||
|
||||
@@ -390,10 +390,11 @@ final readonly class EmployeeLeaveSummaryProvider implements ProviderInterface
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
$periodStart = $this->normalizeDate($periodStart);
|
||||
$periodEnd = $this->normalizeDate($periodEnd);
|
||||
$coveredMonths = 0.0;
|
||||
$cursor = $periodStart->modify('first day of this month')->setTime(0, 0);
|
||||
$periodStart = $this->normalizeDate($periodStart);
|
||||
$periodEnd = $this->normalizeDate($periodEnd);
|
||||
$publicHolidays = [] !== $suspensions ? $this->buildPublicHolidayMap($periodStart, $periodEnd) : [];
|
||||
$coveredMonths = 0.0;
|
||||
$cursor = $periodStart->modify('first day of this month')->setTime(0, 0);
|
||||
while ($cursor <= $periodEnd) {
|
||||
$monthStart = $cursor > $periodStart ? $cursor : $periodStart;
|
||||
$monthEnd = $cursor->modify('last day of this month')->setTime(0, 0);
|
||||
@@ -401,11 +402,19 @@ final readonly class EmployeeLeaveSummaryProvider implements ProviderInterface
|
||||
$monthEnd = $periodEnd;
|
||||
}
|
||||
|
||||
$coveredDays = ((int) $monthEnd->diff($monthStart)->format('%a')) + 1;
|
||||
if ([] !== $suspensions) {
|
||||
$suspendedDays = $this->suspensionDaysCalculator->countSuspendedDaysInMonth($monthStart, $monthEnd, $suspensions);
|
||||
$coveredDays = max(0, $coveredDays - $suspendedDays);
|
||||
if ($suspendedDays > 0) {
|
||||
$businessDays = $this->countBusinessDays($monthStart, $monthEnd, $publicHolidays);
|
||||
$suspendedBusinessDays = $this->suspensionDaysCalculator->countSuspendedBusinessDays($monthStart, $monthEnd, $suspensions, $publicHolidays);
|
||||
$coveredMonths += max(0, $businessDays - $suspendedBusinessDays) / 22.0;
|
||||
$cursor = $cursor->modify('first day of next month');
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$coveredDays = ((int) $monthEnd->diff($monthStart)->format('%a')) + 1;
|
||||
$daysInMonth = (int) $cursor->format('t');
|
||||
$coveredMonths += $coveredDays / $daysInMonth;
|
||||
|
||||
@@ -526,10 +535,13 @@ final readonly class EmployeeLeaveSummaryProvider implements ProviderInterface
|
||||
];
|
||||
}
|
||||
|
||||
private function countBusinessDays(DateTimeImmutable $from, DateTimeImmutable $to): int
|
||||
/**
|
||||
* @param null|array<string, string> $publicHolidays pre-built map (built if null)
|
||||
*/
|
||||
private function countBusinessDays(DateTimeImmutable $from, DateTimeImmutable $to, ?array $publicHolidays = null): int
|
||||
{
|
||||
$publicHolidays = $this->buildPublicHolidayMap($from, $to);
|
||||
$count = 0;
|
||||
$publicHolidays ??= $this->buildPublicHolidayMap($from, $to);
|
||||
$count = 0;
|
||||
for ($cursor = $from; $cursor <= $to; $cursor = $cursor->modify('+1 day')) {
|
||||
$weekDay = (int) $cursor->format('N');
|
||||
$dayKey = $cursor->format('Y-m-d');
|
||||
|
||||
Reference in New Issue
Block a user