Files
pta/app/Controllers/PtaController.php
Loic Masi 5fbf76868f pour prod
2026-08-07 16:13:43 +02:00

175 lines
7.7 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
namespace App\Controllers;
use App\Core\Access;
use App\Core\Csrf;
use App\Core\JsonResponse;
use App\Core\Request;
use App\Models\AgentModel;
use App\Models\PtaModel;
use App\Models\StructureModel;
use DateTimeImmutable;
use PDO;
use Throwable;
final class PtaController
{
private PtaModel $ptaModel;
private AgentModel $agentModel;
private StructureModel $structureModel;
private Access $access;
public function __construct(private PDO $pdo)
{
$this->ptaModel = new PtaModel($pdo);
$this->agentModel = new AgentModel($pdo);
$this->structureModel = new StructureModel($pdo);
$this->access = new Access($pdo);
}
public function summary(): void
{
$this->access->requireService();
$agentId = filter_input(INPUT_GET, 'agent_id', FILTER_VALIDATE_INT);
$date = trim((string) ($_GET['date'] ?? date('Y-m-d')));
$parsed = DateTimeImmutable::createFromFormat('!Y-m-d', $date);
if (!$agentId || !$parsed || $parsed->format('Y-m-d') !== $date) {
JsonResponse::send(422, ['error' => 'Agent ou date de référence invalide.']);
}
try {
JsonResponse::send(200, $this->ptaModel->summary((int) $agentId, $date));
} catch (Throwable $e) {
JsonResponse::send(500, [
'error' => 'Impossible de calculer le PTA de lagent.',
'details' => (getenv('PTA_DEBUG') ?: '1') !== '0' ? $e->getMessage() : null,
]);
}
}
public function constraint(): void
{
$this->access->requireService();
Request::requireMethod('POST');
$payload = Request::json();
Csrf::assertPayload($payload);
$action = strtoupper(trim((string) ($payload['action'] ?? 'SAVE')));
$agentId = filter_var($payload['agent_id'] ?? null, FILTER_VALIDATE_INT);
if (!$agentId || $this->agentModel->findActive((int) $agentId) === null) {
JsonResponse::send(422, ['error' => 'Agent invalide.']);
}
if ($action === 'DELETE') {
$constraintId = filter_var($payload['constraint_id'] ?? null, FILTER_VALIDATE_INT);
if (!$constraintId) {
JsonResponse::send(422, ['error' => 'Contrainte invalide.']);
}
$deleted = $this->ptaModel->deleteConstraint((int) $constraintId, (int) $agentId);
JsonResponse::send($deleted ? 200 : 404, [
'message' => $deleted ? 'La contrainte a été supprimée.' : 'Contrainte introuvable.',
]);
}
$type = strtoupper(trim((string) ($payload['type_contrainte'] ?? '')));
$start = trim((string) ($payload['date_debut'] ?? ''));
$end = trim((string) ($payload['date_fin'] ?? ''));
$comment = trim((string) ($payload['commentaire'] ?? ''));
$startDate = DateTimeImmutable::createFromFormat('!Y-m-d', $start);
$endDate = $end !== '' ? DateTimeImmutable::createFromFormat('!Y-m-d', $end) : null;
if (!in_array($type, ['MEDICALE', 'TEMPS_PARTIEL_THERAPEUTIQUE'], true)
|| !$startDate || $startDate->format('Y-m-d') !== $start
|| ($end !== '' && (!$endDate || $endDate->format('Y-m-d') !== $end || $endDate < $startDate))
|| $comment === '') {
JsonResponse::send(422, ['error' => 'Type, dates ou commentaire de contrainte invalides.']);
}
$rate = $payload['quotite_temporaire'] ?? null;
$rate = ($rate === null || $rate === '') ? null : filter_var($rate, FILTER_VALIDATE_FLOAT);
if ($rate !== null && ($rate === false || $rate <= 0 || $rate > 100)) {
JsonResponse::send(422, ['error' => 'La quotité temporaire doit être comprise entre 1 et 100 %.']);
}
$maxDayHours = $payload['maximum_heures_jour'] ?? null;
$maxWeekHours = $payload['maximum_heures_semaine'] ?? null;
$maxDayMinutes = ($maxDayHours === null || $maxDayHours === '') ? null : (int) round((float) $maxDayHours * 60);
$maxWeekMinutes = ($maxWeekHours === null || $maxWeekHours === '') ? null : (int) round((float) $maxWeekHours * 60);
try {
$id = $this->ptaModel->saveConstraint([
'id_agent' => (int) $agentId,
'type_contrainte' => $type,
'date_debut' => $start,
'date_fin' => $end !== '' ? $end : null,
'quotite_temporaire' => $rate,
'maximum_minutes_jour' => $maxDayMinutes,
'maximum_minutes_semaine' => $maxWeekMinutes,
'interdit_matin' => !empty($payload['interdit_matin']) ? 1 : 0,
'interdit_midi' => !empty($payload['interdit_midi']) ? 1 : 0,
'interdit_soir' => !empty($payload['interdit_soir']) ? 1 : 0,
'commentaire' => $comment,
]);
JsonResponse::send(201, ['message' => 'La contrainte prioritaire a été enregistrée.', 'id_contrainte' => $id]);
} catch (Throwable $e) {
JsonResponse::send(500, ['error' => 'Impossible denregistrer la contrainte.', 'details' => $e->getMessage()]);
}
}
public function wish(): void
{
$this->access->requireService();
Request::requireMethod('POST');
$payload = Request::json();
Csrf::assertPayload($payload);
$action = strtoupper(trim((string) ($payload['action'] ?? 'SAVE')));
$agentId = filter_var($payload['agent_id'] ?? null, FILTER_VALIDATE_INT);
if (!$agentId || $this->agentModel->findActive((int) $agentId) === null) {
JsonResponse::send(422, ['error' => 'Agent invalide.']);
}
if ($action === 'DELETE') {
$wishId = filter_var($payload['wish_id'] ?? null, FILTER_VALIDATE_INT);
if (!$wishId) {
JsonResponse::send(422, ['error' => 'Préférence invalide.']);
}
$deleted = $this->ptaModel->deleteWish((int) $wishId, (int) $agentId);
JsonResponse::send($deleted ? 200 : 404, [
'message' => $deleted ? 'La préférence ou interdiction a été supprimée.' : 'Élément introuvable.',
]);
}
$structureId = filter_var($payload['structure_id'] ?? null, FILTER_VALIDATE_INT);
$type = strtoupper(trim((string) ($payload['type_souhait'] ?? '')));
$priority = filter_var($payload['priorite'] ?? 1, FILTER_VALIDATE_INT);
$distance = $payload['distance_km'] ?? null;
$distance = ($distance === null || $distance === '') ? null : filter_var($distance, FILTER_VALIDATE_FLOAT);
$comment = trim((string) ($payload['commentaire'] ?? ''));
if (!$structureId || $this->structureModel->findActive((int) $structureId) === null
|| !in_array($type, ['PREFERENCE', 'INTERDICTION'], true)
|| !$priority || $priority < 1 || $priority > 5
|| ($distance !== null && ($distance === false || $distance < 0))) {
JsonResponse::send(422, ['error' => 'Lieu, type, priorité ou distance invalide.']);
}
try {
$id = $this->ptaModel->saveWish([
'id_agent' => (int) $agentId,
'id_structure' => (int) $structureId,
'type_souhait' => $type,
'priorite' => (int) $priority,
'distance_km' => $distance,
'commentaire' => $comment !== '' ? $comment : null,
]);
JsonResponse::send(201, ['message' => 'La préférence de lieu a été enregistrée.', 'id_souhait' => $id]);
} catch (Throwable $e) {
JsonResponse::send(500, ['error' => 'Impossible denregistrer la préférence.', 'details' => $e->getMessage()]);
}
}
}