# Ouverture d'une période

Documentation technique GRH — suivi d’ouverture de période / exercice (verrou `RHOUV*`, reprise phase A/B, droit `TM_EXO`, journal des événements).

Voir aussi la [doc utilisateur](https://wikiapp.heberg-eig.fr/books/mise-a-jour-decembre-2026/page/ouverture-dune-periode).

## 1. Objectif

Sécuriser l’ouverture de **période** et d’**exercice** : un seul poste à la fois, reprise après coupure sans rejouer inutilement les étapes déjà OK, traçabilité dans le journal des événements.

## 2. Fichiers / unités

Copie de travail sous `sources_modifiees/ouverture_periode/` — ne pas éditer directement les sources EIG.

<table id="bkmrk-unit%C3%A9r%C3%B4le-mensuel.pe"> <thead><tr><th>Unité</th><th>Rôle</th></tr></thead> <tbody> <tr><td><code>Mensuel&#46;Periode&#46;I&#95;OuvertureSuivi</code></td><td>Enums, constantes timeout, interface suivi</td></tr> <tr><td><code>Mensuel&#46;Periode&#46;U&#95;OuvertureSuivi</code></td><td>Verrou, étapes, heartbeat, reprise</td></tr> <tr><td><code>Mensuel&#46;Periode&#46;F&#95;Ouverture</code></td><td>Orchestration PER/EXE, UI busy, reprise écran</td></tr> <tr><td><code>d&#95;GRHmain</code></td><td>Garde connexion (EN\_COURS / INTERROMPU), droit après init</td></tr> <tr><td><code>Menu&#46;Fr&#95;GRHMainMenu</code></td><td>Ouverture forcée reprise, <code>act&#95;exercices</code> / <code>TM&#95;EXO</code></td></tr> <tr><td><code>U&#95;GRHNotificationDB</code></td><td>Heartbeat Notif\_USER (session visible)</td></tr> <tr><td><code>ddl&#47;RHOUVPERIODE&#46;sql</code></td><td>Tables Firebird + générateur</td></tr> </tbody></table>

## 3. Tables

### RHOUVPERIODE

<table id="bkmrk-champr%C3%B4le-ouvidpk-%28g"> <thead><tr><th>Champ</th><th>Rôle</th></tr></thead> <tbody> <tr><td><code>OUVID</code></td><td>PK (générateur <code>RH&#95;GENID&#95;OUVPERIODE</code>)</td></tr> <tr><td><code>OUVSTATUT</code></td><td>0 EN\_COURS · 1 INTERROMPU · 2 TERMINE · 3 ABANDONNE</td></tr> <tr><td><code>OUVPERIODE</code></td><td>Index AAAAMM période **cible**</td></tr> <tr><td><code>OUVUSER</code> / <code>OUVATTACH</code></td><td>Utilisateur / ConnectionID verrou</td></tr> <tr><td><code>OUVHB</code></td><td>Dernier heartbeat</td></tr> <tr><td><code>OUVETAPE</code> / <code>OUVMESSAGE</code></td><td>Étape courante / message</td></tr> </tbody></table>

`RHOUVETAPE` : une ligne par étape (`ETAPCODE` = `TOuvEtape`, statut A\_FAIRE / EN\_COURS / OK / KO / IGNORE).

## 4. Constantes d’activation / timing

<table id="bkmrk-constanteunit%C3%A9d%C3%A9faut"> <thead><tr><th>Constante</th><th>Unité</th><th>Défaut</th><th>Rôle</th></tr></thead> <tbody> <tr> <td><code>C&#95;USE&#95;OUVERTURE&#95;SUIVI</code></td> <td><code>I&#95;OuvertureSuivi</code></td> <td>**True**</td> <td>Active / coupe tout le suivi (verrou, étapes, heartbeat, reprise)</td> </tr> <tr> <td><code>C&#95;OUV&#95;HB&#95;TIMEOUT&#95;SEC</code></td> <td><code>I&#95;OuvertureSuivi</code></td> <td>**90**</td> <td>Délai sans heartbeat avant <code>INTERROMPU</code></td> </tr> <tr> <td><code>C&#95;OUV&#95;HB&#95;INTERVAL&#95;SEC</code></td> <td><code>I&#95;OuvertureSuivi</code></td> <td>15</td> <td>Fréquence du heartbeat suivi</td> </tr> <tr> <td><code>C&#95;USE&#95;NOTIF&#95;USER&#95;HEARTBEAT&#95;THREAD</code></td> <td><code>U&#95;GRHNotificationDB</code></td> <td>**True**</td> <td><code>True</code> = heartbeat USERCONNECT sur thread dédié ; <code>False</code> = WM\_TIMER historique</td> </tr> </tbody></table>

## 5. Pipeline

`Controles users` → **DemarrerSuivi** (verrou) → alertes DSN / P99 / CanChange\* → PreBascule → Bascule → PostOuverture → Terminer

\* En reprise : alertes DSN / P99 / « forcer le changement » sautées.

- `ExecuterPreBascule` — CHG\_HOR (mois), TAUX\_PAS, DSN, ARCH\_\*
- `ExecuterBascule` — CLOSE\_PER → BASCULE (trx) → DATE / INFO\_ASSO / DEBLOC
- `ExecuterPostOuverture` — ARCH\_HISTO (EXE) → APRES\_OUV → message → `Terminer`

Le verrou est posé **avant** les dialogues DSN / CanChange. Abandon d’un contrôle → `AbandonnerSuiviSiActif`.

## 6. Verrou &amp; heartbeat

- **EN\_COURS** + heartbeat &lt; 90 s → autre session refusée (« Réessayez plus tard »).
- Process tué → heartbeat expire → **INTERROMPU** au prochain démarrage.
- Fin OK → `Terminer` → **TERMINE** + arrêt heartbeat (déverrouillage immédiat).
- Abandon / contrôles KO après démarrage → **ABANDONNE**.

## 7. Reprise phase A / B

<table id="bkmrk-phasecrit%C3%A8recomporte"> <thead><tr><th>Phase</th><th>Critère</th><th>Comportement</th></tr></thead> <tbody> <tr> <td>**A**</td> <td>Période ouverte ≠ cible</td> <td>Étapes pré-bascule déjà <code>OK</code> conservées. Reset seulement EN\_COURS/KO.</td> </tr> <tr> <td>**B**</td> <td>Période ouverte = cible</td> <td>Étapes ≤ bascule → IGNORE. Post-bascule → A\_FAIRE. Ne pas re-basculer.</td> </tr> </tbody></table>

`AssureInfoAssoGRH` : en reprise, `CanChangePeriode` est sauté → recréer `_InfoAssoGRH` avant `SaveToDB`.

## 8. Droits

Menu : `act_exercices.Enabled := CanOpen('TM_EXO')`  
Init : `InitOpenOf('TM_EXO', FonctionOK(110,100) and DroitSurToutesSection)`

- Après `doInitDroitsUsers` : si reprise demandée et pas `CanOpen('TM_EXO')` → refus.
- `CheckExerciceExist` / écran : même garde.

## 9. UI pendant traitement

- `SetUIOuvertureBusy` — désactive boutons / navigation.
- `_INTRT` — bloque Escape / fermeture (`CanClose := False`).

## 10. Erreurs &amp; arrêt

<table id="bkmrk-cascomportement-exce"> <thead><tr><th>Cas</th><th>Comportement</th></tr></thead> <tbody> <tr> <td>Exception pendant ouverture / reprise</td> <td><code>StopperOuvertureSurException</code> → message, <code>PasserInterrompu</code>, journal, <code>Application&#46;Terminate</code></td> </tr> <tr> <td>Contrôle métier KO</td> <td><code>AbandonnerSuiviSiActif</code> — pas d’arrêt appli</td> </tr> <tr> <td>Refus droit TM\_EXO</td> <td>Exception / message — pas de traitement</td> </tr> </tbody></table>

## 11. Journal des événements

Traces via `_GetBigBrother.AddEventGlobal` (libellé UI : **journal des événements**). Source typique : `F_SaisieExercices` / `D_GRHMain`.