['absence_balance:read']], denormalizationContext: ['groups' => ['absence_balance:write']], )] #[ORM\Entity(repositoryClass: AbsenceBalanceRepository::class)] #[ORM\Table(name: 'absence_balance')] #[ORM\UniqueConstraint(name: 'uniq_absence_balance_user_type_period', columns: ['user_id', 'type', 'period'])] class AbsenceBalance { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column] #[Groups(['absence_balance:read'])] private ?int $id = null; #[ORM\ManyToOne(targetEntity: User::class)] #[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')] #[Groups(['absence_balance:read'])] private ?User $user = null; #[ORM\Column(type: Types::STRING, length: 32, enumType: AbsenceType::class)] #[Groups(['absence_balance:read'])] private AbsenceType $type; /** Reference period, e.g. "2025-2026" for paid leave or "2025" for yearly. */ #[ORM\Column(length: 16)] #[Groups(['absence_balance:read'])] private ?string $period = null; /** Days acquired during the *previous* reference period (Congés N-1): fully available to take. */ #[ORM\Column(type: Types::FLOAT)] #[Groups(['absence_balance:read', 'absence_balance:write'])] private float $acquired = 0.0; /** Days being accrued during the *current* reference period (Congés N): "en cours d'acquisition". */ #[ORM\Column(type: Types::FLOAT)] #[Groups(['absence_balance:read', 'absence_balance:write'])] private float $acquiring = 0.0; #[ORM\Column(type: Types::FLOAT)] #[Groups(['absence_balance:read', 'absence_balance:write'])] private float $taken = 0.0; /** Sum of days in PENDING requests, for information. */ #[ORM\Column(type: Types::FLOAT)] #[Groups(['absence_balance:read'])] private float $pending = 0.0; /** Last month (format YYYY-MM) for which the monthly accrual was applied. */ #[ORM\Column(length: 7, nullable: true)] private ?string $lastAccruedMonth = null; /** Total entitlement for the period, both finalized (N-1) and in-progress (N). */ #[Groups(['absence_balance:read'])] public function getAcquiredTotal(): float { return $this->acquired + $this->acquiring; } /** * Days the employee can still take: in this organisation the days being * accrued (N) are posable too, so they count towards what is available. */ #[Groups(['absence_balance:read'])] public function getAvailable(): float { return $this->acquired + $this->acquiring - $this->taken; } #[Groups(['absence_balance:read'])] public function getLabel(): string { return $this->type->label(); } public function getId(): ?int { return $this->id; } public function getUser(): ?User { return $this->user; } public function setUser(?User $user): static { $this->user = $user; return $this; } public function getType(): AbsenceType { return $this->type; } public function setType(AbsenceType $type): static { $this->type = $type; return $this; } public function getPeriod(): ?string { return $this->period; } public function setPeriod(string $period): static { $this->period = $period; return $this; } public function getAcquired(): float { return $this->acquired; } public function setAcquired(float $acquired): static { $this->acquired = $acquired; return $this; } public function getAcquiring(): float { return $this->acquiring; } public function setAcquiring(float $acquiring): static { $this->acquiring = $acquiring; return $this; } public function getTaken(): float { return $this->taken; } public function setTaken(float $taken): static { $this->taken = $taken; return $this; } public function getPending(): float { return $this->pending; } public function setPending(float $pending): static { $this->pending = $pending; return $this; } public function getLastAccruedMonth(): ?string { return $this->lastAccruedMonth; } public function setLastAccruedMonth(?string $lastAccruedMonth): static { $this->lastAccruedMonth = $lastAccruedMonth; return $this; } }