diff --git a/VERSIONS_HOTLINE/88956 b/VERSIONS_HOTLINE/88956
new file mode 100644
index 0000000000000000000000000000000000000000..b14d508e5fe8849d9170424097c522243887cdc5
--- /dev/null
+++ b/VERSIONS_HOTLINE/88956
@@ -0,0 +1 @@
+ - ticket #88956 : Rapport système : Ajout du niveau de base de données attendu et courant pour un meilleur diagnostique des mises à jours
\ No newline at end of file
diff --git a/VERSIONS_HOTLINE/89128 b/VERSIONS_HOTLINE/89128
new file mode 100644
index 0000000000000000000000000000000000000000..e6df06576ed6a5b08ca172a0768c24a1158482c5
--- /dev/null
+++ b/VERSIONS_HOTLINE/89128
@@ -0,0 +1 @@
+ - ticket #89128 : Cosmogramme : Correction du libellé de la variable "unicite_code_barres"
\ No newline at end of file
diff --git a/VERSIONS_HOTLINE/89508 b/VERSIONS_HOTLINE/89508
new file mode 100644
index 0000000000000000000000000000000000000000..351b1a47d71e4f2cef7ac8a8722a1fa7d9de2e3f
--- /dev/null
+++ b/VERSIONS_HOTLINE/89508
@@ -0,0 +1 @@
+ - ticket #89508 : Babelthèque : compatibilité HTTPS
\ No newline at end of file
diff --git a/VERSIONS_HOTLINE/89745 b/VERSIONS_HOTLINE/89745
new file mode 100644
index 0000000000000000000000000000000000000000..bb03d0abb23bdb8e9b53b8e19d6eb5ad4189f134
--- /dev/null
+++ b/VERSIONS_HOTLINE/89745
@@ -0,0 +1 @@
+ - ticket #89745 : SIGB Koha : Correction de la prise en compte de l'information "réservé par d'autres" lorsque plus d'une réservation est en cours
\ No newline at end of file
diff --git a/VERSIONS_HOTLINE/91377 b/VERSIONS_HOTLINE/91377
new file mode 100644
index 0000000000000000000000000000000000000000..223a16478d443b19bfd2ffb79b73fb8bb0cafff2
--- /dev/null
+++ b/VERSIONS_HOTLINE/91377
@@ -0,0 +1 @@
+ - ticket #91377 : Affichage boite 2 colonnes : problème de duplication des articles
\ No newline at end of file
diff --git a/VERSIONS_HOTLINE/92511 b/VERSIONS_HOTLINE/92511
new file mode 100644
index 0000000000000000000000000000000000000000..47cc0d40a3f3e6ba350c790b8519517f4bdb6ba2
--- /dev/null
+++ b/VERSIONS_HOTLINE/92511
@@ -0,0 +1 @@
+ - ticket #92511 : PMB: correction de prise en compte de la date de retour des prêts pour le statut en retard
\ No newline at end of file
diff --git a/VERSIONS_HOTLINE/92518 b/VERSIONS_HOTLINE/92518
new file mode 100644
index 0000000000000000000000000000000000000000..ad90847d9a3ee3863ce3df869c15cfac977f4621
--- /dev/null
+++ b/VERSIONS_HOTLINE/92518
@@ -0,0 +1 @@
+ - ticket #92518 : SIGB PMB : correction de l'affichage des messages d'erreur de prolongation
\ No newline at end of file
diff --git a/cosmogramme/php/classes/classe_notice_integration.php b/cosmogramme/php/classes/classe_notice_integration.php
index 53df279299acb5553deda62d4bb69f477b4f5043..180443e837fa3cdda08c18c7618badf4129c8153 100644
--- a/cosmogramme/php/classes/classe_notice_integration.php
+++ b/cosmogramme/php/classes/classe_notice_integration.php
@@ -736,10 +736,13 @@ class notice_integration {
     }
 
     if (!empty($code_barres))  {
-      $unicite_codes_barres = getVariable('unicite_code_barres');
-      $delete_duplicates_args = ($unicite_codes_barres == '1') ? [] : ['id_int_bib' => $this->id_int_bib];
-      $delete_duplicates_args['id_notice'] = $id_notice;
-      $delete_duplicates_args['code_barres'] = $code_barres;
+      $unicite_codes_barres = Class_CosmoVar::get(Class_Notice_DoubleFinder::VAR_BARCODE_UNIQ_MODE);
+      $delete_duplicates_args = ['id_notice' => $id_notice,
+                                 'code_barres' => $code_barres];
+
+      if ($unicite_codes_barres == Class_CosmoVar::UNIQ_BARCODE_WITHIN_LIBRARY)
+        $delete_duplicates_args['id_int_bib'] = $this->id_int_bib;
+
       Class_Exemplaire::deleteBy($delete_duplicates_args);
     }
 
diff --git a/cosmogramme/sql/patch/patch_373.php b/cosmogramme/sql/patch/patch_373.php
new file mode 100644
index 0000000000000000000000000000000000000000..301eff1d9e2eb178ac40e37a8cdb7081c987dbbe
--- /dev/null
+++ b/cosmogramme/sql/patch/patch_373.php
@@ -0,0 +1,6 @@
+<?php
+$adapter = Zend_Db_Table_Abstract::getDefaultAdapter();
+try {
+  $adapter->query("UPDATE `variables` SET liste='0:Code-barres uniquement\r\n1:Bibliothèque + codes-barres' WHERE clef='unicite_code_barres'");
+
+} catch(Exception $e) {}
diff --git a/cosmogramme/tests/php/classes/CarthameIntegrationTest.php b/cosmogramme/tests/php/classes/CarthameIntegrationTest.php
index 6c97ae89bed819660171a14ae7facc38c491891d..cdf69fc11d9d1b81a65ec6aaabf0c63d634085c4 100644
--- a/cosmogramme/tests/php/classes/CarthameIntegrationTest.php
+++ b/cosmogramme/tests/php/classes/CarthameIntegrationTest.php
@@ -32,7 +32,7 @@ abstract class CarthameIntegrationTestCase extends NoticeIntegrationTestCase {
 						 'non_exportable'=> 'electre;decitre;gam;zebris',
 						 'controle_codes_barres'=> 0,
 						 'unimarc_zone_titre' => '200$a;461$t',
-						 'unicite_code_barres' => 0,
+						 'unicite_code_barres' => Class_CosmoVar::UNIQ_BARCODE_ONLY,
 						 'champs_sup' => '',
 						 'ean_345' => ''];
 		foreach($vars as $key => $value)
diff --git a/cosmogramme/tests/php/classes/NoticeIntegrationAloesTest.php b/cosmogramme/tests/php/classes/NoticeIntegrationAloesTest.php
index 9acd648e55fb0d34b9c8ad985f48e9a05004c155..f14a43f727fc9e1bec7d8ad2cc2261581ab70a74 100644
--- a/cosmogramme/tests/php/classes/NoticeIntegrationAloesTest.php
+++ b/cosmogramme/tests/php/classes/NoticeIntegrationAloesTest.php
@@ -24,7 +24,13 @@ require_once 'NoticeIntegrationTest.php';
 
 
 abstract class NoticeIntegrationAloesTestCase extends NoticeIntegrationTestCase {
-	public function getProfilDonnees() {
+  public function setUp() {
+    parent::setUp();
+    Class_CosmoVar::setValueOf('unicite_code_barres', Class_CosmoVar::UNIQ_BARCODE_WITHIN_LIBRARY);
+  }
+
+
+  public function getProfilDonnees() {
 		return Class_IntProfilDonnees::forALOES()
 			->setIdProfil(111)
 			->getRawAttributes();
@@ -32,6 +38,7 @@ abstract class NoticeIntegrationAloesTestCase extends NoticeIntegrationTestCase
 }
 
 
+
 class NoticeIntegrationAloes11septembre2001Test extends NoticeIntegrationAloesTestCase {
 	public function getProfilDonnees() {
 		return Class_IntProfilDonnees::forALOES()
@@ -275,7 +282,7 @@ class NoticeIntegrationAloesDimancheALaPiscineTest extends NoticeIntegrationAloe
 			->setIdProfil(111)
       ->setItemField(Class_IntProfilDonnees::FIELD_ITEM_EMPLACEMENT, 'u')
 			->getRawAttributes();
-      }
+  }
 
 
 	public function setUp() {
@@ -302,7 +309,7 @@ class NoticeIntegrationAloesDimancheALaPiscineTest extends NoticeIntegrationAloe
 																				 'id_bib' => 4,
 																				 'invisible' => 0]);
 
-		Storm_Test_ObjectWrapper::onLoaderOfModel('Class_Exemplaire');
+		$this->onLoaderOfModel('Class_Exemplaire');
 		$this->loadNotice("unimarc_dimanche_a_la_piscine");
 	}
 
diff --git a/cosmogramme/tests/php/classes/NoticeIntegrationDedupTest.php b/cosmogramme/tests/php/classes/NoticeIntegrationDedupTest.php
index 8f3b325827a604ec712e787cca9895268f8e2de2..42f838e6c3c1d5f31b6be6f75ad1a58fec74b08d 100644
--- a/cosmogramme/tests/php/classes/NoticeIntegrationDedupTest.php
+++ b/cosmogramme/tests/php/classes/NoticeIntegrationDedupTest.php
@@ -63,7 +63,7 @@ class NoticeIntegrationDedupWithoutIsbnTest extends NoticeIntegrationTestCase {
 			'non_exportable'=> 'electre;decitre;gam;zebris',
 			'controle_codes_barres'=> 0,
 			'unimarc_zone_titre' => '200$a;461$t',
-			'unicite_code_barres' => 0,
+			'unicite_code_barres' => Class_CosmoVar::UNIQ_BARCODE_ONLY,
 			'champs_sup' => '',
 			'ean_345' => '']);
 
@@ -96,7 +96,7 @@ class NoticeIntegrationDedupSameUnimarcLoadedTest extends NoticeIntegrationTestC
 			'non_exportable'=> 'electre;decitre;gam;zebris',
 			'controle_codes_barres'=> 0,
 			'unimarc_zone_titre' => '200$a;461$t',
-			'unicite_code_barres' => 0,
+			'unicite_code_barres' => Class_CosmoVar::UNIQ_BARCODE_ONLY,
 			'champs_sup' => '',
 			'ean_345' => '']);
 
@@ -171,7 +171,7 @@ class NoticeIntegrationDedupCaliceWithoutIsbnTest extends NoticeIntegrationTestC
                         'non_exportable'=> 'electre;decitre;gam;zebris',
                         'controle_codes_barres' => 1,
                         'unimarc_zone_titre' => '200$a;461$t',
-                        'unicite_code_barres' => 0,
+                        'unicite_code_barres' => Class_CosmoVar::UNIQ_BARCODE_ONLY,
                         'champs_sup' => '',
                         'ean_345' => 1]);
 
@@ -184,3 +184,69 @@ class NoticeIntegrationDedupCaliceWithoutIsbnTest extends NoticeIntegrationTestC
 		$this->assertEquals(2, Class_Notice::count());
 	}
 }
+
+
+
+
+/** @see http://forge.afi-sa.fr/issues/89128 */
+class NoticeIntegrationDedupOnBarcodeWithinLibraryTest extends NoticeIntegrationTestCase {
+  public function getProfilDonnees() {
+		return Class_IntProfilDonnees::forPMB()
+      ->setIdProfil(113)
+      ->getRawAttributes();
+	}
+
+
+  public function setUp() {
+    parent::setUp();
+
+    $this->fixture('Class_Notice',
+                   ['id' => 30,
+                    'type_doc' => 1,
+                    'alpha_titre' => 'ACTUALITE DU VIRTUEL',
+                    'alpha_auteur' => 'FR BNF',
+                    'titres' => 'ACTUALITE AKTUALIT VIRTUEL',
+                    'auteurs' => 'BNF',
+                    'editeur' => '[Centre national d\'art et de culture Georges-Pompidou (Paris)]',
+                    'isbn' => '978-2-7189-6666-4',
+                    'unimarc' => '',
+                    'ean' => null,
+                    'id_commerciale' => '',
+                    'id_bnf' => '',
+                    'clef_alpha' => 'ACTUALITEDUVIRTUEL--FRB--CENTRENATIONALDARTETDECULTUREGEORGESPOMPIDOUPARIS-1997-5',
+                    'clef_oeuvre' => 'ACTUALITEDUVIRTUEL--FRB-',
+                    'clef_chapeau' => '',
+                    'qualite' => 10,
+                    'date_creation' => '2015-05-02 00:00:00',
+                    'date_maj' => '2015-09-13 13:22:53',
+                    'url_vignette' => Class_WebService_Vignette::NO_DATA,
+                    'url_image' => Class_WebService_Vignette::NO_DATA]);
+
+
+    $this->fixture('Class_Exemplaire',
+                   ['id' => 23,
+                    'id_notice' => 30,
+                    'code_barres' => '18120',
+                    'id_int_bib' => 6]);
+  }
+
+
+  /** @test */
+  public function withUniciteCodeBarresOnlyNumberOfRecordsShouldBeOne() {
+    Class_CosmoVar::set(Class_Notice_DoubleFinder::VAR_BARCODE_UNIQ_MODE,
+                        Class_CosmoVar::UNIQ_BARCODE_ONLY);
+ 		$this->loadNotice('unimarc_pmb_pierres');
+    $this->assertCount(1, Class_Notice::findAll());
+    $this->assertCount(1, Class_Exemplaire::findAll());
+  }
+
+
+  /** @test */
+  public function withUniciteCodeBarresWithLibraryNumberOfRecordsShouldBeTwo() {
+    Class_CosmoVar::set(Class_Notice_DoubleFinder::VAR_BARCODE_UNIQ_MODE,
+                        Class_CosmoVar::UNIQ_BARCODE_WITHIN_LIBRARY);
+ 		$this->loadNotice('unimarc_pmb_pierres');
+    $this->assertCount(2, Class_Notice::findAll());
+    $this->assertCount(2, Class_Exemplaire::findAll());
+  }
+}
\ No newline at end of file
diff --git a/cosmogramme/tests/php/classes/NoticeIntegrationSuccinteTest.php b/cosmogramme/tests/php/classes/NoticeIntegrationSuccinteTest.php
index efb3636e1bc7c0ba5057ce50dfc593596f19f502..d6e1569eb884b6338683097acd6d247283bb0292 100644
--- a/cosmogramme/tests/php/classes/NoticeIntegrationSuccinteTest.php
+++ b/cosmogramme/tests/php/classes/NoticeIntegrationSuccinteTest.php
@@ -33,7 +33,7 @@ class NoticeIntegrationSuccinteTest extends ModelTestCase {
 												'non_exportable'=> 'electre;decitre;gam;zebris',
 												'controle_codes_barres'=> 0,
 												'unimarc_zone_titre' => '200$a;461$t',
-												'unicite_code_barres' => 0,
+												'unicite_code_barres' => Class_CosmoVar::UNIQ_BARCODE_ONLY,
 												'champs_sup' => '',
 												'ean_345' => '',
 												'Z3950_cache_only' => '0',
@@ -104,7 +104,7 @@ class NoticeIntegrationSuccinteTest extends ModelTestCase {
 																		'statut_z3950' => "3",
 																		'serveur' => "Bnf",
 																		'erreur' => false,
-																		'unimarc' => '01075cjm  22002893  450 001002100000009004700021020001700068021005400085071004100139073001800180100004100198101000800239102000700247126002500254200007900279210006800358215004700426306003500473608002100508608001600529608003500545686007000580700003600650716002900686801003900715930003100754FRBNF400642570000008http://catalogue.bnf.fr/ark:/12148/cb400642576  aFRb70601036  5FR-759999999:SDC 12-202181aFRbDLS-20051103-917001bInsideOutMusicaSPV 48622 CDcboÃite 0a0693723486222  a20051103d2005    u  y0frey50      ba0 aeng  aDE  aaguxhxx||||||cdbbex1 a?bEnregistrement sonorefNeal Morse, chant, guit., claviers [acc. instr.]  aKlevecInsideOutMusica[Paris]c[distrib. Wagram music]dP 2005  a1 disque compact (56 min 26 s)e1 brochure  aProd. : InsideOutMusic, P 2005  arock, pop2frTAV  arock2frTAV  aÂedition phonographique2frTAV  a1062Cadre de classement de la Bibliographie nationale franÐcaise |314208951aMorsebNeal47214545  314032403aInsideOutMusic 0aFRbBNFc20051103gAFNOR2intermrc  5FR-759999999:SDC 12-202181'])
+																		'unimarc' => '01075cjm  22002893  450 001002100000009004700021020001700068021005400085071004100139073001800180100004100198101000800239102000700247126002500254200007900279210006800358215004700426306003500473608002100508608001600529608003500545686007000580700003600650716002900686801003900715930003100754FRBNF400642570000008http://catalogue.bnf.fr/ark:/12148/cb400642576  aFRb70601036  5FR-759999999:SDC 12-202181aFRbDLS-20051103-917001bInsideOutMusicaSPV 48622 CDcboîte 0a0693723486222  a20051103d2005    u  y0frey50      ba0 aeng  aDE  aaguxhxx||||||cdbbex1 a?bEnregistrement sonorefNeal Morse, chant, guit., claviers [acc. instr.]  aKlevecInsideOutMusica[Paris]c[distrib. Wagram music]dP 2005  a1 disque compact (56 min 26 s)e1 brochure  aProd. : InsideOutMusic, P 2005  arock, pop2frTAV  arock2frTAV  aÉdition phonographique2frTAV  a1062Cadre de classement de la Bibliographie nationale française |314208951aMorsebNeal47214545  314032403aInsideOutMusic 0aFRbBNFc20051103gAFNOR2intermrc  5FR-759999999:SDC 12-202181'])
 												 ->beStrict())
 			->traiteSuccinte($succinte);
 
diff --git a/cosmogramme/tests/php/classes/NoticeIntegrationTest.php b/cosmogramme/tests/php/classes/NoticeIntegrationTest.php
index 0d4388a0818d01a491dd4aca9fc0e5c7e3d9e3a5..cc0fc85e4fc3fec52e6e9a21517a2a7b180b72b5 100644
--- a/cosmogramme/tests/php/classes/NoticeIntegrationTest.php
+++ b/cosmogramme/tests/php/classes/NoticeIntegrationTest.php
@@ -92,7 +92,7 @@ abstract class NoticeIntegrationTestCase extends ModelTestCase {
                         'non_exportable'=> 'electre;decitre;gam;zebris',
                         'controle_codes_barres'=> 0,
                         'unimarc_zone_titre' => '200$a;461$t',
-                        'unicite_code_barres' => 0,
+                        'unicite_code_barres' => Class_CosmoVar::UNIQ_BARCODE_ONLY,
                         'champs_sup' => '',
                         'ean_345' => ''])
 			->setListeCache(['nature_docs'=> "1:Collection\r\n2:Dataset\r\n3:Event\r\n4:Image",
diff --git a/cosmogramme/tests/php/classes/unimarc_pmb_pierres.txt b/cosmogramme/tests/php/classes/unimarc_pmb_pierres.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f61b765ea7dab08bb57eab917f9e3ade9e74121f
--- /dev/null
+++ b/cosmogramme/tests/php/classes/unimarc_pmb_pierres.txt
@@ -0,0 +1 @@
+01446nam0 22002291i 450 0010005000001000035000050090015000402000087000550100031001421010008001732150018001813270010001993190028002097000028002377020043002652100040003082250039003484100039003878960186004269950085006129960519006972872  a20101012u        u  u0frey50    a1979-01-011 aCes pierres qui attendentePour un dialogue entre l'hindouisme et le christianisme  a978-2-7189-0137-4dE 28.200 afre  a268 p.d20 cm  aIndex  aAucun droit spécifique 1aCocagnacbA.M.9id:2149 1aDorébJoseph4080f1936-....9id:1123  aParisbPariscDescléed19799id:412 aJésus et Jésus-Christv89id:201 0tJésus et Jésus-Christv89id:201  ahttps://brieuc.bibliossimo.net/pmb/opac_css/getimage.php?url_image=http%3A%2F%2Fimages-eu.amazon.com%2Fimages%2FP%2F%21%21isbn%21%21.08.MZZZZZZZ.jpg&noticecode=9782718901374&vigurl=  aMédiathèque Saint-YvescMédiathèque Saint-Yvesf18120kC274ruuqCollections  f18120kC274m00000000n00000000aMédiathèque Saint-Yvesb1vSalle RuffeletxCollectionsyCollectionseLivre1Empruntable319expl_id:191029create_date:2014-03-04 10:31:219expl_cb:181209expl_cote:C2749expl_statut:19statut_libelle:Empruntable9expl_typdoc:19tdoc_libelle:Livre9expl_section:19section_libelle:Collections9sdoc_codage_import:Collections9expl_owner:19lender_libelle:Médiathèque Saint-Yves9codestat_libelle:Exemplaires9pret_flag:19location_libelle:Salle Ruffelet9locdoc_codage_import:8
\ No newline at end of file
diff --git a/library/Class/CosmoVar.php b/library/Class/CosmoVar.php
index 2d947484e044bead92e5a26303d698592989138e..fdc23f30455c4b93b8c55303619fe68dee1704bd 100644
--- a/library/Class/CosmoVar.php
+++ b/library/Class/CosmoVar.php
@@ -105,6 +105,9 @@ class Class_CosmoVar extends Storm_Model_Abstract {
   const DOUBLE_SEARCH_ALPHA_KEY = 1;
   const DOUBLE_SEARCH_IDS = 0;
 
+  const UNIQ_BARCODE_ONLY = 0;
+  const UNIQ_BARCODE_WITHIN_LIBRARY = 1;
+
   const PICKUP_LOCATION_ITEM = 0;
   const PICKUP_LOCATION_CHOICE = 1;
   const PICKUP_LOCATION_PATRON = 2;
diff --git a/library/Class/Notice/DoubleFinder.php b/library/Class/Notice/DoubleFinder.php
index 628c45bbb43a52f6452646a95ff4adf63ee4b4cd..dd6642a4620c0576ba9e86c0a7c3670cb7579d78 100644
--- a/library/Class/Notice/DoubleFinder.php
+++ b/library/Class/Notice/DoubleFinder.php
@@ -21,8 +21,9 @@
 
 
 class Class_Notice_DoubleFinder {
-  const VAR_BARCODE_UNIQ_MODE = 'unicite_code_barres';
-  const VAR_DOUBLE_MODE = 'mode_doublon';
+  const
+    VAR_BARCODE_UNIQ_MODE = 'unicite_code_barres',
+    VAR_DOUBLE_MODE = 'mode_doublon';
 
   protected
     $_barcode_uniq_mode,
@@ -90,7 +91,7 @@ class Class_Notice_DoubleFinder {
       return;
 
     $conditions = ['code_barres' => $item['code_barres']];
-    if ($this->_barcode_uniq_mode == '1')
+    if ($this->_barcode_uniq_mode == Class_CosmoVar::UNIQ_BARCODE_WITHIN_LIBRARY)
       $conditions['id_int_bib'] = (int) $this->_library->getId();
 
     return $this->_getRecordIdByItem($conditions);
diff --git a/library/Class/Profil.php b/library/Class/Profil.php
index 113a15d3acd16cb04bc7496074a2a0aa145557f8..ebccc2da9e659d97fb09a1ce67f525457dcef949 100644
--- a/library/Class/Profil.php
+++ b/library/Class/Profil.php
@@ -2348,7 +2348,7 @@ class Class_Profil extends Storm_Model_Abstract {
     foreach($modules as $key => $module) {
       if(   $module['type_module'] == $type_module
          && $module['parent_id'] == $id
-         && $key >= 1000
+         && $key >= Class_Systeme_ModulesAccueil_ConteneurDeuxColonnes::MODULE_ID_SHIFT
          && $key == $two_cols_pref['col_' . $colonne . '_module_id'])
         return $key;
     }
diff --git a/library/Class/Systeme/ModulesAccueil/ConteneurDeuxColonnes.php b/library/Class/Systeme/ModulesAccueil/ConteneurDeuxColonnes.php
index 206b9ea4df6da90c64aa0d4a77a314dd454ef277..c92bd8e0a1bf540686501abe1b536072eeda8499 100644
--- a/library/Class/Systeme/ModulesAccueil/ConteneurDeuxColonnes.php
+++ b/library/Class/Systeme/ModulesAccueil/ConteneurDeuxColonnes.php
@@ -21,6 +21,7 @@
 
 class Class_Systeme_ModulesAccueil_ConteneurDeuxColonnes extends Class_Systeme_ModulesAccueil_Null {
   const CODE = 'CONTENEUR_DEUX_COLONNES';
+  const MODULE_ID_SHIFT = 1000;
 
   protected
     $_group = Class_Systeme_ModulesAccueil::GROUP_SITE,
@@ -77,7 +78,7 @@ class Class_Systeme_ModulesAccueil_ConteneurDeuxColonnes extends Class_Systeme_M
 
   public static function getOrCreateModuleForCol($profil, $id, $type_module, $colonne) {
     if(!$id = $profil->getModuleIdFromCol($id, $type_module, $colonne))
-      return $profil->createNewModuleAccueilId(1000);
+      return $profil->createNewModuleAccueilId(static::MODULE_ID_SHIFT);
 
     return $id;
   }
diff --git a/library/Class/Systeme/Report.php b/library/Class/Systeme/Report.php
index 0b1a9fc48798a4c722e3c423f7853d961ba3919f..0856570d39d59b9ba48bf38b2d7f75dcaa2c5b7f 100644
--- a/library/Class/Systeme/Report.php
+++ b/library/Class/Systeme/Report.php
@@ -81,6 +81,12 @@ class Class_Systeme_Report_Headers extends Class_Systeme_Report_Abstract {
                         $this->_('Base de données'),
                         array_at('dbname',
                                  Zend_Db_Table::getDefaultAdapter()->getConfig()));
+
+    $visitor->visitData('patch_level',
+                        $this->_('Niveau de patch'),
+                        ['expected' => (string)(new Class_Migration_Patchs)->getLastPatchNumber(),
+                         'actual' => Class_CosmoVar::get('patch_level')]);
+
     $visitor->visitData('php', $this->_('PHP'), PHP_VERSION);
   }
 }
diff --git a/library/Class/WebService/SIGB/Emprunt.php b/library/Class/WebService/SIGB/Emprunt.php
index 0e1b66f89bbaf5b9a2b308e372e98fceb420d2b1..ab0ec1fb122728f595b1ed3dc92b9e14efa345ff 100644
--- a/library/Class/WebService/SIGB/Emprunt.php
+++ b/library/Class/WebService/SIGB/Emprunt.php
@@ -171,13 +171,20 @@ class Class_WebService_SIGB_Emprunt extends Class_WebService_SIGB_ExemplaireOper
     if ('end_issue_date' == $key)
       return $this->_isBeforeDate($this->getIssueDate(), $value);
 
-    if (!'onhold' == $key)
+    if ('onhold' != $key)
       return true;
 
     if ('all' == $value)
       return true;
 
-    return $this->getOnhold() == (('yes' == $value) ? 1 : 0);
+    return ('yes' == $value)
+      ? $this->isOnHold()
+      : !$this->isOnHold();
+  }
+
+
+  public function isOnHold() {
+    return 0 != $this->getOnHold();
   }
 
 
diff --git a/library/Class/WebService/SIGB/PMB/Service.php b/library/Class/WebService/SIGB/PMB/Service.php
index b16d8830251aa5a836a88405d446dcd96c59ac58..120e7afb3b61459b0695e14834afc8d5e81450d2 100644
--- a/library/Class/WebService/SIGB/PMB/Service.php
+++ b/library/Class/WebService/SIGB/PMB/Service.php
@@ -88,13 +88,13 @@ class Class_Webservice_SIGB_PMB_Service extends Class_WebService_SIGB_AbstractSe
                                                        $exemplaire->getIdOrigine()]);
     $result = (array) $this->_getJsonData($json, 'result');
 
-    if(!$result)
-      return ['status' => false, 'erreur' => $this->_('Réservation impossible : le service de réservation PMB via webservice est indisponible')];
+    if (!$result)
+      return $this->_error($this->_('Réservation impossible : le service de réservation PMB via webservice est indisponible'));
 
     if(isset($result['error']))
-      return ['status' => false, 'erreur' => $this->_('Réservation impossible : Vous avez déjà réservé cette exemplaire')];
+      return $this->_error($this->_('Réservation impossible : Vous avez déjà réservé cette exemplaire'));
 
-    return true;
+    return $this->_success();
   }
 
 
@@ -102,16 +102,23 @@ class Class_Webservice_SIGB_PMB_Service extends Class_WebService_SIGB_AbstractSe
     $session_token = $this->openSessionForUser($user);
     $json = $this->httpPost('pmbesOPACEmpr_delete_resa', [$session_token,
                                                           $reservation_id]);
-    return true;
+    return $this->_success();
   }
 
 
   public function prolongerPret($user, $pret_id) {
     $session_token = $this->openSessionForUser($user);
-    if(!$json = $this->httpPost('pmbesSelfServices_self_renew', [$session_token, $pret_id]))
-      return ['statut' => false, 'erreur' => $this->_('Prolongation impossible : le service de prolongation PMB via webservice est indisponible')];
+    if((!$json = $this->httpPost('pmbesSelfServices_self_renew', [$session_token, $pret_id]))
+       || (!$result = json_decode($json, true)))
+      return $this->_error($this->_('Prolongation impossible : le service de prolongation PMB via webservice est indisponible'));
 
-    return true;
+    if (array_key_exists('result', $result)
+        && is_array($result['result'])
+        && array_key_exists('message', $result['result'])
+        && $message = $result['result']['message'])
+      return $this->_error($message);
+
+    return $this->_success();
   }
 
 
@@ -196,7 +203,7 @@ class Class_Webservice_SIGB_PMB_Service extends Class_WebService_SIGB_AbstractSe
       ->setId($emprunt_json['expl_id'])
       ->setTitre($emprunt_json['expl_libelle'])
       ->setCodeBarre($emprunt_json['expl_cb'])
-      ->setDateRetour(implode('-', array_reverse(explode('/', $emprunt_json['loan_returndate']))));
+      ->setDateRetour($emprunt_json['loan_returndate']);
 
     return $emprunt;
   }
@@ -339,4 +346,3 @@ class JsonWebClient {
   }
 
 }
-?>
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/Portail.php b/library/ZendAfi/View/Helper/Portail.php
index 184446f9d786b52765791af0b4d1f40c0674f2b1..4f50bdddead695171ac33d55b05411c83c18ad09 100644
--- a/library/ZendAfi/View/Helper/Portail.php
+++ b/library/ZendAfi/View/Helper/Portail.php
@@ -30,7 +30,9 @@ class ZendAfi_View_Helper_Portail extends ZendAfi_View_Helper_BaseHelper {
       $ret[$division_demandee] = '';
 
     foreach ($cfg_accueil["modules"] as $id_module => $module) {
-      if ($id_module === null) continue;
+      if ($id_module === null
+          || Class_Systeme_ModulesAccueil_ConteneurDeuxColonnes::MODULE_ID_SHIFT <= $id_module)
+        continue;
 
       $helper = ZendAfi_View_Helper_Accueil_Base::getModuleHelperFromParams($id_module, $module, $this->view);
       if (!$helper) continue;
diff --git a/public/opac/js/babeltheque.js b/public/opac/js/babeltheque.js
index d7b59b925973cd59a712253935bc13256881b085..3962718e3c3c4c5d1ed5073d9bcf055e8bf4af35 100644
--- a/public/opac/js/babeltheque.js
+++ b/public/opac/js/babeltheque.js
@@ -1,103 +1,103 @@
 (function() {
-	var getJSQueryString = function(script) {
-		var
-		  scripts = document.getElementsByTagName('script'),
-		  i, 
-		  curScript;
+  var getJSQueryString = function(script) {
+    var
+    scripts = document.getElementsByTagName('script'),
+    i, 
+    curScript;
 
-		for (i = 0; i < scripts.length; ++i) {
-			curScript = scripts[i];
+    for (i = 0; i < scripts.length; ++i) {
+      curScript = scripts[i];
 
-			if (curScript.src.match(script)) {
-				return  (curScript.src.match(/\?(.*)/) || [undefined])[1];
-			}
-		}
-	}
+      if (curScript.src.match(script)) {
+	return  (curScript.src.match(/\?(.*)/) || [undefined])[1];
+      }
+    }
+  }
 
 
-	var getJSParams = function(script) {
-		var 
-		  qs = getJSQueryString(script),
-		  search = /([^&=]+)=?([^&]*)/g,
-		  urlParams = {};
+  var getJSParams = function(script) {
+    var 
+    qs = getJSQueryString(script),
+    search = /([^&=]+)=?([^&]*)/g,
+    urlParams = {};
 
-		while (match = search.exec(qs))
+    while (match = search.exec(qs))
       urlParams[match[1]] = match[2];
 
-		return urlParams;
-	}
+    return urlParams;
+  }
 
 
-	var getJSParamNamed = function (script, name) {
-		return  getJSParams(script)[name];
-	}
+  var getJSParamNamed = function (script, name) {
+    return  getJSParams(script)[name];
+  }
 
 
-	var bwid = getJSParamNamed('babeltheque.js', 'bwid');
+  var bwid = getJSParamNamed('babeltheque.js', 'bwid');
 
-	window.loadBabelthequeScript = function(isbn) {
-		insertBabelthequeISBNTag(isbn);
-		$.getScript('http://www.babeltheque.com/bw_' + bwid +'.js');
-	}
+  window.loadBabelthequeScript = function(isbn) {
+    insertBabelthequeISBNTag(isbn);
+    $.getScript('https://www.babelio.com/bw_' + bwid +'.js');
+  }
 })();
 
 
 $.fn.babelthequeTag=function(info) {
-	return this.each(function() {
-		$(this).append('<div id="BW_'+info+'"></div>');
-	});
+  return this.each(function() {
+    $(this).append('<div id="BW_'+info+'"></div>');
+  });
 }
 
 
 var insertBabelthequeISBNTag = function(isbn) {
-	if (!$('input#BW_id_isbn').length)
-		$('body').append('<input type="hidden" id="BW_id_isbn" value="'+isbn+'"\>');
+  if (!$('input#BW_id_isbn').length)
+    $('body').append('<input type="hidden" id="BW_id_isbn" value="'+isbn+'"\>');
 }
 
 
 var blocNoticeAfterLoad = function (info, isbn, target) {
-	if ("" == isbn)
-		return;
+  if ("" == isbn)
+    return;
 
-	var callback = $(window).attr(info + 'NoticeAfterLoad');
-	if (undefined == callback)
-		return;
+  var callback = $(window).attr(info + 'NoticeAfterLoad');
+  if (undefined == callback)
+    return;
 
-	callback(target);
-	loadBabelthequeScript(isbn);
+  callback(target);
+  loadBabelthequeScript(isbn);
 }
 
 
 var tagsNoticeAfterLoad = function(target) {
-	target.prepend('<div id="BW_etiquettes"></div>');
+  target.prepend('<div id="BW_etiquettes"></div>');
 }
 
 
 var avisNoticeAfterLoad = function(target) {
-	var tr_critiques = target.find('table tr:nth-child(2)');
+  var tr_critiques = target.find('table tr:nth-child(2)');
 
-	if (!tr_critiques.find('ul').length)
-		$('<ul></ul>').appendTo(tr_critiques);
+  if (!tr_critiques.find('ul').length)
+    $('<ul></ul>').appendTo(tr_critiques);
 
-	var ul_critiques = tr_critiques.find('ul');
-	
-	$('<li class="notes_avis_babeltheque"><span id="BW_notes"></span><span id="BW_critiques"></span> <span id="BW_critiques_pro"></span></li>')
-	.appendTo(ul_critiques);
+  var ul_critiques = tr_critiques.find('ul');
+  
+  $('<li class="notes_avis_babeltheque"><span id="BW_notes"></span><span id="BW_critiques"></span> <span id="BW_critiques_pro"></span></li>')
+    .appendTo(ul_critiques);
 }
 
 
 var videosNoticeAfterLoad = function(target) {
-	target.find('td:contains("Aucune vidéo")').remove();
-	target.prepend('<div id="BW_videos"></div>');
+  target.find('td:contains("Aucune vidéo")').remove();
+  target.prepend('<div id="BW_videos"></div>');
 }
 
 
 var resumeNoticeAfterLoad = function(target) {
-	target.find('td:contains("Aucune information")').remove();
-	target.babelthequeTag('citations');
+  target.find('td:contains("Aucune information")').remove();
+  target.babelthequeTag('citations');
 }
 
 
 var babelthequeNoticeAfterLoad = function(target) {
-	target.empty().babelthequeTag('suggestions');
+  target.empty().babelthequeTag('suggestions');
 }
diff --git a/tests/application/modules/opac/controllers/IndexControllerTest.php b/tests/application/modules/opac/controllers/IndexControllerTest.php
index 9b090e54950e46b9927e67daf2973aa8246fb953..d3516064752d2aae8b8c0fca5c3da3c38a312ebe 100644
--- a/tests/application/modules/opac/controllers/IndexControllerTest.php
+++ b/tests/application/modules/opac/controllers/IndexControllerTest.php
@@ -754,14 +754,39 @@ class IndexControllerStatusTest extends AbstractControllerTestCase {
   public function setUp() {
     parent::setUp();
     Class_AdminVar::set('ALLOWED_DISK_SPACE', 1);
+    Class_CosmoVar::set('patch_level', '369');
+
+    $filesystem = $this->mock()
+                       ->whenCalled('glob')
+                       ->answers(['cosmogramme/sql/patch/patch_372.php']);
+    Class_Migration_Patchs::setFileSystem($filesystem);
+
     $this->dispatch('/opac/index/status', true);
     $this->_json = json_decode($this->_response->getBody(), true);
   }
 
 
+  public function tearDown() {
+    Class_Migration_Patchs::setFileSystem(null);
+    parent::tearDown();
+  }
+
+
   /** @test */
   public function dateCreationShouldBeSet() {
-    $this->assertNotNull($this->_json['headers']['creation_datetime'], $this->_json);
+    $this->assertNotNull($this->_json['headers']['creation_datetime']);
+  }
+
+
+  /** @test */
+  public function actualPatchLevelShouldBe369() {
+    $this->assertEquals('369', $this->_json['headers']['patch_level']['actual']);
+  }
+
+
+  /** @test */
+  public function expectedPatchLevelShouldBeLastPatchNumber() {
+    $this->assertEquals('372', $this->_json['headers']['patch_level']['expected']);
   }
 }
 
@@ -968,4 +993,30 @@ class IndexControllerSiteDownActionTest extends AbstractControllerTestCase {
   public function frontNavCssShouldBeLoaded() {
     $this->assertXPath('//link[contains(@href, "front_nav.css")]');
   }
+}
+
+
+
+class IndexControllerPageWithDoubleColumnsTest extends AbstractControllerTestCase {
+  protected $_storm_default_to_volatile = true;
+
+  public function setUp() {
+    parent::setUp();
+    $this->onLoaderOfModel('Class_Article')
+         ->whenCalled('getArticlesByPreferences')
+         ->answers([]);
+
+    $this->fixture('Class_Profil',
+               ['id' => 3,
+                'cfg_accueil' => 'a:4:{s:7:"modules";a:15:{i:7;a:3:{s:8:"division";s:1:"1";s:11:"type_module";s:11:"RECH_SIMPLE";s:11:"preferences";a:19:{s:5:"titre";s:0:"";s:7:"message";s:0:"";s:7:"exemple";s:0:"";s:10:"select_bib";s:1:"0";s:10:"select_doc";s:1:"0";s:13:"select_annexe";s:1:"0";s:7:"largeur";s:3:"140";s:17:"recherche_avancee";s:2:"on";s:8:"type_doc";s:0:"";s:3:"tri";s:1:"*";s:15:"profil_redirect";s:1:"3";s:11:"placeholder";s:36:"Rechercher à Croissy et au Vésinet";s:13:"search_button";s:0:"";s:10:"domain_ids";s:0:"";s:19:"domain_select_style";s:6:"select";s:5:"boite";s:22:"boite_recherche_simple";s:9:"id_module";s:1:"7";s:7:"Valider";s:7:"Valider";s:0:"";s:0:"";}}i:5;a:3:{s:8:"division";s:1:"1";s:11:"type_module";s:4:"NEWS";s:11:"preferences";a:20:{s:5:"titre";s:15:"INFOS PRATIQUES";s:6:"anchor";s:0:"";s:19:"allow_link_on_title";s:1:"1";s:8:"type_aff";s:1:"1";s:12:"id_categorie";s:0:"";s:8:"id_items";s:7:"269-267";s:6:"nb_aff";s:1:"1";s:10:"nb_analyse";s:1:"5";s:13:"display_order";s:9:"Selection";s:19:"display_titles_only";s:1:"0";s:8:"rss_avis";s:1:"0";s:14:"op_largeur_img";s:3:"200";s:6:"layout";s:4:"grid";s:16:"op_hauteur_boite";s:3:"400";s:5:"boite";s:19:"boite_titre_encadre";s:9:"id_module";s:1:"5";s:11:"style_liste";s:4:"none";s:13:"styles_reload";s:1:"0";s:7:"Valider";s:7:"Valider";s:0:"";s:0:"";}}i:8;a:3:{s:8:"division";s:1:"1";s:11:"type_module";s:13:"MENU_VERTICAL";s:11:"preferences";a:11:{s:14:"afficher_titre";s:1:"1";s:11:"menu_deplie";s:1:"0";s:8:"new_html";s:1:"0";s:11:"toggle_menu";s:1:"0";s:4:"menu";s:3:"3-5";s:5:"boite";s:20:"boite_titre_souligne";s:5:"titre";s:0:"";s:9:"id_module";s:1:"8";s:10:"profile_id";s:1:"3";s:7:"Valider";s:7:"Valider";s:0:"";s:0:"";}}i:1;a:3:{s:8:"division";s:1:"1";s:11:"type_module";s:13:"MENU_VERTICAL";s:11:"preferences";a:8:{s:14:"afficher_titre";s:1:"1";s:11:"menu_deplie";s:1:"0";s:8:"new_html";s:1:"0";s:11:"toggle_menu";s:1:"0";s:4:"menu";s:3:"3-8";s:5:"boite";s:20:"boite_titre_souligne";s:5:"titre";s:0:"";s:9:"id_module";s:1:"1";}}i:11;a:3:{s:8:"division";s:1:"1";s:11:"type_module";s:13:"MENU_VERTICAL";s:11:"preferences";a:10:{s:14:"afficher_titre";s:1:"1";s:11:"menu_deplie";s:1:"0";s:8:"new_html";s:1:"0";s:11:"toggle_menu";s:1:"0";s:4:"menu";s:3:"3-6";s:5:"boite";s:20:"boite_titre_souligne";s:5:"titre";s:0:"";s:9:"id_module";s:2:"11";s:7:"Valider";s:7:"Valider";s:0:"";s:0:"";}}i:4;a:3:{s:8:"division";s:1:"1";s:11:"type_module";s:13:"MENU_VERTICAL";s:11:"preferences";a:8:{s:14:"afficher_titre";s:1:"1";s:11:"menu_deplie";s:1:"0";s:8:"new_html";s:1:"0";s:11:"toggle_menu";s:1:"0";s:4:"menu";s:3:"3-9";s:5:"boite";s:20:"boite_titre_souligne";s:5:"titre";s:0:"";s:9:"id_module";s:1:"4";}}i:6;a:3:{s:8:"division";s:1:"2";s:11:"type_module";s:4:"NEWS";s:11:"preferences";a:40:{s:5:"titre";s:0:"";s:6:"anchor";s:0:"";s:19:"allow_link_on_title";s:1:"1";s:8:"type_aff";s:1:"1";s:12:"id_categorie";s:0:"";s:8:"id_items";s:9:"2284-2239";s:6:"nb_aff";s:1:"1";s:10:"nb_analyse";s:2:"50";s:13:"display_order";s:9:"Selection";s:19:"display_titles_only";s:1:"0";s:8:"rss_avis";s:1:"0";s:14:"op_largeur_img";s:2:"85";s:6:"layout";s:4:"grid";s:16:"op_hauteur_boite";s:1:"0";s:5:"boite";s:0:"";s:9:"id_module";s:1:"6";s:10:"profile_id";s:1:"3";s:11:"style_liste";s:20:"diaporama_navigation";s:10:"nb_notices";s:2:"30";s:8:"only_img";s:1:"1";s:9:"aleatoire";s:1:"1";s:3:"tri";s:1:"1";s:14:"op_hauteur_img";s:3:"115";s:13:"op_transition";s:0:"";s:11:"op_captions";s:1:"0";s:11:"op_autoplay";s:1:"0";s:10:"op_visible";s:1:"0";s:8:"op_speed";s:1:"0";s:7:"op_auto";s:1:"0";s:9:"op_scroll";s:1:"1";s:12:"id_catalogue";s:3:"156";s:9:"id_panier";s:1:"0";s:15:"profil_redirect";s:0:"";s:0:"";s:0:"";s:13:"styles_reload";s:1:"0";s:18:"op_navigation_mode";s:13:"next_previous";s:18:"op_navigation_unit";s:1:"%";s:26:"op_navigation_window_width";s:3:"100";s:27:"op_navigation_window_height";s:3:"490";s:19:"op_navigation_cycle";s:5:"10000";}}i:1000;a:6:{s:11:"type_module";s:4:"NEWS";s:11:"preferences";a:23:{s:5:"titre";s:10:"Animations";s:6:"anchor";s:0:"";s:19:"allow_link_on_title";s:1:"0";s:8:"type_aff";s:1:"1";s:12:"id_categorie";s:0:"";s:8:"id_items";s:13:"2286-246-2269";s:6:"nb_aff";s:1:"1";s:10:"nb_analyse";s:1:"5";s:13:"display_order";s:9:"Selection";s:19:"display_titles_only";s:1:"0";s:8:"rss_avis";s:1:"0";s:14:"op_largeur_img";s:3:"200";s:6:"layout";s:4:"grid";s:16:"op_hauteur_boite";s:3:"400";s:5:"boite";s:25:"boite_titre_sous_la_barre";s:10:"profile_id";s:1:"3";s:11:"style_liste";s:20:"diaporama_navigation";s:13:"styles_reload";s:1:"0";s:18:"op_navigation_mode";s:7:"buttons";s:18:"op_navigation_unit";s:1:"%";s:26:"op_navigation_window_width";s:3:"100";s:27:"op_navigation_window_height";s:3:"250";s:19:"op_navigation_cycle";s:1:"0";}s:9:"id_module";s:4:"1000";s:9:"parent_id";s:2:"12";s:10:"profile_id";s:1:"3";s:8:"division";s:1:"2";}i:0;a:1:{s:8:"division";s:1:"2";}i:1001;a:6:{s:11:"type_module";s:4:"NEWS";s:11:"preferences";a:23:{s:5:"titre";s:10:"ACTUALITES";s:6:"anchor";s:0:"";s:19:"allow_link_on_title";s:1:"0";s:8:"type_aff";s:1:"1";s:12:"id_categorie";s:0:"";s:8:"id_items";s:29:"2297-1961-2238-2208-2115-1950";s:6:"nb_aff";s:1:"1";s:10:"nb_analyse";s:1:"5";s:13:"display_order";s:9:"Selection";s:19:"display_titles_only";s:1:"0";s:8:"rss_avis";s:1:"0";s:14:"op_largeur_img";s:3:"200";s:6:"layout";s:4:"grid";s:16:"op_hauteur_boite";s:3:"400";s:5:"boite";s:25:"boite_titre_sous_la_barre";s:10:"profile_id";s:1:"3";s:11:"style_liste";s:20:"diaporama_navigation";s:13:"styles_reload";s:1:"0";s:18:"op_navigation_mode";s:7:"buttons";s:18:"op_navigation_unit";s:2:"px";s:26:"op_navigation_window_width";s:3:"420";s:27:"op_navigation_window_height";s:3:"240";s:19:"op_navigation_cycle";s:4:"5000";}s:9:"id_module";s:4:"1001";s:9:"parent_id";s:2:"12";s:10:"profile_id";s:1:"3";s:8:"division";s:1:"2";}i:12;a:5:{s:11:"type_module";s:23:"CONTENEUR_DEUX_COLONNES";s:11:"preferences";a:11:{s:5:"titre";s:0:"";s:15:"col_gauche_type";s:4:"NEWS";s:15:"col_droite_type";s:4:"NEWS";s:5:"boite";s:0:"";s:9:"id_module";s:2:"12";s:11:"type_module";s:23:"CONTENEUR_DEUX_COLONNES";s:8:"division";s:1:"2";s:8:"rss_avis";s:1:"0";s:20:"col_gauche_module_id";s:4:"1000";s:20:"col_droite_module_id";s:4:"1001";s:10:"profile_id";s:1:"3";}s:10:"profile_id";s:1:"3";s:8:"division";s:1:"2";s:20:"col_gauche_module_id";s:4:"1000";}i:3;a:3:{s:8:"division";s:1:"2";s:11:"type_module";s:7:"KIOSQUE";s:11:"preferences";a:27:{s:5:"titre";s:42:"Nos coups de coeur Jeunesse - 2017 à 2019";s:11:"style_liste";s:9:"jcarousel";s:10:"nb_notices";s:2:"20";s:8:"only_img";s:1:"1";s:9:"aleatoire";s:1:"1";s:3:"tri";s:1:"1";s:10:"nb_analyse";s:2:"50";s:14:"op_hauteur_img";s:3:"120";s:13:"op_transition";s:0:"";s:14:"op_largeur_img";s:2:"90";s:16:"op_hauteur_boite";s:1:"0";s:11:"op_captions";s:1:"0";s:11:"op_autoplay";s:1:"0";s:10:"op_visible";s:1:"0";s:8:"op_speed";s:1:"0";s:7:"op_auto";s:1:"2";s:9:"op_scroll";s:1:"1";s:8:"rss_avis";s:1:"0";s:12:"id_catalogue";s:3:"134";s:9:"id_panier";s:0:"";s:15:"profil_redirect";s:1:"3";s:5:"boite";s:20:"boite_titre_souligne";s:9:"id_module";s:1:"3";s:11:"type_module";s:7:"KIOSQUE";s:8:"division";s:1:"2";s:13:"styles_reload";s:1:"0";s:10:"profile_id";s:1:"3";}}i:2;a:3:{s:8:"division";s:1:"4";s:11:"type_module";s:11:"RECH_SIMPLE";s:11:"preferences";a:23:{s:5:"titre";s:0:"";s:7:"message";s:0:"";s:7:"exemple";s:0:"";s:10:"select_bib";s:1:"0";s:10:"select_doc";s:1:"0";s:13:"select_annexe";s:1:"0";s:7:"largeur";s:3:"140";s:17:"recherche_avancee";s:1:"0";s:8:"type_doc";s:0:"";s:3:"tri";s:1:"*";s:15:"profil_redirect";s:1:"1";s:11:"placeholder";s:31:"Rechercher dans tout le réseau";s:13:"search_button";s:0:"";s:10:"domain_ids";s:0:"";s:19:"domain_select_style";s:6:"select";s:5:"boite";s:0:"";s:9:"id_module";s:1:"2";s:11:"type_module";s:11:"RECH_SIMPLE";s:8:"division";s:1:"4";s:7:"Valider";s:7:"Valider";s:0:"";s:0:"";s:8:"id_items";s:0:"";s:8:"rss_avis";s:1:"0";}}i:10;a:3:{s:8:"division";s:1:"4";s:11:"type_module";s:13:"MENU_VERTICAL";s:11:"preferences";a:10:{s:14:"afficher_titre";s:1:"0";s:11:"menu_deplie";s:1:"0";s:8:"new_html";s:1:"1";s:11:"toggle_menu";s:1:"0";s:4:"menu";s:3:"1-H";s:5:"boite";s:0:"";s:5:"titre";s:0:"";s:9:"id_module";s:2:"10";s:7:"Valider";s:7:"Valider";s:0:"";s:0:"";}}i:9;a:3:{s:8:"division";s:1:"4";s:11:"type_module";s:5:"LOGIN";s:11:"preferences";a:20:{s:5:"titre";s:12:"Se connecter";s:14:"titre_connecte";s:0:"";s:11:"identifiant";s:20:"N° de carte-lecteur";s:19:"identifiant_exemple";s:0:"";s:12:"mot_de_passe";s:24:"année naissance lecteur";s:20:"mot_de_passe_exemple";s:0:"";s:14:"lien_connexion";s:12:"Se connecter";s:24:"lien_mot_de_passe_oublie";s:22:"Mot de passe oublié ?";s:17:"lien_creer_compte";s:0:"";s:16:"pre-registration";s:0:"";s:16:"message_connecte";s:7:"Bonjour";s:11:"lien_compte";s:10:"Mon compte";s:17:"lien_deconnection";s:0:"";s:16:"pre_registration";s:0:"";s:16:"autocomplete_off";s:1:"1";s:15:"profil_redirect";s:0:"";s:22:"profil_logout_redirect";s:0:"";s:5:"boite";s:20:"boite_login_banniere";s:9:"id_module";s:1:"9";s:0:"";s:0:"";}}}s:14:"use_parent_css";s:1:"1";s:7:"sitemap";s:1:"1";s:8:"page_css";s:0:"";}'
+               ]);
+    $this->dispatch('/opac/index/index/id_profil/3');
+  }
+
+
+  /** @test */
+  public function pageShouldNotContainsDuplicateArticles() {
+    $this->assertXPathCount('//div[@id="boite_1000"]', 1);
+    $this->assertXPathCount('//div[@id="boite_1001"]', 1);
+  }
 }
\ No newline at end of file
diff --git a/tests/application/modules/opac/controllers/NoticeAjaxControllerTest.php b/tests/application/modules/opac/controllers/NoticeAjaxControllerTest.php
index 3e5d39dde78a50a13ab3bf474f9c680d73247901..70891b3613aff27be1e9cf2d4c29570022eb1e62 100644
--- a/tests/application/modules/opac/controllers/NoticeAjaxControllerTest.php
+++ b/tests/application/modules/opac/controllers/NoticeAjaxControllerTest.php
@@ -964,18 +964,15 @@ class NoticeAjaxControllerExemplairesTest extends NoticeAjaxControllerExemplaire
 
 
 class NoticeAjaxControllerBabelthequeTest extends AbstractControllerTestCase {
-
+  protected $_storm_default_to_volatile = true;
 
   public function setUp() {
     parent::setUp();
 
-    Class_Notice::getLoader()
-      ->newInstanceWithId(157675)
-      ->setIsbn('978-2-226-21993-0');
+    $this->fixture('Class_Notice', ['id' => 157675,
+                                    'isbn' => '978-2-226-21993-0']);
 
-    Class_AdminVar::getLoader()
-      ->newInstanceWithId('BABELTHEQUE_JS')
-      ->setValeur('http://www.babeltheque.com/bw_85.js');
+    Class_AdminVar::set('BABELTHEQUE_JS', 'https://www.babelio.com/bw_85.js');
 
     $this->dispatch('/opac/noticeajax/babeltheque?id_notice=N157675', true);
   }
@@ -983,7 +980,7 @@ class NoticeAjaxControllerBabelthequeTest extends AbstractControllerTestCase {
 
   /** @test */
   public function responseShouldContainsBabelthequeScript() {
-    $this->assertXPath('//script[@src="http://www.babeltheque.com/bw_85.js"]');
+    $this->assertXPath('//script[@src="https://www.babelio.com/bw_85.js"]');
   }
 
 
@@ -1008,8 +1005,6 @@ class NoticeAjaxControllerBabelthequeTest extends AbstractControllerTestCase {
 
 
 class NoticeAjaxControllerBabelthequeWithoutOptionTest extends AbstractControllerTestCase {
-
-
   public function setUp() {
     parent::setUp();
 
diff --git a/tests/db/UpgradeDBTest.php b/tests/db/UpgradeDBTest.php
index 6132a4ec3fadda56cd833430dd1530cb55c0e562..fdecc7505705321ca12a956ddd6addae9398b634 100644
--- a/tests/db/UpgradeDBTest.php
+++ b/tests/db/UpgradeDBTest.php
@@ -2625,6 +2625,7 @@ class UpgradeDB_371_Test extends UpgradeDBTestCase {
 
 
 
+
 class UpgradeDB_372_Test extends UpgradeDBTestCase {
   public function prepare() {
     $this->dropTable('rendez_vous_user_notification');
@@ -2674,4 +2675,22 @@ class UpgradeDB_372_Test extends UpgradeDBTestCase {
   public function shouldHavePrimaryId() {
     $this->assertPrimary('rendez_vous_user_notification', 'id');
   }
+}
+
+
+
+
+class UpgradeDB_373_Test extends UpgradeDBTestCase {
+  public function prepare() {
+    $this->silentQuery("UPDATE `variables` SET liste='0:Bibliothèque + codes-barres\r\n1:Code-barres uniquement' WHERE clef='unicite_code_barres'");
+  }
+
+
+  /** @test */
+  public function firstOptionShouldBeBarcodeOnlyThenWithBib() {
+    $this->assertEquals(['0' => 'Code-barres uniquement',
+                         '1' => 'Bibliothèque + codes-barres'],
+                        Class_CosmoVar::getList('unicite_code_barres'));
+  }
+
 }
\ No newline at end of file
diff --git a/tests/fixtures/ChamberyKohaFixtures.php b/tests/fixtures/ChamberyKohaFixtures.php
index d7d6f435813b55f52c4331ec1ffb631d83dea888..46cec73408f3b99623a7594589118da2c3d4e978 100644
--- a/tests/fixtures/ChamberyKohaFixtures.php
+++ b/tests/fixtures/ChamberyKohaFixtures.php
@@ -431,8 +431,8 @@ class ChamberyKohaFixtures {
   }
 
 
-    public static function getPatronInfoChambelleWithOnhold() {
-      return '<?xml version="1.0" encoding="UTF-8" ?>
+  public static function getPatronInfoChambelleWithOnhold() {
+    return '<?xml version="1.0" encoding="UTF-8" ?>
 <GetPatronInfo>
   <city>Gotham City</city>
   <altcontactaddress2></altcontactaddress2>
@@ -557,11 +557,11 @@ class ChamberyKohaFixtures {
   <B_phone></B_phone>
 </GetPatronInfo>
 ';
-    }
+  }
 
 
-    public static function getPatronInfoChambelleWithItemonhold() {
-      return '<?xml version="1.0" encoding="UTF-8" ?>
+  public static function getPatronInfoChambelleWithItemonhold() {
+    return '<?xml version="1.0" encoding="UTF-8" ?>
 <GetPatronInfo>
   <city>Gotham City</city>
   <altcontactaddress2></altcontactaddress2>
@@ -686,5 +686,133 @@ class ChamberyKohaFixtures {
   <B_phone></B_phone>
 </GetPatronInfo>
 ';
-    }
-}
\ No newline at end of file
+  }
+
+  public static function getPatronInfoChambelleWithManyItemonhold() {
+    return '<?xml version="1.0" encoding="UTF-8" ?>
+<GetPatronInfo>
+  <city>Gotham City</city>
+  <altcontactaddress2></altcontactaddress2>
+  <B_address2></B_address2>
+  <altcontactfirstname></altcontactfirstname>
+  <sort2></sort2>
+  <borrowernumber>6871</borrowernumber>
+  <altcontactphone></altcontactphone>
+  <title></title>
+  <dateexpiry>2019-06-30</dateexpiry>
+  <mobile>06 01 02 03 04</mobile>
+  <cardnumber>90519000053165</cardnumber>
+  <B_streetnumber></B_streetnumber>
+  <dateenrolled>2014-04-29</dateenrolled>
+  <altcontactzipcode></altcontactzipcode>
+  <streettype></streettype>
+  <sort1>12</sort1>
+  <email>xxx@xxx.fr</email>
+  <contactfirstname></contactfirstname>
+  <B_country></B_country>
+  <B_email></B_email>
+  <phone>01 02 03 04 05</phone>
+  <B_address></B_address>
+  <branchcode>PUKA</branchcode>
+  <guarantorid>0</guarantorid>
+  <emailpro></emailpro>
+  <phonepro></phonepro>
+  <B_city></B_city>
+  <gonenoaddress>0</gonenoaddress>
+  <privacy_guarantor_checkouts>0</privacy_guarantor_checkouts>
+  <categorycode>J14</categorycode>
+  <dateofbirth>2004-11-10</dateofbirth>
+  <lost>0</lost>
+  <zipcode>1123</zipcode>
+  <lang>default</lang>
+  <altcontactaddress3></altcontactaddress3>
+  <checkprevcheckout>inherit</checkprevcheckout>
+  <fax>01 02 03 04 05</fax>
+  <streetnumber></streetnumber>
+  <altcontactaddress1></altcontactaddress1>
+  <address2></address2>
+  <updated_on>2017-03-23 13:22:49</updated_on>
+  <loans>
+    <loan>
+      <replacementpricedate>2009-10-01</replacementpricedate>
+      <issuedate>2016-05-24 00:00</issuedate>
+      <issues>3</issues>
+      <issue_id>272</issue_id>
+      <author>René Gouichoux, Pronto</author>
+      <permanent_location>Romans enfant</permanent_location>
+      <itemlost>0</itemlost>
+      <overdue>1</overdue>
+      <publishercode>F. Nathan</publishercode>
+      <surname>Aguetant</surname>
+      <biblioitemnumber>4107</biblioitemnumber>
+      <firstname>Agathe</firstname>
+      <notforloan>0</notforloan>
+      <holdingbranch>PUKA</holdingbranch>
+      <itemnumber>5111</itemnumber>
+      <auto_renew>0</auto_renew>
+      <frameworkcode></frameworkcode>
+      <barcode>00519000083096</barcode>
+      <itemonhold>3</itemonhold>
+      <renewals>28</renewals>
+      <publicationyear>2004</publicationyear>
+      <location>Romans enfant</location>
+      <withdrawn>0</withdrawn>
+      <date_due>2017-06-14 00:00</date_due>
+      <dateaccessioned>2014-06-26</dateaccessioned>
+      <itemtype>LIVR</itemtype>
+      <damaged>0</damaged>
+      <homebranch>PUKA</homebranch>
+      <more_subfields_xml>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;collection
+  xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
+  xsi:schemaLocation=&quot;http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd&quot;
+  xmlns=&quot;http://www.loc.gov/MARC21/slim&quot;&gt;
+
+&lt;record&gt;
+  &lt;leader&gt;         a              &lt;/leader&gt;
+  &lt;datafield tag=&quot;999&quot; ind1=&quot; &quot; ind2=&quot; &quot;&gt;
+    &lt;subfield code=&quot;h&quot;&gt;8309&lt;/subfield&gt;
+    &lt;subfield code=&quot;j&quot;&gt;Librairie jeunesse au pays ble&lt;/subfield&gt;
+    &lt;subfield code=&quot;q&quot;&gt;Jeunes&lt;/subfield&gt;
+    &lt;subfield code=&quot;p&quot;&gt;5,35&lt;/subfield&gt;
+    &lt;subfield code=&quot;s&quot;&gt;24/04/2004&lt;/subfield&gt;
+  &lt;/datafield&gt;
+&lt;/record&gt;
+
+&lt;/collection&gt;</more_subfields_xml>
+      <itemcallnumber>E GOU</itemcallnumber>
+      <itype>LIVR</itype>
+      <branchcode>PUKA</branchcode>
+      <date_due_sql>2017-06-14 00:00:00</date_due_sql>
+      <biblionumber>4107</biblionumber>
+      <onloan>2016-06-14</onloan>
+      <datecreated>2014-06-26</datecreated>
+      <cardnumber>90519000053165</cardnumber>
+      <datelastborrowed>2016-05-24</datelastborrowed>
+      <timestamp>2017-03-23 13:24:14</timestamp>
+      <title>Quel bazar, Léonard !</title>
+      <borrowernumber>6871</borrowernumber>
+      <datelastseen>2016-05-24</datelastseen>
+      <isbn>2092502611</isbn>
+      <onsite_checkout>0</onsite_checkout>
+      <cn_sort>E_GOU</cn_sort>
+    </loan>
+  </loans>
+  <firstname>Agathe</firstname>
+  <B_zipcode></B_zipcode>
+  <sex></sex>
+  <othernames></othernames>
+  <privacy>1</privacy>
+  <surname>Aguetant</surname>
+  <B_streettype></B_streettype>
+  <altcontactsurname></altcontactsurname>
+  <login_attempts>0</login_attempts>
+  <initials></initials>
+  <branchname>Pukapuka</branchname>
+  <contactname></contactname>
+  <address>6871 rue de Agathe</address>
+  <B_phone></B_phone>
+</GetPatronInfo>
+';
+  }
+}
diff --git a/tests/library/Class/WebService/SIGB/PMBTest.php b/tests/library/Class/WebService/SIGB/PMBTest.php
index 9e3b1c2e2783240055a2e2ed82153f33685aa2ff..33c7fba343f864628c9d0eda83bb436455695645 100644
--- a/tests/library/Class/WebService/SIGB/PMBTest.php
+++ b/tests/library/Class/WebService/SIGB/PMBTest.php
@@ -54,7 +54,7 @@ abstract class PMBTestCase extends ModelTestCase {
 
       ->whenCalled('httpPost')
       ->with('pmbesSelfServices_self_renew', ['faf3404e9d51b48e47745556789b55401', 15])
-      ->answers(null)
+      ->answers('{"id":1,"result":{"status":1,"message":"Prolongation non activ\u00e9e","transaction_date":"20190516    164241","title":"7d918cd04e21cb62d886dea49a6b711314","due_date":"20190516    164241"},"error":null}')
 
       ->whenCalled('httpPost')
       ->with('pmbesOPACEmpr_add_resa', ['faf3404e9d51b48e47745556789b55401', '456789'])
@@ -174,8 +174,8 @@ class PMBServiceTest extends PMBTestCase {
    * @depends emprunteurLoansShouldContainsFahrenheit
    * @test
    */
-  public function loanFahrenhitReturnDateShouldBe2012_12_11($loans) {
-    $this->assertEquals('2012-12-11', $loans[0]->getDateRetour());
+  public function loanFahrenhitReturnDateShouldBe11_12_2012($loans) {
+    $this->assertEquals('11/12/2012', $loans[0]->getDateRetour());
   }
 
 
@@ -209,19 +209,23 @@ class PMBServiceTest extends PMBTestCase {
 
 
   /** @test */
-  public function renewLoansShouldReturnError() {
-    $this->assertContains(false, $this->_service->prolongerPret($this->_paul, 15));
+  public function renewLoansShouldReturnMessageProlongationNonActive() {
+    $this->assertEquals(['statut' => false,
+                         'erreur' => 'Prolongation non activée'],
+                        $this->_service->prolongerPret($this->_paul, 15));
   }
 
 
   /** @test */
   public function bookingItemShouldReturnSuccess() {
-    $this->assertTrue($this->_service->reserverExemplaire($this->_paul, $this->_le_kiosque, '000018'));
+    $this->assertEquals(['statut' => true, 'erreur' => ''],
+                        $this->_service->reserverExemplaire($this->_paul, $this->_le_kiosque, '000018'));
   }
 
 
   /** @test */
   public function cancelBookingShouldReturnSuccess() {
-    $this->assertTrue($this->_service->supprimerReservation($this->_paul, 456));
+    $this->assertEquals(['statut' => true, 'erreur' => ''],
+                        $this->_service->supprimerReservation($this->_paul, 456));
   }
 }
\ No newline at end of file
diff --git a/tests/scenarios/HandleOnholdTest/HandleOnholdTest.php b/tests/scenarios/HandleOnholdTest/HandleOnholdTest.php
index ee22f36392e86b31d6c6fdf00d9f641470e41898..5f7712528f9ae3a9bafb300734a207f90414b3de 100644
--- a/tests/scenarios/HandleOnholdTest/HandleOnholdTest.php
+++ b/tests/scenarios/HandleOnholdTest/HandleOnholdTest.php
@@ -272,4 +272,15 @@ class HandleOnholdWithItemOnHoldTest extends HandleOnholdDispatchTestCase {
       ->with($this->_ilsdi . '?service=GetPatronInfo&patron_id=18&show_contact=1&show_loans=1&show_holds=1')
       ->answers(ChamberyKohaFixtures::getPatronInfoChambelleWithItemonhold());
   }
+}
+
+
+
+class HandleOnholdWithManyItemOnHoldTest extends HandleOnholdDispatchTestCase {
+  protected function _addCallToWebClient() {
+    $this->_mock_web_client
+      ->whenCalled('open_url')
+      ->with($this->_ilsdi . '?service=GetPatronInfo&patron_id=18&show_contact=1&show_loans=1&show_holds=1')
+      ->answers(ChamberyKohaFixtures::getPatronInfoChambelleWithManyItemonhold());
+  }
 }
\ No newline at end of file