Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b5e7395760 | ||
| 380c72c242 | |||
|
|
107417a571 | ||
| 5ff7e356be |
@@ -1,2 +1,2 @@
|
||||
parameters:
|
||||
app.version: '0.1.14'
|
||||
app.version: '0.1.16'
|
||||
|
||||
@@ -427,8 +427,11 @@ export const useHoursPage = () => {
|
||||
|
||||
const getPresenceDayValue = (employeeId: number) => {
|
||||
const row = rows.value[employeeId]
|
||||
const basePresence = (row?.isPresentMorning ? 0.5 : 0) + (row?.isPresentAfternoon ? 0.5 : 0)
|
||||
const creditedPresence = dayContextByEmployeeId.value.get(employeeId)?.creditedPresenceUnits ?? 0
|
||||
const dayRow = dayContextByEmployeeId.value.get(employeeId)
|
||||
const absentMorning = dayRow?.absentMorning ?? false
|
||||
const absentAfternoon = dayRow?.absentAfternoon ?? false
|
||||
const basePresence = ((row?.isPresentMorning && !absentMorning) ? 0.5 : 0) + ((row?.isPresentAfternoon && !absentAfternoon) ? 0.5 : 0)
|
||||
const creditedPresence = dayRow?.creditedPresenceUnits ?? 0
|
||||
const total = Math.min(1, basePresence + creditedPresence)
|
||||
return Number.isInteger(total) ? String(total) : total.toFixed(1)
|
||||
}
|
||||
|
||||
@@ -60,11 +60,6 @@ final readonly class WorkedHoursCreditPolicy
|
||||
bool $absentMorning,
|
||||
bool $absentAfternoon
|
||||
): float {
|
||||
$type = $absence->getType();
|
||||
if (!$type?->getCountAsWorkedHours()) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
$employee = $absence->getEmployee();
|
||||
if (null === $employee) {
|
||||
return 0.0;
|
||||
@@ -74,9 +69,14 @@ final readonly class WorkedHoursCreditPolicy
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
$halfUnits = ($absentMorning ? 1 : 0) + ($absentAfternoon ? 1 : 0);
|
||||
// Règle forfait:
|
||||
// - demi-journée d'absence => 0.5 travaillé
|
||||
// - journée complète d'absence => 0 travaillé
|
||||
if ($absentMorning xor $absentAfternoon) {
|
||||
return 0.5;
|
||||
}
|
||||
|
||||
return $halfUnits * 0.5;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
public function resolveContractDayMinutes(?int $weeklyHours, int $isoWeekDay): int
|
||||
|
||||
@@ -125,6 +125,14 @@ final readonly class WorkHourBulkUpsertProcessor implements ProcessorInterface
|
||||
continue;
|
||||
}
|
||||
|
||||
// Si aucune donnée n'a changé, on ne touche pas la ligne:
|
||||
// cela évite de perdre les validations existantes (site/RH) sur un simple enregistrement.
|
||||
if (null !== $existing && $this->isSameAsExisting($existing, $normalized)) {
|
||||
++$result->processed;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->isEntryEmpty($normalized)) {
|
||||
// Convention choisie: une ligne vide supprime l'enregistrement existant.
|
||||
if ($existing) {
|
||||
|
||||
@@ -135,6 +135,8 @@ final readonly class WorkHourWeeklySummaryProvider implements ProviderInterface
|
||||
$creditedByEmployeeDate = [];
|
||||
$creditedPresenceByEmployeeDate = [];
|
||||
$absenceByEmployeeDate = [];
|
||||
$absentMorningByEmployeeDate = [];
|
||||
$absentAfternoonByEmployeeDate = [];
|
||||
$absenceLabelByEmployeeDate = [];
|
||||
$absenceColorByEmployeeDate = [];
|
||||
foreach ($absences as $absence) {
|
||||
@@ -153,7 +155,9 @@ final readonly class WorkHourWeeklySummaryProvider implements ProviderInterface
|
||||
|
||||
[$absentMorning, $absentAfternoon] = $this->absenceSegmentsResolver->resolveForDate($absence, $date);
|
||||
if ($absentMorning || $absentAfternoon) {
|
||||
$absenceByEmployeeDate[$employeeId][$date] = true;
|
||||
$absenceByEmployeeDate[$employeeId][$date] = true;
|
||||
$absentMorningByEmployeeDate[$employeeId][$date] = ($absentMorningByEmployeeDate[$employeeId][$date] ?? false) || $absentMorning;
|
||||
$absentAfternoonByEmployeeDate[$employeeId][$date] = ($absentAfternoonByEmployeeDate[$employeeId][$date] ?? false) || $absentAfternoon;
|
||||
if (!isset($absenceLabelByEmployeeDate[$employeeId][$date])) {
|
||||
$absenceLabelByEmployeeDate[$employeeId][$date] = $absence->getType()?->getLabel();
|
||||
}
|
||||
@@ -202,8 +206,10 @@ final readonly class WorkHourWeeklySummaryProvider implements ProviderInterface
|
||||
$metrics->addCreditedMinutes($creditedMinutes);
|
||||
$present = null;
|
||||
if ($isPresenceTracking) {
|
||||
$morning = ($entry['isPresentMorning'] ?? false) ? 0.5 : 0.0;
|
||||
$afternoon = ($entry['isPresentAfternoon'] ?? false) ? 0.5 : 0.0;
|
||||
$absentMorning = $absentMorningByEmployeeDate[$employeeId][$date] ?? false;
|
||||
$absentAfternoon = $absentAfternoonByEmployeeDate[$employeeId][$date] ?? false;
|
||||
$morning = (($entry['isPresentMorning'] ?? false) && !$absentMorning) ? 0.5 : 0.0;
|
||||
$afternoon = (($entry['isPresentAfternoon'] ?? false) && !$absentAfternoon) ? 0.5 : 0.0;
|
||||
$creditedPresence = $creditedPresenceByEmployeeDate[$employeeId][$date] ?? 0.0;
|
||||
$present = min(1.0, $morning + $afternoon + $creditedPresence);
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ final class WorkHourWeeklySummaryProviderTest extends TestCase
|
||||
self::assertSame(210, $result->rows[0]->weeklyOvertime50Minutes);
|
||||
self::assertSame(1230, $result->rows[0]->weeklyRecoveryMinutes);
|
||||
|
||||
self::assertSame(1.0, $result->rows[1]->weeklyPresenceCount);
|
||||
self::assertSame(0.0, $result->rows[1]->weeklyPresenceCount);
|
||||
self::assertTrue($result->rows[1]->daily[0]->hasAbsence);
|
||||
self::assertSame('Congé', $result->rows[1]->daily[0]->absenceLabel);
|
||||
self::assertSame('#000', $result->rows[1]->daily[0]->absenceColor);
|
||||
|
||||
Reference in New Issue
Block a user