6 KiB
Synchronisation Escada (pull)
La synchronisation depuis Escada télécharge les PDFs / vues (absences, BN, Matu, notes, fiches, notices) et les importe en base. C'est l'opération la plus complexe de l'application.
Page : /escada
Sélection des classes
La liste des classes vient d'un cache disque (data/esacada_classes.json) rempli via le bouton Actualiser. Le rafraîchissement lance une session Playwright qui se connecte à Escadaweb et récupère la liste complète des classes.
Note : MP, MI et « Formation » sont filtrées de l'affichage UI mais conservées dans le cache (elles servent au matching Matu pro).
Options de synchronisation
| Option | Effet |
|---|---|
| Absences | Télécharge les PDFs d'absences + parse + import |
| BN | Bulletins de notes + moyennes Matu (semestres complets) |
| Notes | Notes d'examens finales |
| Données apprentis | Fiches personnelles : adresse, entreprise, formateur, représentant légal, statut compensation des désavantages, majeur/mineur |
| Notices | Importe l'historique des notices Escada (table apprenti_notices) |
Force réimportation complète
La case « Forcer la réimportation complète » (signalée en jaune) écrase tous les statuts d'absences côté local par les valeurs du PDF, et vide les pendings des absences concernées.
À utiliser uniquement quand on veut reprendre l'état complet d'Escada (par exemple après un test ou une corruption locale).
Sans ce flag :
- Les absences modifiées localement et pas encore poussées (= en pending) sont préservées.
- Les nouvelles absences du PDF sont importées normalement.
- Les absences orphelines (présentes en DB mais absentes du PDF) sont supprimées.
Phases d'exécution
Phase 1 : Scraping (Playwright)
scripts/sync_esacada.py --sync-all CLASSE1 CLASSE2 ...
- Playwright ouvre Escadaweb avec un profil persistant (
data/browser_profile/). - Pour chaque classe sélectionnée :
- Télécharge le PDF d'absences
- Télécharge le PDF de bulletin
- Télécharge le PDF de notes
- Pour les apprentis Matu : télécharge le PDF Matu de la classe MP correspondante
- Scrape les fiches personnelles (vue ViewLernende — y compris représentant légal + flag compensation)
- Si l'option « Notices » est cochée : pull l'historique via
pull_notices.py
- À la fin, écrit
ALL_DONEdans la sortie standard etdata/sync_last_result.json(timestamp).
Phase 2 : Import en DB
scripts/run_imports.py est lancé par le wrapper après réception du signal ALL_DONE :
- Parse chaque PDF d'absences → upsert des
Absence(déduplication sur (apprenti, date, période)) - Parse les BN → insère
NotesBulletin(toutes les notes du BN sont stockées, pas seulement les moyennes) - Parse les notes → insère
NotesExamen - Parse les fiches → upsert
ApprentiFiche(adresse perso, entreprise, représentant légal, compensation_desavantages, majeur) - Détecte les orphelines (absences en DB mais absentes du PDF dans la fenêtre temporelle) et les supprime (sauf si elles ont un pending, sans force).
- Écrit
data/sync_last_result.jsonavec les compteurs détaillés.
Re-parsing sans re-téléchargement
scripts/run_imports.py --reparse-bn-only permet de re-traiter tous les PDFs déjà téléchargés (utile après un changement dans le parser BN, sans relancer Playwright).
Pendings : modifications locales en attente
Quand un utilisateur modifie une absence dans l'application (page Apprentis), une entrée est créée dans la table EscadaPending avec une action :
E: marquer comme excusée sur EscadaN: marquer comme non excusée sur Escadaclear: retirer l'absence sur Escada (= remettre l'apprenti présent)
Ces pendings sont visibles sur la page /escada dans la section « Modifications en attente ». Le bouton Pousser vers Escada les vide en envoyant chaque modification.
Notices Escada (import et création)
Les notices sont les remarques rattachées à un apprenti dans Escada (avis de sanction, retenue, remarque libre, etc.).
Import (pull)
scripts/pull_notices.py lit la vue Escada de chaque classe, scrape les notices, et upsert dans la table apprenti_notices (clé (apprenti, date_event, titre)). Affichage en lecture seule dans l'onglet « Notices » de la fiche apprenti et de la vue classe.
Création (push)
Voir le chapitre dédié Push vers Escada — la création locale d'un avis de sanction ou de retenue crée une Notice (table locale), qui est ensuite poussée vers Escada par scripts/push_notices.py.
Cas particuliers gérés
| Situation | Sans force | Avec force |
|---|---|---|
| Absence dans PDF + pending sur la même | Pending préservé | Pending écrasé |
| Absence dans PDF + DB sans pending | Mise à jour si différent | Mise à jour systématique |
| Absence dans DB, absente du PDF, sans pending | Supprimée (orpheline) | Supprimée |
| Absence dans DB, absente du PDF, avec pending=clear | Conservée (le clear gagne) | Supprimée |
Diagnostic
- Timeout > 15 min : vérifier les logs
data/logs/operations.log. Souvent un problème Playwright (captcha, session expirée). - Aucune classe récupérée : token de session Escada expiré → relancer le rafraîchissement (re-login automatique avec les identifiants stockés en /params, code 2FA généré via
totp_secret). - Logs détaillés : page
/logsafficheoperations.logen temps réel.