Ajout des commentaires dans le code
This commit is contained in:
@@ -19,6 +19,28 @@ use DomainException;
|
||||
use PDO;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Semaines types : modèles lundi→vendredi rattachés à UN agent.
|
||||
*
|
||||
* Une semaine type n'est PAS un planning : elle décrit une organisation
|
||||
* générique et ne produit aucun créneau tant qu'elle n'est pas appliquée à une
|
||||
* semaine (apply) ou dupliquée sur une période (applyPeriod). Voir README_V7_10.md.
|
||||
*
|
||||
* Deux origines pour une semaine type, qui convergent vers
|
||||
* WeekTemplateModel::persistTemplate() :
|
||||
* - store() : capture d'une semaine réellement planifiée ;
|
||||
* - storeEntries() : composition directe dans l'éditeur.
|
||||
*
|
||||
* Tout est réservé au Service Enfance : un modèle porte des créneaux sur
|
||||
* plusieurs lieux, il déborde donc du périmètre d'un responsable de structure.
|
||||
*
|
||||
* Convention de codes d'erreur propre à ce contrôleur :
|
||||
* - 409 / TEMPLATE_EXISTS : un modèle porte déjà ce nom (l'interface propose
|
||||
* alors de le remplacer en renvoyant replace: true) ;
|
||||
* - 422 / TEMPLATE_INVALID : contenu du modèle refusé.
|
||||
* Le tri se fait sur le TEXTE du message d'exception (« déjà ce nom ») : toute
|
||||
* reformulation de ce message dans WeekTemplateModel casse la distinction.
|
||||
*/
|
||||
final class WeekTemplateController
|
||||
{
|
||||
private WeekTemplateModel $templateModel;
|
||||
@@ -34,6 +56,12 @@ final class WeekTemplateController
|
||||
$this->access = new Access($pdo);
|
||||
}
|
||||
|
||||
/**
|
||||
* GET api/week_templates.php — liste des semaines types d'un agent.
|
||||
*
|
||||
* Ne renvoie que des compteurs, pas le contenu : la liste sert à choisir,
|
||||
* show() sert à ouvrir.
|
||||
*/
|
||||
public function index(): void
|
||||
{
|
||||
$this->access->requireService();
|
||||
@@ -59,7 +87,16 @@ final class WeekTemplateController
|
||||
}
|
||||
|
||||
/**
|
||||
* Contenu détaillé d'une semaine type, pour l'ouvrir dans l'éditeur.
|
||||
* GET api/week_template.php — contenu détaillé d'une semaine type.
|
||||
*
|
||||
* Le modèle est retrouvé par (template_id, agent_id) et non par le seul
|
||||
* identifiant : c'est ce qui empêche de lire le modèle d'un autre agent en
|
||||
* changeant l'identifiant dans l'URL.
|
||||
*
|
||||
* Les drapeaux `structure_active` et `motif_actif` sont conservés bien que
|
||||
* toujours vrais à la création : un lieu ou un motif peut être désactivé
|
||||
* APRÈS l'enregistrement du modèle, et l'éditeur doit le signaler plutôt que
|
||||
* d'échouer au moment de l'application.
|
||||
*/
|
||||
public function show(): void
|
||||
{
|
||||
@@ -103,7 +140,14 @@ final class WeekTemplateController
|
||||
}
|
||||
|
||||
/**
|
||||
* Enregistre une semaine type composée dans l'éditeur.
|
||||
* POST api/save_week_template_entries.php — enregistre un modèle composé
|
||||
* directement dans l'éditeur (V7.10).
|
||||
*
|
||||
* Les listes de motifs et de lieux autorisés sont calculées ICI puis
|
||||
* transmises au modèle : celui-ci ne connaît pas les règles d'accès et se
|
||||
* contente de rejeter ce qui n'est pas dans les listes reçues.
|
||||
*
|
||||
* Charge utile : agent_id, name, entries[], replace (bool), csrf_token.
|
||||
*/
|
||||
public function storeEntries(): void
|
||||
{
|
||||
@@ -172,6 +216,14 @@ final class WeekTemplateController
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* POST api/save_week_template.php — capture une semaine planifiée en modèle.
|
||||
*
|
||||
* Point de départ historique : l'utilisateur saisit une semaine « normale »,
|
||||
* puis la fige comme modèle réutilisable.
|
||||
*
|
||||
* Charge utile : agent_id, week, name, replace (bool), csrf_token.
|
||||
*/
|
||||
public function store(): void
|
||||
{
|
||||
$this->access->requireService();
|
||||
@@ -214,6 +266,15 @@ final class WeekTemplateController
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* POST api/apply_week_template.php — applique un modèle à UNE semaine.
|
||||
*
|
||||
* Deux modes : `merge` complète les créneaux existants, `replace` les
|
||||
* remplace. Appliquer sur une semaine validée la repasse en brouillon
|
||||
* (`requires_revalidation`).
|
||||
*
|
||||
* Charge utile : template_id, agent_id, week, mode (merge|replace), csrf_token.
|
||||
*/
|
||||
public function apply(): void
|
||||
{
|
||||
$this->access->requireService();
|
||||
@@ -268,6 +329,21 @@ final class WeekTemplateController
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* POST api/preview_week_template_period.php — simulation SANS écriture.
|
||||
*
|
||||
* Étape obligatoire dans l'interface avant applyPeriod() : une application
|
||||
* sur période touche des dizaines de semaines et peut rouvrir des plannings
|
||||
* validés. L'utilisateur doit voir le volume avant de confirmer.
|
||||
*
|
||||
* `period_filter` restreint le périmètre au calendrier scolaire :
|
||||
* all → toutes les semaines de l'intervalle ;
|
||||
* school → semaines scolaires seulement (périscolaire) ;
|
||||
* extra → vacances scolaires seulement (extrascolaire).
|
||||
*
|
||||
* Charge utile : template_id, agent_id, start_date, end_date, mode,
|
||||
* period_filter, csrf_token.
|
||||
*/
|
||||
public function previewPeriod(): void
|
||||
{
|
||||
$this->access->requireService();
|
||||
@@ -323,6 +399,18 @@ final class WeekTemplateController
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* POST api/apply_week_template_period.php — applique un modèle sur une période.
|
||||
*
|
||||
* Mêmes paramètres que previewPeriod(), mais avec écriture. Le message de
|
||||
* retour est volontairement détaillé (créés / ignorés / remplacés / rouverts) :
|
||||
* l'opération est massive, difficile à annuler à la main, et l'utilisateur
|
||||
* doit pouvoir vérifier a posteriori qu'elle a fait ce qu'il attendait.
|
||||
*
|
||||
* Les quotas sont renvoyés indexés par date de début de période : une
|
||||
* application à cheval sur deux années civiles touche DEUX quotas annuels
|
||||
* distincts, et l'interface doit rafraîchir les deux.
|
||||
*/
|
||||
public function applyPeriod(): void
|
||||
{
|
||||
$this->access->requireService();
|
||||
@@ -420,6 +508,14 @@ final class WeekTemplateController
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* POST api/delete_week_template.php — supprime une semaine type.
|
||||
*
|
||||
* La suppression est filtrée par agent_id ; un modèle appartenant à un autre
|
||||
* agent ressort en 404 plutôt qu'en 403, pour ne pas révéler son existence.
|
||||
* Les créneaux DÉJÀ appliqués ne sont pas touchés : le modèle n'est qu'un
|
||||
* patron, pas un lien vivant vers les plannings produits.
|
||||
*/
|
||||
public function destroy(): void
|
||||
{
|
||||
$this->access->requireService();
|
||||
@@ -440,6 +536,11 @@ final class WeekTemplateController
|
||||
JsonResponse::send(200, ['success' => true, 'message' => 'Semaine type supprimée.']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Décode « AAAA-Www ». Copie locale, comme dans les autres contrôleurs.
|
||||
*
|
||||
* @return array{0: int, 1: int}|null [année ISO, semaine], ou null.
|
||||
*/
|
||||
private function parseWeek(string $value): ?array
|
||||
{
|
||||
if (!preg_match('/^(\d{4})-W(\d{2})$/', $value, $matches)) {
|
||||
|
||||
Reference in New Issue
Block a user