eptm_dashboard/docs/03-push-escada.md

94 lines
4.1 KiB
Markdown
Raw Permalink 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.

# Push vers Escada
Le push envoie les modifications locales (absences en `EscadaPending` + notices en attente dans `Notice`) vers Escadaweb via Playwright.
## Page : `/escada` → « Pousser vers Escada »
### Quand un pending d'absence est créé ?
Chaque modification d'absence dans l'application crée ou met à jour une entrée dans `EscadaPending` :
| Action utilisateur | Pending créé |
|---------------------------------------------------|---------------------|
| Marquer P3 comme excusée | `action=E` |
| Marquer P5 comme non excusée | `action=N` |
| Retirer une absence (présent) | `action=clear` |
| Excuse rapide d'une journée (page Apprentis) | `action=E` × n |
| « Absent toute la journée » (selon horaire classe)| `action=N` × n (sur enregistrement) |
La contrainte d'unicité `(apprenti_id, date, periode)` garantit qu'une période a au plus un pending. Si on modifie deux fois la même période, le dernier pending écrase le précédent.
## Phases du push d'absences
### Phase 1 : Préparation
`scripts/push_to_escada.py` :
1. Lit toutes les entrées de `EscadaPending`
2. Groupe par classe pour minimiser les navigations Escada
3. Lance Playwright
### Phase 2 : Exécution Playwright
Pour chaque pending :
1. Navigue jusqu'à la page d'absences de l'apprenti dans Escadaweb
2. Trouve la cellule (date × période)
3. Selon l'action :
- `E` : sélectionne « Excusée » dans le dropdown
- `N` : sélectionne « Non excusée »
- `clear` : remet à blanc (= apprenti présent)
4. Clique sur **Speichern** (Enregistrer)
5. Si OK → supprime l'entrée du `EscadaPending`
6. Si erreur → conserve l'entrée et la liste dans `PUSH_DONE`
### Phase 3 : Rapport
Le script imprime une ligne `PUSH_DONE {"ok": N, "err": [...]}` à la fin. L'app la parse et affiche :
- Nombre d'envois OK
- Liste des erreurs (chaque erreur mentionne l'apprenti, la date et la période)
## Push de notices
Les notices créées localement (création d'avis de retenue ou de sanction depuis l'app) sont enregistrées dans la table `Notice` (statut `pending`), puis poussées par `scripts/push_notices.py`.
### Workflow
1. L'utilisateur clique sur « Générer l'avis » dans une modale d'avis sanction/retenue. Cela :
- Génère le PDF (téléchargement)
- Crée une `Notice` avec `source="sanction"` ou `"retenue"`, `status="pending"`, et le préfixe `(<username>)` est ajouté en début de la remarque pour traçabilité
2. La file `Notice (status=pending)` est visible côté admin sur `/escada` ou via les tâches cron.
3. `push_notices.py` :
- Lit les notices `pending`
- Pour chaque, navigue dans Escada (page de l'apprenti → onglet Notices) et crée la notice avec son titre + remarque + date
- Marque comme `synced` si OK, `error` (+ `error_msg`) sinon
### task_kind cron
- `task_kind=push` + `sync_abs=1` → pousse les absences
- `task_kind=push` + `sync_notices=1` → pousse les notices
- `task_kind=push` + les deux → push absences puis notices (séquentiel)
## Que faire si un push échoue ?
1. **Vérifier les logs** (`/logs`) — l'erreur exacte est tracée.
2. **Causes fréquentes** :
- Session Escada expirée → relancer un Actualiser sur la page Escada (re-login automatique)
- Apprenti avec un nom différent dans Escada → renommage à faire dans la DB ou côté Escada
- Page de notation verrouillée par un collègue (Escada utilise des locks pessimistes)
3. **Re-tenter** : les pendings (et notices `pending`/`error`) restent en file d'attente, un nouveau push les retraitera.
## Audit
Chaque push manuel logue qui l'a déclenché :
```
[abs] {user} : Push Escada démarré par {username}
[notice] {user} : création (sanction) pour {apprenti}
[notice] {user} : création (retenue) pour {apprenti} — case=devoir
```
Côté résultat :
- `Push terminé — ok:N erreurs:M` dans `operations.log`
## Push automatique via cron
Les tâches planifiées de type `push` ou `push_then_sync` exécutent les mêmes scripts. Voir la section [Tâches planifiées](#).