feat : ajout d'un champ commentaire sur les contrats + correction de plusieurs bugs
This commit is contained in:
@@ -21,5 +21,7 @@ final class ContractHistoryItem
|
||||
public string $startDate,
|
||||
#[Groups(['employee:read'])]
|
||||
public ?string $endDate,
|
||||
#[Groups(['employee:read'])]
|
||||
public ?string $comment = null,
|
||||
) {}
|
||||
}
|
||||
|
||||
@@ -78,6 +78,9 @@ class Employee
|
||||
#[Groups(['employee:write'])]
|
||||
private ?bool $contractPaidLeaveSettled = null;
|
||||
|
||||
#[Groups(['employee:write'])]
|
||||
private ?string $contractComment = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->createdAt = new DateTimeImmutable();
|
||||
@@ -202,6 +205,18 @@ class Employee
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getContractComment(): ?string
|
||||
{
|
||||
return $this->contractComment;
|
||||
}
|
||||
|
||||
public function setContractComment(?string $contractComment): self
|
||||
{
|
||||
$this->contractComment = $contractComment;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Groups(['employee:read'])]
|
||||
public function getCurrentContractNature(): string
|
||||
{
|
||||
@@ -243,6 +258,7 @@ class Employee
|
||||
contractNature: $period->getContractNatureEnum()->value,
|
||||
startDate: $period->getStartDate()->format('Y-m-d'),
|
||||
endDate: $period->getEndDate()?->format('Y-m-d'),
|
||||
comment: $period->getComment(),
|
||||
);
|
||||
},
|
||||
$periods
|
||||
|
||||
@@ -40,6 +40,9 @@ class EmployeeContractPeriod
|
||||
#[ORM\Column(type: 'boolean', options: ['default' => false])]
|
||||
private bool $paidLeaveSettled = false;
|
||||
|
||||
#[ORM\Column(type: 'text', nullable: true)]
|
||||
private ?string $comment = null;
|
||||
|
||||
#[ORM\Column(type: 'datetime_immutable')]
|
||||
private DateTimeImmutable $createdAt;
|
||||
|
||||
@@ -136,4 +139,16 @@ class EmployeeContractPeriod
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getComment(): ?string
|
||||
{
|
||||
return $this->comment;
|
||||
}
|
||||
|
||||
public function setComment(?string $comment): self
|
||||
{
|
||||
$this->comment = $comment;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ use ApiPlatform\Metadata\GetCollection;
|
||||
use ApiPlatform\Metadata\Patch;
|
||||
use App\Repository\WorkHourRepository;
|
||||
use App\State\WorkHourSiteValidationProcessor;
|
||||
use DateTimeImmutable;
|
||||
use DateTimeInterface;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Serializer\Attribute\Groups;
|
||||
@@ -106,6 +107,10 @@ class WorkHour
|
||||
#[Groups(['work_hour:read', 'work_hour:site_validate'])]
|
||||
private bool $isSiteValid = false;
|
||||
|
||||
#[ORM\Column(type: 'datetime_immutable', nullable: true)]
|
||||
#[Groups(['work_hour:read'])]
|
||||
private ?DateTimeImmutable $updatedAt = null;
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
@@ -274,4 +279,16 @@ class WorkHour
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getUpdatedAt(): ?DateTimeImmutable
|
||||
{
|
||||
return $this->updatedAt;
|
||||
}
|
||||
|
||||
public function setUpdatedAt(?DateTimeImmutable $updatedAt): self
|
||||
{
|
||||
$this->updatedAt = $updatedAt;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ final readonly class EmployeeContractChangeRequest
|
||||
public ?DateTimeImmutable $contractStartDate,
|
||||
public ?DateTimeImmutable $contractEndDate,
|
||||
public ?bool $contractPaidLeaveSettled,
|
||||
public ?string $contractComment,
|
||||
) {}
|
||||
|
||||
public function hasPeriodChangeRequest(): bool
|
||||
@@ -21,7 +22,8 @@ final readonly class EmployeeContractChangeRequest
|
||||
return null !== $this->contractNature
|
||||
|| null !== $this->contractStartDate
|
||||
|| null !== $this->contractEndDate
|
||||
|| null !== $this->contractPaidLeaveSettled;
|
||||
|| null !== $this->contractPaidLeaveSettled
|
||||
|| null !== $this->contractComment;
|
||||
}
|
||||
|
||||
public function isCloseOnlyRequest(bool $contractChanged): bool
|
||||
|
||||
@@ -18,6 +18,7 @@ final class EmployeeContractChangeRequestFactory
|
||||
contractStartDate: $this->parseOptionalYmd($employee->getContractStartDate(), 'contractStartDate'),
|
||||
contractEndDate: $this->parseOptionalYmd($employee->getContractEndDate(), 'contractEndDate'),
|
||||
contractPaidLeaveSettled: $employee->getContractPaidLeaveSettled(),
|
||||
contractComment: $employee->getContractComment(),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,8 @@ final readonly class EmployeeContractPeriodManager implements EmployeeContractPe
|
||||
public function closeCurrentPeriod(
|
||||
?EmployeeContractPeriod $todayPeriod,
|
||||
DateTimeImmutable $requestedEndDate,
|
||||
bool $paidLeaveSettled
|
||||
bool $paidLeaveSettled,
|
||||
?string $comment = null
|
||||
): void {
|
||||
if (null === $todayPeriod) {
|
||||
throw new UnprocessableEntityHttpException('No active contract period to close.');
|
||||
@@ -58,6 +59,7 @@ final readonly class EmployeeContractPeriodManager implements EmployeeContractPe
|
||||
|
||||
$todayPeriod->setEndDate($requestedEndDate);
|
||||
$todayPeriod->setPaidLeaveSettled($paidLeaveSettled);
|
||||
$todayPeriod->setComment($comment);
|
||||
$this->entityManager->flush();
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,8 @@ interface EmployeeContractPeriodManagerInterface
|
||||
public function closeCurrentPeriod(
|
||||
?EmployeeContractPeriod $todayPeriod,
|
||||
DateTimeImmutable $requestedEndDate,
|
||||
bool $paidLeaveSettled
|
||||
bool $paidLeaveSettled,
|
||||
?string $comment = null
|
||||
): void;
|
||||
|
||||
public function createNextPeriod(
|
||||
|
||||
@@ -69,13 +69,8 @@ final readonly class WorkedHoursCreditPolicy
|
||||
return 0.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;
|
||||
}
|
||||
|
||||
// Règle forfait: les absences ne créditent jamais de présence.
|
||||
// Seules les checkboxes cochées par l'employé comptent.
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
|
||||
@@ -90,7 +90,8 @@ final readonly class EmployeeWriteProcessor implements ProcessorInterface
|
||||
$this->periodManager->closeCurrentPeriod(
|
||||
$todayPeriod,
|
||||
$requestedEndDate,
|
||||
$changeRequest->contractPaidLeaveSettled ?? false
|
||||
$changeRequest->contractPaidLeaveSettled ?? false,
|
||||
$changeRequest->contractComment
|
||||
);
|
||||
|
||||
return $result;
|
||||
|
||||
@@ -98,6 +98,7 @@ final readonly class WorkHourBulkUpsertProcessor implements ProcessorInterface
|
||||
$normalized = $this->normalizeEntry($entry, $employeeId, $isPresenceTracking);
|
||||
$existing = $existingByEmployeeId[$employeeId] ?? null;
|
||||
$isAdmin = in_array('ROLE_ADMIN', $user->getRoles(), true);
|
||||
$isSelf = in_array('ROLE_SELF', $user->getRoles(), true);
|
||||
|
||||
if ($existing?->isValid()) {
|
||||
if (!$this->isSameAsExisting($existing, $normalized)) {
|
||||
@@ -145,6 +146,9 @@ final readonly class WorkHourBulkUpsertProcessor implements ProcessorInterface
|
||||
->setWorkDate($workDate)
|
||||
;
|
||||
$this->hydrateWorkHour($workHour, $normalized);
|
||||
if ($isSelf) {
|
||||
$workHour->setUpdatedAt(new DateTimeImmutable());
|
||||
}
|
||||
$this->entityManager->persist($workHour);
|
||||
$existingByEmployeeId[$employeeId] = $workHour;
|
||||
++$result->created;
|
||||
@@ -169,6 +173,9 @@ final readonly class WorkHourBulkUpsertProcessor implements ProcessorInterface
|
||||
}
|
||||
|
||||
$this->hydrateWorkHour($workHour, $normalized);
|
||||
if (!$isAdmin) {
|
||||
$workHour->setUpdatedAt(new DateTimeImmutable());
|
||||
}
|
||||
++$result->processed;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user