Apparence
Exporter CEGI vers la GTA
Ce guide concerne l'administrateur du serveur Windows CEGI. Le module se trouve dans scripts/cegi/. Il utilise Windows PowerShell 5.1, le DSN ODBC ALFA et l'assemblage .NET fourni avec WinSCP. L'assemblage installé sur le poste de test ne fonctionne pas sous PowerShell 7.
La collecte reçoit les salariés et les droits à congés. Le flux congés initialise les droits puis importe les cumuls mensuels ; son fonctionnement est décrit dans Imports CEGI par SFTP. Avant le premier dépôt, validez les totaux et les périodes avec la paie, puis suivez la procédure d'initialisation des droits CA.
Déposer manuellement sur le poste local
Aucune opération de ce guide ne vise la préproduction.
- Depuis le dépôt, exécutez
powershell.exe -NoProfile -File scripts/cegi/Initialize-LocalSftp.ps1. Le script prépare les comptes sur127.0.0.1:8088, remplace les secrets d'exemple dans.envet lit la clé publique dans le conteneur local. - Chargez les paramètres avec
docker compose up -d --no-deps sftpgo backend worker beat. - Dans WinSCP : protocole SFTP, hôte 127.0.0.1, port 2222, utilisateur cegi-depositor. Le mot de passe est
SFTP_DEPOSITOR_PASSWORDdans le.envlocal. Comparez l'empreinte avec celle annoncée par l'initialisation. - Déposez le CSV à la racine
/. Désactivez la reprise par fichier temporaire et la conservation des dates de modification dans les paramètres de transfert. - Lancez
docker compose exec -T backend python manage.py poll_sftp_imports. - Consultez les Lots d'import, puis les compteurs. Un matricule absent de la base locale rejette le fichier : importez d'abord les salariés concernés.
L'importeur voit /incoming ; le déposant voit ce même dossier comme /. Il peut téléverser et lister les noms, mais ni télécharger, ni écraser, renommer ou supprimer. Le droit de lister est nécessaire à l'ouverture d'une session WinSCP.
SFTPGo conserve les transferts incomplets dans /srv/sftpgo/upload-tmp, hors du dossier collecté et sur le même volume. Le fichier final n'apparaît qu'après transfert complet. Une interruption ne publie pas de fichier partiel.
L'initialisation ne réinitialise aucun volume. Elle refuse une racine inattendue sur un compte existant ou une authentification administrateur inconnue.
Installer l'exporteur sur CEGI
Copiez scripts/cegi/ dans C:\APAJH\CegiExport, puis config.example.json en config.json hors du dépôt. Exécutez sous le compte Windows propriétaire du DSN utilisateur ALFA. Accordez à ce compte seulement les droits SQL SELECT nécessaires : le script utilise l'authentification Windows et ne peut pas réduire les droits d'un compte déjà privilégié.
Vérifiez Get-OdbcDsn -Name ALFA et testez l'extraction dans le processus choisi. La mention « 32/64-bit » d'un DSN utilisateur ne garantit pas que son pilote existe dans les deux architectures.
Renseignez l'hôte SFTP, le port et l'empreinte vérifiée dans config.json. 127.0.0.1 désigne la machine exécutant le script, pas automatiquement le poste de développement. Le raccordement réseau depuis CEGI est une étape distincte.
powershell
powershell.exe -NoProfile -File .\Save-SftpCredential.ps1 -ConfigPath C:\APAJH\CegiExport\config.jsonLe secret saisi est chiffré par Windows pour ce compte et cette machine, dans sftp.credential.xml. Le dossier de travail est réservé au compte et à SYSTEM. Recréez le secret sur un autre serveur ou compte ; ne le copiez pas. Les secrets Docker restent dans .env, jamais dans Git ni dans le modèle JSON.
Requêtes et formats
Congés
sql/leave.sql conserve l'agrégation CP/AJ en jours de la requête validée, ancienneté comprise, sans déduire les prises ni couper l'année au mois précédent. Le script fournit ses paramètres ODBC : les marqueurs ? ne s'exécutent pas directement dans SSMS.
| Acquisition configurée | Année de prise | État validé |
|---|---|---|
| 2025 | 2026 | final |
| 2026 | 2027 | accruing |
Modifiez LeavePeriods après validation paie ; le passage d'année ne finalise rien automatiquement. L'extraction inclut tous les mouvements des années sélectionnées, même datés dans le futur. Son horodatage n'est pas une clôture paie.
Le CSV UTF-8 séparé par ; contient pers_mat, usage_year, entitlement_status, acquired_days, snapshot_at. Les matricules restent du texte. Un montant négatif, trop élevé, avec plus de deux décimales ou un doublon bloque l'envoi, sans correction silencieuse.
Salariés et établissements
EmployeesQuery désigne sql/employees.sql, la requête à 37 colonnes construite depuis le schéma et les catalogues transmis. Le modèle de configuration utilise le chemin d'installation C:\APAJH\CegiExport\sql\employees.sql : adaptez-le si vous installez ailleurs. Validez d'abord le résultat dans SSMS sur CEGI, puis utilisez ExportOnly avant le premier transfert. sql/employee-source-catalog.sql fournit les codes source à vérifier pour les horaires, coordonnées et attributs, sans afficher de données personnelles.
Le catalogue transmis confirme les sources suivantes. Les nombres de salariés du catalogue comptent les historiques ; ils ne prouvent pas la présence d'une valeur à la date d'extraction.
| Donnée cible | Source confirmée |
|---|---|
attr_danc | Attribut DANC, date de référence pour l'ancienneté |
cont_hheb | Constante mensuelle AARM résolue, convertie en hebdomadaire (× 12 / 52) |
pers_dnai | Date de naissance PYPERSONNE.PER_NAISSANCE |
pers_tel2 (fixe personnel) | Type de coordonnées 1 |
pers_tel3 (mobile personnel) | Type de coordonnées 2 |
pers_email (personnel) | Type de coordonnées 5 |
per_sexe | Civilités 1/Madame et 2/Mademoiselle → F ; 3/Monsieur → H |
pos_cod, pos_lib (fonction GTA) | PYQUAL_CNT → PYQUALIFICATION |
code_qc, lib_qc | PYQCONV_CNT → PYQUALCONV |
cont_cod, lib_typcont | PYTYPECNT_CNT → PYTYPECONTRAT |
PYPOSITION contient PERMANENT et REMPLAÇANT : ces positions administratives ne remplissent pas la fonction GTA. Une fonction absente reste vide ; elle n'est pas remplacée par la qualification conventionnelle. La qualification du contrat prend en revanche pos_lib s'il est renseigné, sinon lib_qc. Les codes pos_cod et code_qc restent chacun associés à leur champ source ; aucune substitution de code n'est effectuée.
L'export produit 37 en-têtes. À l'import, seuls les en-têtes et valeurs suivants sont obligatoires : cont_id, pers_mat, pers_nom, pers_pre, cont_datd, cont_hheb, cont_cod, dos_code. Les identifiants CEGI permettent le rapprochement et le rejeu sans doublon. Les autres colonnes peuvent être absentes, vides ou contenir NULL (sans distinction de casse) : elles sont importées comme non renseignées. Une valeur fournie doit respecter son format. pers_matp, s'il est renseigné, doit correspondre à pers_mat. lib_typcont est nécessaire uniquement si le code désigne un type encore inconnu de GTA ; sinon son absence conserve le libellé du référentiel. Une absence de téléphone ou d'email n'est pas remplacée par une autre coordonnée. Les colonnes inutilisées niv_* et par_* restent vides.
Les colonnes pers_tel1, doc_lib, per_enf, code_pay, code_emb, lib_emb, cont_sdtc et cont_datfprev sont retirées. Les anciens CSV restent acceptés : leur contenu dans ces colonnes est ignoré. Le rattachement utilise uniquement dos_code ; le libellé du dossier n'est pas nécessaire. La fin du contrat provient uniquement de cont_datf, qui peut être vide. La date de naissance pers_dnai reste exportée et importée.
Le téléphone professionnel, le nombre d'enfants à charge et le motif d'embauche déjà présents dans GTA sont préservés lors des réimports. Ils restent vides par défaut sur les nouvelles fiches ou nouveaux contrats. Le téléphone professionnel se renseigne dans GTA selon les droits habituels. L'attribut ENFCH a été identifié pour les enfants à charge, mais son import séparé n'est pas encore construit et aucune tâche supplémentaire n'est installée.
La requête conserve les contrats sans fin réelle ou dont la fin réelle est au 31 décembre 2025 ou après. Elle produit une ligne par contrat : deux contrats d'un même salarié ne constituent pas un doublon. Elle bloque un matricule partagé par deux personnes, un contrat en double et les historiques qui donnent plusieurs valeurs applicables à la même date. Les données du contrat sont lues à la date d'extraction, ramenée au début pour un contrat futur ou à la fin pour un contrat terminé. Les données personnelles sont communes aux contrats et lues à la date d'extraction. Les seules écritures SQL sont dans une table temporaire de session ; les tables CEGI ne sont pas modifiées.
Les types 3 et 4 désignent le mobile et le courriel professionnels : ils ne remplacent pas les coordonnées personnelles. L'attribut SITUA est identifié pour la situation familiale, mais les 37 colonnes actuelles ne contiennent pas cette donnée. L'ancienneté initialisée PYANCINI ne contient aucune ligne dans le catalogue transmis.
Le résultat de sql/employee-hours.sql confirme AARM = 151.67 et AARN = 35 au niveau national, avec des valeurs AARM propres aux contrats. Aucune valeur AARN n'est remontée aux autres niveaux à la date du contrôle. L'interface CEGI prévoit une résolution contrat → établissement → entreprise → national pour ces constantes. Appliquer cette règle à AARN fournirait donc 35 heures même pour les contrats dont le mensuel est réduit.
La règle validée utilise le mensuel AARM individuel (à défaut, sa valeur héritée) uniquement pour calculer l'hebdomadaire : mensuel × 12 / 52, arrondi à deux décimales, puis exprimé en centièmes entiers dans cont_hheb. Le calcul part de la précision source, sans arrondir le mensuel au préalable. Ainsi, 121.335 donne 2800, et 60.668 donne 1400.
cont_hmes est retiré du nouveau CSV. La GTA calcule toujours le mensuel par hebdomadaire × 52 / 12, arrondi à deux décimales. Les anciens fichiers avec cont_hmes restent acceptés par le récepteur, mais cette colonne est ignorée, même si elle est vide ou incohérente. L'exporteur produit exclusivement le nouveau format à 37 colonnes. La migration supprime le champ mensuel CEGI historique ; les contrats existants utilisent aussi le calcul GTA.
Exécutez sql/employee-establishments.sql dans SSMS. Les liens sont :
| Information | Source |
|---|---|
Dossier de paie : dos_code, doc_lib | PYCONTRAT.RGPCNT_ID → PYREGROUPECNT |
| Établissement employeur | PYCONTRAT.ETA_ID → PYETABLISSEMENT.ETAB_ID → CMETABLISSEMENT |
Le diagnostic exclut les contrats sortis avant le 31 décembre 2025 et affiche un contrat par personne : actif en priorité, sinon passé, sinon futur, puis début décroissant et identifiant. Ce choix de diagnostic ne doit pas supprimer les contrats simultanés du flux définitif sans validation métier.
Les exemples reçus confirment 20DP/Siège et 30DP/EPAS pour la paie, avec les établissements 20P et 30P. Le récepteur utilise dos_code pour le rattachement paie du contrat. Le lieu de travail est exclu du flux CEGI : il se renseigne dans la GTA. L'import ne renseigne pas ce lieu à la création et préserve les lieux principal et secondaires existants lors des mises à jour.
Extraire et déposer
powershell
powershell.exe -NoProfile -File .\Export-Cegi.ps1 -Flow Leave -ConfigPath C:\APAJH\CegiExport\config.json -Action ExportOnly
powershell.exe -NoProfile -File .\Export-Cegi.ps1 -Flow Leave -ConfigPath C:\APAJH\CegiExport\config.json -Action SendLe second appel utilise le CSV déjà préparé. Pour l'autre flux, utilisez -Flow Employees. Pour un CSV récupéré manuellement, ajoutez -InputCsv C:\Exports\conges.csv aux deux appels.
Le dossier de travail contient les CSV, un manifeste d'attente par flux, les reçus et runs.jsonl. Une relance conserve les octets et l'horodatage. Une modification du fichier ou de la destination bloque la reprise. Le reçu empêche un second envoi pour le même cycle. Une ancienne attente est traitée avant une nouvelle extraction : relancez ensuite pour le cycle courant.
Si un fichier existe après un transfert incertain, le module tente de comparer son empreinte distante. Le déposant peut ne pas avoir ce droit : la reprise reste alors bloquée. L'administrateur compare le SHA-256 du manifeste avec le lot GTA ou via l'importeur, sans transmettre ce compte à l'exporteur. Après confirmation, il déplace Leave.pending.json vers Leave.<Cycle>.sent.json (ou l'équivalent Employees). En cas d'écart, conservez les fichiers et investiguez.
Les journaux n'enregistrent pas les données salariés. « Déposé » ne signifie pas « importé » : contrôlez la GTA. La purge locale n'est pas automatique ; appliquez la durée de conservation retenue aux CSV confirmés, sans supprimer une attente non résolue.
Planifier après les essais
Windows doit utiliser le fuseau Paris. Depuis le compte d'exécution :
powershell
powershell.exe -NoProfile -File .\Install-CegiTasks.ps1 -ConfigPath C:\APAJH\CegiExport\config.json -DefinitionOnly
powershell.exe -NoProfile -File .\Install-CegiTasks.ps1 -ConfigPath C:\APAJH\CegiExport\config.jsonLa première commande affiche les définitions sans installer. La seconde demande le mot de passe Windows pour une exécution sans session ouverte. Le compte doit avoir le droit d'ouverture de session en tant que tâche et celui d'enregistrer les tâches. Le script ne modifie aucune stratégie Windows. -Flows Leave installe uniquement les congés si le flux salariés n'est pas validé.
Les horaires sont 03 h 45 chaque jour et 04 h 00 le 6 de chaque mois. Deux reprises sont espacées de dix minutes, avec cinq minutes maximum par exécution, sans concurrence. Une échéance manquée est rattrapée au démarrage. Un dépôt après 04 h 37 attend la collecte suivante, sauf lancement manuel dans la GTA.
Pour corriger un mois déjà envoyé, conservez le reçu précédent dans un dossier d'archives hors des noms actifs puis relancez. Ne supprimez pas une attente pour forcer une nouvelle extraction. Vérifiez aussi le fonctionnement sans session RDP.
Vérifications
powershell
powershell.exe -NoProfile -File scripts/cegi/Test-CegiExport.ps1
powershell.exe -NoProfile -File scripts/cegi/Test-LocalSftp.ps1
docker compose run --rm --no-deps --entrypoint pytest backend tests/test_payroll_leave.py tests/test_data_imports.py -qLe test SFTP utilise un fichier artificiel, vérifie son empreinte via l'importeur, le supprime, puis contrôle un transfert interrompu. Il ne crée aucun droit salarié. Les tests du récepteur travaillent dans une base de test.