eptm_dashboard/data/docs/02-sync-escada.md

4.4 KiB

Synchronisation Escada (pull)

La synchronisation depuis Escada télécharge les PDFs (absences, BN, notes, fiches) 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 Selenium 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

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 (Selenium)

scripts/sync_esacada.py --sync-all CLASSE1 CLASSE2 ...

  1. Selenium ouvre Escadaweb avec un profil persistant (data/browser_profile/)
  2. 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)
  3. À la fin, écrit ALL_DONE dans la sortie standard et data/sync_all_done.json (timestamp).

Phase 2 : Import en DB

scripts/run_imports.py est lancé par le wrapper après réception du signal ALL_DONE :

  1. Parse chaque PDF d'absences → upsert des Absence (avec déduplication sur (apprenti, date, période))
  2. Parse les BN → insère NotesBulletin
  3. Parse les notes → insère NotesExamen
  4. Parse les fiches → upsert ApprentiFiche
  5. 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).
  6. Écrit data/sync_last_result.json avec les compteurs détaillés.

Pendings : modifications locales en attente

Quand un utilisateur modifie une absence dans l'application (page Apprenti), une entrée est créée dans la table EscadaPending avec une action :

  • E : marquer comme excusée sur Escada
  • N : marquer comme non excusée sur Escada
  • clear : retirer l'absence sur Escada (= remettre l'apprenti présent)

Ces pendings sont visibles sur la page /escada dans la section "Modifications en attente".

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 Selenium (captcha, session expirée).
  • Aucune classe récupérée : token de session Escada expiré → relancer le rafraîchissement.
  • Logs détaillés : page /logs affiche operations.log en temps réel.