diff --git a/VERSIONS_HOTLINE/147634 b/VERSIONS_HOTLINE/147634
new file mode 100644
index 0000000000000000000000000000000000000000..997f37134dc1bd945e242283c3e5053ed3ebc924
--- /dev/null
+++ b/VERSIONS_HOTLINE/147634
@@ -0,0 +1 @@
+ - correctif #147634 : Préinscription : Les mails de préinscription avec le SIGB Nanook peuvent être customisés avec les entrées {user.first_name} {user.last_name} pour afficher respectivement le prénom et le nom rentrés par l'utilisateur
\ No newline at end of file
diff --git a/application/modules/opac/controllers/AuthController.php b/application/modules/opac/controllers/AuthController.php
index 880fd0c14907462fc9611f89de54e94718127061..9eb3ae8cad13a803ffc5ecfd4451a3846d62f34a 100644
--- a/application/modules/opac/controllers/AuthController.php
+++ b/application/modules/opac/controllers/AuthController.php
@@ -581,54 +581,53 @@ class AuthController extends ZendAfi_Controller_Action {
 
 
   public function preRegistrationAction() {
-    $this->view->titre = $this->_('Demande de préinscription');
-    $this->view->help_message = nl2br(Class_Profil::getCurrentProfil()->getModulePreference('auth', 'pre-registration', 'help_message'));
-    $registration = new Class_User_PreRegistration($this->view,
-                                                   function ($message) {
-                                                     $this->_helper->notify($message); });
-
-    if (!$form = $registration->getForm()) {
-      $this->_helper->notify($this->_('Cette fonctionnalité n\'est pas activée.'));
-      return $this->_redirect('opac/index');
-    }
-
     if ('' != $this->_getParam('website'))
-      return $this->_redirect('/');
+      return $this->_redirectToReferer();
 
-    $form = $registration->getForm();
-
-    if ($user = Class_Users::getIdentity()) {
-      $form->populate(['birthDate' => $user->getNaissance(),
-                       'mail' => $user->getMail(),
-                       'mail2' => $user->getMail(),
-                       'lastName' => $user->getNom(),
-                       'firstName' => $user->getPrenom(),
-                       'town' => $user->getVille(),
-                       'zipcode' => $user->getCodePostal(),
-                       'address' => $user->getAdresse()]);
+    $registration = Class_WebService_SIGB_AbstractPreRegistration::newFor(Class_Users::getIdentity());
+
+    if ( ! $registration->isEnabled()) {
+      $this->_helper->notify(implode(' ', $registration->getLogger()->getMessages()));
+      return $this->_redirectToReferer();
     }
 
-    $this->view->form = $form->populate(ZendAfi_Filters_Post::filterStatic($this->_request->getParams()));
+    $this->view->titre = $this->_('Demande de préinscription');
+    $this->view->form = $registration->getForm();
+    $this->view->help_message =
+      (nl2br(Class_Profil::getCurrentProfil()
+             ->getModulePreference('auth',
+                                   'pre-registration',
+                                   'help_message')));
 
     if (!$this->_request->isPost())
       return;
 
     $data = ZendAfi_Filters_Post::filterStatic($this->_request->getPost());
-    unset($data['website']);
 
-    if (!$form->isValid($data))
+    $this->view->form->populate($data);
+
+    if (!$this->view->form->isValid($data))
       return;
 
-    $registration->send($data, $user)
-      ? $this->_preRegistrationRedirect('pre-registration-success',
-                                        $registration->getLibrary())
-      : $this->_preRegistrationRedirect('pre-registration',
-                                        $registration->getLibrary());
-  }
+    unset($data['website']);
+    unset($data[Class_WebService_SIGB_AbstractPreRegistration::REQUIRED_CHECKBOX_NAME]);
+
+    $registration_data = $registration->getData($data);
+
+    $registration->send($registration_data);
+
+    if ($messages = $registration->getLogger()->getMessages()) {
+      $this->_helper->notify(implode(' ', $messages));
+      return $this->_redirectToReferer();
+    }
+
+    $registration->sendMail($registration_data);
 
+    if ($messages = $registration->getLogger()->getMessages())
+      $this->_helper->notify(implode(' ', $messages));
 
-  protected function _preRegistrationRedirect($action, $library) {
-    $this->_redirect($this->view->absoluteUrl(['action' => $action, 'id_bib' => $library->getId()]));
+    $this->_redirect($this->view->url(['action' => 'pre-registration-success',
+                                       'id_bib' => $registration_data->getLibraryId()]));
   }
 
 
diff --git a/library/Class/IntBib.php b/library/Class/IntBib.php
index f487b079903e071a2aa3deb47ebec92b1d10a0f6..13f95a28c8f84b7ac79440b11f4edba1bcb480cf 100644
--- a/library/Class/IntBib.php
+++ b/library/Class/IntBib.php
@@ -128,25 +128,45 @@ class IntBibLoader extends Storm_Model_Loader {
   }
 
 
-  public function findAllNanookWithPreRegistration() {
-    $collection = new Storm_Model_Collection(Class_IntBib::findAll());
-    $combo = $collection
-      ->select(function($int_bib)
-               {
-                 return $int_bib->isPreRegistrationNanookEnabled();
-               })
-      ->injectInto([],
-                   function($combo, $library)
-                   {
-                     $combo[$library->getId()] = $library->getLabel();
-                     return $combo;
-                   });
+  public function findAllNanookLabelsWithPreRegistration() {
+    $combo =
+      $this->_findAllWithPreRegistration(fn($int_bib) => $int_bib->isPreRegistrationNanookEnabled())
+           ->injectInto([],
+                        function($combo, $library)
+                        {
+                          $combo[$library->getId()] = $library->getLabel();
+                          return $combo;
+                        });
 
     asort($combo, SORT_STRING | SORT_FLAG_CASE);
     return $combo;
   }
 
 
+
+  public function findAllKohaLabelsWithPreRegistration() : array {
+    $branchcodes = [];
+
+    foreach(Class_IntBib::findAllKohaWithPreRegistration() as $int_bib) {
+      $from_webservice = $int_bib->getSIGBComm()->getBranches($int_bib->getId());
+      $branchcodes = array_merge($branchcodes, $from_webservice);
+    }
+
+    return $branchcodes;
+  }
+
+
+  public function findAllKohaWithPreRegistration() : array {
+    return $this->_findAllWithPreRegistration(fn($int_bib) => $int_bib->isPreRegistrationKohaEnabled())->getArrayCopy();
+  }
+
+
+  protected function _findAllWithPreRegistration(Closure $filter_callback) : Storm_Collection {
+    $collection = new Storm_Model_Collection(Class_IntBib::findAll());
+    return $collection->select(fn($int_bib) => $filter_callback($int_bib));
+  }
+
+
   public function findAllWithPreRegistration() {
     return (new Storm_Model_Collection(Class_IntBib::findAll()))
       ->select(function($int_bib) { return $int_bib->isPreRegistrationEnabled();});
diff --git a/library/Class/User/PreRegistration.php b/library/Class/User/PreRegistration.php
deleted file mode 100644
index e2618601b2dee65fdb7193dfd56be40c77e8d28c..0000000000000000000000000000000000000000
--- a/library/Class/User/PreRegistration.php
+++ /dev/null
@@ -1,119 +0,0 @@
-<?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 Class_User_PreRegistration {
-  use Trait_Translator;
-
-  protected
-    $_view,
-    $_notify_callback,
-    $_webservice,
-    $_library,
-    $_email;
-
-
-  public function __construct($view, $notify_callback) {
-    $this->_view = $view;
-    $this->_notify_callback = $notify_callback;
-    $this->_webservice = new Class_WebService_SIGB_PreRegistration;
-  }
-
-
-  public function getForm() {
-    return $this->_webservice->getForm();
-  }
-
-
-  /**
-   * @param $data array
-   *
-   * @return bool true when successful, otherwise false
-   */
-  public function send($data, $user) {
-    $this->_webservice->send($data, $user);
-    $this->_library = $this->_webservice->getBib($data);
-
-    if ($this->_webservice->hasError()) {
-      $this->_notify($this->joinErrorsWith(BR));
-      return false;
-    }
-
-
-    if ($this->_email = $this->_webservice->getEmail($data))
-      $this->_sendEmailNotification($data);
-
-    return true;
-  }
-
-
-  public function joinErrorsWith($separator) {
-    return $this->_webservice->joinErrorsWith($separator);
-  }
-
-
-  public function getLibrary() {
-    return $this->_library;
-  }
-
-
-  protected function _notify($message) {
-    if (isset($this->_notify_callback))
-      call_user_func($this->_notify_callback, $message);
-  }
-
-
-  protected function _sendEmailNotification($data) {
-    $subject = $this->_templatedOrStatic($data, 'NOTIFICATION_SUBJECT_PREREGISTRATION', '_staticMailSubject');
-    $body = $this->_templatedOrStatic($data, 'NOTIFICATION_TEMPLATE_PREREGISTRATION', '_staticMailContent');
-    $mailer = new Class_MailHtml();
-
-    if (true === $mailer->mail($this->_email, $subject, $body, true))
-      $this->_notify($this->_('Un email de confirmation de préinscription vous a été envoyé à l\'adresse %s .',
-                              $this->_view->tag('b', $this->_email)));
-  }
-
-
-  protected function _templatedOrStatic($data, $var_name, $static_content_callback) {
-    if (!$template = Class_AdminVar::getValueOrDefault($var_name))
-      return call_user_func([$this, $static_content_callback]);
-
-    $modelfusion = (new Class_ModeleFusion())
-      ->setContenu($template)
-      ->setDataSource(['library' => $this->getLibrary(), 'user' => new Class_Entity($data)]);
-
-    return ($templated = $modelfusion->getContenuFusionne())
-      ? $templated
-      : call_user_func([$this, $static_content_callback]);
-  }
-
-
-  protected function _staticMailSubject() {
-    return ($library = $this->getLibrary())
-      ? $this->_('Préinscription à %s', $library->getLibelle())
-      : $this->_('Préinscription');
-  }
-
-
-  protected function _staticMailContent() {
-    return $this->_view->tagPreRegistration($this->getLibrary());
-  }
-}
diff --git a/library/Class/WebService/SIGB/AbstractPreRegistration.php b/library/Class/WebService/SIGB/AbstractPreRegistration.php
new file mode 100644
index 0000000000000000000000000000000000000000..3ae5e9ceed62e8a9c979bc089147cac200e19ab5
--- /dev/null
+++ b/library/Class/WebService/SIGB/AbstractPreRegistration.php
@@ -0,0 +1,136 @@
+<?php
+/**
+ * Copyright (c) 2012-2017, 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
+ */
+
+
+abstract class Class_WebService_SIGB_AbstractPreRegistration {
+
+  use Trait_Translator, Trait_Logger;
+
+  const REQUIRED_CHECKBOX_NAME = 'conditions_message';
+
+  protected
+    $_user,
+    $_form;
+
+
+  public static function newFor(?Class_Users $user)
+    : Class_WebService_SIGB_AbstractPreRegistration {
+    $pre_registration = new Class_WebService_SIGB_PreRegistration_Null($user);
+
+    if ( ! $first = Class_IntBib::findAllWithPreRegistration()->first())
+      return $pre_registration;
+
+    return $first->isCommNanook()
+      ? new Class_WebService_SIGB_Nanook_PreRegistration($user)
+      : new Class_WebService_SIGB_Koha_PreRegistration($user);
+  }
+
+
+  public function __construct(?Class_Users $user) {
+    if ($user)
+      $this->setUser($user);
+
+    $this
+      ->initForm()
+      ->setLogger(new Class_Log);
+  }
+
+
+  public function isEnabled() : bool {
+    if ( $this->_user && ( ! $this->_user->isInvite())) {
+      $this->getLogger()->log($this->_('%s, vous ne pouvez pas vous préinscrire à partir d\'un compte déjà connecté.', $this->_user->getNomAff()));
+      return false;
+    }
+
+    if ( ! $enabled_in_settings = $this->_isIntBibWithPreRegistrationEnabled())
+      $this->getLogger()->log($this->_('Malheureusement, la fonctionnalité de préinscription n\'est pas activée.'));
+
+    return $enabled_in_settings;
+  }
+
+
+  public function sendMail(Class_WebService_SIGB_PreRegistration_AbstractData $data) : self {
+    (new Class_WebService_SIGB_PreRegistration_Mail($data))
+      ->setLogger($this->getLogger())
+      ->send();
+
+    return $this;
+  }
+
+
+  public function setUser(Class_Users $user) : self {
+    $this->_user = $user;
+    return $this;
+  }
+
+
+  public function getForm() : ZendAfi_Form {
+    return $this->_form;
+  }
+
+
+  public function setForm(ZendAfi_Form $form) : self {
+    $this->_form = $form;
+    return $this;
+  }
+
+
+  public function initForm() : self {
+    if ($this->_form)
+      return $this->_form;
+
+    $form = $this->_getFormInstance();
+    $form = $this->_populateFormWith($form, $this->_user);
+
+    if ( ! $validation_message = trim(Class_AdminVar::get('PREREGISTRATION_CONDITIONS_MESSAGE')))
+      return $this->setForm($form);
+
+    $form->addElement('requiredCheckbox',
+                      static::REQUIRED_CHECKBOX_NAME,
+                      ['label' => $validation_message ]);
+
+    $form->addDisplayGroup(['conditions_message'], 'conditions',
+                           ['legend' => $this->_('Conditions')]);
+
+    return $this->setForm($form);
+  }
+
+
+  protected function _isIntBibWithPreRegistrationEnabled() : bool {
+    return ( (bool) (new Storm_Collection(Class_IntBib::findAll()))
+            ->detect(fn($int_bib) => $int_bib->isPreRegistrationEnabled()))
+      ?? false;
+  }
+
+
+  protected function _populateFormWith(ZendAfi_Form $form,
+                                       ?Class_Users $user) : ZendAfi_Form {
+    return $user
+      ? $form->populate($this->getData([])->getUserDataForForm($user))
+      : $form;
+  }
+
+
+  abstract protected function _getFormInstance() : ZendAfi_Form;
+
+  abstract public function send(Class_WebService_SIGB_PreRegistration_AbstractData $data) : self;
+  abstract public function getData(array $data_as_array) : Class_WebService_SIGB_PreRegistration_AbstractData;
+}
\ No newline at end of file
diff --git a/library/Class/WebService/SIGB/AbstractRESTService.php b/library/Class/WebService/SIGB/AbstractRESTService.php
index f1562ea28ecbb44a77df23cfc77fb9b6e3ab778a..fb54082b6b813d3404b51c643a4d5f41c312c8b7 100644
--- a/library/Class/WebService/SIGB/AbstractRESTService.php
+++ b/library/Class/WebService/SIGB/AbstractRESTService.php
@@ -147,7 +147,7 @@ abstract class Class_WebService_SIGB_AbstractRESTService extends Class_WebServic
 
     try {
       return $response_closure($closure, $url);
-    } catch (Exception $e) {
+    } catch (Throwable $e) {
       $this->logError($url, $e->getMessage());
       $this->_has_network_error = true;
       return '';
diff --git a/library/Class/WebService/SIGB/Koha/PreRegistration.php b/library/Class/WebService/SIGB/Koha/PreRegistration.php
new file mode 100644
index 0000000000000000000000000000000000000000..10c2324fda18da6d8de8d13c2a1ab2d56487f3c3
--- /dev/null
+++ b/library/Class/WebService/SIGB/Koha/PreRegistration.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright (c) 2012-2022, 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 Class_WebService_SIGB_Koha_PreRegistration extends Class_WebService_SIGB_AbstractPreRegistration {
+
+
+  public function send(Class_WebService_SIGB_PreRegistration_AbstractData $data) : self {
+    if( ! $data->getLibrary()) {
+      $this->getLogger()->log($this->_('Échec de la préinscription, la bibliothèque sélectionnée n\'est pas valide.'));
+      return $this;
+    }
+
+    $response = Class_IntBib::find($data->getBranchId())
+      ->getSIGBComm()
+      ->preRegistration($data->prepareForWebService());
+
+    if( ! $response['statut'])
+      $this->getLogger()->log($response['erreur']);
+
+    return $this;
+  }
+
+
+  public function getData(array $data_as_array) : Class_WebService_SIGB_PreRegistration_AbstractData {
+    return new Class_WebService_SIGB_Koha_PreRegistration_Data($data_as_array);
+  }
+
+
+  protected function _getFormInstance() : ZendAfi_Form {
+    return new ZendAfi_Form_PreRegistration_Koha;
+  }
+}
diff --git a/library/Class/WebService/SIGB/Koha/PreRegistration/Data.php b/library/Class/WebService/SIGB/Koha/PreRegistration/Data.php
new file mode 100644
index 0000000000000000000000000000000000000000..309c8cb76e767a9da0250088590acf054df8b8f9
--- /dev/null
+++ b/library/Class/WebService/SIGB/Koha/PreRegistration/Data.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ * Copyright (c) 2012-2022, 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 Class_WebService_SIGB_Koha_Preregistration_Data extends Class_WebService_SIGB_PreRegistration_AbstractData {
+
+  const
+    BRANCH_ID = 0,
+    BRANCH_CODE = 1;
+
+
+  protected static array $_fields_map =
+    ['prenom' => 'firstname',
+     'nom' => 'surname',
+     'telephone' => 'phone',
+     'id_site' => 'branchcode',
+     'mail' => 'email',
+     'naissance' => 'dateofbirth',
+     'ville' => 'city',
+     'code_postal' => 'zipcode',
+     'adresse' => 'address'];
+
+
+  protected function _getBranchCode() : string {
+    return $this->_dataInBranch(static::BRANCH_CODE);
+  }
+
+
+  public function getBranchId() : string {
+    return $this->_dataInBranch(static::BRANCH_ID);
+  }
+
+
+  protected function _dataInBranch($key) : string {
+    if (!isset($this->_data_as_array['branchcode']))
+      return '';
+
+    $branchcode_as_array = explode('|', $this->_data_as_array['branchcode']);
+
+    return $branchcode_as_array[$key] ?? '';
+  }
+
+
+  public function getEmail() : string {
+    return $this->_data_as_array['email'] ?? '';
+  }
+
+
+  public function prepareForWebService() : array {
+    $data = $this->_data_as_array;
+
+    $data['branchcode'] = $this->_getBranchCode();
+    $data['dateofbirth'] = Class_Date::human($data['dateofbirth'] ?? '', '%Y-%m-%d');
+
+    return array_filter($data);
+  }
+}
diff --git a/library/Class/WebService/SIGB/Nanook/PreRegistration.php b/library/Class/WebService/SIGB/Nanook/PreRegistration.php
new file mode 100644
index 0000000000000000000000000000000000000000..22a21aec8446a9cccf3a4f1b576df56cd5be6ea6
--- /dev/null
+++ b/library/Class/WebService/SIGB/Nanook/PreRegistration.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Copyright (c) 2012-2022, 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 Class_WebService_SIGB_Nanook_Preregistration extends Class_WebService_SIGB_AbstractPreRegistration {
+
+
+  public function getData(array $data_as_array) : Class_WebService_SIGB_PreRegistration_AbstractData {
+    return new Class_WebService_SIGB_Nanook_PreRegistration_Data($data_as_array);
+  }
+
+
+  protected function _getFormInstance() : ZendAfi_Form {
+    return new ZendAfi_Form_PreRegistration_Nanook;
+  }
+
+
+  public function send(Class_WebService_SIGB_PreRegistration_AbstractData $data) : self {
+    $id = $data->getBranchId();
+
+    if(!$int_bib = Class_IntBib::find($id)) {
+      $this->getLogger()->log($this->_('Échec de la préinscription, la médiathèque sélectionnée n\'existe pas.'));
+      return $this;
+    }
+
+    $response = $int_bib->getSIGBComm()->preRegistration($data);
+
+    if (!$response['statut']) {
+      $this->getLogger()->log($response['erreur']);
+      return $this;
+    }
+
+    return $this->_updateUser($id, $response);
+  }
+
+
+  protected function _updateUser(int $library_id, array $response) {
+    if ( ! $this->_user)
+      return $this;
+
+    if (! $this->_user->isInvite()) {
+      $this->getLogger()->log($this->_('Votre compte ne vous permet pas de vous préinscrire.'));
+      return $this;
+    }
+
+    $this->_user
+      ->beAbonneSIGB()
+      ->setIdSite($library_id)
+      ->setIdIntBib($library_id)
+      ->setIdabon($this->_user->getLogin());
+
+    if (isset($response['patron_id']))
+      $this->_user->setIdSigb($response['patron_id']);
+
+    if ( ! $this->_user->save())
+      $this->getLogger()->log($this->_user->getError());
+
+    return $this;
+  }
+}
diff --git a/library/Class/WebService/SIGB/Nanook/PreRegistration/Data.php b/library/Class/WebService/SIGB/Nanook/PreRegistration/Data.php
new file mode 100644
index 0000000000000000000000000000000000000000..5f047ec30247dc9d12d0dda96f8920570915fed7
--- /dev/null
+++ b/library/Class/WebService/SIGB/Nanook/PreRegistration/Data.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Copyright (c) 2012-2022, 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 Class_WebService_SIGB_Nanook_Preregistration_Data extends Class_WebService_SIGB_PreRegistration_AbstractData {
+
+
+  protected static array $_fields_map =
+    ['prenom' => 'firstName',
+     'nom' => 'lastName',
+     'mail' => ['mail', 'mail2'],
+     'naissance' => 'birthDate',
+     'ville' => 'town',
+     'code_postal' => 'zipcode',
+     'adresse' => 'address'];
+
+
+  protected function _getBranchCode() : string {
+    return $this->_data_as_array['site'] ?? '0';
+  }
+
+
+  public function getBranchId() : string {
+    return $this->_getBranchCode();
+  }
+
+
+  public function getEmail() : string {
+    return $this->_data_as_array['mail'] ?? '';
+  }
+}
diff --git a/library/Class/WebService/SIGB/Nanook/Service.php b/library/Class/WebService/SIGB/Nanook/Service.php
index 326ae4d51180be37d7423e30295561125319f2be..2d7aa47e5aaecd7e2ec299ae374c75535c32e6a9 100644
--- a/library/Class/WebService/SIGB/Nanook/Service.php
+++ b/library/Class/WebService/SIGB/Nanook/Service.php
@@ -387,11 +387,31 @@ class Class_Webservice_SIGB_Nanook_Service extends Class_WebService_SIGB_Abstrac
   }
 
 
-  public function preRegistration($data) {
-    $data = array_filter($data);
+  protected function _getFieldsAllowedForPreregistration(){
+    return [
+            'mail',
+            'site',
+            'lastName',
+            'firstName',
+            'password',
+            'birthDate',
+            'town',
+            'zipcode',
+            'address',
+            'phoneNumber',
+            'lastNameResp',
+            'firstNameResp'
+    ];
+  }
+
+
+  public function preRegistration(Class_WebService_SIGB_Nanook_Preregistration_Data $data) {
+    $tags_to_keep = $this->_getFieldsAllowedForPreregistration();
+
+    $data = array_filter($data->getDataAsArray(),
+                         fn ($val, $key) => in_array($key, $tags_to_keep) && $val,
+                         ARRAY_FILTER_USE_BOTH);
 
-    unset($data['mail2']);
-    unset($data['password2']);
     $data['site'] = (int) $data['site'];
 
     $url = $this->buildQueryURL(['service' => 'pre-register']);
@@ -425,6 +445,11 @@ class Class_Webservice_SIGB_Nanook_Service extends Class_WebService_SIGB_Abstrac
   }
 
 
+  public function getEmail($data){
+    return  $data['mail'] ?? '';
+  }
+
+
   public function providesPickupLocations() {
     if (null !== $this->_provide_pickup_locations)
       return $this->_provide_pickup_locations;
diff --git a/library/Class/WebService/SIGB/PreRegistration.php b/library/Class/WebService/SIGB/PreRegistration.php
deleted file mode 100644
index 7a42688212c92f522a965a86bb7ff975ff8894e4..0000000000000000000000000000000000000000
--- a/library/Class/WebService/SIGB/PreRegistration.php
+++ /dev/null
@@ -1,271 +0,0 @@
-<?php
-/**
- * Copyright (c) 2012-2017, 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 Class_WebService_SIGB_PreRegistration {
-  use Trait_Translator;
-  const REQUIRED_CHECKBOX_NAME = 'conditions_message';
-
-  protected
-    $_enabled,
-    $_strategy,
-    $_errors;
-
-
-  public function isEnabled() {
-    return !$this->_getIntBibWithPreRegistrationEnabled()->isEmpty();
-  }
-
-
-  public function getForm() {
-    if (!$this->isEnabled())
-      return;
-
-    $form = $this->getStrategy()->getForm();
-
-    if (!$validation_message = Class_AdminVar::get('PREREGISTRATION_CONDITIONS_MESSAGE'))
-      return $form;
-
-    $form->addElement('requiredCheckbox',
-                      static::REQUIRED_CHECKBOX_NAME,
-                      ['label' => $validation_message ]);
-
-    $form->addDisplayGroup(['conditions_message'], 'conditions',
-                           ['legend' => $this->_('Conditions')]);
-    return $form;
-  }
-
-
-  public function getBranchCode($data) {
-    return $this->getStrategy()->getBranchCode($data);
-  }
-
-
-  public function getEmail($data) {
-    return $this->getStrategy()->getEmail($data);
-  }
-
-
-  public function getBib($data) {
-    $code = $this->getBranchCode($data);
-    $annex = Class_CodifAnnexe::findFirstBy(['code' => $code]);
-    return $annex->getBib();
-  }
-
-
-  protected function getStrategy() {
-    if ($this->_strategy)
-      return $this->_strategy;
-
-    if (!$first = Class_IntBib::findAllWithPreRegistration()->first())
-      return $this->_strategy = new Class_WebService_SIGB_PreRegistrationAbstract($this);
-
-    if ($first->isCommNanook())
-      return $this->_strategy = new Class_WebService_SIGB_PreRegistrationNanook($this);
-
-    if ($first->isCommKoha())
-      return $this->_strategy = new Class_WebService_SIGB_PreRegistrationKoha($this);
-  }
-
-
-  public function send($data, $user) {
-    if (isset($data[ static::REQUIRED_CHECKBOX_NAME ]))
-      unset($data[ static::REQUIRED_CHECKBOX_NAME ]);
-    return $this->getStrategy()->send($data, $user);
-  }
-
-
-  public function addError($message) {
-    $this->getErrors()->append($message);
-  }
-
-
-  public function getErrors() {
-    if(!$this->_errors)
-      $this->_errors = new Storm_Collection();
-
-    return $this->_errors;
-  }
-
-
-  public function hasError() {
-    return !$this->getErrors()->isEmpty();
-  }
-
-
-  public function joinErrorsWith($separator) {
-    return implode($separator, $this->getErrors()->getArrayCopy());
-  }
-
-
-  protected function _getIntBibWithPreRegistrationEnabled() {
-    if (!$this->_enabled)
-      $this->_enabled = (new Storm_Model_Collection(Class_IntBib::findAll()))
-        ->select(function($int_bib) { return $int_bib->isPreRegistrationEnabled(); });
-
-    return $this->_enabled;
-  }
-}
-
-
-
-
-class Class_WebService_SIGB_PreRegistrationAbstract {
-  protected $_pre_registration;
-
-  public function __construct($pre_registration) {
-    $this->_pre_registration = $pre_registration;
-  }
-
-
-  public function getForm() {}
-
-
-  public function send($data, $user) {}
-
-
-  public function getBranchCode($data) {}
-
-
-  public function getEmail($data) {}
-}
-
-
-
-
-class Class_WebService_SIGB_PreRegistrationNanook extends Class_WebService_SIGB_PreRegistrationAbstract{
-  public function getForm() {
-    return new ZendAfi_Form_PreRegistration_Nanook();
-  }
-
-
-  public function send($data, $user) {
-    if(!$int_bib = Class_IntBib::find($this->getBranchCode($data)))
-      return $this->_pre_registration->addError($this->_('Échec de la préinscription, la médiathèque sélectionnée n\'existe pas.'));
-
-    $response = $int_bib->getSIGBComm()->preRegistration($data);
-
-    if (!$response['statut'])
-      return $this->_pre_registration->addError($response['erreur']);
-
-    return $this->_updateUser($user, $int_bib, $response);
-  }
-
-
-  public function getBranchCode($data) {
-    return isset($data['site'])
-      ? $data['site']
-      : 0;
-  }
-
-
-  public function getEmail($data) {
-    return isset($data['mail'])
-      ? $data['mail']
-      : '';
-  }
-
-
-  protected function _updateUser($user, $int_bib, $response) {
-    if (!$user)
-      return $this;
-
-    $user->beAbonneSIGB()
-         ->setIdSite($int_bib->getId())
-         ->setIntBib($int_bib)
-         ->setIdabon($user->getLogin());
-
-    if (isset($response['patron_id']))
-      $user->setIdSigb($response['patron_id']);
-
-    $user->save();
-    return $this;
-  }
-}
-
-
-
-
-class Class_WebService_SIGB_PreRegistrationKoha extends Class_WebService_SIGB_PreRegistrationAbstract {
-
-  public function getForm() {
-    return ZendAfi_Form_PreRegistration_Koha::newWithOptions(['branchescodes' => $this->_getBranchescodes()]);
-  }
-
-
-  public function send($data, $user) {
-    $int_bib = $this->_extractIntBibFrom($data);
-    return $this->_preRegistrationWithKoha($int_bib, $data);
-  }
-
-
-  public function getBranchCode($data) {
-    if(!isset($data['branchcode']))
-      return 0;
-    return explode('|', $data['branchcode'])[1];
-  }
-
-
-  public function getEmail($data) {
-    return isset($data['email'])
-      ? $data['email']
-      : '';
-  }
-
-
-  protected function _getBranchescodes() {
-    $branchcodes = [];
-
-    foreach(Class_IntBib::findAllWithPreRegistration() as $int_bib) {
-      $from_webservice = $int_bib->getSIGBComm()->getBranches($int_bib->getId());
-      $branchcodes = array_merge($branchcodes, $from_webservice);
-    }
-
-    return $branchcodes;
-  }
-
-
-  protected function _preRegistrationWithKoha($int_bib, $data) {
-    if(!$int_bib = Class_IntBib::find($int_bib)) {
-     $this->_pre_registration->addError($this->_('Échec de la préinscription, les informations saisies sont invalides.'));
-     return $this;
-    }
-
-    $data['branchcode'] = $this->getBranchCode($data);
-
-    if(isset($data['dateofbirth']))
-      $data['dateofbirth'] = Class_Date::humanDate($data['dateofbirth'],'yyyy-MM-dd');
-
-    $response = $int_bib->getSIGBComm()->preRegistration($data);
-
-    if(!$response['statut'])
-      $this->_pre_registration->addError($response['erreur']);
-
-    return $this;
-  }
-
-
-  protected function _extractIntBibFrom($data) {
-    if(!isset($data['branchcode']))
-      return 0;
-    return explode('|', $data['branchcode'])[0];
-  }
-}
diff --git a/library/Class/WebService/SIGB/PreRegistration/AbstractData.php b/library/Class/WebService/SIGB/PreRegistration/AbstractData.php
new file mode 100644
index 0000000000000000000000000000000000000000..7b978d5c6ce7c0802603fdd2b8eda0913bdb25ac
--- /dev/null
+++ b/library/Class/WebService/SIGB/PreRegistration/AbstractData.php
@@ -0,0 +1,111 @@
+<?php
+/**
+ * Copyright (c) 2012-2022, 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
+ */
+
+
+abstract class Class_WebService_SIGB_PreRegistration_AbstractData {
+
+  protected array $_data_as_array = [];
+  protected static array $_fields_map = [];
+
+
+  public function __construct(array $data) {
+    $this->_data_as_array = $data;
+  }
+
+
+  public function getUserDataForForm(Class_Users $user) : array {
+    $mapped_data = [];
+    foreach(array_filter($user->getRawAttributes()) as $db_field_name => $value)
+      $mapped_data = $this->_injectFormAttribute($db_field_name, $value, $mapped_data);
+
+    return $mapped_data;
+  }
+
+
+  protected function _injectFormAttribute(string $db_field_name,
+                                          string $value,
+                                          array $mapped_data) : array {
+
+    $mapping = static::$_fields_map;
+
+    if ( ! isset($mapping[$db_field_name]))
+      return $mapped_data;
+
+    $form_field_names = $mapping[$db_field_name];
+
+    $form_field_names = is_array($form_field_names)
+      ? $form_field_names
+      : [$form_field_names];
+
+    foreach($form_field_names as $form_field_name)
+      $mapped_data[$form_field_name] = $value;
+
+    return $mapped_data;
+  }
+
+
+  public function setDataAsArray(array $data_as_array) : self {
+    $this->_data_as_array = $data_as_array;
+    return $this;
+  }
+
+
+  public function getDataAsArray() : array {
+    return $this->_data_as_array;
+  }
+
+
+  public function getValueOfAttribute(string $attribute_name) : string {
+    $mapping = static::$_fields_map;
+    if (isset($mapping[$attribute_name])
+        && ($sigb_attribute = $mapping[$attribute_name])
+        && isset($this->_data_as_array[$sigb_attribute]))
+      return $this->_data_as_array[$sigb_attribute];
+
+    return $this->_data_as_array[$attribute_name] ?? '';
+  }
+
+
+  public function getLibraryId() : int {
+    return ($annexe = Class_CodifAnnexe::findFirstBy(['code' => $this->_getBranchCode()]))
+      ? $annexe->getIdBib()
+      : 0;
+  }
+
+
+  public function getLibrary() : ?Class_Bib {
+    return ($annexe = Class_CodifAnnexe::findFirstBy(['code' => $this->_getBranchCode()]))
+      ? $annexe->getBib()
+      : null;
+  }
+
+
+  public function getUserForMailTemplateInstance()
+    : Class_WebService_SIGB_PreRegistration_UserForMailTemplate {
+    return new Class_WebService_SIGB_PreRegistration_UserForMailTemplate($this);
+  }
+
+  abstract protected function _getBranchCode() : string;
+
+  abstract public function getBranchId() : string;
+
+  abstract public function getEmail() : string;
+}
diff --git a/library/Class/WebService/SIGB/PreRegistration/Mail.php b/library/Class/WebService/SIGB/PreRegistration/Mail.php
new file mode 100644
index 0000000000000000000000000000000000000000..847e30187ab808666aca7b249251390fb93ecc13
--- /dev/null
+++ b/library/Class/WebService/SIGB/PreRegistration/Mail.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ * Copyright (c) 2012-2022, 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 Class_WebService_SIGB_PreRegistration_Mail {
+
+  use Trait_Logger, Trait_Translator;
+
+
+  protected $_data;
+
+
+  public function __construct(Class_WebService_SIGB_PreRegistration_AbstractData $data) {
+    $this->_data = $data;
+  }
+
+
+  public function send() : self {
+    $subject =
+     $this->_templatedOrStatic($this->_data,
+                               'NOTIFICATION_SUBJECT_PREREGISTRATION',
+                               '_staticMailSubject');
+
+    $body =
+      $this->_templatedOrStatic($this->_data,
+                                'NOTIFICATION_TEMPLATE_PREREGISTRATION',
+                                '_staticMailContent');
+
+    $mailer = new Class_MailHtml;
+
+    $result = $mailer->mail($this->_data->getEmail(), $subject, $body, true);
+
+    $message = ($result === true)
+      ? $this->_('Un email de confirmation de préinscription vous a été envoyé à l\'adresse <b>%s</b>.', $this->_data->getEmail())
+      : $message;
+
+    $this->getLogger()->log($message);
+
+    return $this;
+  }
+
+
+  protected function _templatedOrStatic(Class_WebService_SIGB_PreRegistration_AbstractData $data,
+                                        string $var_name,
+                                        string $callback_name) : string {
+    if (!$template = Class_AdminVar::getValueOrDefault($var_name))
+      return call_user_func([$this, $callback_name]);
+
+    $modelfusion = (new Class_ModeleFusion)
+      ->setContenu($template)
+      ->setDataSource(['library' => $data->getLibrary(),
+                       'user' => $data->getUserForMailTemplateInstance()]);
+
+    return ($templated = $modelfusion->getContenuFusionne())
+      ? $templated
+      : call_user_func([$this, $callback_name]);
+  }
+
+
+  protected function _staticMailSubject() {
+    return ($library = $this->getLibrary())
+      ? $this->_('Préinscription à %s', $library->getLibelle())
+      : $this->_('Préinscription');
+  }
+
+
+  protected function _staticMailContent() {
+    return $this->_view->tagPreRegistration($this->getLibrary());
+  }
+}
diff --git a/library/Class/WebService/SIGB/PreRegistration/Null.php b/library/Class/WebService/SIGB/PreRegistration/Null.php
new file mode 100644
index 0000000000000000000000000000000000000000..19c6ffe26edbbe7cc045321abb0144f2144cc52a
--- /dev/null
+++ b/library/Class/WebService/SIGB/PreRegistration/Null.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Copyright (c) 2012-2022, 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 Class_WebService_SIGB_PreRegistration_Null extends Class_WebService_SIGB_AbstractPreRegistration {
+
+
+  public function send(Class_WebService_SIGB_PreRegistration_AbstractData $data) : self {
+    return $this;
+  }
+
+
+  public function getData(array $data_as_array)
+    : Class_WebService_SIGB_PreRegistration_AbstractData {
+    return new Class_WebService_SIGB_PreRegistration_NullData([]);
+  }
+
+
+  protected function _getFormInstance() : ZendAfi_Form {
+    return new ZendAfi_Form;
+  }
+
+
+  protected function _populateFormWith(ZendAfi_Form $form,
+                                       ?Class_Users $user) : ZendAfi_Form {
+    return $form;
+  }
+}
\ No newline at end of file
diff --git a/library/Class/WebService/SIGB/PreRegistration/NullData.php b/library/Class/WebService/SIGB/PreRegistration/NullData.php
new file mode 100644
index 0000000000000000000000000000000000000000..ffa693daee85aa5420511ba12be65674984abf96
--- /dev/null
+++ b/library/Class/WebService/SIGB/PreRegistration/NullData.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Copyright (c) 2012-2022, 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 Class_WebService_SIGB_PreRegistration_NullData extends Class_WebService_SIGB_PreRegistration_AbstractData {
+
+  protected function _getBranchCode() : string {
+    return '';
+  }
+
+
+  public function getBranchId() : string {
+    return '';
+  }
+
+
+  public function getEmail() : string {
+    return '';
+  }
+}
diff --git a/library/Class/WebService/SIGB/PreRegistration/UserForMailTemplate.php b/library/Class/WebService/SIGB/PreRegistration/UserForMailTemplate.php
new file mode 100644
index 0000000000000000000000000000000000000000..1a824a070d98763f8744f55a8e66c0f62bac8654
--- /dev/null
+++ b/library/Class/WebService/SIGB/PreRegistration/UserForMailTemplate.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Copyright (c) 2012-2022, 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 Class_WebService_SIGB_PreRegistration_UserForMailTemplate {
+
+
+  protected $_data;
+
+
+  public function __construct(Class_WebService_SIGB_PreRegistration_AbstractData $data) {
+    $this->_data = $data;
+  }
+
+
+  public function callGetterByAttributeName(string $name) {
+    return $this->_data->getValueOfAttribute($name);
+  }
+}
diff --git a/library/ZendAfi/Form/PreRegistration/Koha.php b/library/ZendAfi/Form/PreRegistration/Koha.php
index 40672625453348928ffe854f483d8068b039c6fc..199658dae565cfb404b4119f5901306e7ef948dd 100644
--- a/library/ZendAfi/Form/PreRegistration/Koha.php
+++ b/library/ZendAfi/Form/PreRegistration/Koha.php
@@ -29,7 +29,7 @@ class ZendAfi_Form_PreRegistration_Koha extends ZendAfi_Form {
                   'branchcode',
                   ['label' => $this->_('Bibliothèque'),
                    'required' => true,
-                   'multiOptions' => $this->_getBranchcodes()])
+                   'multiOptions' => Class_IntBib::findAllKohaLabelsWithPreRegistration()])
 
       ->addElement('text',
                    'surname',
diff --git a/library/ZendAfi/Form/PreRegistration/Nanook.php b/library/ZendAfi/Form/PreRegistration/Nanook.php
index b0d41d17fb49761ccac393352dfd72623d95fcff..36df1b8b0b3722a53314f0817f9414564e886883 100644
--- a/library/ZendAfi/Form/PreRegistration/Nanook.php
+++ b/library/ZendAfi/Form/PreRegistration/Nanook.php
@@ -30,7 +30,7 @@ class ZendAfi_Form_PreRegistration_Nanook extends ZendAfi_Form {
       ->addElement('select',
                    'site',
                    ['label' => $this->_('Médiathèque'),
-                    'multiOptions' => Class_IntBib::findAllNanookWithPreRegistration()])
+                    'multiOptions' => Class_IntBib::findAllNanookLabelsWithPreRegistration()])
 
       ->addElement('text',
                    'lastName',
diff --git a/tests/application/modules/opac/controllers/AuthControllerPreRegistrationTest.php b/tests/application/modules/opac/controllers/AuthControllerPreRegistrationTest.php
index b6ddcf769742b46c875a5460b13f5650785bbf87..05980b61ec458542f0fc463e0b0d88d50ea6f02d 100644
--- a/tests/application/modules/opac/controllers/AuthControllerPreRegistrationTest.php
+++ b/tests/application/modules/opac/controllers/AuthControllerPreRegistrationTest.php
@@ -19,6 +19,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
 
+
 require_once 'tests/fixtures/KohaFixtures.php';
 require_once 'tests/fixtures/NanookFixtures.php';
 
@@ -31,6 +32,9 @@ abstract class AuthControllerPreRegistrationTestCase extends AbstractControllerT
     Class_WebService_SIGB_Nanook::reset();
 
     ZendAfi_Auth::getInstance()->clearIdentity();
+    $_SERVER['HTTP_REFERER']='/auth/pre-registration';
+
+    Class_WebService_SIGB_AbstractRESTService::shouldThrowError(true);
 
     $this->mock_transport = new MockMailTransport();
     Zend_Mail::setDefaultTransport($this->mock_transport);
@@ -48,12 +52,12 @@ abstract class AuthControllerPreRegistrationTestCase extends AbstractControllerT
 
 
 
+
 abstract class AuthControllerPreRegistrationKohaTestCase
   extends AuthControllerPreRegistrationTestCase {
 
   public function setUp() {
     parent::setUp();
-
     $this->mock_web_client = KohaFixtures::mockWebClientForPreRegistration($this);
   }
 }
@@ -62,10 +66,10 @@ abstract class AuthControllerPreRegistrationKohaTestCase
 
 
 class AuthControllerPreRegistrationKohaDispatchTest extends AuthControllerPreRegistrationKohaTestCase {
+
   public function setUp() {
     parent::setUp();
-
-    $this->dispatch('/opac/auth/pre-registration', true);
+    $this->dispatch('/opac/auth/pre-registration');
   }
 
 
@@ -97,6 +101,7 @@ class AuthControllerPreRegistrationKohaDispatchTest extends AuthControllerPreReg
 
 
 abstract class AuthControllerPreRegistrationKohaPostDispatchTestCase extends AuthControllerPreRegistrationKohaTestCase {
+
   protected $_required_checkbox = false;
   protected $_required_value = false;
 
@@ -113,7 +118,10 @@ abstract class AuthControllerPreRegistrationKohaPostDispatchTestCase extends Aut
              'city' => 'Gotham',
              'email' => 'thom@mail.com',
              'phone' => '0123456789'];
-    $this->mock_web_client = KohaFixtures::mockWebClientForPreRegistration($this,$data);
+
+    $this->mock_web_client = KohaFixtures::mockWebClientForPreRegistration($this, $data)
+      ->beStrict();
+
     if ($this->_required_checkbox)
       Class_AdminVar::set('PREREGISTRATION_CONDITIONS_MESSAGE', '<a href="#">Vous devez accepter les conditions de validation</a>');
     $values = [];
@@ -121,6 +129,8 @@ abstract class AuthControllerPreRegistrationKohaPostDispatchTestCase extends Aut
     if ($this->_required_checkbox)
       $values = ['conditions_message' => $this->_required_value];
 
+    $this->_setTemplateNotification();
+
     $this->postDispatch('auth/pre-registration',
                         array_merge ($values, ['branchcode' => '41|GRA',
                                                'surname' => 'Boulard',
@@ -134,6 +144,10 @@ abstract class AuthControllerPreRegistrationKohaPostDispatchTestCase extends Aut
                                                'phone' => '0123456789',
                                                'website' => '']));
   }
+
+  private function _setTemplateNotification(){
+    Class_AdminVar::set('NOTIFICATION_TEMPLATE_PREREGISTRATION',"Bonjour {user.prenom} {user.nom},<br><br><p>Votre demande d'inscription à <b>{library.libelle}</b> a bien été enregistrée.</p><p>Afin de finaliser votre inscription, merci de vous rendre dans votre médiathèque : <b>{library.adresse} {library.cp} {library.ville}</b></p>");
+  }
 }
 
 
@@ -143,7 +157,7 @@ class AuthControllerPreRegistrationKohaPostDispatchTest extends AuthControllerPr
 
   /** @test */
   public function responseShouldRedirectToPreRegistrationSuccessIdBibFortyFive() {
-    $this->assertRedirectTo('http://localhost' . BASE_URL . '/auth/pre-registration-success/id_bib/45');
+    $this->assertRedirectTo('/auth/pre-registration-success/id_bib/45');
   }
 
 
@@ -154,6 +168,39 @@ class AuthControllerPreRegistrationKohaPostDispatchTest extends AuthControllerPr
   }
 
 
+  /** @test */
+  public function mailContentShouldContainsBonjourThomBoulard() {
+    $this->assertContains("Bonjour Thom Boulard,",
+                          quoted_printable_decode($this->mock_transport->getSentMails()[0]
+                                                  ->getBodyHtml(true)));
+  }
+
+
+  /** @test */
+  public function mailContentShouldBeVotreDemande() {
+    $this->assertContains("<p>Votre demande d'inscription à <b>Médiathèque de Grans</b> a bien été enregistrée.</p><p>Afin de finaliser votre inscription, merci de vous rendre dans votre médiathèque : <b>1 rue proche de la mer 83756 Juan les Pins</b></p>",
+                          quoted_printable_decode($this->mock_transport->getSentMails()[0]
+                                                  ->getBodyHtml(true)));
+  }
+}
+
+
+
+class AuthControllerPreRegistrationKohaPostDispatchWithSuccessAndCustomTemplate extends AuthControllerPreRegistrationKohaPostDispatchTestCase {
+  private function _setTemplateNotification(){
+    Class_AdminVar::set('NOTIFICATION_TEMPLATE_PREREGISTRATION',"Bonjour {user.firstname} {user.surname},<br><br><p>Votre demande d'inscription à <b>{library.libelle}</b> a bien été enregistrée.</p><p>Afin de finaliser votre inscription, merci de vous rendre dans votre médiathèque : <b>{library.adresse} {library.cp} {library.ville}</b></p>");
+  }
+
+
+
+  /** @test */
+  public function mailContentShouldContainsBonjourThomBoulard() {
+    $this->assertContains("Bonjour Thom Boulard,",
+                          quoted_printable_decode($this->mock_transport->getSentMails()[0]
+                                                  ->getBodyHtml(true)));
+  }
+
+
   /** @test */
   public function mailContentShouldBeVotreDemande() {
     $this->assertContains("<p>Votre demande d'inscription à <b>Médiathèque de Grans</b> a bien été enregistrée.</p><p>Afin de finaliser votre inscription, merci de vous rendre dans votre médiathèque : <b>1 rue proche de la mer 83756 Juan les Pins</b></p>",
@@ -172,7 +219,7 @@ class AuthControllerPreRegistrationKohaWithRequiredCondtionChecked extends AuthC
 
   /** @test */
   public function responseShouldRedirectToPreRegistrationSuccess() {
-    $this->assertRedirectTo('http://localhost' . BASE_URL . '/auth/pre-registration-success/id_bib/45');
+    $this->assertRedirectTo('/auth/pre-registration-success/id_bib/45');
   }
 }
 
@@ -194,7 +241,7 @@ class AuthControllerPreRegistrationKohaWithRequiredCondtionNotChecked extends Au
 
 
 
-class AuthControllerKohaPreRegistrationSpammedPostDispatchTest extends AuthControllerPreRegistrationKohaTestCase {
+class AuthControllerPreRegistrationKohaSpammedPostDispatchTest extends AuthControllerPreRegistrationKohaTestCase {
   public function setUp() {
     parent::setUp();
 
@@ -213,14 +260,14 @@ class AuthControllerKohaPreRegistrationSpammedPostDispatchTest extends AuthContr
 
   /** @test */
   public function responseShouldRedirectToRoot() {
-    $this->assertRedirectTo('/');
+    $this->assertRedirectTo('/auth/pre-registration');
   }
 }
 
 
 
 
-class AuthControllerKohaPreRegistrationInvalidBirthDatePostDispatchTest extends AuthControllerPreRegistrationKohaTestCase {
+class AuthControllerPreRegistrationKohaInvalidBirthDatePostDispatchTest extends AuthControllerPreRegistrationKohaTestCase {
   public function setUp() {
     parent::setUp();
 
@@ -279,8 +326,14 @@ class AuthControllerPreRegistrationKohaPostDispatchWithErrorReturnedTest extends
 
 
   /** @test */
-  public function responseShouldRedirectToPreRegistrationErrorIdBibFive() {
-    $this->assertRedirectTo('http://localhost' . BASE_URL . '/auth/pre-registration/id_bib/45');
+  public function responseShouldRedirectToPreRegistrationError() {
+    $this->assertRedirectTo('/auth/pre-registration');
+  }
+
+
+  /** @test */
+  public function errorMessageShouldBe() {
+    $this->assertFlashMessengerContentContains('Échec de la préinscription, les informations saisies sont invalides.');
   }
 }
 
@@ -291,7 +344,7 @@ class AuthControllerPreRegistrationKohaSuccessDispatchTest extends AuthControlle
   public function setUp() {
     parent::setUp();
 
-    $this->dispatch('/auth/pre-registration-success/id_bib/45', true);
+    $this->dispatch('/auth/pre-registration-success/id_bib/45');
   }
 
 
@@ -314,17 +367,17 @@ abstract class AuthControllerPreRegistrationNanookTestCase
 
   public function setUp() {
     parent::setUp();
-    $this->fixture('Class_CodifAnnexe',
+    $this->fixture(Class_CodifAnnexe::class,
                    ['id' => 1,
                     'id_bib' => 1,
                     'id_origine' => '1',
                     'libelle' => 'ARCADIA']);
 
 
-    $this->fixture('Class_Bib',
+    $this->fixture(Class_Bib::class,
                    ['id' => 1, 'libelle' => 'Arcadia']);
 
-    $this->fixture('Class_IntBib',
+    $this->fixture(Class_IntBib::class,
                    ['id' => 1,
                     'comm_params' => ['url_serveur' => 'http://super.nano.ok/ilsdi/arcadia',
                                       'pre-registration' => 1],
@@ -456,24 +509,27 @@ class AuthControllerPreRegistrationNanookPostDispatchTest
               'address' => '123'])
       ->answers(NanooKFixtures::xmlGetPatronInfoFrancoisMorel());
 
-    $this->postDispatch('/opac/auth/pre-registration', ['site' => '1',
-                                                        'lastName' => 'Jiro',
-                                                        'firstName' => 'Tom',
-                                                        'mail' => 'test@test.fr',
-                                                        'mail2' => 'test@test.fr',
-                                                        'password' => 'pwd123456',
-                                                        'password2' => 'pwd123456',
-                                                        'birthDate' => '2001-05-05',
-                                                        'town' => 'titi',
-                                                        'zipcode' => '123456',
-                                                        'address' => '123',
-                                                        'website' => '']);
+    Class_AdminVar::set('NOTIFICATION_TEMPLATE_PREREGISTRATION',"Bonjour {user.prenom} {user.nom},<br><br><p>Votre demande d'inscription à <b>{library.libelle}</b> a bien été enregistrée.</p><p>Afin de finaliser votre inscription, merci de vous rendre dans votre médiathèque : <b>{library.adresse} {library.cp} {library.ville}</b></p>");
+
+    $this->postDispatch('/opac/auth/pre-registration',
+                        ['site' => '1',
+                         'lastName' => 'Jiro',
+                         'firstName' => 'Tom',
+                         'mail' => 'test@test.fr',
+                         'mail2' => 'test@test.fr',
+                         'password' => 'pwd123456',
+                         'password2' => 'pwd123456',
+                         'birthDate' => '2001-05-05',
+                         'town' => 'titi',
+                         'zipcode' => '123456',
+                         'address' => '123',
+                         'website' => '']);
   }
 
 
   /** @test */
   public function responseShouldRedirectToPreRegistrationSuccessIdBibOne() {
-    $this->assertRedirectTo('http://localhost' . BASE_URL . '/auth/pre-registration-success/id_bib/1');
+    $this->assertRedirectTo('/auth/pre-registration-success/id_bib/1');
   }
 
 
@@ -485,7 +541,8 @@ class AuthControllerPreRegistrationNanookPostDispatchTest
 
   /** @test */
   public function mailToShouldBeTestAndNanook() {
-    $this->assertEquals(['test@test.fr','nanook@afi-sa.net'], $this->mock_transport->getSentMails()[0]->getRecipients());
+    $this->assertEquals(['test@test.fr','nanook@afi-sa.net'],
+                        $this->mock_transport->getSentMails()[0]->getRecipients());
   }
 
 
@@ -494,6 +551,16 @@ class AuthControllerPreRegistrationNanookPostDispatchTest
     $this->assertContains('Préinscription à Arcadia',
                           quoted_printable_decode($this->mock_transport->getSentMails()[0]->getSubject()));
   }
+
+
+  /** @test */
+  public function mailBodyShouldContainsBonjourTomJiro() {
+    $this->assertContains('Bonjour Tom Jiro,',
+                          quoted_printable_decode($this->mock_transport
+                                                  ->getSentMails()[0]
+                                                  ->getBodyHtml()
+                                                  ->getContent()));
+  }
 }
 
 
@@ -543,8 +610,8 @@ abstract class AuthControllerPreRegistrationNanookPostErrorTestCase
 
 
   /** @test */
-  public function responseShouldRedirectToPreRegistrationErrorIdBibOne() {
-    $this->assertRedirectTo('http://localhost' . BASE_URL . '/auth/pre-registration/id_bib/1');
+  public function responseShouldRedirectToPreRegistrationError() {
+    $this->assertRedirectTo('/auth/pre-registration');
   }
 
 
@@ -654,8 +721,8 @@ class AuthControllerPreRegistrationNanookPostDispatchErrorPatronPasswordNotSecur
 
 
   /** @test */
-  public function responseShouldRedirectToPreRegistrationErrorIdBibOne() {
-    $this->assertRedirectTo('http://localhost' . BASE_URL . '/auth/pre-registration/id_bib/1');
+  public function responseShouldRedirectToPreRegistrationError() {
+    $this->assertRedirectTo('/auth/pre-registration');
   }
 
 
@@ -690,8 +757,8 @@ class AuthControllerPreRegistrationNanookPostDispatchSpamTest
 
 
   /** @test */
-  public function shouldRedirectToHome() {
-    $this->assertRedirectTo('/');
+  public function shouldRedirectToReferer() {
+    $this->assertRedirectTo('/auth/pre-registration');
   }
 }
 
@@ -751,13 +818,13 @@ class AuthControllerPreRegistrationWithNoPreRegistrationTest extends AuthControl
     parent::setUp();
     Class_IntBib::find(1)->setCommParams(['url_serveur' => 'http://super.nano.ok/ilsdi/arcadia',
                                           'pre-registration' => 0])->save();
-    $this->dispatch('/opac/auth/pre-registration', true);
+    $this->dispatch('/opac/auth/pre-registration');
   }
 
 
   /** @test */
   public function pageShouldDisplayErrorPreinscriptionDeactivated() {
-    $this->assertFlashMessengerContentContains('Cette fonctionnalité n\'est pas activé');
+    $this->assertFlashMessengerContentContains('Malheureusement, la fonctionnalité de préinscription n\'est pas activée.');
   }
 }
 
@@ -768,7 +835,7 @@ class AuthControllerPreRegistrationSettingsTest extends AuthControllerPreRegistr
   public function setUp() {
     parent::setUp();
 
-    ZendAfi_Auth::getInstance()->logUser($this->fixture('Class_Users',
+    ZendAfi_Auth::getInstance()->logUser($this->fixture(Class_Users::class,
                                                         ['id' => 78,
                                                          'login' => 'sadm',
                                                          'password' => 'um',
@@ -856,18 +923,19 @@ class AuthControllerPreRegistrationNanookDispatchAsInviteAndPostDispatchTest ext
       ->answers('<?xml version="1.0" encoding="UTF-8"?>
 <GetPatronInfo><patronId>5352</patronId><barcode></barcode><lastName>Ro</lastName><firstName>Toto</firstName><siteId>1</siteId></GetPatronInfo>');
 
-    $this->postDispatch('/opac/auth/pre-registration', ['site' => '1',
-                                                        'lastName' => 'Ro',
-                                                        'firstName' => 'Toto',
-                                                        'mail' => 'to@to.ro',
-                                                        'mail2' => 'to@to.ro',
-                                                        'password' => 'pwd123456',
-                                                        'password2' => 'pwd123456',
-                                                        'birthDate' => '1988-04-16',
-                                                        'town' => 'Annecy',
-                                                        'zipcode' => '74000',
-                                                        'address' => '11 bd du Fier',
-                                                        'website' => '']);
+    $this->postDispatch('/opac/auth/pre-registration',
+                        ['site' => '1',
+                         'lastName' => 'Ro',
+                         'firstName' => 'Toto',
+                         'mail' => 'to@to.ro',
+                         'mail2' => 'to@to.ro',
+                         'password' => 'pwd123456',
+                         'password2' => 'pwd123456',
+                         'birthDate' => '1988-04-16',
+                         'town' => 'Annecy',
+                         'zipcode' => '74000',
+                         'address' => '11 bd du Fier',
+                         'website' => '']);
   }
 
 
@@ -912,3 +980,322 @@ class AuthControllerPreRegistrationNanookDispatchAsInviteAndPostDispatchTest ext
                       implode(';', $totoro->getErrors()));
   }
 }
+
+
+
+
+
+class AuthControllerPreRegistrationDisabledTest extends AbstractControllerTestCase {
+
+
+  /** @test */
+  public function withNoConnectedUserShouldReturnPreRegistrationNotSet() {
+    ZendAfi_Auth::getInstance()->clearIdentity();
+    $this->dispatch('/auth/pre-registration');
+    $this->assertFlashMessengerContentContains('Malheureusement, la fonctionnalité de préinscription n\'est pas activée.');
+  }
+
+
+  /** @test */
+  public function withBorowerConnectedShouldReturnPreRegistrationNotAllowed() {
+    $antoine =
+      $this->fixture(Class_Users::class,
+                     ['id' => 7879,
+                      'login' => 'Antoine',
+                      'password' => 'L\'animal',
+                      'role_level' => ZendAfi_Acl_AdminControllerRoles::ABONNE_SIGB,
+                      'idabon' => 8888888,
+                      'id_site' => 99999999
+                     ]);
+
+    ZendAfi_Auth::getInstance()->logUser($antoine);
+    $this->dispatch('/auth/pre-registration');
+    $this->assertFlashMessengerContentContains('Antoine, vous ne pouvez pas vous préinscrire à partir d\'un compte déjà connecté.');
+  }
+}
+
+
+
+
+class AuthControllerPreRegistrationKohaDispatchAsInviteTest extends AuthControllerPreRegistrationKohaTestCase {
+  public function setUp() {
+    parent::setUp();
+
+    $totoro = $this->fixture(Class_Users::class,
+                             ['id' => 19,
+                              'nom' => 'Ro',
+                              'prenom' => 'Toto',
+                              'naissance' => '1988-04-16',
+                              'login' => 'totoro',
+                              'password' => 'secret',
+                              'mail' => 'to@to.ro',
+                              'adresse' => '1 rue Ghibli',
+                              'code_postal' => '74000',
+                              'telephone' => '012345678',
+                              'ville' => 'Annecy',
+                              'role_level' => ZendAfi_Acl_AdminControllerRoles::INVITE]);
+
+    ZendAfi_Auth::getInstance()->logUser($totoro);
+
+    $this->dispatch('/opac/auth/pre-registration');
+  }
+
+
+  public function expectedInputValues() {
+    return
+      [
+       ['firstname', 'Toto'],
+       ['surname' , 'Ro'],
+       ['phone', '012345678'],
+       ['email', 'to@to.ro'],
+       ['dateofbirth', '1988-04-16'],
+       ['city', 'Annecy'],
+       ['zipcode', '74000'],
+       ['address', '1 rue Ghibli']];
+  }
+
+
+  /**
+   * @dataProvider expectedInputValues
+   * @test
+   */
+  public function inputValueShouldBe($input_name, $expected_value) {
+    $this->assertXPath(sprintf('//input[@name="%s"][@value="%s"]',
+                               $input_name,
+                               $expected_value)
+                       , $this->_response->getBody());
+  }
+}
+
+
+
+
+class AuthControllerPreRegistrationKohaDispatchNotLoggedTest extends AuthControllerPreRegistrationKohaTestCase {
+  public function setUp() {
+    parent::setUp();
+
+    ZendAfi_Auth::getInstance()->clearIdentity();
+
+    $this->dispatch('/opac/auth/pre-registration');
+  }
+
+
+  public function expectedInputValues() {
+    return
+      [
+       ['firstname', ''],
+       ['surname' , ''],
+       ['phone', ''],
+       ['email', ''],
+       ['dateofbirth', ''],
+       ['city', ''],
+       ['zipcode', ''],
+       ['address', '']];
+  }
+
+
+  /**
+   * @dataProvider expectedInputValues
+   * @test
+   */
+  public function inputValueShouldBe($input_name, $expected_value) {
+    $this->assertXPath(sprintf('//input[@name="%s"][@value="%s"]',
+                               $input_name,
+                               $expected_value)
+                       , $this->_response->getBody());
+  }
+}
+
+
+
+
+class AuthControllerPreRegistrationNanookDispatchNotLoggedTest extends AuthControllerPreRegistrationNanookAsInviteTestCase {
+  public function setUp() {
+    parent::setUp();
+
+    ZendAfi_Auth::getInstance()->clearIdentity();
+
+    $this->dispatch('/opac/auth/pre-registration');
+  }
+
+
+  public function expectedInputValues() {
+    return
+      [['birthDate', ''],
+      ['mail', ''],
+      ['mail2', ''],
+      ['lastName', ''],
+      ['firstName', ''],
+      ['town', ''],
+      ['zipcode', ''],
+       ['address', '']];
+  }
+
+
+  /**
+   * @dataProvider expectedInputValues
+   * @test
+   */
+  public function inputValueShouldBe($input_name, $expected_value) {
+    $this->assertXPath(sprintf('//input[@name="%s"][@value="%s"]',
+                               $input_name,
+                               $expected_value)
+                       , $this->_response->getBody());
+  }
+}
+
+
+
+
+
+class AuthControllerPreRegistrationNullTest extends ModelTestCase {
+  /** @test */
+  public function nullPreRegistrationDataShouldBeNullData() {
+    $this->assertNotNull((new Class_WebService_SIGB_PreRegistration_Null(null))->getData([]));
+  }
+}
+
+
+
+
+class AuthControllerPreRegistrationKohaPostDispatchWithUnknownLocalBranchTest extends AuthControllerPreRegistrationKohaTestCase {
+  public function setUp() {
+    parent::setUp();
+
+    $data =
+      ['branchcode' => 'FOSPC',
+       'surname' => 'Boulard',
+       'firstname' => 'Thom',
+       'dateofbirth' => '1940-09-15',
+       'streetnumber' => '10',
+       'address' => 'rue secret',
+       'zipcode' => '01630',
+       'city' => 'Gotham',
+       'email' => 'thom@mail.com',
+       'phone' => '0123456789'];
+
+    $this->postDispatch('auth/pre-registration',
+                        array_merge($data,
+                                    ['branchcode' => '43|FOSPC']));
+  }
+
+
+  /** @test */
+  public function responseShouldRedirectToPreRegistrationError() {
+    $this->assertRedirectTo('/auth/pre-registration');
+  }
+
+
+  /** @test */
+  public function flashMessengerShouldContainsEchecDeLaPreinscriptionBibliothequeInvalid() {
+    $this->assertFlashMessengerContentContains('Échec de la préinscription, la bibliothèque sélectionnée n\'est pas valide.');
+  }
+}
+
+
+
+
+abstract class AuthControllerPreRegistrationKohaPostDispatchWithWebServiceErrorTestCase extends AuthControllerPreRegistrationKohaTestCase {
+  public function setUp() {
+    parent::setUp();
+
+    $data =
+      ['branchcode' => 'GRA',
+       'surname' => 'Boulard',
+       'firstname' => 'Thom',
+       'dateofbirth' => '1940-09-15',
+       'streetnumber' => '10',
+       'address' => 'rue secret',
+       'zipcode' => '01630',
+       'city' => 'Gotham',
+       'email' => 'thom@mail.com',
+       'phone' => '0123456789'];
+
+    $this->mock_web_client = KohaFixtures::mockWebClientForPreRegistration($this,
+                                                                             $data);
+
+    Class_WebService_SIGB_AbstractRESTService::shouldThrowError(false);
+    Class_IntBib::find(41)->getSIGBComm()->setWebClient($this->_setWebClientErrors($data));
+
+    $this->postDispatch('auth/pre-registration',
+                        $this->_postData($data));
+  }
+
+
+  /** @test */
+  public function responseShouldRedirectToAuthPreRegistration() {
+    $this->assertRedirectTo('/auth/pre-registration');
+  }
+
+
+  protected function _postData(array $data) : array {
+    return array_merge($data, ['branchcode' => '41|GRA']);
+  }
+
+
+  abstract protected function _setWebClientErrors(array $data);
+}
+
+
+
+
+class AuthControllerPreRegistrationKohaPostDispatchWithWebServiceThrowErrorTest extends AuthControllerPreRegistrationKohaPostDispatchWithWebServiceErrorTestCase {
+
+  protected function _setWebClientErrors(array $data) {
+    return $this->mock_web_client
+      ->whenCalled('postData')
+      ->with('http://catalogue.sanop318.biblibre.com/cgi-bin/koha/rest.pl/user',
+             ['data' => json_encode($data)])
+      ->willDo(function() {throw new Error('error 500');});
+  }
+
+
+  /** @test */
+  public function flashMessengerShouldContainsEchecDeLaPreinscriptionBibliothequeInvalid() {
+    $this->assertFlashMessengerContentContains('Échec de la préinscription, une erreur inconnue est survenue.');
+  }
+}
+
+
+
+
+class AuthControllerPreRegistrationKohaPostDispatchWithWebServiceThrowExceptionTest extends AuthControllerPreRegistrationKohaPostDispatchWithWebServiceErrorTestCase {
+
+  protected function _setWebClientErrors(array $data) {
+    return $this->mock_web_client
+      ->whenCalled('postData')
+      ->with('http://catalogue.sanop318.biblibre.com/cgi-bin/koha/rest.pl/user',
+             ['data' => json_encode($data)])
+      ->willDo(function() {throw new Exception('error 404');});
+  }
+
+
+  /** @test */
+  public function flashMessengerShouldContainsEchecDeLaPreinscriptionBibliothequeInvalid() {
+    $this->assertFlashMessengerContentContains('Échec de la préinscription, une erreur inconnue est survenue.');
+  }
+}
+
+
+
+
+class AuthControllerPreRegistrationKohaPostDispatchWithWebServiceBranchesErrorExceptionTest extends AuthControllerPreRegistrationKohaPostDispatchWithWebServiceErrorTestCase {
+
+  protected function _setWebClientErrors(array $data) {
+    return $this->mock_web_client
+      ->whenCalled('open_url')
+      ->with('http://catalogue.sanop318.biblibre.com/cgi-bin/koha/rest.pl/branches')
+      ->willDo(function() {throw new Exception('error 404');});
+  }
+
+
+  protected function _postData(array $data) : array {
+    return array_merge($data, ['branchcode' => 'erreur']);
+  }
+
+
+  /** @test */
+  public function flashMessengerShouldContainsEchecDeLaPreinscriptionBibliothequeInvalid() {
+    $this->assertFlashMessengerContentContains('Échec de la préinscription, la bibliothèque sélectionnée n\'est pas valide.');
+  }
+}
\ No newline at end of file
diff --git a/tests/fixtures/KohaFixtures.php b/tests/fixtures/KohaFixtures.php
index f19519f847af7c1598234034512804e6c2574ee0..fdf3058301138161e7332677b33b8cdafb978f5c 100644
--- a/tests/fixtures/KohaFixtures.php
+++ b/tests/fixtures/KohaFixtures.php
@@ -44,7 +44,9 @@ class KohaFixtures {
   }
 
 
-  public static function mockWebClientForPreRegistration($controller,$data_success = null, $data_error =null)  {
+  public static function mockWebClientForPreRegistration($controller,
+                                                         $data_success = null,
+                                                         $data_error =null)  {
     $controller->fixture('Class_CodifAnnexe',
                          ['id' => 41,
                           'id_bib' => 45,
@@ -64,6 +66,7 @@ class KohaFixtures {
                                                ['url_serveur' => 'http://catalogue.sanop318.biblibre.com/cgi-bin/koha/ilsdi.pl',
                                                 'pre-registration' => 1],
                                                'comm_sigb' => Class_IntBib::COM_KOHA]);
+
     Class_IntBib::newInstanceWithIdAssertSave(43,
                                               ['comm_params' =>
                                                ['url_serveur' => 'http://catalogue.sanop318.biblibre.com/cgi-bin/koha/ilsdi.pl',
@@ -77,6 +80,7 @@ class KohaFixtures {
 
     $mock_web_client
       ->whenCalled('open_url')
+      ->with('http://catalogue.sanop318.biblibre.com/cgi-bin/koha/rest.pl/branches')
       ->answers(static::branches());
 
     if ($data_success)
diff --git a/tests/scenarios/Templates/TemplatesAuthPreRegisterTest.php b/tests/scenarios/Templates/TemplatesAuthPreRegisterTest.php
index 01096e6f1664afc86b3a9edb3fe3a5dc690aa4c0..837e5978dd6c532ad0ed8b06c42b789bb00ca0a6 100644
--- a/tests/scenarios/Templates/TemplatesAuthPreRegisterTest.php
+++ b/tests/scenarios/Templates/TemplatesAuthPreRegisterTest.php
@@ -20,36 +20,47 @@
  */
 
 
-class TemplatesAuthPreRegisterTest extends Admin_AbstractControllerTestCase {
-  protected $_storm_default_to_volatile = true;
+class TemplatesAuthPreRegisterActionDispatchTest extends AbstractControllerTestCase {
 
   public function setUp() {
     parent::setUp();
 
-    $this->fixture('Class_IntBib',
-                   ['id' => 1,
-                    'comm_params' => ['url_serveur' => 'http://super.nano.ok/ilsdi/arcadia',
-                                      'pre-registration' => 1],
-                    'comm_sigb' => Class_IntBib::COM_NANOOK]);
-
     $this->_buildTemplateProfil(['id' => 1,
                                  'libelle' => 'Somewhere in time'])
          ->setCfgModulesPreferences(['help_message' => "Go and register to<br>my library"],
                                     'auth',
                                     'pre-registration');
-  }
 
+    ZendAfi_Auth::getInstance()->clearIdentity();
 
-  /** @test */
-  public function configFormShouldContainsTextAreaHelpMessage() {
-    $this->dispatch('/admin/widget/edit-action/id/auth_pre-registration/id_profil/1');
-    $this->assertXPath('//form//textarea[@name="help_message"]');
+    $this->fixture('Class_IntBib',
+                   ['id' => 1,
+                    'comm_params' => ['url_serveur' => 'http://super.nano.ok/ilsdi/arcadia',
+                                      'pre-registration' => 1],
+                    'comm_sigb' => Class_IntBib::COM_NANOOK]);
+
+    $this->dispatch('/auth/pre-registration');
   }
 
 
   /** @test */
   public function pageShouldContainsParagrahWithGoAndRegisterToMyLibrary() {
-    $this->dispatch('/auth/pre-registration');
     $this->assertXPath('//p[@class="help_message"][contains(text(), "Go and register")]/br');
   }
 }
+
+
+
+
+class TemplatesAuthPreRegisterAdminEditActionDispatchTest extends Admin_AbstractControllerTestCase {
+
+  public function setUp() {
+    parent::setUp();
+    $this->dispatch('/admin/widget/edit-action/id/auth_pre-registration/id_profil/1');
+  }
+
+  /** @test */
+  public function configFormShouldContainsTextAreaHelpMessage() {
+    $this->assertXPath('//form//textarea[@name="help_message"]');
+  }
+}
\ No newline at end of file
diff --git a/tests/scenarios/Templates/TemplatesFormTest.php b/tests/scenarios/Templates/TemplatesFormTest.php
index d9ea1fb257d37d854e420af7d0fe1b3f1f688f5e..7ea3580754160a548c0325a4297bce7c58814175 100644
--- a/tests/scenarios/Templates/TemplatesFormTest.php
+++ b/tests/scenarios/Templates/TemplatesFormTest.php
@@ -90,7 +90,7 @@ class TemplatesFormPreRegistrationWithConditionsPostTest extends TemplatesFormPr
 
   /** @test */
   public function responseShouldRedirectToPreRegistrationSuccessIdBibFive() {
-    $this->assertRedirectTo('http://localhost' . BASE_URL . '/auth/pre-registration-success/id_bib/45');
+    $this->assertRedirectTo('/auth/pre-registration-success/id_bib/45');
   }
 }