removeProcessor->process($data, $operation, $uriVariables, $context); } if (!$data instanceof Employee) { return $this->persistProcessor->process($data, $operation, $uriVariables, $context); } $isNew = null === $data->getId(); $previousContract = $this->resolvePreviousContract($data); $result = $this->persistProcessor->process($data, $operation, $uriVariables, $context); $currentContract = $data->getContract(); if (!$currentContract instanceof Contract) { return $result; } $today = new DateTimeImmutable('today'); $changeRequest = $this->changeRequestFactory->fromEmployee($data); if ($isNew) { $startDate = $changeRequest->contractStartDate ?? new DateTimeImmutable('1970-01-01'); $nature = $changeRequest->contractNature ?? ContractNature::CDI; $this->periodManager->ensureContractPeriodExists( employee: $data, contract: $currentContract, startDate: $startDate, endDate: $changeRequest->contractEndDate, nature: $nature, isDriver: $changeRequest->isDriver ?? false, ); $data->setEntryDate($startDate); $this->entityManager->flush(); $empName = trim(($data->getLastName() ?? '').' '.($data->getFirstName() ?? '')); $this->auditLogger->log( $data, 'create', 'employee', $data->getId(), sprintf('Employé %s créé (contrat: %s)', $empName, $currentContract->getName() ?? ''), ['new' => ['name' => $empName, 'contract' => $currentContract->getName(), 'nature' => $nature->value, 'startDate' => $startDate->format('d/m/Y')]], ); $this->entityManager->flush(); return $result; } if ($this->isSameContract($previousContract, $currentContract) && !$changeRequest->hasPeriodChangeRequest()) { return $result; } $empName = trim(($data->getLastName() ?? '').' '.($data->getFirstName() ?? '')); $this->auditLogger->log( $data, 'update', 'employee', $data->getId(), sprintf('Contrat modifié pour %s : %s → %s', $empName, $previousContract?->getName() ?? 'aucun', $currentContract->getName() ?? ''), ['old' => ['contract' => $previousContract?->getName()], 'new' => ['contract' => $currentContract->getName()]], ); $this->entityManager->flush(); $todayPeriod = $this->periodRepository->findOneCoveringDate($data, $today); $effectivePeriod = $todayPeriod ?? $this->periodRepository->findLatestPeriod($data); $currentPeriodContract = $effectivePeriod?->getContract(); $contractChanged = $currentPeriodContract instanceof Contract ? $currentPeriodContract->getId() !== $currentContract->getId() : true; $isCloseOnlyRequest = $changeRequest->isCloseOnlyRequest($contractChanged); if ($isCloseOnlyRequest) { $requestedEndDate = $changeRequest->contractEndDate; if (null === $requestedEndDate) { throw new UnprocessableEntityHttpException('contractEndDate is required for close-only request.'); } $isAlreadyEnded = null === $todayPeriod; $this->periodManager->closeCurrentPeriod( $effectivePeriod, $requestedEndDate, $changeRequest->contractPaidLeaveSettled ?? false, $changeRequest->contractComment, $isAlreadyEnded ); return $result; } $startDate = $changeRequest->contractStartDate ?? $today; $nature = $changeRequest->contractNature ?? $effectivePeriod?->getContractNatureEnum() ?? ContractNature::CDI; $this->periodManager->createNextPeriod( employee: $data, contract: $currentContract, startDate: $startDate, endDate: $changeRequest->contractEndDate, nature: $nature, todayPeriod: $effectivePeriod, isDriver: $changeRequest->isDriver ?? false, ); return $result; } private function resolvePreviousContract(Employee $employee): ?Contract { if (null === $employee->getId()) { return null; } $originalData = $this->entityManager->getUnitOfWork()->getOriginalEntityData($employee); $original = $originalData['contract'] ?? null; return $original instanceof Contract ? $original : null; } private function isSameContract(?Contract $first, ?Contract $second): bool { if (null === $first || null === $second) { return $first === $second; } return $first->getId() === $second->getId(); } }