105 lines
3.4 KiB
PHP
105 lines
3.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Service\Contracts;
|
|
|
|
use App\Entity\Contract;
|
|
use App\Entity\Employee;
|
|
use App\Entity\EmployeeContractPeriod;
|
|
use App\Enum\ContractNature;
|
|
use App\Repository\EmployeeContractPeriodRepository;
|
|
use DateTimeImmutable;
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
|
|
|
|
final readonly class EmployeeContractPeriodManager implements EmployeeContractPeriodManagerInterface
|
|
{
|
|
public function __construct(
|
|
private EntityManagerInterface $entityManager,
|
|
private EmployeeContractPeriodRepository $periodRepository,
|
|
private EmployeeContractPeriodBuilder $periodBuilder,
|
|
private EmployeeContractPeriodValidator $periodValidator,
|
|
) {}
|
|
|
|
public function ensureContractPeriodExists(
|
|
Employee $employee,
|
|
Contract $contract,
|
|
DateTimeImmutable $startDate,
|
|
?DateTimeImmutable $endDate,
|
|
ContractNature $nature,
|
|
bool $isDriver = false,
|
|
): void {
|
|
$this->periodValidator->assertPeriodDates($startDate, $endDate, $nature);
|
|
|
|
$covered = $this->periodRepository->findOneCoveringDate($employee, $startDate);
|
|
if (null !== $covered) {
|
|
return;
|
|
}
|
|
|
|
$this->persistNewPeriod($employee, $contract, $startDate, $endDate, $nature, $isDriver);
|
|
$this->entityManager->flush();
|
|
}
|
|
|
|
public function closeCurrentPeriod(
|
|
?EmployeeContractPeriod $todayPeriod,
|
|
DateTimeImmutable $requestedEndDate,
|
|
bool $paidLeaveSettled,
|
|
?string $comment = null,
|
|
bool $isAlreadyEnded = false
|
|
): void {
|
|
if (null === $todayPeriod) {
|
|
throw new UnprocessableEntityHttpException('No active contract period to close.');
|
|
}
|
|
|
|
if (!$isAlreadyEnded) {
|
|
$this->periodValidator->assertCloseEndDateCanBeApplied(
|
|
$todayPeriod->getStartDate(),
|
|
$todayPeriod->getEndDate(),
|
|
$requestedEndDate,
|
|
$todayPeriod->getContractNatureEnum()
|
|
);
|
|
}
|
|
|
|
$todayPeriod->setEndDate($requestedEndDate);
|
|
$todayPeriod->setPaidLeaveSettled($paidLeaveSettled);
|
|
$todayPeriod->setComment($comment);
|
|
$this->entityManager->flush();
|
|
}
|
|
|
|
public function createNextPeriod(
|
|
Employee $employee,
|
|
Contract $contract,
|
|
DateTimeImmutable $startDate,
|
|
?DateTimeImmutable $endDate,
|
|
ContractNature $nature,
|
|
?EmployeeContractPeriod $todayPeriod,
|
|
bool $isDriver = false,
|
|
): void {
|
|
$this->periodValidator->assertPeriodDates($startDate, $endDate, $nature);
|
|
|
|
if (null !== $todayPeriod) {
|
|
$this->periodValidator->assertNextStartDateCompatible($startDate, $todayPeriod);
|
|
|
|
if (null === $todayPeriod->getEndDate()) {
|
|
$todayPeriod->setEndDate($startDate->modify('-1 day'));
|
|
}
|
|
}
|
|
|
|
$this->persistNewPeriod($employee, $contract, $startDate, $endDate, $nature, $isDriver);
|
|
$this->entityManager->flush();
|
|
}
|
|
|
|
private function persistNewPeriod(
|
|
Employee $employee,
|
|
Contract $contract,
|
|
DateTimeImmutable $startDate,
|
|
?DateTimeImmutable $endDate,
|
|
ContractNature $nature,
|
|
bool $isDriver = false,
|
|
): void {
|
|
$period = $this->periodBuilder->build($employee, $contract, $startDate, $endDate, $nature, $isDriver);
|
|
$this->entityManager->persist($period);
|
|
}
|
|
}
|