eptm_dashboard/docs/02-sync-escada.md

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 ...

  1. Playwright 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 — y compris représentant légal + flag compensation)
    • Si l'option « Notices » est cochée : pull l'historique via pull_notices.py
  3. À la fin, écrit ALL_DONE dans la sortie standard et data/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 :

  1. Parse chaque PDF d'absences → upsert des Absence (déduplication sur (apprenti, date, période))
  2. Parse les BN → insère NotesBulletin (toutes les notes du BN sont stockées, pas seulement les moyennes)
  3. Parse les notes → insère NotesExamen
  4. Parse les fiches → upsert ApprentiFiche (adresse perso, entreprise, représentant légal, compensation_desavantages, majeur)
  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.

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 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 ». 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 /logs affiche operations.log en temps réel.