pour prod
This commit is contained in:
529
app/Controllers/AgentController.php
Normal file
529
app/Controllers/AgentController.php
Normal file
@@ -0,0 +1,529 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Controllers;
|
||||
|
||||
use App\Core\Access;
|
||||
use App\Core\Csrf;
|
||||
use App\Core\JsonResponse;
|
||||
use App\Core\PdfResponse;
|
||||
use App\Core\Request;
|
||||
use App\Models\AgentModel;
|
||||
use App\Models\QuotaModel;
|
||||
use App\Models\StructureModel;
|
||||
use App\Services\AgentHoursContractPdfService;
|
||||
use App\Services\AgentTimeSummaryPdfService;
|
||||
use App\Services\PlanningPdfService;
|
||||
use DateTimeImmutable;
|
||||
use PDO;
|
||||
use Throwable;
|
||||
|
||||
final class AgentController
|
||||
{
|
||||
private AgentModel $agentModel;
|
||||
private StructureModel $structureModel;
|
||||
private QuotaModel $quotaModel;
|
||||
private Access $access;
|
||||
|
||||
public function __construct(private PDO $pdo)
|
||||
{
|
||||
$this->agentModel = new AgentModel($pdo);
|
||||
$this->structureModel = new StructureModel($pdo);
|
||||
$this->quotaModel = new QuotaModel($pdo);
|
||||
$this->access = new Access($pdo);
|
||||
}
|
||||
|
||||
public function listForPlanning(): void
|
||||
{
|
||||
$this->access->requireDraftEditor();
|
||||
$selectedLocation = filter_input(INPUT_GET, 'structure_id', FILTER_VALIDATE_INT) ?: 0;
|
||||
if ($selectedLocation) {
|
||||
$this->access->requireStructureEdit((int) $selectedLocation);
|
||||
}
|
||||
JsonResponse::send(200, ['agents' => $this->agentModel->listForLocation((int) $selectedLocation)]);
|
||||
}
|
||||
|
||||
public function overview(): void
|
||||
{
|
||||
$agentId = filter_input(INPUT_GET, 'agent_id', FILTER_VALIDATE_INT);
|
||||
$weekValue = trim((string) ($_GET['week'] ?? ''));
|
||||
$week = $this->parseWeek($weekValue);
|
||||
|
||||
if (!$agentId || $week === null) {
|
||||
JsonResponse::send(400, ['error' => 'Agent ou semaine invalide.']);
|
||||
}
|
||||
$this->access->requireAgentView((int) $agentId);
|
||||
|
||||
$agent = $this->agentModel->findActive((int) $agentId);
|
||||
if ($agent === null) {
|
||||
JsonResponse::send(404, ['error' => 'Agent introuvable.']);
|
||||
}
|
||||
|
||||
[$year, $weekNumber] = $week;
|
||||
$weekStart = (new DateTimeImmutable())->setISODate($year, $weekNumber, 1)->format('Y-m-d');
|
||||
$weekEnd = (new DateTimeImmutable())->setISODate($year, $weekNumber, 7)->format('Y-m-d');
|
||||
|
||||
JsonResponse::send(200, [
|
||||
'agent' => $agent,
|
||||
'week' => ['value' => $weekValue, 'date_debut' => $weekStart, 'date_fin' => $weekEnd],
|
||||
'quota' => $this->quotaModel->forDateForApi((int) $agentId, $weekStart),
|
||||
'entries' => $this->agentModel->entriesForWeek((int) $agentId, $year, $weekNumber),
|
||||
]);
|
||||
}
|
||||
|
||||
public function monthOverview(): void
|
||||
{
|
||||
$agentId = filter_input(INPUT_GET, 'agent_id', FILTER_VALIDATE_INT);
|
||||
$monthValue = trim((string) ($_GET['month'] ?? ''));
|
||||
|
||||
if (!$agentId || !preg_match('/^(\d{4})-(\d{2})$/', $monthValue, $matches)) {
|
||||
JsonResponse::send(400, ['error' => 'Agent ou mois invalide.']);
|
||||
}
|
||||
$this->access->requireAgentView((int) $agentId);
|
||||
|
||||
$year = (int) $matches[1];
|
||||
$monthNumber = (int) $matches[2];
|
||||
if ($monthNumber < 1 || $monthNumber > 12) {
|
||||
JsonResponse::send(400, ['error' => 'Mois invalide.']);
|
||||
}
|
||||
|
||||
$agent = $this->agentModel->findActive((int) $agentId);
|
||||
if ($agent === null) {
|
||||
JsonResponse::send(404, ['error' => 'Agent introuvable.']);
|
||||
}
|
||||
|
||||
$firstDay = new DateTimeImmutable(sprintf('%04d-%02d-01', $year, $monthNumber));
|
||||
$lastDay = $firstDay->modify('last day of this month');
|
||||
$gridStart = $firstDay->modify('-' . ((int) $firstDay->format('N') - 1) . ' days');
|
||||
$lastWeekMonday = $lastDay->modify('-' . ((int) $lastDay->format('N') - 1) . ' days');
|
||||
$gridEnd = $lastWeekMonday->modify('+4 days');
|
||||
|
||||
$dayLabels = [1 => 'Lundi', 2 => 'Mardi', 3 => 'Mercredi', 4 => 'Jeudi', 5 => 'Vendredi'];
|
||||
$monthLabels = [
|
||||
1 => 'Janvier', 2 => 'Février', 3 => 'Mars', 4 => 'Avril', 5 => 'Mai', 6 => 'Juin',
|
||||
7 => 'Juillet', 8 => 'Août', 9 => 'Septembre', 10 => 'Octobre', 11 => 'Novembre', 12 => 'Décembre',
|
||||
];
|
||||
$weeks = [];
|
||||
|
||||
for ($monday = $gridStart; $monday <= $lastWeekMonday; $monday = $monday->modify('+7 days')) {
|
||||
$days = [];
|
||||
for ($weekday = 1; $weekday <= 5; $weekday++) {
|
||||
$date = $monday->modify('+' . ($weekday - 1) . ' days');
|
||||
$days[] = [
|
||||
'date' => $date->format('Y-m-d'),
|
||||
'label' => $dayLabels[$weekday],
|
||||
'display' => $date->format('d/m'),
|
||||
'in_month' => (int) $date->format('n') === $monthNumber,
|
||||
];
|
||||
}
|
||||
$weeks[] = [
|
||||
'value' => sprintf('%04d-W%02d', (int) $monday->format('o'), (int) $monday->format('W')),
|
||||
'number' => (int) $monday->format('W'),
|
||||
'date_debut' => $monday->format('Y-m-d'),
|
||||
'date_fin' => $monday->modify('+4 days')->format('Y-m-d'),
|
||||
'days' => $days,
|
||||
];
|
||||
}
|
||||
|
||||
JsonResponse::send(200, [
|
||||
'agent' => $agent,
|
||||
'month' => [
|
||||
'value' => $monthValue,
|
||||
'year' => $year,
|
||||
'month' => $monthNumber,
|
||||
'label' => $monthLabels[$monthNumber] . ' ' . $year,
|
||||
'date_debut' => $firstDay->format('Y-m-d'),
|
||||
'date_fin' => $lastDay->format('Y-m-d'),
|
||||
'grid_start' => $gridStart->format('Y-m-d'),
|
||||
'grid_end' => $gridEnd->format('Y-m-d'),
|
||||
],
|
||||
'weeks' => $weeks,
|
||||
'quota' => $this->quotaModel->forDateForApi((int) $agentId, $firstDay->format('Y-m-d')),
|
||||
'entries' => $this->agentModel->entriesForDateRange(
|
||||
(int) $agentId,
|
||||
$gridStart->format('Y-m-d'),
|
||||
$gridEnd->format('Y-m-d')
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
public function timeSummaryPdf(): void
|
||||
{
|
||||
$agentId = filter_input(INPUT_GET, 'agent_id', FILTER_VALIDATE_INT);
|
||||
$dateValue = trim((string) ($_GET['date'] ?? ''));
|
||||
$year = filter_input(INPUT_GET, 'year', FILTER_VALIDATE_INT);
|
||||
|
||||
if ($dateValue === '' && $year) {
|
||||
$dateValue = sprintf('%04d-01-01', (int) $year);
|
||||
}
|
||||
$date = DateTimeImmutable::createFromFormat('!Y-m-d', $dateValue);
|
||||
|
||||
if (!$agentId || !$date || $date->format('Y-m-d') !== $dateValue) {
|
||||
http_response_code(400);
|
||||
echo 'Agent ou date de référence invalide.';
|
||||
return;
|
||||
}
|
||||
$this->access->requireAgentView((int) $agentId);
|
||||
|
||||
$agent = $this->agentModel->findActive((int) $agentId);
|
||||
if ($agent === null) {
|
||||
http_response_code(404);
|
||||
echo 'Agent introuvable.';
|
||||
return;
|
||||
}
|
||||
|
||||
$quota = $this->quotaModel->forDateForApi((int) $agentId, $dateValue);
|
||||
$summary = $this->agentModel->timeSummaryForRange(
|
||||
(int) $agentId,
|
||||
(string) $quota['date_debut_periode'],
|
||||
(string) $quota['date_fin_periode']
|
||||
);
|
||||
$pdf = (new AgentTimeSummaryPdfService())->annualSummary($agent, $quota, $summary);
|
||||
|
||||
PdfResponse::inline(
|
||||
$pdf,
|
||||
sprintf(
|
||||
'bilan_heures_%s_%s_%s_%s.pdf',
|
||||
$agent['nom'],
|
||||
$agent['prenom'],
|
||||
str_replace('-', '', (string) $quota['date_debut_periode']),
|
||||
str_replace('-', '', (string) $quota['date_fin_periode'])
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function pdf(): void
|
||||
{
|
||||
$agentId = filter_input(INPUT_GET, 'agent_id', FILTER_VALIDATE_INT);
|
||||
$weekValue = trim((string) ($_GET['week'] ?? ''));
|
||||
$week = $this->parseWeek($weekValue);
|
||||
$weekCount = filter_input(INPUT_GET, 'weeks', FILTER_VALIDATE_INT) ?: 7;
|
||||
$weekCount = in_array((int) $weekCount, [6, 7], true) ? (int) $weekCount : 7;
|
||||
|
||||
if (!$agentId || $week === null) {
|
||||
http_response_code(400);
|
||||
echo 'Agent ou semaine invalide.';
|
||||
return;
|
||||
}
|
||||
$this->access->requireAgentView((int) $agentId);
|
||||
|
||||
$agent = $this->agentModel->findActive((int) $agentId);
|
||||
if ($agent === null) {
|
||||
http_response_code(404);
|
||||
echo 'Agent introuvable.';
|
||||
return;
|
||||
}
|
||||
|
||||
[$year, $weekNumber] = $week;
|
||||
$firstMonday = (new DateTimeImmutable())->setISODate($year, $weekNumber, 1);
|
||||
$weeks = [];
|
||||
|
||||
for ($index = 0; $index < $weekCount; $index++) {
|
||||
$monday = $firstMonday->modify('+' . ($index * 7) . ' days');
|
||||
$isoYear = (int) $monday->format('o');
|
||||
$isoWeek = (int) $monday->format('W');
|
||||
$weeks[] = [
|
||||
'value' => sprintf('%04d-W%02d', $isoYear, $isoWeek),
|
||||
'date_debut' => $monday->format('Y-m-d'),
|
||||
'date_fin' => $monday->modify('+6 days')->format('Y-m-d'),
|
||||
];
|
||||
}
|
||||
|
||||
$lastFriday = $firstMonday->modify('+' . (($weekCount - 1) * 7 + 4) . ' days');
|
||||
$entries = $this->agentModel->entriesForDateRange(
|
||||
(int) $agentId,
|
||||
$firstMonday->format('Y-m-d'),
|
||||
$lastFriday->format('Y-m-d')
|
||||
);
|
||||
|
||||
$pdf = (new PlanningPdfService())->agentWeeks(
|
||||
$agent,
|
||||
$entries,
|
||||
$weeks,
|
||||
$this->quotaModel->forDateForApi((int) $agentId, $firstMonday->format('Y-m-d'))
|
||||
);
|
||||
|
||||
PdfResponse::inline(
|
||||
$pdf,
|
||||
sprintf(
|
||||
'planning_%s_%s_%s_%d_semaines.pdf',
|
||||
$agent['nom'],
|
||||
$agent['prenom'],
|
||||
str_replace('-W', '_S', $weekValue),
|
||||
$weekCount
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function hoursContractPdf(): void
|
||||
{
|
||||
$agentId = filter_input(INPUT_GET, 'agent_id', FILTER_VALIDATE_INT);
|
||||
$dateValue = trim((string) ($_GET['date'] ?? ''));
|
||||
$year = filter_input(INPUT_GET, 'year', FILTER_VALIDATE_INT);
|
||||
|
||||
if ($dateValue === '' && $year) {
|
||||
$dateValue = sprintf('%04d-01-01', (int) $year);
|
||||
}
|
||||
$date = DateTimeImmutable::createFromFormat('!Y-m-d', $dateValue);
|
||||
|
||||
if (!$agentId || !$date || $date->format('Y-m-d') !== $dateValue) {
|
||||
http_response_code(400);
|
||||
echo 'Agent ou date de référence invalide.';
|
||||
return;
|
||||
}
|
||||
$this->access->requireAgentView((int) $agentId);
|
||||
|
||||
$agent = $this->agentModel->findActive((int) $agentId);
|
||||
if ($agent === null) {
|
||||
http_response_code(404);
|
||||
echo 'Agent introuvable.';
|
||||
return;
|
||||
}
|
||||
|
||||
$quota = $this->quotaModel->forDateForApi((int) $agentId, $dateValue);
|
||||
$pdf = (new AgentHoursContractPdfService())->annualContract($agent, $quota);
|
||||
|
||||
PdfResponse::inline(
|
||||
$pdf,
|
||||
sprintf(
|
||||
'contrat_horaire_%s_%s_%s.pdf',
|
||||
$agent['nom'],
|
||||
$agent['prenom'],
|
||||
str_replace('-', '', (string) $quota['date_debut_periode'])
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function assignments(): void
|
||||
{
|
||||
$this->access->requireService();
|
||||
if (($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'GET') {
|
||||
JsonResponse::send(200, ['agents' => $this->agentModel->allActive()]);
|
||||
}
|
||||
|
||||
Request::requireMethod('POST');
|
||||
$payload = Request::json();
|
||||
Csrf::assertPayload($payload);
|
||||
|
||||
$agentId = filter_var($payload['agent_id'] ?? null, FILTER_VALIDATE_INT);
|
||||
$rawStructure = $payload['structure_id'] ?? null;
|
||||
$structureId = ($rawStructure === null || $rawStructure === '' || $rawStructure === 0)
|
||||
? null
|
||||
: filter_var($rawStructure, FILTER_VALIDATE_INT);
|
||||
if (!$agentId) {
|
||||
JsonResponse::send(422, ['error' => 'Agent invalide.']);
|
||||
}
|
||||
if ($this->agentModel->findActive((int) $agentId) === null) {
|
||||
JsonResponse::send(404, ['error' => 'Agent introuvable.']);
|
||||
}
|
||||
if ($structureId !== null && $this->structureModel->findActive((int) $structureId) === null) {
|
||||
JsonResponse::send(422, ['error' => 'Lieu d’affectation invalide ou inactif.']);
|
||||
}
|
||||
|
||||
try {
|
||||
$this->agentModel->updateAssignment((int) $agentId, $structureId !== null ? (int) $structureId : null);
|
||||
} catch (Throwable $e) {
|
||||
JsonResponse::send(500, [
|
||||
'error' => 'Impossible de modifier les paramètres de l’agent.',
|
||||
'details' => (getenv('PTA_DEBUG') ?: '1') !== '0' ? $e->getMessage() : null,
|
||||
]);
|
||||
}
|
||||
|
||||
JsonResponse::send(200, [
|
||||
'message' => $structureId === null
|
||||
? 'Les paramètres de l’agent ont été mis à jour sans lieu principal.'
|
||||
: 'Le lieu principal de l’agent a été mis à jour.',
|
||||
]);
|
||||
}
|
||||
|
||||
public function create(): void
|
||||
{
|
||||
$this->access->requireService();
|
||||
Request::requireMethod('POST');
|
||||
$payload = Request::json();
|
||||
Csrf::assertPayload($payload);
|
||||
|
||||
$matricule = trim((string) ($payload['matricule'] ?? ''));
|
||||
$nom = trim((string) ($payload['nom'] ?? ''));
|
||||
$prenom = trim((string) ($payload['prenom'] ?? ''));
|
||||
$email = trim((string) ($payload['email'] ?? ''));
|
||||
$telephone = trim((string) ($payload['telephone'] ?? ''));
|
||||
$adresse = trim((string) ($payload['adresse'] ?? ''));
|
||||
$estDiplome = filter_var($payload['est_diplome'] ?? false, FILTER_VALIDATE_BOOLEAN);
|
||||
$diplomeLibelle = trim((string) ($payload['diplome_libelle'] ?? ''));
|
||||
$structureId = filter_var($payload['structure_id'] ?? null, FILTER_VALIDATE_INT);
|
||||
$rate = filter_var($payload['quotite_travail'] ?? null, FILTER_VALIDATE_FLOAT);
|
||||
$contractStart = trim((string) ($payload['date_debut_contrat'] ?? ''));
|
||||
$contractStartDate = DateTimeImmutable::createFromFormat('!Y-m-d', $contractStart);
|
||||
$contractEnd = trim((string) ($payload['date_fin_contrat'] ?? ''));
|
||||
$contractEndDate = $contractEnd !== '' ? DateTimeImmutable::createFromFormat('!Y-m-d', $contractEnd) : null;
|
||||
$postId = filter_var($payload['id_poste'] ?? null, FILTER_VALIDATE_INT);
|
||||
$contractType = strtoupper(trim((string) ($payload['type_contrat'] ?? 'PERMANENT')));
|
||||
$trainingPlanned = filter_var($payload['formation_repartition_annuelle'] ?? false, FILTER_VALIDATE_BOOLEAN);
|
||||
$ptaComment = trim((string) ($payload['commentaire_pta'] ?? ''));
|
||||
$validPostIds = array_map(static fn(array $post): int => (int) $post['id_poste'], $this->agentModel->allPosts());
|
||||
|
||||
if ($matricule === '' || $nom === '' || $prenom === '' || !$structureId || !$postId
|
||||
|| !in_array((int) $postId, $validPostIds, true)
|
||||
|| !in_array($contractType, ['PERMANENT', 'TEMPORAIRE'], true)
|
||||
|| !$contractStartDate || $contractStartDate->format('Y-m-d') !== $contractStart
|
||||
|| ($contractEnd !== '' && (!$contractEndDate || $contractEndDate->format('Y-m-d') !== $contractEnd || $contractEndDate < $contractStartDate))) {
|
||||
JsonResponse::send(422, ['error' => 'Le matricule, le nom, le prénom, le poste, le type de contrat, le lieu principal et des dates de contrat cohérentes sont obligatoires.']);
|
||||
}
|
||||
if ($rate === false || $rate <= 0 || $rate > 100) {
|
||||
JsonResponse::send(422, ['error' => 'La quotité de travail doit être comprise entre 1 et 100 %.']);
|
||||
}
|
||||
if ($email !== '' && filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
|
||||
JsonResponse::send(422, ['error' => 'L’adresse e-mail saisie n’est pas valide.']);
|
||||
}
|
||||
if (strlen($matricule) > 50 || strlen($nom) > 100 || strlen($prenom) > 100 || strlen($email) > 255
|
||||
|| strlen($telephone) > 30 || strlen($adresse) > 255 || strlen($diplomeLibelle) > 150 || strlen($ptaComment) > 1000) {
|
||||
JsonResponse::send(422, ['error' => 'Un des champs dépasse la longueur autorisée.']);
|
||||
}
|
||||
if ($this->structureModel->findActive((int) $structureId) === null) {
|
||||
JsonResponse::send(422, ['error' => 'Le lieu d’affectation principal sélectionné est invalide ou inactif.']);
|
||||
}
|
||||
if ($this->agentModel->matriculeExists($matricule)) {
|
||||
JsonResponse::send(409, ['error' => 'Un agent utilise déjà ce matricule.']);
|
||||
}
|
||||
|
||||
try {
|
||||
$created = $this->agentModel->createWithDefaults([
|
||||
'matricule' => $matricule,
|
||||
'nom' => $nom,
|
||||
'prenom' => $prenom,
|
||||
'email' => $email !== '' ? $email : null,
|
||||
'telephone' => $telephone !== '' ? $telephone : null,
|
||||
'adresse' => $adresse !== '' ? $adresse : null,
|
||||
'est_diplome' => $estDiplome,
|
||||
'diplome_libelle' => $estDiplome && $diplomeLibelle !== '' ? $diplomeLibelle : null,
|
||||
'structure_id' => (int) $structureId,
|
||||
'quotite_travail' => (float) $rate,
|
||||
'date_debut_contrat' => $contractStart,
|
||||
'date_fin_contrat' => $contractEnd !== '' ? $contractEnd : null,
|
||||
'id_poste' => (int) $postId,
|
||||
'type_contrat' => $contractType,
|
||||
'formation_repartition_annuelle' => $trainingPlanned,
|
||||
'commentaire_pta' => $ptaComment !== '' ? $ptaComment : null,
|
||||
]);
|
||||
} catch (Throwable $e) {
|
||||
JsonResponse::send(500, [
|
||||
'error' => 'Impossible de créer l’agent.',
|
||||
'details' => (getenv('PTA_DEBUG') ?: '1') !== '0' ? $e->getMessage() : null,
|
||||
]);
|
||||
}
|
||||
|
||||
$structure = $this->structureModel->findActive((int) $structureId);
|
||||
JsonResponse::send(201, [
|
||||
'message' => sprintf('%s %s a été ajouté avec le lieu principal « %s ».', $prenom, $nom, $structure['nom']),
|
||||
'agent' => array_merge($created, [
|
||||
'matricule' => $matricule,
|
||||
'nom' => $nom,
|
||||
'prenom' => $prenom,
|
||||
'email' => $email !== '' ? $email : null,
|
||||
'telephone' => $telephone !== '' ? $telephone : null,
|
||||
'adresse' => $adresse !== '' ? $adresse : null,
|
||||
'est_diplome' => $estDiplome ? 1 : 0,
|
||||
'diplome_libelle' => $estDiplome && $diplomeLibelle !== '' ? $diplomeLibelle : null,
|
||||
'id_structure' => (int) $structureId,
|
||||
'structure_nom' => (string) $structure['nom'],
|
||||
'structure_type_affectation' => (string) $structure['type_affectation'],
|
||||
'quotite_travail' => (float) $rate,
|
||||
'date_debut_contrat' => $contractStart,
|
||||
'date_fin_contrat' => $contractEnd !== '' ? $contractEnd : null,
|
||||
'id_poste' => (int) $postId,
|
||||
'poste_libelle' => (string) (array_values(array_filter($this->agentModel->allPosts(), static fn(array $post): bool => (int) $post['id_poste'] === (int) $postId))[0]['libelle'] ?? ''),
|
||||
'type_contrat' => $contractType,
|
||||
'formation_repartition_annuelle' => $trainingPlanned ? 1 : 0,
|
||||
'commentaire_pta' => $ptaComment !== '' ? $ptaComment : null,
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
public function updateProfile(): void
|
||||
{
|
||||
$this->access->requireService();
|
||||
Request::requireMethod('POST');
|
||||
$payload = Request::json();
|
||||
Csrf::assertPayload($payload);
|
||||
|
||||
$agentId = filter_var($payload['agent_id'] ?? null, FILTER_VALIDATE_INT);
|
||||
$email = trim((string) ($payload['email'] ?? ''));
|
||||
$telephone = trim((string) ($payload['telephone'] ?? ''));
|
||||
$adresse = trim((string) ($payload['adresse'] ?? ''));
|
||||
$estDiplome = filter_var($payload['est_diplome'] ?? false, FILTER_VALIDATE_BOOLEAN);
|
||||
$diplomeLibelle = trim((string) ($payload['diplome_libelle'] ?? ''));
|
||||
$contractStart = trim((string) ($payload['date_debut_contrat'] ?? ''));
|
||||
$contractStartDate = DateTimeImmutable::createFromFormat('!Y-m-d', $contractStart);
|
||||
$contractEnd = trim((string) ($payload['date_fin_contrat'] ?? ''));
|
||||
$contractEndDate = $contractEnd !== '' ? DateTimeImmutable::createFromFormat('!Y-m-d', $contractEnd) : null;
|
||||
$postId = filter_var($payload['id_poste'] ?? null, FILTER_VALIDATE_INT);
|
||||
$contractType = strtoupper(trim((string) ($payload['type_contrat'] ?? 'PERMANENT')));
|
||||
$trainingPlanned = filter_var($payload['formation_repartition_annuelle'] ?? false, FILTER_VALIDATE_BOOLEAN);
|
||||
$ptaComment = trim((string) ($payload['commentaire_pta'] ?? ''));
|
||||
$validPostIds = array_map(static fn(array $post): int => (int) $post['id_poste'], $this->agentModel->allPosts());
|
||||
$rawStructure = $payload['structure_id'] ?? null;
|
||||
$structureId = ($rawStructure === null || $rawStructure === '' || $rawStructure === 0)
|
||||
? null
|
||||
: filter_var($rawStructure, FILTER_VALIDATE_INT);
|
||||
|
||||
if (!$agentId) {
|
||||
JsonResponse::send(422, ['error' => 'Agent invalide.']);
|
||||
}
|
||||
if ($this->agentModel->findActive((int) $agentId) === null) {
|
||||
JsonResponse::send(404, ['error' => 'Agent introuvable.']);
|
||||
}
|
||||
if (!$postId || !in_array((int) $postId, $validPostIds, true)
|
||||
|| !in_array($contractType, ['PERMANENT', 'TEMPORAIRE'], true)
|
||||
|| !$contractStartDate || $contractStartDate->format('Y-m-d') !== $contractStart
|
||||
|| ($contractEnd !== '' && (!$contractEndDate || $contractEndDate->format('Y-m-d') !== $contractEnd || $contractEndDate < $contractStartDate))) {
|
||||
JsonResponse::send(422, ['error' => 'Le poste, le type de contrat et les dates du contrat doivent être valides.']);
|
||||
}
|
||||
if ($email !== '' && filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
|
||||
JsonResponse::send(422, ['error' => 'L’adresse e-mail saisie n’est pas valide.']);
|
||||
}
|
||||
if (strlen($email) > 255 || strlen($telephone) > 30 || strlen($adresse) > 255 || strlen($diplomeLibelle) > 150 || strlen($ptaComment) > 1000) {
|
||||
JsonResponse::send(422, ['error' => 'Un des champs dépasse la longueur autorisée.']);
|
||||
}
|
||||
if ($structureId !== null && $this->structureModel->findActive((int) $structureId) === null) {
|
||||
JsonResponse::send(422, ['error' => 'Lieu d’affectation principal invalide ou inactif.']);
|
||||
}
|
||||
|
||||
try {
|
||||
$this->agentModel->updateProfile((int) $agentId, [
|
||||
'email' => $email !== '' ? $email : null,
|
||||
'telephone' => $telephone !== '' ? $telephone : null,
|
||||
'adresse' => $adresse !== '' ? $adresse : null,
|
||||
'est_diplome' => $estDiplome,
|
||||
'diplome_libelle' => $estDiplome && $diplomeLibelle !== '' ? $diplomeLibelle : null,
|
||||
'date_debut_contrat' => $contractStart,
|
||||
'date_fin_contrat' => $contractEnd !== '' ? $contractEnd : null,
|
||||
'id_poste' => (int) $postId,
|
||||
'type_contrat' => $contractType,
|
||||
'formation_repartition_annuelle' => $trainingPlanned,
|
||||
'commentaire_pta' => $ptaComment !== '' ? $ptaComment : null,
|
||||
'structure_id' => $structureId !== null ? (int) $structureId : null,
|
||||
]);
|
||||
} catch (Throwable $e) {
|
||||
JsonResponse::send(500, [
|
||||
'error' => 'Impossible de modifier les informations de l’agent.',
|
||||
'details' => (getenv('PTA_DEBUG') ?: '1') !== '0' ? $e->getMessage() : null,
|
||||
]);
|
||||
}
|
||||
|
||||
JsonResponse::send(200, [
|
||||
'message' => 'Les informations de l’agent ont été mises à jour.',
|
||||
'agent' => $this->agentModel->findActive((int) $agentId),
|
||||
]);
|
||||
}
|
||||
|
||||
private function parseWeek(string $value): ?array
|
||||
{
|
||||
if (!preg_match('/^(\d{4})-W(\d{2})$/', $value, $matches)) {
|
||||
return null;
|
||||
}
|
||||
$week = (int) $matches[2];
|
||||
return $week >= 1 && $week <= 53 ? [(int) $matches[1], $week] : null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user