Compare commits

..

3 Commits

Author SHA1 Message Date
gitea-actions
c35edb9a1c chore: bump version to v0.1.36
All checks were successful
Auto Tag Develop / tag (push) Successful in 4s
Build Release Artefact / build (push) Successful in 1m15s
2026-03-13 11:24:19 +00:00
4b04be1d1b Merge remote-tracking branch 'origin/develop' into develop
Some checks failed
Auto Tag Develop / tag (push) Has been cancelled
2026-03-13 12:24:11 +01:00
b24dd8595d fix : calcule des jours de présence + SiteFilterSelector.vue 2026-03-13 12:23:55 +01:00
4 changed files with 66 additions and 10 deletions

View File

@@ -1,2 +1,2 @@
parameters:
app.version: '0.1.35'
app.version: '0.1.36'

View File

@@ -14,7 +14,7 @@
<div
v-if="isOpen"
class="absolute left-0 top-full z-20 mt-2 max-h-80 w-full overflow-auto rounded-md border border-neutral-200 bg-white p-3 shadow-lg"
class="z-50 absolute left-0 top-full z-20 mt-2 max-h-80 w-full overflow-auto rounded-md border border-neutral-200 bg-white p-3 shadow-lg"
>
<div class="flex flex-col gap-2">
<label

View File

@@ -191,6 +191,43 @@ final class WorkHourRepository extends ServiceEntityRepository implements WorkHo
return $result;
}
/**
* Return the set of Y-m-d dates where the employee has worked hours on the given dates.
*
* @param list<string> $dates Y-m-d formatted dates
*
* @return array<string, true> Y-m-d => true
*/
public function findWorkedDatesAmong(Employee $employee, array $dates): array
{
if ([] === $dates) {
return [];
}
$placeholders = [];
$params = ['employee' => $employee->getId()];
foreach (array_values($dates) as $i => $date) {
$key = "d{$i}";
$placeholders[] = ":{$key}";
$params[$key] = $date;
}
$sql = sprintf(
'SELECT work_date FROM work_hours WHERE employee_id = :employee AND work_date IN (%s) AND (morning_from IS NOT NULL OR afternoon_from IS NOT NULL OR evening_from IS NOT NULL)',
implode(', ', $placeholders)
);
$conn = $this->getEntityManager()->getConnection();
$rows = $conn->fetchAllAssociative($sql, $params);
$result = [];
foreach ($rows as $row) {
$result[(string) $row['work_date']] = true;
}
return $result;
}
public function hasPendingSiteValidationForSiteAndDate(int $siteId, DateTimeInterface $date): bool
{
$workDate = DateTimeImmutable::createFromInterface($date);

View File

@@ -565,16 +565,34 @@ final readonly class EmployeeLeaveSummaryProvider implements ProviderInterface
$weekendWorkedDays = $this->workHourRepository->countWeekendWorkedDaysByMonth($employee, $from, $to);
$absences = $this->absenceRepository->findByEmployeeAndOverlappingDateRange($employee, $from, $to);
// Count absence days per month (0.5 for half-days).
// Find which public holidays were actually worked (should count as presence).
$workedHolidays = [] !== $publicHolidays
? $this->workHourRepository->findWorkedDatesAmong($employee, array_keys($publicHolidays))
: [];
// Count absence days per month, iterating day by day to handle multi-day absences
// and properly distribute across months.
$absenceDaysByMonth = [];
foreach ($absences as $absence) {
$date = DateTimeImmutable::createFromInterface($absence->getStartDate());
$monthKey = $date->format('Y-m');
$days = 1.0;
if ($absence->getStartHalf() === $absence->getEndHalf()) {
$days = 0.5;
$start = DateTimeImmutable::createFromInterface($absence->getStartDate())->setTime(0, 0);
$end = DateTimeImmutable::createFromInterface($absence->getEndDate())->setTime(0, 0);
for ($day = $start; $day <= $end; $day = $day->modify('+1 day')) {
$weekDay = (int) $day->format('N');
// Skip weekends
if ($weekDay >= 6) {
continue;
}
$monthKey = $day->format('Y-m');
[$am, $pm] = $this->resolveSegmentsForDate($absence, $day->format('Y-m-d'));
$dayAmount = ($am ? 0.5 : 0.0) + ($pm ? 0.5 : 0.0);
if ($dayAmount <= 0.0) {
continue;
}
$absenceDaysByMonth[$monthKey] = ($absenceDaysByMonth[$monthKey] ?? 0.0) + $dayAmount;
}
$absenceDaysByMonth[$monthKey] = ($absenceDaysByMonth[$monthKey] ?? 0.0) + $days;
}
// Count business days and public holidays per month.
@@ -595,7 +613,8 @@ final readonly class EmployeeLeaveSummaryProvider implements ProviderInterface
$day = $day->modify('+1 day')
) {
$weekDay = (int) $day->format('N');
if ($weekDay <= 5 && !isset($publicHolidays[$day->format('Y-m-d')])) {
$dayKey = $day->format('Y-m-d');
if ($weekDay <= 5 && (!isset($publicHolidays[$dayKey]) || isset($workedHolidays[$dayKey]))) {
++$businessDays;
}
}