7187989003
Auto Tag Develop / tag (push) Successful in 12s
Le libellé sous le nom de l'employé affiche en suffixe les jours du planning workDaysHours au format court (ex. BUREAU — CDI — LU,JE) pour les contrats CUSTOM. Résolu à la date filtrée et exposé via WorkHourDayContext.workDaysHours ; formaté front par formatWorkedDaysShort. Limité aux CUSTOM (35h/39h/forfait/intérim sans planning → rien affiché) et à l'écran Heures (pas Heures Conducteurs). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
137 lines
5.0 KiB
PHP
137 lines
5.0 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Dto\WorkHours;
|
|
|
|
final class DayContextRow
|
|
{
|
|
public function __construct(
|
|
public int $employeeId,
|
|
public bool $hasContractAtDate = true,
|
|
public ?string $absenceLabel = null,
|
|
public ?string $absenceColor = null,
|
|
public ?string $absenceHalf = null,
|
|
public bool $absentMorning = false,
|
|
public bool $absentAfternoon = false,
|
|
public int $creditedMinutes = 0,
|
|
public float $creditedPresenceUnits = 0.0,
|
|
public bool $isDriverContract = false,
|
|
public bool $hasFormation = false,
|
|
public ?string $formationLabel = null,
|
|
public int $virtualHolidayMinutes = 0,
|
|
public ?string $contractNature = null,
|
|
public ?string $trackingMode = null,
|
|
public ?int $weeklyHours = null,
|
|
public ?string $contractType = null,
|
|
public ?string $contractName = null,
|
|
/** @var null|array<int, int> iso day (1=Mon..5=Fri) → minutes, planning des jours travaillés (CUSTOM uniquement) */
|
|
public ?array $workDaysHours = null,
|
|
) {}
|
|
|
|
public function setFormation(string $label): void
|
|
{
|
|
$this->hasFormation = true;
|
|
$this->formationLabel = $label;
|
|
}
|
|
|
|
public function addAbsence(
|
|
?string $label,
|
|
?string $color,
|
|
bool $morning,
|
|
bool $afternoon,
|
|
int $creditedMinutes,
|
|
float $creditedPresenceUnits
|
|
): void {
|
|
// Fusionne plusieurs absences du même jour sur la ligne salarié.
|
|
$this->absentMorning = $this->absentMorning || $morning;
|
|
$this->absentAfternoon = $this->absentAfternoon || $afternoon;
|
|
|
|
// Garde un libellé lisible: unique si possible, sinon "Absences multiples".
|
|
if (null === $this->absenceLabel) {
|
|
$this->absenceLabel = $label;
|
|
} elseif ($label !== $this->absenceLabel) {
|
|
$this->absenceLabel = 'Absences multiples';
|
|
}
|
|
|
|
// Si plusieurs types d'absence différents sont fusionnés sur la même journée,
|
|
// on retire la couleur métier spécifique.
|
|
if (null === $this->absenceColor) {
|
|
$this->absenceColor = $color;
|
|
} elseif ($color !== $this->absenceColor) {
|
|
$this->absenceColor = null;
|
|
}
|
|
|
|
// AM/PM seulement pour les demi-journées, null pour journée complète.
|
|
$this->absenceHalf = $this->resolveHalfLabel($this->absentMorning, $this->absentAfternoon);
|
|
// Cumule les minutes créditées par les absences "comptées comme travaillées".
|
|
$this->creditedMinutes += $creditedMinutes;
|
|
// Cumule les unités de présence créditées (0.5 par demi-journée).
|
|
$this->creditedPresenceUnits += $creditedPresenceUnits;
|
|
}
|
|
|
|
/**
|
|
* @return array{
|
|
* employeeId:int,
|
|
* hasContractAtDate:bool,
|
|
* absenceLabel:?string,
|
|
* absenceColor:?string,
|
|
* absenceHalf:?string,
|
|
* absentMorning:bool,
|
|
* absentAfternoon:bool,
|
|
* creditedMinutes:int,
|
|
* creditedPresenceUnits:float,
|
|
* isDriverContract:bool,
|
|
* hasFormation:bool,
|
|
* formationLabel:?string,
|
|
* virtualHolidayMinutes:int,
|
|
* contractNature:?string,
|
|
* trackingMode:?string,
|
|
* weeklyHours:?int,
|
|
* contractType:?string,
|
|
* contractName:?string,
|
|
* workDaysHours:?array<int, int>
|
|
* }
|
|
*/
|
|
public function toArray(): array
|
|
{
|
|
return [
|
|
'employeeId' => $this->employeeId,
|
|
'hasContractAtDate' => $this->hasContractAtDate,
|
|
'absenceLabel' => $this->absenceLabel,
|
|
'absenceColor' => $this->absenceColor,
|
|
'absenceHalf' => $this->absenceHalf,
|
|
'absentMorning' => $this->absentMorning,
|
|
'absentAfternoon' => $this->absentAfternoon,
|
|
'creditedMinutes' => $this->creditedMinutes,
|
|
'creditedPresenceUnits' => $this->creditedPresenceUnits,
|
|
'isDriverContract' => $this->isDriverContract,
|
|
'hasFormation' => $this->hasFormation,
|
|
'formationLabel' => $this->formationLabel,
|
|
'virtualHolidayMinutes' => $this->virtualHolidayMinutes,
|
|
'contractNature' => $this->contractNature,
|
|
'trackingMode' => $this->trackingMode,
|
|
'weeklyHours' => $this->weeklyHours,
|
|
'contractType' => $this->contractType,
|
|
'contractName' => $this->contractName,
|
|
'workDaysHours' => $this->workDaysHours,
|
|
];
|
|
}
|
|
|
|
private function resolveHalfLabel(bool $morning, bool $afternoon): ?string
|
|
{
|
|
// Matin + après-midi => journée complète, pas de libellé AM/PM.
|
|
if ($morning && $afternoon) {
|
|
return null;
|
|
}
|
|
if ($morning) {
|
|
return 'AM';
|
|
}
|
|
if ($afternoon) {
|
|
return 'PM';
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|