diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7264619af1bdfb59c37f6e229187fec48710cf3b..aa02a772e7d9fa9f5792c28cfc4a5d9dc61e8b55 100755
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -90,6 +90,7 @@ Objectif : Plafonds personnalisables & refonte gestion des statuts
 * Correction sur la suppression de service lorsque la clôture de service a été historisé (#42046)
 * Le calcul des choix minimum/maximum est de nouveau fiable (#42080)
 * Liens inactifs lors du changement d'année universitaire (#40992)
+* Dans certains cas avec des motifs de non paiements, le détail des services n'affichait pas toutes les heures
 
 ## Notes de mise à jour
 
@@ -102,7 +103,7 @@ Objectif : Plafonds personnalisables & refonte gestion des statuts
 * Pour les instances qui utilisent le module Export Siham, vous devez renseigner un nouveau paramètre dans Administration > paramètres généraux > Gestion export RH, il vous faut sélectionner l'étape de la feuille de route franchie à partir de laquelle l'intervenant peut être exporté dans SIHAM.
 * La vue source [SRC_INTERVENANT](doc/Connecteurs-Import/Générique/SRC_INTERVENANT.sql) doit être mise à jour. 
 * Par précaution, la mise à jour désactive la synchronisation sur la table INTERVENANT. Vous devrez manuellement remettre en place cette synchronisation après avoir mis à jour votre vue source SRC_INTERVENANT.
-
+* ** ATTENTION** Les indicateurs portant sur les anciens plafonds ayant été supprimés et remplacés par de tous nouveaux indicateurs, les notifications par mail et abonnements correspondants seront résiliés
 
 # OSE 17.3 (17/03/2022)
 
diff --git a/admin/actions/maj-public-links.php b/admin/actions/maj-public-links.php
new file mode 100644
index 0000000000000000000000000000000000000000..eae3813af82ffd6b22abdee1847857eb598a1a86
--- /dev/null
+++ b/admin/actions/maj-public-links.php
@@ -0,0 +1,3 @@
+<?php
+
+// à supprimer pour la v19
\ No newline at end of file
diff --git a/admin/migration/v18Divers.php b/admin/migration/v18Divers.php
index db17f57a84263634393ab1dbf38d6138ee0f4e7b..0b87d6d7cdc5733589b64455e4902336b43b1ba8 100644
--- a/admin/migration/v18Divers.php
+++ b/admin/migration/v18Divers.php
@@ -26,6 +26,11 @@ class v18Divers extends AbstractMigration
         $bdd = $this->manager->getBdd();
         $c   = $this->manager->getOseAdmin()->getConsole();
 
+        // test pour savoir si on est bien en V17 minimum
+        if (!$this->manager->hasColumn('INTERVENANT', 'EXPORT_DATE')) {
+            $c->printDie('Attention : vous devez d\'abord mettre à jour en version 17.3 AVANT de mettre à jour en version 18');
+        }
+
         try {
             $c->msg('Coupure forcée de la synchronisation sur la table INTERVENANT');
             $bdd->exec("UPDATE IMPORT_TABLES SET SYNC_ENABLED = 0 WHERE TABLE_NAME = 'INTERVENANT'");
@@ -36,7 +41,7 @@ class v18Divers extends AbstractMigration
         $this->sauvegardes();
 
         try {
-            $c->msg('Suppression de la contrainte TYPE_INTERVENANT_CODE_UN en prévision de sa recréation');
+            $c->msg('Suppression des affectations de recherche ayant des structures invalides');
             $bdd->exec("DELETE FROM AFFECTATION_RECHERCHE WHERE structure_id NOT IN (SELECT ID FROM STRUCTURE)");
         } catch (\Exception $e) {
             // rien à faire : la contrainte a déjà du être supprimée
diff --git a/admin/migration/v18Indicateurs.php b/admin/migration/v18Indicateurs.php
new file mode 100644
index 0000000000000000000000000000000000000000..f22425802c5e6ceb479c4be2296966645b3144cb
--- /dev/null
+++ b/admin/migration/v18Indicateurs.php
@@ -0,0 +1,53 @@
+<?php
+
+
+
+
+
+class v18Indicateurs extends AbstractMigration
+{
+
+    public function description(): string
+    {
+        return "Migration des indicateurs de OSE 17 vers OSE 18";
+    }
+
+
+
+    public function utile(): bool
+    {
+        return true;
+
+        return $this->manager->hasNew('table', 'TYPE_INDICATEUR');
+    }
+
+
+
+    public function before()
+    {
+        $bdd = $this->manager->getBdd();
+        $c   = $this->manager->getOseAdmin()->getConsole();
+
+        $c->begin('Préparation à la mise à jour des indicateurs');
+
+        $bdd->exec('ALTER TABLE INDICATEUR ADD (TYPE_INDICATEUR_ID NUMBER)');
+        $bdd->exec('CREATE TABLE TYPE_INDICATEUR (  
+              ID NUMBER NOT NULL ENABLE,
+              LIBELLE VARCHAR2(60 CHAR) NOT NULL ENABLE,
+              ORDRE NUMBER DEFAULT 1 NOT NULL ENABLE
+            )');
+
+        $indicateurs = require $this->manager->getOseAdmin()->getOseDir() . '/data/indicateurs.php';
+        foreach ($indicateurs as $libelle => $type) {
+            $data = ['ID' => $type['id'], 'LIBELLE' => $libelle];
+            $bdd->getTable('TYPE_INDICATEUR')->insert($data);
+            foreach ($type['indicateurs'] as $numero => $indicateur) {
+                $bdd->getTable('INDICATEUR')->update(['TYPE_INDICATEUR_ID' => $type['id']], ['NUMERO' => $numero]);
+            }
+        }
+
+        $bdd->exec('DELETE FROM INDICATEUR WHERE TYPE_INDICATEUR_ID IS NULL');
+
+        $c->end('Préparation à la migration des indicateurs terminée');
+    }
+}
\ No newline at end of file
diff --git a/admin/migration/v18Statuts.php b/admin/migration/v18Statuts.php
index 248de5091c282172b520714f0c95d48760acd4c7..398cf71a1df0421a57d2cd23a2559fc9fc4d8cfa 100644
--- a/admin/migration/v18Statuts.php
+++ b/admin/migration/v18Statuts.php
@@ -26,12 +26,6 @@ class v18Statuts extends AbstractMigration
         $bdd = $this->manager->getBdd();
         $c   = $this->manager->getOseAdmin()->getConsole();
 
-        try {
-            $this->preMigrationIndicateurs();
-        } catch (\Exception $e) {
-            $c->println($e->getMessage(), $c::COLOR_RED);
-        }
-
         try {
             $this->preMigrationStatuts();
         } catch (\Exception $e) {
@@ -124,27 +118,6 @@ class v18Statuts extends AbstractMigration
 
 
 
-    public function preMigrationIndicateurs()
-    {
-        $bdd = $this->manager->getBdd();
-        $c   = $this->manager->getOseAdmin()->getConsole();
-
-        $c->begin('Préparation à la mise à jour des indicateurs');
-        if (!$this->manager->hasTable('TYPE_INDICATEUR')) {
-            $bdd->exec('ALTER TABLE INDICATEUR ADD (TYPE_INDICATEUR_ID NUMBER)');
-            $bdd->exec('CREATE TABLE TYPE_INDICATEUR (  
-              ID NUMBER NOT NULL ENABLE,
-              LIBELLE VARCHAR2(60 CHAR) NOT NULL ENABLE,
-              ORDRE NUMBER DEFAULT 1 NOT NULL ENABLE
-            )');
-            $bdd->exec('INSERT INTO TYPE_INDICATEUR (ID, LIBELLE, ORDRE) VALUES (1,\'provisoire\', 1)');
-            $bdd->exec('UPDATE INDICATEUR SET TYPE_INDICATEUR_ID = 1');
-        }
-        $c->end('Préparation à la migration des indicateurs terminée');
-    }
-
-
-
     public function preMigrationStatuts()
     {
         $bdd = $this->manager->getBdd();
diff --git a/module/Application/src/View/Helper/VolumeHoraire/Liste.php b/module/Application/src/View/Helper/VolumeHoraire/Liste.php
index 38b2d0f91fb450baf558a0b5911431ba2d0245c5..8c12ef1b7925c9691e3eb97dcea45a6a6f77d992 100755
--- a/module/Application/src/View/Helper/VolumeHoraire/Liste.php
+++ b/module/Application/src/View/Helper/VolumeHoraire/Liste.php
@@ -158,7 +158,15 @@ class Liste extends AbstractViewHelper
         $out      .= "</tr>\n";
         $periodes = $this->getPeriodes();
         foreach ($periodes as $periode) {
-            $vhl               = $this->getVolumeHoraireListe()->setPeriode($periode)->setTypeIntervention(false);
+            $vhl = $this->getVolumeHoraireListe()->createChild()->setPeriode($periode)->setTypeIntervention(false);
+
+            /* Gestion des mauvaises périodes */
+            $forbiddenPeriode = $vhl->getService()?->getElementPedagogique()?->getPeriode() ?? $periode !== $periode;
+            if ($forbiddenPeriode) {
+                $this->hasForbiddenPeriodes = true;
+            }
+
+            /*Listage des motifs de non paiement */
             $motifsNonPaiement = [];
             if ($canViewMNP) {  // découpage par motif de non paiement
                 $motifsNonPaiement = $vhl->getMotifsNonPaiement();
@@ -169,18 +177,13 @@ class Liste extends AbstractViewHelper
             if (empty($motifsNonPaiement)) {
                 $motifsNonPaiement = [0 => false];
             }
+
+            /* Affichage par motif de non paiement */
             foreach ($motifsNonPaiement as $motifNonPaiement) {
-                $readOnly         = $motifNonPaiement instanceof MotifNonPaiement && !$canEditMNP;
-                $forbiddenPeriode = false;
-                if (
-                    $this->getVolumeHoraireListe()->getService()
-                    && $this->getVolumeHoraireListe()->getService()->getElementPedagogique()
-                    && $this->getVolumeHoraireListe()->getService()->getElementPedagogique()->getPeriode()
-                    && $this->getVolumeHoraireListe()->getService()->getElementPedagogique()->getPeriode() !== $periode
-                ) {
-                    $forbiddenPeriode           = true;
-                    $this->hasForbiddenPeriodes = true;
-                }
+                $vhl->setMotifNonPaiement($motifNonPaiement);
+                if ($vhl->getHeures() == 0) continue; // rien à afficher
+
+                $readOnly = $motifNonPaiement instanceof MotifNonPaiement && !$canEditMNP;
                 if ($forbiddenPeriode) {
                     $out .= '<tr class="bg-danger">';
                     $out .= "<td><abbr title=\"La période n'est pas conforme à l'enseignement\">" . $this->renderPeriode($periode) . "</abbr></td>\n";
@@ -190,8 +193,7 @@ class Liste extends AbstractViewHelper
                 }
 
                 foreach ($this->typesIntervention as $typeIntervention) {
-                    $vhl->setMotifNonPaiement($motifNonPaiement)
-                        ->setTypeIntervention($typeIntervention);
+                    $vhl->setTypeIntervention($typeIntervention);
                     if ($vhl->getHeures() == 0) {
                         $class = "heures-empty";
                     } else {