feat(absence) : migrate Absence domain into module (back)
LST-66 (2.3) backend. Behaviour-preserving move of the absences domain into
src/Module/Absence/. API operations, securities, routes and the 10 MCP tool
names are unchanged.
- 3 entities + 3 enums moved to Domain/{Entity,Enum}; user relations stay on
UserInterface. 3 repositories split into Domain/Repository interfaces +
Doctrine impls (bound in services.yaml); find() kept off interfaces
(findById instead).
- Pure services (AbsenceDayCalculator, PublicHolidayProvider) -> Domain/Service;
AbsenceBalanceService -> Application/Service; State (5), controllers (5),
10 MCP tools and AccrueLeaveCommand -> Infrastructure/.
- New LeaveProfileInterface contract (Shared) exposes the HR getters used by
AbsenceBalanceService/AccrueLeaveCommand; User implements it -> Absence no
longer imports the concrete Core User. MCP tools/command inject
UserRepositoryInterface (findById) instead of the concrete repository.
- Timestampable/Blamable added to AbsenceBalance and AbsencePolicy (additive
migration: created_at/updated_at + created_by/updated_by FK ON DELETE SET
NULL + COMMENT). AbsenceRequest untouched (already has createdAt/reviewedAt).
- AbsenceModule registered (id absence, 4 RBAC perms, not re-wired); doctrine
mapping added; team-absences sidebar item gated by the module.
161 tests green, mapping valid, no API route regression, cs-fixer clean.
This commit is contained in:
@@ -1,209 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use ApiPlatform\Metadata\ApiResource;
|
||||
use ApiPlatform\Metadata\Get;
|
||||
use ApiPlatform\Metadata\GetCollection;
|
||||
use ApiPlatform\Metadata\Patch;
|
||||
use App\Enum\AbsenceType;
|
||||
use App\Repository\AbsenceBalanceRepository;
|
||||
use App\Shared\Domain\Contract\UserInterface;
|
||||
use App\State\AbsenceBalanceProvider;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Serializer\Attribute\Groups;
|
||||
|
||||
/**
|
||||
* Per-employee, per-type leave balance for a given reference period.
|
||||
*/
|
||||
#[ApiResource(
|
||||
operations: [
|
||||
new GetCollection(
|
||||
paginationEnabled: false,
|
||||
security: "is_granted('ROLE_USER')",
|
||||
provider: AbsenceBalanceProvider::class,
|
||||
),
|
||||
new Get(
|
||||
security: "is_granted('ROLE_USER')",
|
||||
provider: AbsenceBalanceProvider::class,
|
||||
),
|
||||
new Patch(security: "is_granted('ROLE_ADMIN')"),
|
||||
],
|
||||
normalizationContext: ['groups' => ['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: UserInterface::class)]
|
||||
#[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')]
|
||||
#[Groups(['absence_balance:read'])]
|
||||
private ?UserInterface $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(): ?UserInterface
|
||||
{
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
public function setUser(?UserInterface $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;
|
||||
}
|
||||
}
|
||||
@@ -1,171 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use ApiPlatform\Metadata\ApiResource;
|
||||
use ApiPlatform\Metadata\Get;
|
||||
use ApiPlatform\Metadata\GetCollection;
|
||||
use ApiPlatform\Metadata\Patch;
|
||||
use App\Enum\AbsenceType;
|
||||
use App\Repository\AbsencePolicyRepository;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Serializer\Attribute\Groups;
|
||||
|
||||
/**
|
||||
* Per-type configuration of absence rules. Overrides the legal defaults and
|
||||
* lets an admin tune days/year, days/event, notice period, etc.
|
||||
*/
|
||||
#[ApiResource(
|
||||
operations: [
|
||||
new GetCollection(
|
||||
paginationEnabled: false,
|
||||
security: "is_granted('ROLE_USER')",
|
||||
),
|
||||
new Get(security: "is_granted('ROLE_USER')"),
|
||||
new Patch(security: "is_granted('ROLE_ADMIN')"),
|
||||
],
|
||||
normalizationContext: ['groups' => ['absence_policy:read']],
|
||||
denormalizationContext: ['groups' => ['absence_policy:write']],
|
||||
order: ['type' => 'ASC'],
|
||||
)]
|
||||
#[ORM\Entity(repositoryClass: AbsencePolicyRepository::class)]
|
||||
#[ORM\Table(name: 'absence_policy')]
|
||||
#[ORM\UniqueConstraint(name: 'uniq_absence_policy_type', columns: ['type'])]
|
||||
class AbsencePolicy
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column]
|
||||
#[Groups(['absence_policy:read'])]
|
||||
private ?int $id = null;
|
||||
|
||||
#[ORM\Column(type: Types::STRING, length: 32, enumType: AbsenceType::class)]
|
||||
#[Groups(['absence_policy:read', 'absence_balance:read', 'absence_request:read'])]
|
||||
private AbsenceType $type;
|
||||
|
||||
/** Yearly entitlement (e.g. 25 for paid leave); null when not relevant. */
|
||||
#[ORM\Column(type: Types::FLOAT, nullable: true)]
|
||||
#[Groups(['absence_policy:read', 'absence_policy:write'])]
|
||||
private ?float $daysPerYear = null;
|
||||
|
||||
/** Days granted per event (e.g. 4 for marriage); null when not relevant. */
|
||||
#[ORM\Column(type: Types::FLOAT, nullable: true)]
|
||||
#[Groups(['absence_policy:read', 'absence_policy:write'])]
|
||||
private ?float $daysPerEvent = null;
|
||||
|
||||
#[ORM\Column]
|
||||
#[Groups(['absence_policy:read', 'absence_policy:write'])]
|
||||
private bool $justificationRequired = false;
|
||||
|
||||
/** Minimum notice period in days (e.g. 30 for paid leave, 0 for sick leave). */
|
||||
#[ORM\Column]
|
||||
#[Groups(['absence_policy:read', 'absence_policy:write'])]
|
||||
private int $noticeDays = 0;
|
||||
|
||||
/** true => "jours ouvrés" (Mon-Fri), false => "jours ouvrables" (Mon-Sat). */
|
||||
#[ORM\Column]
|
||||
#[Groups(['absence_policy:read', 'absence_policy:write'])]
|
||||
private bool $countWorkingDaysOnly = true;
|
||||
|
||||
#[ORM\Column]
|
||||
#[Groups(['absence_policy:read', 'absence_policy:write'])]
|
||||
private bool $active = true;
|
||||
|
||||
#[Groups(['absence_policy:read'])]
|
||||
public function getLabel(): string
|
||||
{
|
||||
return $this->type->label();
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getType(): AbsenceType
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function setType(AbsenceType $type): static
|
||||
{
|
||||
$this->type = $type;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDaysPerYear(): ?float
|
||||
{
|
||||
return $this->daysPerYear;
|
||||
}
|
||||
|
||||
public function setDaysPerYear(?float $daysPerYear): static
|
||||
{
|
||||
$this->daysPerYear = $daysPerYear;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDaysPerEvent(): ?float
|
||||
{
|
||||
return $this->daysPerEvent;
|
||||
}
|
||||
|
||||
public function setDaysPerEvent(?float $daysPerEvent): static
|
||||
{
|
||||
$this->daysPerEvent = $daysPerEvent;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isJustificationRequired(): bool
|
||||
{
|
||||
return $this->justificationRequired;
|
||||
}
|
||||
|
||||
public function setJustificationRequired(bool $justificationRequired): static
|
||||
{
|
||||
$this->justificationRequired = $justificationRequired;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getNoticeDays(): int
|
||||
{
|
||||
return $this->noticeDays;
|
||||
}
|
||||
|
||||
public function setNoticeDays(int $noticeDays): static
|
||||
{
|
||||
$this->noticeDays = $noticeDays;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isCountWorkingDaysOnly(): bool
|
||||
{
|
||||
return $this->countWorkingDaysOnly;
|
||||
}
|
||||
|
||||
public function setCountWorkingDaysOnly(bool $countWorkingDaysOnly): static
|
||||
{
|
||||
$this->countWorkingDaysOnly = $countWorkingDaysOnly;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isActive(): bool
|
||||
{
|
||||
return $this->active;
|
||||
}
|
||||
|
||||
public function setActive(bool $active): static
|
||||
{
|
||||
$this->active = $active;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -1,327 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use ApiPlatform\Metadata\ApiResource;
|
||||
use ApiPlatform\Metadata\Delete;
|
||||
use ApiPlatform\Metadata\Get;
|
||||
use ApiPlatform\Metadata\GetCollection;
|
||||
use ApiPlatform\Metadata\Patch;
|
||||
use ApiPlatform\Metadata\Post;
|
||||
use App\Enum\AbsenceStatus;
|
||||
use App\Enum\AbsenceType;
|
||||
use App\Enum\HalfDay;
|
||||
use App\Repository\AbsenceRequestRepository;
|
||||
use App\Shared\Domain\Contract\UserInterface;
|
||||
use App\State\AbsenceCancelProcessor;
|
||||
use App\State\AbsenceRequestProcessor;
|
||||
use App\State\AbsenceRequestProvider;
|
||||
use App\State\AbsenceReviewProcessor;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Serializer\Attribute\Groups;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
#[ApiResource(
|
||||
operations: [
|
||||
new GetCollection(
|
||||
paginationEnabled: false,
|
||||
security: "is_granted('ROLE_USER')",
|
||||
provider: AbsenceRequestProvider::class,
|
||||
),
|
||||
new Get(
|
||||
security: "is_granted('ROLE_USER')",
|
||||
provider: AbsenceRequestProvider::class,
|
||||
),
|
||||
new Post(
|
||||
security: "is_granted('ROLE_USER')",
|
||||
processor: AbsenceRequestProcessor::class,
|
||||
),
|
||||
new Patch(
|
||||
uriTemplate: '/absence_requests/{id}/approve',
|
||||
security: "is_granted('ROLE_ADMIN')",
|
||||
processor: AbsenceReviewProcessor::class,
|
||||
provider: AbsenceRequestProvider::class,
|
||||
),
|
||||
new Patch(
|
||||
uriTemplate: '/absence_requests/{id}/reject',
|
||||
security: "is_granted('ROLE_ADMIN')",
|
||||
processor: AbsenceReviewProcessor::class,
|
||||
provider: AbsenceRequestProvider::class,
|
||||
),
|
||||
new Patch(
|
||||
uriTemplate: '/absence_requests/{id}/cancel',
|
||||
security: "is_granted('ROLE_USER')",
|
||||
processor: AbsenceCancelProcessor::class,
|
||||
provider: AbsenceRequestProvider::class,
|
||||
),
|
||||
new Delete(security: "is_granted('ROLE_ADMIN')"),
|
||||
],
|
||||
normalizationContext: ['groups' => ['absence_request:read']],
|
||||
denormalizationContext: ['groups' => ['absence_request:write']],
|
||||
order: ['createdAt' => 'DESC'],
|
||||
)]
|
||||
#[ORM\Entity(repositoryClass: AbsenceRequestRepository::class)]
|
||||
#[ORM\Table(name: 'absence_request')]
|
||||
class AbsenceRequest
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column]
|
||||
#[Groups(['absence_request:read'])]
|
||||
private ?int $id = null;
|
||||
|
||||
#[ORM\ManyToOne(targetEntity: UserInterface::class)]
|
||||
#[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')]
|
||||
#[Groups(['absence_request:read'])]
|
||||
private ?UserInterface $user = null;
|
||||
|
||||
#[ORM\Column(type: Types::STRING, length: 32, enumType: AbsenceType::class)]
|
||||
#[Groups(['absence_request:read', 'absence_request:write'])]
|
||||
#[Assert\NotNull]
|
||||
private ?AbsenceType $type = null;
|
||||
|
||||
#[ORM\Column(type: Types::DATE_IMMUTABLE)]
|
||||
#[Groups(['absence_request:read', 'absence_request:write'])]
|
||||
#[Assert\NotNull]
|
||||
private ?DateTimeImmutable $startDate = null;
|
||||
|
||||
#[ORM\Column(type: Types::DATE_IMMUTABLE)]
|
||||
#[Groups(['absence_request:read', 'absence_request:write'])]
|
||||
#[Assert\NotNull]
|
||||
private ?DateTimeImmutable $endDate = null;
|
||||
|
||||
#[ORM\Column(type: Types::STRING, length: 16, nullable: true, enumType: HalfDay::class)]
|
||||
#[Groups(['absence_request:read', 'absence_request:write'])]
|
||||
private ?HalfDay $startHalfDay = null;
|
||||
|
||||
#[ORM\Column(type: Types::STRING, length: 16, nullable: true, enumType: HalfDay::class)]
|
||||
#[Groups(['absence_request:read', 'absence_request:write'])]
|
||||
private ?HalfDay $endHalfDay = null;
|
||||
|
||||
/** Number of deducted days, computed server-side at creation. */
|
||||
#[ORM\Column(type: Types::FLOAT)]
|
||||
#[Groups(['absence_request:read'])]
|
||||
private float $countedDays = 0.0;
|
||||
|
||||
#[ORM\Column(type: Types::TEXT, nullable: true)]
|
||||
#[Groups(['absence_request:read', 'absence_request:write'])]
|
||||
private ?string $reason = null;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
#[Groups(['absence_request:read'])]
|
||||
private ?string $justificationFileName = null;
|
||||
|
||||
#[ORM\Column(type: Types::STRING, length: 16, enumType: AbsenceStatus::class)]
|
||||
#[Groups(['absence_request:read'])]
|
||||
private AbsenceStatus $status = AbsenceStatus::Pending;
|
||||
|
||||
#[ORM\Column(type: Types::TEXT, nullable: true)]
|
||||
#[Groups(['absence_request:read', 'absence_request:write'])]
|
||||
private ?string $rejectionReason = null;
|
||||
|
||||
#[ORM\Column(type: Types::DATETIME_IMMUTABLE)]
|
||||
#[Groups(['absence_request:read'])]
|
||||
private ?DateTimeImmutable $createdAt = null;
|
||||
|
||||
#[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: true)]
|
||||
#[Groups(['absence_request:read'])]
|
||||
private ?DateTimeImmutable $reviewedAt = null;
|
||||
|
||||
#[ORM\ManyToOne(targetEntity: UserInterface::class)]
|
||||
#[ORM\JoinColumn(nullable: true, onDelete: 'SET NULL')]
|
||||
#[Groups(['absence_request:read'])]
|
||||
private ?UserInterface $reviewedBy = null;
|
||||
|
||||
#[Groups(['absence_request:read'])]
|
||||
public function getLabel(): ?string
|
||||
{
|
||||
return $this->type?->label();
|
||||
}
|
||||
|
||||
#[Groups(['absence_request:read'])]
|
||||
public function getJustificationUrl(): ?string
|
||||
{
|
||||
if (null === $this->justificationFileName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return '/api/absence_requests/'.$this->id.'/justificatif';
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getUser(): ?UserInterface
|
||||
{
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
public function setUser(?UserInterface $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 getStartDate(): ?DateTimeImmutable
|
||||
{
|
||||
return $this->startDate;
|
||||
}
|
||||
|
||||
public function setStartDate(?DateTimeImmutable $startDate): static
|
||||
{
|
||||
$this->startDate = $startDate;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getEndDate(): ?DateTimeImmutable
|
||||
{
|
||||
return $this->endDate;
|
||||
}
|
||||
|
||||
public function setEndDate(?DateTimeImmutable $endDate): static
|
||||
{
|
||||
$this->endDate = $endDate;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getStartHalfDay(): ?HalfDay
|
||||
{
|
||||
return $this->startHalfDay;
|
||||
}
|
||||
|
||||
public function setStartHalfDay(?HalfDay $startHalfDay): static
|
||||
{
|
||||
$this->startHalfDay = $startHalfDay;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getEndHalfDay(): ?HalfDay
|
||||
{
|
||||
return $this->endHalfDay;
|
||||
}
|
||||
|
||||
public function setEndHalfDay(?HalfDay $endHalfDay): static
|
||||
{
|
||||
$this->endHalfDay = $endHalfDay;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCountedDays(): float
|
||||
{
|
||||
return $this->countedDays;
|
||||
}
|
||||
|
||||
public function setCountedDays(float $countedDays): static
|
||||
{
|
||||
$this->countedDays = $countedDays;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getReason(): ?string
|
||||
{
|
||||
return $this->reason;
|
||||
}
|
||||
|
||||
public function setReason(?string $reason): static
|
||||
{
|
||||
$this->reason = $reason;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getJustificationFileName(): ?string
|
||||
{
|
||||
return $this->justificationFileName;
|
||||
}
|
||||
|
||||
public function setJustificationFileName(?string $justificationFileName): static
|
||||
{
|
||||
$this->justificationFileName = $justificationFileName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getStatus(): AbsenceStatus
|
||||
{
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
public function setStatus(AbsenceStatus $status): static
|
||||
{
|
||||
$this->status = $status;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getRejectionReason(): ?string
|
||||
{
|
||||
return $this->rejectionReason;
|
||||
}
|
||||
|
||||
public function setRejectionReason(?string $rejectionReason): static
|
||||
{
|
||||
$this->rejectionReason = $rejectionReason;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCreatedAt(): ?DateTimeImmutable
|
||||
{
|
||||
return $this->createdAt;
|
||||
}
|
||||
|
||||
public function setCreatedAt(DateTimeImmutable $createdAt): static
|
||||
{
|
||||
$this->createdAt = $createdAt;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getReviewedAt(): ?DateTimeImmutable
|
||||
{
|
||||
return $this->reviewedAt;
|
||||
}
|
||||
|
||||
public function setReviewedAt(?DateTimeImmutable $reviewedAt): static
|
||||
{
|
||||
$this->reviewedAt = $reviewedAt;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getReviewedBy(): ?UserInterface
|
||||
{
|
||||
return $this->reviewedBy;
|
||||
}
|
||||
|
||||
public function setReviewedBy(?UserInterface $reviewedBy): static
|
||||
{
|
||||
$this->reviewedBy = $reviewedBy;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user