diff --git a/FEATURES/125727 b/FEATURES/125727
new file mode 100644
index 0000000000000000000000000000000000000000..2443168d39bcb49d5a9dce81f57b67bdbcfbce75
--- /dev/null
+++ b/FEATURES/125727
@@ -0,0 +1,10 @@
+        '125727' =>
+            ['Label' => $this->_('Facette nouveauté en résultat de recherche'),
+             'Desc' => $this->_('Ajout de la possibilité d\'afficher une facette "Nouveauté" oui/non basée sur la date de nouveauté la plus élevée parmis tous les exemplaires'),
+             'Image' => '',
+             'Video' => '',
+             'Category' => $this->_('Recherche'),
+             'Right' => function($feature_description, $user) {return true;},
+             'Wiki' => 'http://wiki.bokeh-library-portal.org/index.php?title=Facette_%27Nouveaut%C3%A9%27',
+             'Test' => '',
+             'Date' => '2021-01-14'],
\ No newline at end of file
diff --git a/VERSIONS_WIP/125727 b/VERSIONS_WIP/125727
new file mode 100644
index 0000000000000000000000000000000000000000..d3e051728ca258acc59923c01351521fcb5211ef
--- /dev/null
+++ b/VERSIONS_WIP/125727
@@ -0,0 +1 @@
+ - ticket #125727 : Résultat de recherche : Ajout de la possibilité d'afficher une facette "Nouveauté" oui/non basée sur la date de nouveauté la plus élevée parmis tous les exemplaires
\ No newline at end of file
diff --git a/cosmogramme/tests/php/classes/KohaPeriodiquesTest.php b/cosmogramme/tests/php/classes/KohaPeriodiquesTest.php
index aa9e530cf645174aef5287228255c20b5f92f3de..6a0917953eeb48d8dadd20591485c828708d7ac5 100644
--- a/cosmogramme/tests/php/classes/KohaPeriodiquesTest.php
+++ b/cosmogramme/tests/php/classes/KohaPeriodiquesTest.php
@@ -659,7 +659,7 @@ class KohaPeriodiquesMatriculeAngesTest extends KohaPeriodiquesWithArticlesTestC
 
     $title->updateFacetsFromExemplaires();
 
-    $this->assertEquals('D800 Lfre Tper_title B1 YCHYJR',
+    $this->assertEquals('D800 Lfre Tper_title B1 YCHYJR HNRNR0001',
                         $title->getFacettes());
   }
 
diff --git a/cosmogramme/tests/php/classes/KohaRecordIntegrationTest.php b/cosmogramme/tests/php/classes/KohaRecordIntegrationTest.php
index eb8932f3b92d7de859959eaab17011ccd5a0d44f..171fcb29a5cc0a205e29c67aed00fc07aba6af9c 100644
--- a/cosmogramme/tests/php/classes/KohaRecordIntegrationTest.php
+++ b/cosmogramme/tests/php/classes/KohaRecordIntegrationTest.php
@@ -233,7 +233,7 @@ class KohaRecordIntegrationFacetPresseTest extends KohaRecordIntegrationTestCase
 
   /** @test */
   public function facettesShouldContainsT2AndHANNE0001AndHMOIS0001AndJOUR0001() {
-    $this->assertEquals('HANNE0001 HMOIS0001 HJOUR0001 Lfre T2 B1 YMEDSTMAR',
+    $this->assertEquals('HANNE0001 HMOIS0001 HJOUR0001 Lfre T2 B1 YMEDSTMAR HNRNR0001',
                         Class_Notice::find(1)
                         ->updateFacetsFromExemplaires()
                         ->getFacettes());
@@ -242,7 +242,7 @@ class KohaRecordIntegrationFacetPresseTest extends KohaRecordIntegrationTestCase
 
     /** @test */
   public function facettesForRecord25ShouldContainsT2AndHANNE0001AndHMOIS0001() {
-    $this->assertEquals('HANNE0001 HMOIS0007 HJOUR0006 Lfre T2 B1 YMEDSTMAR',
+    $this->assertEquals('HANNE0001 HMOIS0007 HJOUR0006 Lfre T2 B1 YMEDSTMAR HNRNR0001',
                         Class_Notice::find(25)
                         ->updateFacetsFromExemplaires()
                         ->getFacettes());
diff --git a/cosmogramme/tests/php/classes/NoticeIntegrationTest.php b/cosmogramme/tests/php/classes/NoticeIntegrationTest.php
index 7eb4afa2c5345eb4ed2c330b1c1e2c167f8f11d5..9dc927120c59e4c3df7bed2afc483e2e60ab4eae 100644
--- a/cosmogramme/tests/php/classes/NoticeIntegrationTest.php
+++ b/cosmogramme/tests/php/classes/NoticeIntegrationTest.php
@@ -1239,7 +1239,7 @@ class NoticeIntegrationArchivesAlsaceTest extends NoticeIntegrationTestCase {
 
   /** @test */
   public function facettesWithExemplairesShouldContainsM1AndM2AndD1() {
-    $this->assertEquals('D94438 A1 M1 M2 Lfre T1 B1 YBibliothèque des Dominicains',
+    $this->assertEquals('D94438 A1 M1 M2 Lfre T1 B1 YBibliothèque des Dominicains HNRNR0001',
                         Class_Notice::find(1)->updateFacetsFromExemplaires()->getFacettes());
   }
 }
diff --git a/library/Class/Catalogue.php b/library/Class/Catalogue.php
index c24c70ddb03ee2cb89cbc65119ab72f82a1c44a1..d3ee2453d3f0dda5cda05ec3eec0f8e27e89b0fd 100644
--- a/library/Class/Catalogue.php
+++ b/library/Class/Catalogue.php
@@ -1142,7 +1142,7 @@ class Class_Catalogue extends Storm_Model_Abstract {
 
 
   public function getThesaurusForId($thesaurus) {
-    $startWith = substr($thesaurus->getIdThesaurus(), 0, Class_Notice_Facette::NB_CHAR_THESAURUS);
+    $startWith = substr($thesaurus->getIdThesaurus(), 0, Class_CodifThesaurus::ID_KEY_LENGTH);
 
     $ids='';
     $thesaurus_ids = explode(';',$this->getThesaurus());
diff --git a/library/Class/CodifThesaurus.php b/library/Class/CodifThesaurus.php
index 96b7cf158636b228fe908a303cffa07d42efc0a9..309d09f80ea7701e0454467272026c4ce34d0773 100644
--- a/library/Class/CodifThesaurus.php
+++ b/library/Class/CodifThesaurus.php
@@ -69,6 +69,23 @@ class CodifThesaurusLoader extends Storm_Model_Loader {
   }
 
 
+  public function ensureRecordNovelty() {
+    $this->recordNoveltyFor(true);
+    $this->recordNoveltyFor(false);
+  }
+
+
+  /** @param $flag boolean */
+  public function recordNoveltyFor($flag) {
+    $attributes = ((bool) $flag)
+      ? ['Id' => 1, 'Libelle' => $this->_('Oui')]
+      : ['Id' => 2, 'Libelle' => $this->_('Non')];
+
+    return $this->ensureForModelUnderRoot(new Class_Entity($attributes),
+                                          $this->_fixed['RecordNovelty']);
+  }
+
+
   public function ensureForModelUnderRoot($model, $definition) {
     return ($root = Class_CodifThesaurus::findRootOfId($definition->getId(),
                                                        $definition->getCode(),
@@ -213,7 +230,7 @@ class CodifThesaurusLoader extends Storm_Model_Loader {
 
 
   public function findParent($id_thesaurus) {
-    $parent_str=substr($id_thesaurus,0,strlen($id_thesaurus)-(4-strlen($id_thesaurus)%4));
+    $parent_str = substr($id_thesaurus, 0, strlen($id_thesaurus) - (4 - strlen($id_thesaurus) % 4));
     if (!$parent_str)
       return null;
 
@@ -298,7 +315,7 @@ class CodifThesaurusLoader extends Storm_Model_Loader {
 
 
   public function getIndices($pere, $all = false ) {
-    if(Class_CodifThesaurus::CODE_ROOT != $pere) {
+    if (Class_CodifThesaurus::CODE_ROOT != $pere) {
       $pere = $this->getCodeSur4Chiffres($pere);
       $length = strlen($pere);
 
@@ -306,17 +323,32 @@ class CodifThesaurusLoader extends Storm_Model_Loader {
                                               'order'=> 'id_thesaurus']);
     }
 
-    $where = '';
-
     // while search result do not handle item novelty correctly
-    $to_exclude = [$this->fixedCodeOf('LibraryNovelty'),
-                   $this->fixedCodeOf('AnnexeNovelty')];
+    $to_exclude = [$this->fixedIdOf('LibraryNovelty'),
+                   $this->fixedIdOf('AnnexeNovelty')];
     if (!$all)
-      $to_exclude[] = $this->fixedCodeOf('Domain');
+      $to_exclude[] = $this->fixedIdOf('Domain');
+
+    return $this->_findAllFromRootExcluding($to_exclude);
+  }
+
+
+  public function findAllForDomainCriteria() {
+    // novelty is a criteria in itself
+    // and no domains in domains
+
+    return $this
+      ->_findAllFromRootExcluding([$this->fixedIdOf('RecordNovelty'),
+                                   $this->fixedIdOf('LibraryNovelty'),
+                                   $this->fixedIdOf('AnnexeNovelty'),
+                                   $this->fixedIdOf('Domain')]);
+  }
 
-    $where = sprintf('code not in ("%s") and ', implode('", "', $to_exclude));
 
-    $where .= 'LENGTH(id_thesaurus) in (1,4)';
+  protected function _findAllFromRootExcluding($to_exclude=[]) {
+    $where = sprintf('id_thesaurus not in ("%s") and LENGTH(id_thesaurus) in (1,%d)',
+                     implode('", "', $to_exclude),
+                     Class_CodifThesaurus::ID_KEY_LENGTH);
 
     return Class_CodifThesaurus::findAllBy(['where' => $where,
                                             'order' => 'id_thesaurus']);
diff --git a/library/Class/CodifThesaurusFixed.php b/library/Class/CodifThesaurusFixed.php
index f71397a05ef6d01dc31f775e8a41b5ef449c1297..a8e25790274c75022b56f11740e7dcc5d3971852 100644
--- a/library/Class/CodifThesaurusFixed.php
+++ b/library/Class/CodifThesaurusFixed.php
@@ -27,6 +27,7 @@ class Class_CodifThesaurusFixed extends Class_Entity {
      'CustomField' => ['CFCF', 'Custom fields', 'Champs personnalisés'],
      'LibraryNovelty' => ['NNNN', 'Nouveauté par bibliothèque', 'Nouveauté par bibliothèque'],
      'AnnexeNovelty' => ['NANA', 'Nouveauté par annexe', 'Nouveauté par annexe'],
+     'RecordNovelty' => ['NRNR', 'Nouveauté', 'Nouveauté'],
      'DigitalResources' => ['DRDR', 'Digital resources', 'Ressources numériques'],
      'StreetName' => ['STRE', 'StreetName', 'Nom de rue'],
      'LocationType' => ['LOCA', 'LocationType', 'Type de lieu'],
diff --git a/library/Class/Notice.php b/library/Class/Notice.php
index 32a107f66da7f214d8958ee8bd91b7971f614c2f..04d03289d20f3ddf76ac4cdd27dcf17a1f810680 100644
--- a/library/Class/Notice.php
+++ b/library/Class/Notice.php
@@ -153,15 +153,39 @@ class NoticeLoader extends Storm_Model_Loader {
 
 
   public function indexNoveltyFacets() {
-    $page = 1;
-    while($records = Class_Notice::findAllBy(['where' => 'match(facettes) against("+(HNNNN* HNANA*)" in boolean mode)',
-                                              'limitPage' => [$page, 100]])) {
-      foreach($records as $record)
-        $record->updateNoveltyFacets();
-
-      $this->_cleanMemory();
-      $page++;
+    $facets = ['HNNNN*', 'HNANA*'];
+    if ($novelty_thesaurus = Class_CodifThesaurus::recordNoveltyFor(true))
+      $facets[] = $novelty_thesaurus->getFacetCode();
+    $facets = implode(' ', $facets);
+
+    $record_id = 0;
+    while ($records = $this->_findNoveltyRecordsFrom($facets, $record_id))
+      $record_id = $this->_updateNovelty($records);
+  }
+
+
+  protected function _findNoveltyRecordsFrom($facets, $record_id) {
+    if (null === $record_id)
+      return [];
+
+    $where = sprintf('match(facettes) against("+(%s)" in boolean mode) and id_notice > %d',
+                     $facets, $record_id);
+
+    return Class_Notice::findAllBy(['where' => $where,
+                                    'order' => 'id_notice',
+                                    'limit' => 100]);
+  }
+
+
+  protected function _updateNovelty($records) {
+    $record_id = null;
+    foreach($records as $record) {
+      $record->updateNoveltyFacets();
+      $record_id = $record->getId();
     }
+    $this->_cleanMemory();
+
+    return $record_id;
   }
 }
 
@@ -1778,25 +1802,6 @@ class Class_Notice extends Storm_Model_Abstract {
   }
 
 
-
-  public function getFacetCodesWithoutItemFacets() {
-    $filtered = [Class_Bib::CODE_FACETTE,
-                 Class_CodifEmplacement::CODE_FACETTE,
-                 Class_CodifSection::CODE_FACETTE,
-                 Class_CodifAnnexe::CODE_FACETTE,
-                 Class_CodifTypeDoc::CODE_FACETTE,
-                 Class_Codification::CODE_DATE_NOUVEAUTE,
-                 Class_Codification::CODE_AVAILABILITY];
-
-    return array_filter($this->getFacetCodes(),
-                        function($code) use ($filtered)
-                        {
-                          return !in_array(substr($code, 0, 1),
-                                           $filtered);
-                        });
-  }
-
-
   protected function _fetchItemsToInjectInFacets() {
     if ($this->isPeriodiqueArticle() && ($linked_record = $this->getLinkedSerialRecord()))
       return $linked_record->getExemplaires();
@@ -1816,19 +1821,29 @@ class Class_Notice extends Storm_Model_Abstract {
 
 
   public function updateFacetsFromExemplaires() {
-    $facettes = $this->getFacetCodesWithoutItemFacets();
-    $facettes []= Class_CodifTypeDoc::CODE_FACETTE. $this->getTypeDoc();
+    $facets = Class_Notice_Facette::fromStringWithoutItemFacets($this->getFacettes());
+    $facets = array_map(function($facet) { return $facet->getCle(); },
+                        $facets);
 
+    $facets[] = Class_CodifTypeDoc::CODE_FACETTE . $this->getTypeDoc();
+
+    $is_novelty = false;
     $date_nouveaute = '';
     foreach($this->_fetchItemsToInjectInFacets() as $exemplaire) {
-      $facettes = array_merge($facettes, $exemplaire->getFacets());
+      $facets = array_merge($facets, $exemplaire->getFacets());
+
       $date_nouveaute = ($exemplaire->getDateNouveaute() > $date_nouveaute)
         ? $exemplaire->getDateNouveaute()
         : $date_nouveaute;
+
+      $is_novelty = $is_novelty || $exemplaire->isNouveaute();
     }
 
+    if ($novelty_thesaurus = Class_CodifThesaurus::recordNoveltyFor($is_novelty))
+      $facets[] = $novelty_thesaurus->getFacetCode();
+
     return $this
-      ->setFacettes(array_unique($facettes))
+      ->setFacettes(array_unique($facets))
       ->setDateCreation($date_nouveaute ? ($date_nouveaute . ' 00:00:00') : null);
   }
 
@@ -1846,12 +1861,17 @@ class Class_Notice extends Storm_Model_Abstract {
     $this->deleteFacettes(implode(' ', $existings));
 
     $facets = [];
+    $is_novelty = false;
     foreach($this->getExemplaires() as $item)
       if ($item->isNouveaute()) {
         $facets[] = Class_CodifThesaurus::findForItemLibraryNovelty($item);
         $facets[] = Class_CodifThesaurus::findForItemAnnexeNovelty($item);
+        $is_novelty = true;
       }
 
+    if ($novelty_thesaurus = Class_CodifThesaurus::recordNoveltyFor($is_novelty))
+      $facets[] = $novelty_thesaurus->getFacetCode();
+
     $this->updateFacette(implode(' ', $facets))->save();
     return $this;
   }
diff --git a/library/Class/Notice/Facette.php b/library/Class/Notice/Facette.php
index 7c8f320b8bffb4e03b15cf2205fb04c784c85c2e..96c33793baf6f484fc6c7378c47595aa8c6f69f8 100644
--- a/library/Class/Notice/Facette.php
+++ b/library/Class/Notice/Facette.php
@@ -19,13 +19,13 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
 class Class_Notice_Facette {
-  const NB_CHAR_THESAURUS = 4;
-
   protected static $_instances = [];
 
   protected
     $_cle,
-    $_rubrique;
+    $_rubrique,
+    $_group_code,
+    $_value;
 
 
   public static function fromStringFiltered($facet_string, $callback) {
@@ -35,6 +35,12 @@ class Class_Notice_Facette {
   }
 
 
+  public static function fromStringWithoutItemFacets($facet_string) {
+    return static::fromStringFiltered($facet_string,
+                                      function($facet) { return !$facet->isItem(); });
+  }
+
+
   public static function parseFacettesFromNoticeField($str_facettes) {
     $items = array_filter(explode(' ', trim($str_facettes)));
     $facettes = [];
@@ -88,12 +94,16 @@ class Class_Notice_Facette {
 
 
   public function getValue() {
-    return substr($this->_cle, 1);
+    return $this->_value = $this->_value
+      ? $this->_value
+      : substr($this->_cle, 1);
   }
 
 
   protected function getGroupCodeFromKey() {
-    return static::extractCodeRubrique($this->_cle);
+    return $this->_group_code = $this->_group_code
+      ? $this->_group_code
+      : static::extractCodeRubrique($this->_cle);
   }
 
 
@@ -122,55 +132,98 @@ class Class_Notice_Facette {
   public function isNovelty() {
     return in_array(substr($this->getGroupCodeFromKey(), 1),
                     [Class_CodifThesaurus::fixedIdOf('LibraryNovelty'),
-                     Class_CodifThesaurus::fixedIdOf('AnnexeNovelty')]);
+                     Class_CodifThesaurus::fixedIdOf('AnnexeNovelty'),
+                     Class_CodifThesaurus::fixedIdOf('RecordNovelty')]);
   }
 
 
   public function isAvailability() {
-    return Class_Codification::CODE_AVAILABILITY == $this->getGroupCodeFromKey();
+    return $this->isGroupCode(Class_Codification::CODE_AVAILABILITY);
   }
 
 
   public function isAuthor() {
-    return Class_CodifAuteur::CODE_FACETTE == $this->getGroupCodeFromKey();
+    return $this->isGroupCode(Class_CodifAuteur::CODE_FACETTE);
   }
 
 
   public function isMatter() {
-    return Class_CodifMatiere::CODE_FACETTE == $this->getGroupCodeFromKey();
+    return $this->isGroupCode(Class_CodifMatiere::CODE_FACETTE);
   }
 
 
   public function isDynamicFacet() {
-    return Class_CodifThesaurus::CODE_FACETTE === substr($this->_cle, 0, 1)
+    return $this->isThesaurus()
       && strlen($this->getValue()) === (Class_CodifThesaurus::ID_KEY_LENGTH * 2);
   }
 
 
   public function isDynamicFacetRoot() {
-    return Class_CodifThesaurus::CODE_FACETTE === substr($this->_cle, 0, 1)
+    return $this->isThesaurus()
       && strlen($this->getValue()) === Class_CodifThesaurus::ID_KEY_LENGTH;
   }
 
 
   public function isDocTypeFacet() {
-    return Class_CodifTypeDoc::CODE_FACETTE == $this->getGroupCodeFromKey();
+    return $this->isGroupCode(Class_CodifTypeDoc::CODE_FACETTE);
   }
 
 
   public function isAnnexeFacet() {
-    return Class_CodifAnnexe::CODE_FACETTE == $this->getGroupCodeFromKey();
+    return $this->isGroupCode(Class_CodifAnnexe::CODE_FACETTE);
   }
 
 
   public function isLibraryFacet() {
-    return Class_Bib::CODE_FACETTE == $this->getGroupCodeFromKey();
+    return $this->isGroupCode(Class_Bib::CODE_FACETTE);
   }
 
 
   public function isDomainFacet() {
-    $code = $this->getGroupCodeFromKey();
-    return Class_Catalogue::CODE_FACETTE == $code
-      || Class_CodifThesaurus::CODE_FACETTE == $this->_cle[0];
+    return $this->isGroupCode(Class_Catalogue::CODE_FACETTE) || $this->isThesaurus();
+  }
+
+
+  public function isLocationFacet() {
+    return $this->isGroupCode(Class_CodifEmplacement::CODE_FACETTE);
+  }
+
+
+  public function isSectionFacet() {
+    return $this->isGroupCode(Class_CodifSection::CODE_FACETTE);
+  }
+
+
+  public function isThesaurus() {
+    return Class_CodifThesaurus::CODE_FACETTE === substr($this->_cle, 0, 1);
+  }
+
+
+  public function isRecordNoveltyFacet() {
+    return $this->isDynamicFacetUnder(Class_CodifThesaurus::fixedIdOf('RecordNovelty'));
+  }
+
+
+  public function isDynamicFacetUnder($root_code) {
+    return $this->isDynamicFacet() && substr($this->getGroupCodeFromKey(), 1) === $root_code;
+  }
+
+
+  public function isItem() {
+    return
+      $this->isLibraryFacet()
+      || $this->isLocationFacet()
+      || $this->isSectionFacet()
+      || $this->isAnnexeFacet()
+      || $this->isDocTypeFacet()
+      || $this->isGroupCode(Class_Codification::CODE_DATE_NOUVEAUTE)
+      || $this->isGroupCode(Class_Codification::CODE_AVAILABILITY)
+      || $this->isRecordNoveltyFacet()
+      ;
+  }
+
+
+  public function isGroupCode($code) {
+    return $this->getGroupCodeFromKey() === $code;
   }
 }
\ No newline at end of file
diff --git a/library/ZendAfi/Form/Configuration/Domain.php b/library/ZendAfi/Form/Configuration/Domain.php
index 805b247c442f592b930a2184620cca0a50bc0431..99eaa12bdb3086885d065b99fa62bd2b23d331a3 100644
--- a/library/ZendAfi/Form/Configuration/Domain.php
+++ b/library/ZendAfi/Form/Configuration/Domain.php
@@ -160,7 +160,7 @@ class ZendAfi_Form_Configuration_Domain extends ZendAfi_Form {
       ;
 
     $thesaurus_elements = [];
-    foreach(Class_CodifThesaurus::getIndices('root') as $thesaurus) {
+    foreach(Class_CodifThesaurus::findAllForDomainCriteria() as $thesaurus) {
       $name = $thesaurus->getIdThesaurus();
       $this->addElement('listeSuggestion',
                         $name,
diff --git a/scripts/reindex_local_items_facets.php b/scripts/reindex_local_items_facets.php
new file mode 100644
index 0000000000000000000000000000000000000000..e1f660ec9c263aa5cb183712495e21ee2749dc17
--- /dev/null
+++ b/scripts/reindex_local_items_facets.php
@@ -0,0 +1,59 @@
+<?php
+error_reporting(E_ALL^E_DEPRECATED);
+require __DIR__ . '/../console.php';
+
+echo "\n\nWelcome to the iReindex Items Facets 2000 X tool by @patbator, proudly RTed by @lla \n\n";
+
+echo "\n\nWill update items facets of " . Class_Notice::count() . " records in database\n\n";
+
+class Script_ItemsFacets_Updater {
+  use Trait_MemoryCleaner;
+
+  protected
+    $_adapter,
+    $_last_id = 0,
+    $_page = 1;
+
+  public function __construct() {
+    $this->_adapter = Zend_Db_Table_Abstract::getDefaultAdapter();
+  }
+
+
+  public function run() {
+    while ($records = Class_Notice::findAllBy(['where' => 'id_notice > ' . (int)$this->_last_id,
+                                               'limit' => '1000']))
+      $this->_runPage($records);
+
+    return $this;
+  }
+
+
+  protected function _runPage($records) {
+    echo "\npage: ". $this->_page ."\n";
+    $this->_page++;
+
+    foreach($records as $record)
+      $this->_runOne($record);
+
+    $this->_last_id = $record->getId();
+    $this->_cleanMemory();
+    return $this;
+  }
+
+
+  protected function _runOne($record) {
+    $old = $record->getFacettes();
+    $record->updateFacetsFromExemplaires();
+    if ($old != $record->getFacettes())
+      $record->save();
+
+    echo '.';
+
+    return $this;
+  }
+}
+
+$updater = new Script_ItemsFacets_Updater;
+$updater->run();
+
+echo "\n\nDONE !!!!\n\n";
diff --git a/tests/application/modules/admin/controllers/CatalogueControllerTest.php b/tests/application/modules/admin/controllers/CatalogueControllerTest.php
index 4275650e7e8098756e4ede6a8a045895836e7328..11f6cbf10560ed1f9ba7dd8d02fcf12d947f8785 100644
--- a/tests/application/modules/admin/controllers/CatalogueControllerTest.php
+++ b/tests/application/modules/admin/controllers/CatalogueControllerTest.php
@@ -698,12 +698,12 @@ class CatalogueControllerEditCatalogueTest extends AdminCatalogueControllerTestC
 
     $this->onLoaderOfModel('Class_CodifThesaurus')
          ->whenCalled('findAllBy')
-         ->with(['where' => 'code not in ("Nouveauté par bibliothèque", "Nouveauté par annexe", "Catalogue") and LENGTH(id_thesaurus) in (1,4)',
+         ->with(['where' => 'id_thesaurus not in ("NRNR", "NNNN", "NANA", "CCCC") and LENGTH(id_thesaurus) in (1,4)',
                  'order' => 'id_thesaurus'])
-         ->answers([Class_CodifThesaurus::find(1),
-                    Class_CodifThesaurus::find(2)]);
+         ->answers([Class_CodifThesaurus::find(1), Class_CodifThesaurus::find(2)])
+      ;
 
-    $this->dispatch('/admin/catalogue/edit/id_catalogue/6', true);
+    $this->dispatch('/admin/catalogue/edit/id_catalogue/6');
   }
 
 
diff --git a/tests/application/modules/opac/controllers/NoticeAjaxControllerTest.php b/tests/application/modules/opac/controllers/NoticeAjaxControllerTest.php
index 79877281330f31a9fc6add9bbd5a2ec6eedfbef4..52b1515cf5f64b03fc98f834d6508cd1b8fa65cf 100644
--- a/tests/application/modules/opac/controllers/NoticeAjaxControllerTest.php
+++ b/tests/application/modules/opac/controllers/NoticeAjaxControllerTest.php
@@ -834,8 +834,9 @@ class NoticeAjaxControllerExemplairesWithOtherAnnexTestCase extends AbstractCont
 
   /** @test */
   public function facetsShouldBeUpdatedWithAnnex21() {
-    $this->dispatch('noticeajax/exemplaires/id/123', true);
-    $this->assertEquals('D78092 A3029 A9751 A117014 A117015 M37414 G464 HNNNN0002 HNANA0002 T0 B6 SA9 Eemplacement de test Y21 V6', Class_notice::find(123)->getFacettes());
+    $this->dispatch('noticeajax/exemplaires/id/123');
+    $this->assertEquals('D78092 A3029 A9751 A117014 A117015 M37414 G464 HNNNN0002 HNANA0002 T0 B6 SA9 Eemplacement de test Y21 V6 HNRNR0001',
+                        Class_notice::find(123)->getFacettes());
   }
 }
 
diff --git a/tests/library/Class/CodifThesaurusTest.php b/tests/library/Class/CodifThesaurusTest.php
index 8957f4d7e1d614747fdb26c063f3228ceaf82e35..88166946bbbac6de5a56eb8d15fc1a41ca5bc7db 100644
--- a/tests/library/Class/CodifThesaurusTest.php
+++ b/tests/library/Class/CodifThesaurusTest.php
@@ -171,8 +171,8 @@ class CodifThesaurusGetIndicesRootTest extends ModelTestCase {
 
   /** @test */
   public function shouldExcludeNoveltyAndDomains() {
-    Class_CodifThesaurus::getIndices('root', false);
-    $expected_params = ['where' => 'code not in ("Nouveauté par bibliothèque", "Nouveauté par annexe", "Catalogue") and LENGTH(id_thesaurus) in (1,4)',
+    Class_CodifThesaurus::getIndices('root');
+    $expected_params = ['where' => 'id_thesaurus not in ("NNNN", "NANA", "CCCC") and LENGTH(id_thesaurus) in (1,4)',
                         'order' => 'id_thesaurus'];
 
     $this->assertEquals($expected_params,
@@ -183,7 +183,7 @@ class CodifThesaurusGetIndicesRootTest extends ModelTestCase {
   /** @test */
   public function shouldExcludeNoveltyButNotDomain() {
     Class_CodifThesaurus::getIndices('root', true);
-    $expected_params = ['where' => 'code not in ("Nouveauté par bibliothèque", "Nouveauté par annexe") and LENGTH(id_thesaurus) in (1,4)',
+    $expected_params = ['where' => 'id_thesaurus not in ("NNNN", "NANA") and LENGTH(id_thesaurus) in (1,4)',
                         'order' => 'id_thesaurus'];
     $this->assertEquals($expected_params, Class_CodifThesaurus::getFirstAttributeForLastCallOn('findAllBy'));
   }
diff --git a/tests/library/Class/NoticeNoveltyTest.php b/tests/library/Class/NoticeNoveltyTest.php
index b13299a566fa9bbe6cbb8989c4ed643a9df48c27..92683e8fe15c8874f734db0a6dd92e9af377f2bf 100644
--- a/tests/library/Class/NoticeNoveltyTest.php
+++ b/tests/library/Class/NoticeNoveltyTest.php
@@ -38,33 +38,42 @@ class NoticeNoveltyTest extends ModelTestCase{
                     'libelle' => 'My Annexe']);
 
 
-    $this
+    $record_12 = $this
       ->fixture('Class_Notice',
                 ['id' => 12,
                  'facettes' => 'T1 B4',
-                 'date_creation' => '2017-02-28'])
-      ->addExemplaire($this->fixture('Class_Exemplaire',
-                                     ['id' => 90000,
-                                      'id_bib' => 4,
-                                      'annexe' => 2,
-                                      'date_nouveaute' => '2017-02-28']))
-      ->assertSave();
-
-    $this
+                 'date_creation' => '2017-02-28']);
+    $record_12->addExemplaire($this->fixture('Class_Exemplaire',
+                                             ['id' => 90000,
+                                              'id_bib' => 4,
+                                              'annexe' => 2,
+                                              'date_nouveaute' => '2017-02-28']))
+              ->assertSave();
+
+    $record_15 = $this
       ->fixture('Class_Notice',
                 ['id' => 15,
                  'facettes' => 'T1 B4 HNNNN0001',
-                 'date_creation' => ''])
-      ->addExemplaire($this->fixture('Class_Exemplaire',
-                                     ['id' => 99999,
-                                      'id_bib' => 4,
-                                      'annexe' => 2,
-                                      'date_nouveaute' => '2015-02-28']))
-      ->assertSave();
+                 'date_creation' => '']);
+    $record_15->addExemplaire($this->fixture('Class_Exemplaire',
+                                             ['id' => 99999,
+                                              'id_bib' => 4,
+                                              'annexe' => 2,
+                                              'date_nouveaute' => '2015-02-28']))
+              ->assertSave();
 
 
-    $this->onLoaderOfModel('Class_Notice');
     Class_Notice::setMemoryCleaner(function() {});
+    $this->onLoaderOfModel('Class_Notice')
+         ->whenCalled('findAllBy')
+         ->willDo(function($params) use($record_12, $record_15)
+                  {
+                    if ($params['where'] == 'match(facettes) against("+(HNNNN* HNANA* HNRNR0001)" in boolean mode) and id_notice > 0')
+                      return [$record_12, $record_15];
+
+                    return [];
+                  });
+
     Class_Notice::indexNoveltyFacets();
   }
 
@@ -72,21 +81,22 @@ class NoticeNoveltyTest extends ModelTestCase{
   /** @test */
   public function record12ShouldHaveNoveltyFacet() {
     Class_Notice::find(12)->updateNoveltyFacets();
-    $this->assertEquals('T1 B4 HNNNN0001 HNANA0001',
+    $this->assertEquals('T1 B4 HNNNN0001 HNANA0001 HNRNR0001',
                         Class_Notice::find(12)->getFacettes());
   }
 
 
   /** @test */
   public function record15ShouldNotHaveNoveltyFacet() {
-    $this->assertEquals('T1 B4', Class_Notice::find(15)->getFacettes());
+    $this->assertEquals('T1 B4 HNRNR0002', Class_Notice::find(15)->getFacettes());
   }
 
 
   /** @test */
   public function indexShouldNotFetchAllRecords() {
-    $this->assertEquals(['where' => 'match(facettes) against("+(HNNNN* HNANA*)" in boolean mode)',
-                         'limitPage' => [2, 100]],
+    $this->assertEquals(['where' => 'match(facettes) against("+(HNNNN* HNANA* HNRNR0001)" in boolean mode) and id_notice > 15',
+                         'order' => 'id_notice',
+                         'limit' => 100],
                         Class_Notice::getFirstAttributeForLastCallOn('findAllBy'));
   }
 }
diff --git a/tests/library/Class/NoticeTest.php b/tests/library/Class/NoticeTest.php
index 530dc080800a80752a22d37495703365a0fa5d89..874919d17d9527ac30f0e26776d8b96a64b69b51 100644
--- a/tests/library/Class/NoticeTest.php
+++ b/tests/library/Class/NoticeTest.php
@@ -1010,7 +1010,8 @@ class NoticeUpdateFacetsFromItemsTest extends ModelTestCase {
 
   /** @test */
   public function recordFacetsShouldContainsNoveltyForRoubaixAndNoveltyForLille() {
-    $this->assertEquals('T0 B10 YROUB HNNNN0001 HNANA0001 B11 HNNNN0002', Class_Notice::find(5)->getFacettes());
+    $this->assertEquals('T0 B10 YROUB HNNNN0001 HNANA0001 B11 HNNNN0002 HNRNR0001',
+                        Class_Notice::find(5)->getFacettes());
   }
 }
 
diff --git a/tests/scenarios/NoveltyFacet/NoveltyFacetTest.php b/tests/scenarios/NoveltyFacet/NoveltyFacetTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..a53cbb29bb963345fcb5b7c18c3f2c74d73915ad
--- /dev/null
+++ b/tests/scenarios/NoveltyFacet/NoveltyFacetTest.php
@@ -0,0 +1,199 @@
+<?php
+/**
+ * Copyright (c) 2012-2020, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+class NoveltyFacetSearchResultConfigTest extends Admin_AbstractControllerTestCase {
+  protected $_storm_default_to_volatile = true;
+
+  public function setUp() {
+    parent::setUp();
+    Class_CodifThesaurus::ensureRecordNovelty();
+  }
+
+
+  /** @test */
+  public function noveltyFacetShouldBeAvailableInHistoric() {
+    $this->dispatch('/admin/modules/recherche/config/site/type_module/recherche/id_profil/1/action1/resultat/action2/simple');
+    $this->_assertNoveltyIsAvailable();
+  }
+
+
+  /** @test */
+  public function noveltyFacetShouldBeAvailableInTemplates() {
+    $id = (new Intonation_Template)->tryOn(Class_Profil::getCurrentProfil());
+    $this->dispatch('/admin/widget/edit-action/id/recherche_resultat_simple/id_profil/' . $id);
+    $this->_assertNoveltyIsAvailable();
+  }
+
+
+  protected function _assertNoveltyIsAvailable() {
+    $this->assertXPathContentContains('//div[@data-heading="facettes"]//li[@data-id="HNRNR"]',
+                                      'Nouveauté');
+  }
+}
+
+
+
+
+class NoveltyFacetDomainEditTest extends Admin_AbstractControllerTestCase {
+  protected $_storm_default_to_volatile = true;
+
+
+  public function setUp() {
+    parent::setUp();
+    Class_CodifThesaurus::ensureRecordNovelty();
+    $this->onLoaderOfModel('Class_CodifThesaurus');
+    $this->dispatch('/admin/catalogue/add');
+  }
+
+
+  /** @test */
+  public function pageShouldNotContainRecordNoveltyInput() {
+    $this->assertContains('id_thesaurus not in ("NRNR", "NNNN", "NANA", "CCCC")',
+                          Class_CodifThesaurus::getFirstAttributeForLastCallOn('findAllBy')['where']);
+  }
+}
+
+
+
+
+class NoveltyFacetSearchResultSimpleTest extends AbstractControllerTestCase {
+  protected $_storm_default_to_volatile = true;
+
+
+  public function setUp() {
+    parent::setUp();
+    Class_CodifThesaurus::ensureRecordNovelty();
+
+    $this->fixture('Class_Notice', ['id' => 2]);
+
+    Class_Profil::getCurrentProfil()
+      ->setModulePreference('recherche', 'resultatsimple', 'facettes_codes', 'HNRNR');
+  }
+
+
+  public function facets() {
+    return [['HNRNR0001', 'Oui'],
+            ['HNRNR0002', 'Non']];
+  }
+
+
+  /**
+   * @test
+   * @dataProvider facets
+   */
+  public function withFacetPageShouldContainLinkToFilterByNovelty($facet, $label) {
+    Zend_Registry::set('sql',
+                       $this->mock()
+                       ->whenCalled('fetchAll')
+                       ->with('select id_notice, facettes from notices Where type=1', true, false)
+                       ->answers([[2, $facet]]));
+
+    $this->dispatch('/opac/recherche/simple/expressionRecherche/*');
+    $this->assertXPathContentContains('//a[contains(@href, "/facette/'. $facet .'")]', $label);
+  }
+}
+
+
+
+
+abstract class NoveltyFacetRecordUpdateTestCase extends ModelTestCase {
+  protected $_record;
+
+  public function setUp() {
+    parent::setUp();
+    Class_CodifThesaurus::ensureRecordNovelty();
+    $this->_record = $this->fixture('Class_Notice',
+                                    ['id' => 2,
+                                     'type_doc' => Class_TypeDoc::LIVRE]);
+    Class_Exemplaire::setTimeSource(new TimeSourceForTest('2021-01-14 16:55:16'));
+  }
+
+
+  public function tearDown() {
+    Class_Exemplaire::setTimeSource(null);
+    parent::tearDown();
+  }
+
+
+  /** @test */
+  public function notNoveltyShouldBecomeNovelty() {
+    $this->_recordFacetAndNovelty('T1 HNRNR0002', '2021-02-19');
+    $this->_updateRecord();
+    $this->assertContains('HNRNR0001', $this->_record->getFacettes());
+    $this->assertNotContains('HNRNR0002', $this->_record->getFacettes());
+  }
+
+
+  /** @test */
+  public function noveltyShouldBecomeNotNovelty() {
+    $this->_recordFacetAndNovelty('T1 HNRNR0001', '');
+    $this->_updateRecord();
+    $this->assertContains('HNRNR0002', $this->_record->getFacettes());
+    $this->assertNotContains('HNRNR0001', $this->_record->getFacettes());
+  }
+
+
+  protected function _recordFacetAndNovelty($facets, $novelty_date) {
+    $this->_record
+      ->setFacettes($facets)
+      ->setExemplaires([$this->fixture('Class_Exemplaire',
+                                       ['id' => 3,
+                                        'date_nouveaute' => $novelty_date])])
+      ->assertSave();
+  }
+
+
+  protected function _updateRecord() {
+  }
+}
+
+
+
+
+class NoveltyFacetUpdateFacetsFromExemplairesTest extends NoveltyFacetRecordUpdateTestCase {
+  protected function _updateRecord() {
+    $this->_record->updateFacetsFromExemplaires();
+  }
+}
+
+
+
+
+class NoveltyFacetUpdateNoveltyFacetsTest extends NoveltyFacetRecordUpdateTestCase {
+  protected function _updateRecord() {
+    $this->_record->updateNoveltyFacets();
+  }
+}
+
+
+
+
+class NoveltyFacetIndexTest extends ModelTestCase {
+  /** @test */
+  public function findAllByShouldContainRecordNoveltyFacet() {
+    Class_CodifThesaurus::ensureRecordNovelty();
+    $this->onLoaderOfModel('Class_Notice');
+    Class_Notice::indexNoveltyFacets();
+    $this->assertContains('+(HNNNN* HNANA* HNRNR0001)',
+                          Class_Notice::getFirstAttributeForLastCallOn('findAllBy')['where']);
+  }
+}
\ No newline at end of file