diff --git a/VERSIONS_WIP/27067 b/VERSIONS_WIP/27067
new file mode 100644
index 0000000000000000000000000000000000000000..4266f52e993875e5655677aa4ab02090c27eff40
--- /dev/null
+++ b/VERSIONS_WIP/27067
@@ -0,0 +1 @@
+ - ticket #27067 : Koha : Webservice de création des suggestions
\ No newline at end of file
diff --git a/application/modules/admin/controllers/ModulesController.php b/application/modules/admin/controllers/ModulesController.php
index af8c94016fc094c5266e02bdbcb2334a2caef70e..953109729138940672291e62a4334ecddae05f3c 100644
--- a/application/modules/admin/controllers/ModulesController.php
+++ b/application/modules/admin/controllers/ModulesController.php
@@ -90,6 +90,8 @@ class Admin_ModulesController extends ZendAfi_Controller_Action {
 
 
   public function abonneAction() {
+    if ($this->_getParam('action1') === 'suggestion-achat-add')
+      return $this->_simpleAction('abonne_suggestion_achat_add');
     return $this->_simpleAction('abonne_all');
   }
 
diff --git a/application/modules/admin/views/scripts/modules/abonne_suggestion_achat_add.phtml b/application/modules/admin/views/scripts/modules/abonne_suggestion_achat_add.phtml
new file mode 100644
index 0000000000000000000000000000000000000000..eb1f4c526682ff388450bb76e1a53486023c35cf
--- /dev/null
+++ b/application/modules/admin/views/scripts/modules/abonne_suggestion_achat_add.phtml
@@ -0,0 +1,13 @@
+<?php echo $this->render('modules/_debut.phtml');?>
+<fieldset>
+  <legend><?php echo $this->_('Texte d\'aide') ?></legend>
+  <table cellspacing="2">
+    <tr>
+      <td class="droite"></td>
+      <td class="gauche"><?php echo $this->ckEditor($this->preferences['help-text'],
+                                                    'help-text'); ?></td>
+    </tr>
+  </table>
+</fieldset>
+
+<?php echo $this->render('modules/_fin.phtml');?>
diff --git a/application/modules/opac/controllers/AbonneController.php b/application/modules/opac/controllers/AbonneController.php
index 246ca25151f71f042bf38d0492a0446e2a0e3803..93adf034db24a8b8590c5d3abc7abebc24bc3015 100644
--- a/application/modules/opac/controllers/AbonneController.php
+++ b/application/modules/opac/controllers/AbonneController.php
@@ -870,14 +870,13 @@ class AbonneController extends ZendAfi_Controller_Action {
       return;
     }
 
-    $form = new ZendAfi_Form_SuggestionAchat();
+    $form = ZendAfi_Form_SuggestionAchat::forUser($this->_user);
 
     if ($this->_request->isPost()) {
       $post = $this->_request->getPost();
       unset($post['submit']);
-      $suggestion = (new Class_SuggestionAchat())
-        ->updateAttributes($post)
-        ->setUserId(Class_Users::currentUserId());
+
+      $suggestion = $form->newBuySuggest($post);
 
       if ($form->isValid($suggestion)) {
         $suggestion->save();
@@ -886,11 +885,13 @@ class AbonneController extends ZendAfi_Controller_Action {
         } catch (Zend_Mail_Exception $e) {
           $this->_helper->notify($this->_('Aucun courriel envoyé, erreur: ').$this->_($e->getMessage()));
         }
-        $this->_redirect('/opac/abonne/suggestion-achat-add/id/'.$suggestion->getId());
+        $this->_helper->notify($this->_('Suggestion d\'achat enregistrée'));
+        $this->_redirect('/opac/abonne/suggestion-achat');
       }
     }
 
     $this->view->form = $form;
+    $this->view->preferences = Class_Profil::getCurrentProfil()->getCfgModulesPreferences('abonne', 'suggestion-achat-add');
   }
 
 
diff --git a/application/modules/opac/views/scripts/abonne/suggestion-achat-add.phtml b/application/modules/opac/views/scripts/abonne/suggestion-achat-add.phtml
index 90a97a3ddb0a4c0a9433181daa8d6c5415e80cfe..a65557a761fd611b99d25f9bb9499b55048f5f09 100644
--- a/application/modules/opac/views/scripts/abonne/suggestion-achat-add.phtml
+++ b/application/modules/opac/views/scripts/abonne/suggestion-achat-add.phtml
@@ -1,5 +1,9 @@
 <?php
 $this->openBoite($this->_('Suggérer un achat'));
+if (trim($this->preferences['help-text']))
+  echo $this->tag('div',
+                  $this->preferences['help-text'],
+                  ['class' => 'help-text']);
 echo $this->renderForm($this->form);
 $this->closeBoite();
 ?>
diff --git a/cosmogramme/php/_menu.php b/cosmogramme/php/_menu.php
index d5897758d77f8bf342647929cb9ff424b7db90bc..346fa582655c085848e3aefdf0d96c241221ee4d 100644
--- a/cosmogramme/php/_menu.php
+++ b/cosmogramme/php/_menu.php
@@ -63,7 +63,7 @@ else
 <body class="menu">
 	<a href="<?php print(URL_BASE)?>" target="_top"><img src="<?php print(URL_IMG); ?>home.png" style="cursor:pointer;margin-top:5px;margin-left:7px" title="Retour à l'accueil" border="0"></a>
 	<a href="<?php print(getVariable("url_site"));?>" target="_top"><img src="<?php print(URL_IMG); ?>icone_site.png" style="cursor:pointer;margin-top:5px;margin-left:10px" title="Aller sur le portail" border="0"></a>
-	<a href="http://afi-forge.afi-sa.fr/projects/opacce/wiki/Configuration_Cosmogramme" target="_blank"><img src="<?php print(URL_IMG); ?>help.png" style="cursor:pointer;margin-top:5px;margin-left:10px" title="Aide Cosmogramme" border="0"></a>
+	<a href="http://wiki.bokeh-library-portal.org/index.php/Cat%C3%A9gorie:Interface_administration_Cosmogramme" target="_blank"><img src="<?php print(URL_IMG); ?>help.png" style="cursor:pointer;margin-top:5px;margin-left:10px" title="Aide Cosmogramme" border="0"></a>
 	<a href="<?php print(substr(URL_BASE,0,strlen(URL_BASE)-1)."?action=logout");?>" target="_top"><img src="<?php print(URL_IMG); ?>deconnexion.png" style="cursor:pointer;margin-top:5px;margin-left:10px" title="Se déconnecter" border="0"></a>
 	<div class="menu_section">Intégration</div>
 	<?php
diff --git a/cosmogramme/php/fonctions/objets_saisie.php b/cosmogramme/php/fonctions/objets_saisie.php
index edbc4c93b7eaad342d1a411cfce706c4b7b29834..d3a1632cefdc92be5e945ebc95fc33896f968e39 100644
--- a/cosmogramme/php/fonctions/objets_saisie.php
+++ b/cosmogramme/php/fonctions/objets_saisie.php
@@ -33,6 +33,11 @@ function getComboSimple($name, $valeur, $liste, $tous=false, $events='') {
 }
 
 
+function getOuiNon($name, $value) {
+	return getComboSimple($name, $value, ['' => 'Non', '1' => 'Oui']);
+}
+
+
 function getComboCodif($name, $clef, $valeur, $events='', $tous=false) {
 	$data = fetchOne('select liste from variables where clef=\''. $clef . '\'');
 	$v = array_filter(explode(chr(13) . chr(10), $data));
@@ -97,6 +102,9 @@ function getBlocsParams($id_bib, $type, $valeurs) {
 
 		if ($clef == COM_KOHA)
 			$champs_params[0] = ['url_serveur',
+													 ['restful' => function($id, $valeur) {
+															 return getOuiNon($id, $valeur);
+														 }],
 													 'Interdire_reservation_doc_dispo',
 													 ['Codification_disponibilites' => function($id, $valeur){
 															 return getTextArea($id, $valeur, 30, 20);
diff --git a/library/Class/Entity.php b/library/Class/Entity.php
index 2eb6a5d1de16f246a41f0689532169ae215d7abf..ca9286cafa6cc731bb03ed2dd24a0d5fac6ec4da 100644
--- a/library/Class/Entity.php
+++ b/library/Class/Entity.php
@@ -49,5 +49,17 @@ class Class_Entity {
 
   protected function _set($name, $value) {
     $this->_attribs[$name] = $value;
+    return $this;
+  }
+
+
+  public function updateAttributes($attributes) {
+    $this->_attribs = array_merge($this->_attribs, $attributes);
+    return $this;
+  }
+
+
+  public function toArray() {
+    return $this->_attribs;
   }
 }
diff --git a/library/Class/SuggestionAchat.php b/library/Class/SuggestionAchat.php
index 5a215c5823ca89b89f00f0df474875d87efc947a..699d81d5d3d6b7c377861269a9f2290c68ca4b5a 100644
--- a/library/Class/SuggestionAchat.php
+++ b/library/Class/SuggestionAchat.php
@@ -169,5 +169,19 @@ class Class_SuggestionAchat extends Storm_Model_Abstract {
 
     return $bib->getLibelle();
   }
+
+
+  public function acceptVisitor($visitor) {
+    $visitor
+      ->visitField($this->_('Date de création'), $this->getDateCreation())
+      ->visitField($this->_('Type de document'), $this->getDocumentType())
+      ->visitField($this->_('Titre'), $this->getTitre())
+      ->visitField($this->_('Auteur'), $this->getAuteur())
+      ->visitField($this->_('Lien Internet vers une description'), $this->getDescriptionUrl())
+      ->visitField($this->_('ISBN'), $this->getIsbn())
+      ->visitField($this->_('Commentaire'), $this->getCommentaire());
+
+    return $this;
+  }
 }
 ?>
\ No newline at end of file
diff --git a/library/Class/Systeme/ModulesAppli.php b/library/Class/Systeme/ModulesAppli.php
index d72b2a493e642ac0b8c25ed2d03ff40c4b779fd3..b94dd8c7bf9c38e859e55a9e36a402f0c94e8d01 100644
--- a/library/Class/Systeme/ModulesAppli.php
+++ b/library/Class/Systeme/ModulesAppli.php
@@ -55,7 +55,10 @@ class Class_Systeme_ModulesAppli extends Class_Systeme_ModulesAbstract {
                                            'popup_height' => 300],
                                    'formations' => ['libelle' => 'Contact',
                                                     'popup_width' => 500,
-                                                    'popup_height' => 300]],
+                                                    'popup_height' => 300],
+                                   'suggestion-achat-add' => ['libelle' => 'Suggestions d\'achat',
+                                                              'popup_width' => 700,
+                                                              'popup_height' => 500]],
 
                       'auth' => ['*' => ['libelle' => 'Connexion',
                                          'popup_width' => 500,
@@ -215,6 +218,8 @@ class Class_Systeme_ModulesAppli extends Class_Systeme_ModulesAbstract {
     switch ((string)$type) {
       case "auth": $valeurs = $this->getDefautAuth($action);
         break;
+      case "abonne": $valeurs = $this->getDefautAbonne($action);
+        break;
       case "recherche": $valeurs = $this->getDefautRecherche($action);
         break;
       case "noticeajax": $valeurs = $this->getDefautRecherche("viewnotice");
@@ -251,6 +256,23 @@ class Class_Systeme_ModulesAppli extends Class_Systeme_ModulesAbstract {
   }
 
 
+  /**
+   * @param type $action
+   * @return array
+   */
+  private function getDefautAbonne($action) {
+    $preferences = [];
+
+    switch ((string)$action) {
+      case 'suggestion-achat-add':
+        $preferences['help-text'] = '';
+        break;
+    }
+
+    return $preferences;
+  }
+
+
   /**
    * @param type $action
    * @return int
diff --git a/library/Class/Users.php b/library/Class/Users.php
index e731e38bc6b91f0e2724f58a8778f2a1ee0c7b36..0a7771683313855785a0446873ac9492d31bf5c3 100644
--- a/library/Class/Users.php
+++ b/library/Class/Users.php
@@ -1512,6 +1512,13 @@ class Class_Users extends Storm_Model_Abstract {
   }
 
 
+  public function getSuggestionAchat() {
+    return (($sigb_com = $this->getSIGBComm()) && $sigb_com->providesSuggestions())
+      ? $sigb_com->suggestionsOf($this)
+      : parent::_get('suggestion_achat');
+  }
+
+
   public function registerNotificationsOn($notifiable) {
     (new Class_User_ILSSubscription($this))->registerNotificationsOn($notifiable);
     $this
diff --git a/library/Class/WebService/SIGB/AbstractRESTService.php b/library/Class/WebService/SIGB/AbstractRESTService.php
index 088c8b4067f940999473f093bf1efb7cf148fc4d..4d885503422423d611c4036b21b78e2412cd68fc 100644
--- a/library/Class/WebService/SIGB/AbstractRESTService.php
+++ b/library/Class/WebService/SIGB/AbstractRESTService.php
@@ -20,8 +20,6 @@
  */
 
 abstract class Class_WebService_SIGB_AbstractRESTService extends Class_WebService_SIGB_AbstractService {
-  use Trait_Translator;
-
   protected $_server_root;
   protected $_web_client;
 
@@ -82,9 +80,37 @@ abstract class Class_WebService_SIGB_AbstractRESTService extends Class_WebServic
    * @return string
    */
   public function httpGet($options) {
+    $closure = function($client, $url) {
+      return $client->open_url($url);
+    };
+
+    return $this->_withClientDo($options, $closure);
+  }
+
+
+  /**
+   * @param $options array url query part
+   * @param $datas array posted datas
+   * @return string response body
+   */
+  public function httpPost($options, $datas) {
+    $closure = function($client, $url) use ($datas) {
+      return $client->postData($url, $datas);
+    };
+
+    return $this->_withClientDo($options, $closure);
+  }
+
+
+  /**
+   * @param $options array url query part
+   * @param $closure
+   * @return response body
+   */
+  protected function _withClientDo($options, $closure) {
     $url = $this->buildQueryURL($options);
     try {
-      $response = $this->getWebClient()->open_url($url);
+      $response = $closure($this->getWebClient(), $url);
       $this->log();
       return $response;
     } catch (Exception $e) {
diff --git a/library/Class/WebService/SIGB/AbstractService.php b/library/Class/WebService/SIGB/AbstractService.php
index 919d2aff62c2f5aeed0f801617561f27a86542e2..bdf04883230c6a9c84ba5a3bec039b68e4287211 100644
--- a/library/Class/WebService/SIGB/AbstractService.php
+++ b/library/Class/WebService/SIGB/AbstractService.php
@@ -20,6 +20,8 @@
  */
 
 abstract class Class_WebService_SIGB_AbstractService {
+  use Trait_Translator;
+
   protected static $_logger;
   protected $_notice_cache;
 
@@ -117,14 +119,33 @@ abstract class Class_WebService_SIGB_AbstractService {
   }
 
 
+  public function providesSuggestions() {
+    return false;
+  }
+
+
+  public function suggestionsOf($user) {
+    return [];
+  }
+
+
+  public function newBuySuggestForm() {
+    return new ZendAfi_Form_SuggestionAchat();
+  }
+
+
+  public function suggest($suggestion) {
+    return $this->_error($this->_('Suggestions non prises en charge par ce connecteur'));
+  }
+
+
   protected function _success() {
-    return array('statut' => true, 'erreur' => '');
+    return ['statut' => true, 'erreur' => ''];
   }
 
 
   protected function _error($message) {
-    return array('statut' => false,
-                 'erreur' => $message);
+    return ['statut' => false, 'erreur' => $message];
   }
 
 
@@ -134,8 +155,6 @@ abstract class Class_WebService_SIGB_AbstractService {
 
 
   public function test() {
-    return 'Ce service n\'est pas testable';
+    return $this->_('Ce service n\'est pas testable');
   }
-}
-
-?>
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/library/Class/WebService/SIGB/Koha.php b/library/Class/WebService/SIGB/Koha.php
index ca56c1305a22a8010fdfe38ccdc1c7892806122c..92b0fe85e1346bf8787ff893fa1c8baa91ce3125 100644
--- a/library/Class/WebService/SIGB/Koha.php
+++ b/library/Class/WebService/SIGB/Koha.php
@@ -16,7 +16,7 @@
  *
  * 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 
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
 
 class Class_WebService_SIGB_Koha {
@@ -26,15 +26,18 @@ class Class_WebService_SIGB_Koha {
     return md5(serialize($params));
   }
 
+
   public static function getService($params){
     $key = static::makeKey($params);
     if (!isset(static::$services[$key])) {
-      $instance = new static();
       $params = array_merge(['Interdire_reservation_doc_dispo' => 0,
-                             'Codification_disponibilites' => ''], 
+                             'Codification_disponibilites' => '',
+                             'restful' => ''],
                             $params);
+
       $service = Class_WebService_SIGB_Koha_Service::getService($params['url_serveur'],
-                                                                $params['Interdire_reservation_doc_dispo']==='1');
+                                                                $params['Interdire_reservation_doc_dispo']==='1',
+                                                                $params['restful']==='1');
 
       $service->setCodificationDisponibilites(static::decodeCodificationDisponibilites($params['Codification_disponibilites']));
       static::$services[$key] = $service;
@@ -63,7 +66,6 @@ class Class_WebService_SIGB_Koha {
   public static function reset() {
     static::$services = [];
   }
-
 }
 
 ?>
\ No newline at end of file
diff --git a/library/Class/WebService/SIGB/Koha/BuySuggestForm.php b/library/Class/WebService/SIGB/Koha/BuySuggestForm.php
new file mode 100644
index 0000000000000000000000000000000000000000..8f0da3bb7c4e54203e778db83c51bb0f3732bb9e
--- /dev/null
+++ b/library/Class/WebService/SIGB/Koha/BuySuggestForm.php
@@ -0,0 +1,75 @@
+<?php
+/**
+ * Copyright (c) 2012, 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_BuySuggestForm extends ZendAfi_Form_SuggestionAchat_Abstract {
+
+  public function newBuySuggest($post) {
+    return (new Class_WebService_SIGB_Suggestion())
+      ->updateAttributes($post)
+      ->setUser($this->_user);
+  }
+
+
+  public function init() {
+    parent::init();
+    $this
+
+      ->addElement('text', 'Title', ['label' => $this->_('Titre').' *',
+                                     'placeholder' => $this->_('ex: Harry Potter à l\'école des sorciers'),
+                                     'size' => 80,
+                                     'required' => true,
+                                     'allowEmpty' => false])
+
+      ->addElement('text', 'Author', ['label' => $this->_('Auteur').' *',
+                                      'placeholder' => 'ex: Joanne Kathleen Rowling',
+                                      'size' => 80,
+                                      'required' => true,
+                                      'allowEmpty' => false])
+
+      ->addElement('text', 'Isbn', ['label' => $this->_('Code-barres / ISBN'),
+                                    'placeholder' => 'ex: 2-07-054127-4',
+                                    'size' => 17])
+
+      ->addElement('text', 'PublicationYear', ['label' => $this->_('Année de publication'),
+                                               'size' => 4,
+                                               'maxlength' => 4,
+                                               'placeholder' => '2015',
+                                               'validators' => ['Int']])
+
+      ->addElement('textarea', 'PatronReason', ['label' => '',
+                                                'cols' => 70,
+                                                'rows' => 10])
+
+      ->addDisplayGroup(['Title',
+                         'Author',
+                         'Isbn',
+                         'PublicationYear'],
+                        'suggestion',
+                        ['legend' => $this->_('Informations sur le document')])
+
+      ->addDisplayGroup(['PatronReason'],
+                        'notes_group',
+                        ['legend' => $this->_('Notes')])
+
+      ->addElement('submit', 'submit', ['label' => $this->_('Envoyer')]);
+  }
+}
+?>
\ No newline at end of file
diff --git a/library/Class/WebService/SIGB/Koha/RestfulService.php b/library/Class/WebService/SIGB/Koha/RestfulService.php
new file mode 100644
index 0000000000000000000000000000000000000000..cd382d0552e2484be6c425ce6041238ee2d8b330
--- /dev/null
+++ b/library/Class/WebService/SIGB/Koha/RestfulService.php
@@ -0,0 +1,150 @@
+<?php
+/**
+ * Copyright (c) 2012-2014, 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_RestfulService
+  extends Class_WebService_SIGB_AbstractRESTService {
+
+  protected $_ilsdi_service, $_current_action;
+
+  public static function newFromIlsdi($ilsdi_service) {
+    return new static($ilsdi_service);
+  }
+
+
+  /**
+   * Private as it should be instanciated using newFromIlsdi
+   */
+  private function __construct($ilsdi_service) {
+    $this->_ilsdi_service = $ilsdi_service;
+    $this
+      ->setServerRoot(str_replace('ilsdi.pl', 'rest.pl', $ilsdi_service->getServerRoot()))
+      ->setWebClient($ilsdi_service->getWebClient());
+  }
+
+
+  public function providesSuggestions() {
+    return true;
+  }
+
+
+  public function suggestionsOf($user) {
+    if (!$patron_id = $this->_authenticate($user))
+      return $this->_error($this->_('Échec de l\'authentification par le webservice'));
+
+    $json = $this
+      ->restfulGet('suggestions', ['suggestedby' => $this->_authenticate($user)]);
+
+    if ('[]' !== trim($json) && false === strpos($json, 'suggestedby'))
+      return $this->_error($this->_('Échec de la connexion au webservice, le SIGB a répondu "%s"',
+                                    trim($json)));
+
+    return (new Class_WebService_SIGB_Koha_SuggestionsReader())
+      ->parse($json);
+  }
+
+
+  public function suggest($suggestion) {
+    $datas = ['suggestedby' => $this->_authenticate($suggestion->getUser()),
+              'title' => $suggestion->getTitle(),
+              'author' => $suggestion->getAuthor(),
+              'isbn' => $suggestion->getIsbn(),
+              'patronreason' => $suggestion->getPatronReason(),
+              'publicationyear' => $suggestion->getPublicationYear()];
+
+    $json = $this->restfulPost('suggestions',
+                               ['data' => json_encode($datas)]);
+
+    if ('' == $json || (!$data = json_decode($json)))
+      return $this->_error($this->_('Échec de la suggestion, une erreur inconnue est survenue.'));
+
+    if (isset($data->error))
+      return $this->_error($this->_('Échec de la suggestion, le webservice a répondu "%s"',
+                                    trim($data->error)));
+
+    return $this->_success();
+  }
+
+
+  public function buildQueryURL($options) {
+    return sprintf('%s/%s?%s',
+                   $this->getServerRoot(),
+                   $this->_current_action,
+                   http_build_query($options));
+  }
+
+
+  public function restfulGet($action, $params=[]) {
+    $this->_current_action = $action;
+    return $this->httpGet($params);
+  }
+
+
+  public function restfulPost($action, $datas, $params=[]) {
+    $this->_current_action = $action;
+    return $this->httpPost($params, $datas);
+  }
+
+
+  /**
+   * Handled by ILSDI
+   */
+
+
+  public function _authenticate($user) {
+    return $this->_forwardToIlsdi(__FUNCTION__, func_get_args());
+  }
+
+
+  public function getEmprunteur($user) {
+    return $this->_forwardToIlsdi(__FUNCTION__, func_get_args());
+  }
+
+
+  public function getUserAnnexe($user) {
+    return $this->_forwardToIlsdi(__FUNCTION__, func_get_args());
+  }
+
+
+  public function reserverExemplaire($user, $exemplaire, $code_annexe) {
+    return $this->_forwardToIlsdi(__FUNCTION__, func_get_args());
+  }
+
+
+  public function supprimerReservation($user, $reservation_id) {
+    return $this->_forwardToIlsdi(__FUNCTION__, func_get_args());
+  }
+
+
+  public function prolongerPret($user, $pret_id) {
+    return $this->_forwardToIlsdi(__FUNCTION__, func_get_args());
+  }
+
+
+  public function getNotice($id) {
+    return $this->_forwardToIlsdi(__FUNCTION__, func_get_args());
+  }
+
+
+  protected function _forwardToIlsdi($name, $params) {
+    return call_user_func_array([$this->_ilsdi_service, $name], $params);
+  }
+}
\ No newline at end of file
diff --git a/library/Class/WebService/SIGB/Koha/Service.php b/library/Class/WebService/SIGB/Koha/Service.php
index 9ef31317e49d32e5e74e76fe11ca33748baf3ec1..e53f3cf515204897d17551d52aa081597875c8af 100644
--- a/library/Class/WebService/SIGB/Koha/Service.php
+++ b/library/Class/WebService/SIGB/Koha/Service.php
@@ -23,6 +23,7 @@ class Class_WebService_SIGB_Koha_Service extends Class_WebService_SIGB_AbstractR
 
   protected
     $interdire_resa_doc_dispo = false,
+    $restful = false,
     $codification_disponibilites = [];
 
   public static function newInstance() {
@@ -30,9 +31,11 @@ class Class_WebService_SIGB_Koha_Service extends Class_WebService_SIGB_AbstractR
   }
 
 
-  public static function getService($server_root,$interdire_reservation_doc_dispo=false) {
-    return self::newInstance()->setServerRoot($server_root)
-                              ->setInterdireResaDocDispo($interdire_reservation_doc_dispo);
+  public static function getService($server_root, $interdire_reservation_doc_dispo=false, $restful=false) {
+    return self::newInstance()
+      ->setServerRoot($server_root)
+      ->setInterdireResaDocDispo($interdire_reservation_doc_dispo)
+      ->setRestful($restful);
   }
 
 
@@ -40,10 +43,10 @@ class Class_WebService_SIGB_Koha_Service extends Class_WebService_SIGB_AbstractR
    * @param Class_Users $user
    * @return int
    */
-  protected function _authenticate($user) {
-    $xml_auth = $this->httpGet(array('service' => 'LookupPatron',
-                                     'id' => ($user->hasIdSigb() ? $user->getIdSigb() : $user->getIdabon()),
-                                     'id_type' => 'cardnumber'));
+  public function _authenticate($user) {
+    $xml_auth = $this->httpGet(['service' => 'LookupPatron',
+                                'id' => ($user->hasIdSigb() ? $user->getIdSigb() : $user->getIdabon()),
+                                'id_type' => 'cardnumber']);
 
     return $this->_getTagData($xml_auth, 'id');
   }
@@ -64,10 +67,10 @@ class Class_WebService_SIGB_Koha_Service extends Class_WebService_SIGB_AbstractR
    * @return Class_WebService_SIGB_Emprunteur
    */
   public function getEmprunteur($user) {
-    return $this->ilsdiGetPatronInfo(array('patron_id' => $this->_authenticate($user),
-                                           'show_contact' => 0,
-                                           'show_loans' => 1,
-                                           'show_holds' => 1),
+    return $this->ilsdiGetPatronInfo(['patron_id' => $this->_authenticate($user),
+                                      'show_contact' => 0,
+                                      'show_loans' => 1,
+                                      'show_holds' => 1],
                                      Class_WebService_SIGB_Koha_PatronInfoReader::newInstance());
   }
 
@@ -152,6 +155,42 @@ class Class_WebService_SIGB_Koha_Service extends Class_WebService_SIGB_AbstractR
   }
 
 
+  public function setRestful($flag) {
+    $this->restful = $flag;
+    return $this;
+  }
+
+
+  public function providesSuggestions() {
+    return $this->restful;
+  }
+
+
+  public function suggestionsOf($user) {
+    if (!$this->providesSuggestions())
+      return parent::suggestionsOf($user);
+
+    return $this
+      ->getRestfulService()
+      ->suggestionsOf($user);
+  }
+
+
+  public function suggest($suggestion) {
+    if (!$this->providesSuggestions())
+      return parent::suggest($suggestion);
+
+    return $this
+      ->getRestfulService()
+      ->suggest($suggestion);
+  }
+
+
+  public function getRestfulService() {
+    return Class_WebService_SIGB_Koha_RestfulService::newFromIlsdi($this);
+  }
+
+
   public function getNotice($id) {
     return $this->ilsdiGetRecords($id,
                                   Class_WebService_SIGB_Koha_GetRecordsResponseReader::newInstance()
@@ -177,6 +216,15 @@ class Class_WebService_SIGB_Koha_Service extends Class_WebService_SIGB_AbstractR
       return $e->getMessage() . '\n' . $e->getTraceAsString();
     }
   }
+
+
+
+  public function newBuySuggestForm() {
+    return $this->providesSuggestions()
+      ? new Class_WebService_SIGB_Koha_BuySuggestForm()
+      : parent::newBuySuggestForm();
+  }
+
 }
 
 ?>
\ No newline at end of file
diff --git a/library/Class/WebService/SIGB/Koha/SuggestionsReader.php b/library/Class/WebService/SIGB/Koha/SuggestionsReader.php
new file mode 100644
index 0000000000000000000000000000000000000000..68829492f6fb748af32d29a47286f29b350f14f2
--- /dev/null
+++ b/library/Class/WebService/SIGB/Koha/SuggestionsReader.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * Copyright (c) 2012-2014, 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_SuggestionsReader {
+  use Trait_Translator;
+
+  public function parse($json) {
+    return ($datas = json_decode($json)) ?
+      array_map([$this, '_parseOne'], $datas) : [];
+  }
+
+
+  protected function _parseOne($data) {
+    $library = Class_CodifAnnexe::findFirstBy(['code' => $data->branchcodesuggestedby]);
+    $suggestion = new Class_WebService_SIGB_Suggestion();
+    $suggestion
+      ->setTitle(trim($data->title))
+      ->setAuthor(trim($data->author))
+      ->setPublicationYear(in_array($data->publicationyear, ['', '0']) ?
+                           '' : $data->publicationyear)
+      ->setLibrary($library ? $library->getLibelle() : '')
+      ->setDate(trim($data->suggesteddate))
+      ->setNote(trim($data->note))
+      ->setPatronReason(trim($data->patronreason))
+      ->setStatus($this->_statusLabelFor($data));
+
+    return $suggestion;
+  }
+
+
+  protected function _statusLabelFor($data) {
+    $status = $this->_statusTranslated(trim($data->STATUS));
+    if ($reason = trim($data->reason))
+      $status .= ' (' . $reason . ')';
+
+    return $status;
+  }
+
+
+  public function _statusTranslated($raw_status) {
+    $know_statuses = ['ASKED' => $this->_('En attente'),
+                      'CHECKED' => $this->_('Vérifiée'),
+                      'ACCEPTED' => $this->_('Acceptée'),
+                      'REJECTED' => $this->_('Rejetée'),
+                      'ORDERED' => $this->_('Commandée'),
+                      'AVAILABLE' => $this->_('Disponible')];
+
+    return array_key_exists($raw_status, $know_statuses) ?
+      $know_statuses[$raw_status] : $raw_status;
+  }
+}
\ No newline at end of file
diff --git a/library/Class/WebService/SIGB/Suggestion.php b/library/Class/WebService/SIGB/Suggestion.php
new file mode 100644
index 0000000000000000000000000000000000000000..bcf553891306f3c68448c0c5fecb2a130186a85d
--- /dev/null
+++ b/library/Class/WebService/SIGB/Suggestion.php
@@ -0,0 +1,79 @@
+<?php
+/**
+ * Copyright (c) 2012-2014, 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_Suggestion extends Class_Entity {
+  use Trait_Translator;
+
+  public function __construct() {
+    $this->_attribs = ['Title' => '',
+                       'Author' => '',
+                       'PublicationYear' => '',
+                       'Library' => '',
+                       'Date' => '',
+                       'Note' => '',
+                       'Isbn' => '',
+                       'Status' => ''];
+  }
+
+
+
+
+  public function isValid() {
+    return true;
+  }
+
+
+  public function validate() {
+
+  }
+
+
+  public function getErrors() {
+    return [];
+  }
+
+
+  public function save() {
+    $user = $this->getUser();
+    $user->getSIGBComm()->suggest($this);
+    return true;
+  }
+
+
+  public function sendMail() {
+
+  }
+
+
+  public function acceptVisitor($visitor) {
+    $visitor
+      ->visitField($this->_('Titre'), $this->getTitle())
+      ->visitField($this->_('Auteur'), $this->getAuthor())
+      ->visitField($this->_('Date de publication'), $this->getPublicationYear())
+      ->visitField($this->_('Bibliothèque'), $this->getLibrary())
+      ->visitField($this->_('Date de suggestion'), $this->getDate())
+      ->visitField($this->_('Note'), $this->getPatronReason())
+      ->visitField($this->_('Statut'), $this->getStatus());
+
+    return $this;
+  }
+}
\ No newline at end of file
diff --git a/library/ZendAfi/Form/SuggestionAchat.php b/library/ZendAfi/Form/SuggestionAchat.php
index 91a3263ac04dbd730a376d0081aa3cf37589fc05..84f25e293e923fee9aab029626f053af11639310 100644
--- a/library/ZendAfi/Form/SuggestionAchat.php
+++ b/library/ZendAfi/Form/SuggestionAchat.php
@@ -19,12 +19,10 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
 
-class ZendAfi_Form_SuggestionAchat extends ZendAfi_Form {
+class ZendAfi_Form_SuggestionAchat extends ZendAfi_Form_SuggestionAchat_Abstract {
   public function init() {
     parent::init();
     $this
-      ->setAttrib('id', 'suggestion')
-      ->setAttrib('class', 'zend_form')
       ->addElement('text', 'titre', ['label' => $this->_('Titre').' *',
                                      'placeholder' => $this->_('ex: Harry Potter à l\'école des sorciers'),
                                      'size' => 80])
@@ -33,18 +31,15 @@ class ZendAfi_Form_SuggestionAchat extends ZendAfi_Form {
                                       'placeholder' => 'ex: Joanne Kathleen Rowling',
                                       'size' => 80])
 
-      ->addElement('select', 'type_doc_id', ['label' => $this->_('Type de document').' *',
-      'multioptions' => Class_TypeDoc::getUserFriendlyTypeDocs()])
-
-
-      ->addElement('url', 'description_url', ['label' => $this->_('Lien internet vers une description'),
-                                              'placeholder' => 'ex: http://fr.wikipedia.org/wiki/Harry_Potter_à_l\'école_des_sorciers',
-                                              'size' => 80])
-
       ->addElement('text', 'isbn', ['label' => $this->_('Code-barres / ISBN'),
                                     'placeholder' => 'ex: 2-07-054127-4',
-                                    'size' => 17]);
+                                    'size' => 17])
 
+      ->addElement('select', 'type_doc_id', ['label' => $this->_('Type de document').' *',
+                                             'multioptions' => Class_TypeDoc::getUserFriendlyTypeDocs()])
+      ->addElement('url', 'description_url', ['label' => $this->_('Lien internet vers une description'),
+                                              'placeholder' => 'ex: http://fr.wikipedia.org/wiki/Harry_Potter_à_l\'école_des_sorciers',
+                                              'size' => 80]);
     $common_fields = ['titre', 'auteur', 'type_doc_id',
                       'description_url', 'isbn', 'bib_id'];
 
@@ -52,22 +47,21 @@ class ZendAfi_Form_SuggestionAchat extends ZendAfi_Form {
       $common_fields[] = 'bib_id';
 
     $this->addElement('textarea', 'commentaire', ['label' => '',
-                                               'cols' => 80,
-                                               'rows' => 10])
+                                                  'cols' => 70,
+                                                  'rows' => 10])
 
-      ->addDisplayGroup($common_fields,
-                        'suggestion',
-                        ['legend' => $this->_('Informations sur le document')])
+         ->addDisplayGroup($common_fields,
+                           'suggestion',
+                           ['legend' => $this->_('Informations sur le document')])
 
-      ->addDisplayGroup(['commentaire'],
-                        'commentaires',
-                        ['legend' => $this->_('Pourquoi suggérez-vous ce document ?') . ' *'])
+         ->addDisplayGroup(['commentaire'],
+                           'commentaires',
+                           ['legend' => $this->_('Pourquoi suggérez-vous ce document ?') . ' *'])
 
-      ->addElement('submit', 'submit', ['label' => $this->_('Envoyer')]);
+         ->addElement('submit', 'submit', ['label' => $this->_('Envoyer')]);
   }
 
 
-  /** @return boolean whether selector is added */
   protected function addBibSelector() {
     $user_friendly_bibs = Class_Bib::getUserFriendlyBibs();
     if (empty($user_friendly_bibs))
diff --git a/library/ZendAfi/Form/SuggestionAchat/Abstract.php b/library/ZendAfi/Form/SuggestionAchat/Abstract.php
new file mode 100644
index 0000000000000000000000000000000000000000..eada3f5e48e12ab62dc1eec13e5e1e18e846306d
--- /dev/null
+++ b/library/ZendAfi/Form/SuggestionAchat/Abstract.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Copyright (c) 2012, 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 ZendAfi_Form_SuggestionAchat_Abstract extends ZendAfi_Form {
+  protected $_user;
+
+  public static function forUser($user) {
+    $sigb_comm = $user->getSIGBComm();
+    $form = $sigb_comm
+      ? $sigb_comm->newBuySuggestForm()
+      :  new static();
+
+    return $form->setUser($user);
+  }
+
+
+  public function newBuySuggest($post) {
+    return (new Class_SuggestionAchat())
+      ->updateAttributes($post)
+      ->setUserId($this->_user->getId());
+  }
+
+
+  public function setUser($user) {
+    $this->_user = $user;
+    return $this;
+  }
+
+
+
+  public function init() {
+    parent::init();
+    $this
+      ->setAttrib('id', 'suggestion')
+      ->setAttrib('class', 'zend_form');
+  }
+
+}
+?>
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/Admin/HelpLink.php b/library/ZendAfi/View/Helper/Admin/HelpLink.php
index 4defb96e0e319e0cac8157ced0b349b24e0cb3d4..2e7bb3fc863a80d0a2c4d1b8204479d25bf543cc 100644
--- a/library/ZendAfi/View/Helper/Admin/HelpLink.php
+++ b/library/ZendAfi/View/Helper/Admin/HelpLink.php
@@ -130,7 +130,9 @@ class ZendAfi_View_Helper_Admin_HelpLinkBokehWiki
      'harvest'                => ['jamendo-browse' => 'Jamendo'],
      'modo'                   => ['index' => 'Modération'],
      'modules'                => ['recherche_viewnotice' => 'Affichage_d%27une_notice',
-                                  'recherche_resultat' => 'Paramétrer_une_liste_de_résultat'],
+                                  'recherche_resultat' => 'Paramétrer_une_liste_de_résultat',
+                                  'abonne_suggestion-achat' => 'Suggestion_d\'achat',
+                                  'abonne_suggestion-achat-add' => 'Suggestion_d\'achat'],
      'newsletter'             => ['index' => 'Lettre_d%27information'],
      'profil'                 => ['index' => 'Configurer_un_profil',
                                   'edit' => 'Configurer_un_profil',
diff --git a/library/ZendAfi/View/Helper/ListeSuggestionAchat.php b/library/ZendAfi/View/Helper/ListeSuggestionAchat.php
index 9c1026ae0882405b8c92f2f32efc0d6458100f52..b1d1be5f4756179ff4b929bc9403f28284705f77 100644
--- a/library/ZendAfi/View/Helper/ListeSuggestionAchat.php
+++ b/library/ZendAfi/View/Helper/ListeSuggestionAchat.php
@@ -16,42 +16,51 @@
  *
  * 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 
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
 
 
 
 class ZendAfi_View_Helper_ListeSuggestionAchat extends ZendAfi_View_Helper_BaseHelper {
-  
+
   protected $_user;
 
   public function listeSuggestionAchat($user) {
     $this->_user = $user;
-    return '<div class="suggestion-achat-liste">'.$this->getListeSuggestion().'</div>';
+
+    return $this->_tag('div', $this->getListeSuggestion(),
+                       ['class' => 'suggestion-achat-liste']);
   }
 
 
   public function getListeSuggestion() {
     $suggestions = $this->_user->getSuggestionAchat();
+
+    if ($this->isWebserviceError($suggestions))
+      return $this->renderWebserviceError($suggestions);
+
     $nb_suggestions = count($suggestions);
-    $html = '<span>'.$this->view->_plural($nb_suggestions,
-                                 'Vous n\'avez pas encore fait de suggestion.',
-                                 'Une seule suggestion enregistrée.',
-                                 '%d suggestions enregistrées.',
-                                 $nb_suggestions).
-      '</span>';
-    
-    if(0<$nb_suggestions) {
-          foreach($suggestions as $suggestion_achat) {
-        $html.= '<div>';
-        $html.= $this->view->suggestionAchat($suggestion_achat);
-        $html.= '</div>';
-      }
-    }
-
-    return $html;
+    $html = $this->_tag('span',
+                        $this->view->_plural($nb_suggestions,
+                                             'Vous n\'avez pas encore fait de suggestion.',
+                                             'Une seule suggestion enregistrée.',
+                                             '%d suggestions enregistrées.',
+                                             $nb_suggestions));
+
+    return $html . $this->view->suggestionAchat_Table($suggestions);
   }
 
+
+  protected function isWebserviceError($response) {
+    return is_array($response)
+      && array_key_exists('statut', $response)
+      && false === $response['statut'];
+  }
+
+
+  protected function renderWebserviceError($response) {
+    return $this->_tag('div', $response['erreur']);
+  }
 }
 
 ?>
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/SuggestionAchat.php b/library/ZendAfi/View/Helper/SuggestionAchat.php
deleted file mode 100644
index 7ca4472c4d355209fe028f358fbf06d0f7f53a19..0000000000000000000000000000000000000000
--- a/library/ZendAfi/View/Helper/SuggestionAchat.php
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-/**
- * Copyright (c) 2012, 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 ZendAfi_View_Helper_SuggestionAchat extends ZendAfi_View_Helper_BaseHelper {
-
-  public function suggestionAchat($suggestion_achat) {
-    $html = '<br /><dl>';
-    $attributes = [$this->view->_('Date de création') => $suggestion_achat->getDateCreation(),
-    $this->view->_('Type de document') => $suggestion_achat->getDocumentType(),
-                   $this->view->_('Titre') => $suggestion_achat->getTitre(),
-                   $this->view->_('Auteur') => $suggestion_achat->getAuteur(),
-                   $this->view->_('Lien Internet vers une description') => $suggestion_achat->getDescriptionUrl(),
-                   $this->view->_('ISBN') => $suggestion_achat->getIsbn(),
-                   $this->view->_('Commentaire') => $suggestion_achat->getCommentaire()];
-
-    foreach($attributes as $libelle => $value) {
-      $html.=
-        '<dt>'.$libelle.'</dt>'.
-        '<dd>'.$value.'</dd>';
-    }
-
-    return $html.= '</dl>';
-  }
-
-}
-?>
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/SuggestionAchat/Table.php b/library/ZendAfi/View/Helper/SuggestionAchat/Table.php
new file mode 100644
index 0000000000000000000000000000000000000000..e4b093c3a36b0805e57f5decf7cc4a6c07a76159
--- /dev/null
+++ b/library/ZendAfi/View/Helper/SuggestionAchat/Table.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Copyright (c) 2012, 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 ZendAfi_View_Helper_SuggestionAchat_Table extends ZendAfi_View_Helper_BaseHelper {
+  public function suggestionAchat_Table($suggestions) {
+    if (!count($suggestions))
+      return '';
+
+    Class_ScriptLoader::getInstance()->loadTableSorter();
+
+    return $this->_tag('table',
+                       $this->view->suggestionAchat_TableHeader($suggestions)
+                       . $this->view->suggestionAchat_TableBody($suggestions),
+                       ['class' => 'tablesorter']);
+  }
+}
+
+?>
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/SuggestionAchat/TableBody.php b/library/ZendAfi/View/Helper/SuggestionAchat/TableBody.php
new file mode 100644
index 0000000000000000000000000000000000000000..348ce62bf09131ac39f7c28c7ee94e55e78faae5
--- /dev/null
+++ b/library/ZendAfi/View/Helper/SuggestionAchat/TableBody.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Copyright (c) 2012, 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 ZendAfi_View_Helper_SuggestionAchat_TableBody extends ZendAfi_View_Helper_BaseHelper {
+  protected $_columns;
+
+  public function suggestionAchat_TableBody($suggestions) {
+    return $this->_tag('tbody',
+                       $this->renderRows($suggestions));
+
+  }
+
+  public function renderRows($suggestions) {
+    $html = '';
+    foreach ($suggestions as $suggestion) {
+      $this->_columns = [];
+      $suggestion->acceptVisitor($this);
+      $html .= $this->_tag('tr',
+                           implode($this->_columns));
+    }
+
+    return $html;
+  }
+
+
+  public function visitField($name, $value) {
+    $this->_columns []= $this->_tag('td', $value);
+    return $this;
+  }
+}
+
+?>
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/SuggestionAchat/TableHeader.php b/library/ZendAfi/View/Helper/SuggestionAchat/TableHeader.php
new file mode 100644
index 0000000000000000000000000000000000000000..c5b00f3a70b31480d237d20f965d28428e756bd0
--- /dev/null
+++ b/library/ZendAfi/View/Helper/SuggestionAchat/TableHeader.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Copyright (c) 2012, 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 ZendAfi_View_Helper_SuggestionAchat_TableHeader extends ZendAfi_View_Helper_BaseHelper {
+  protected $_columns;
+
+  public function suggestionAchat_TableHeader($suggestions) {
+    $this->_columns = [];
+    $suggestions[0]->acceptVisitor($this);
+    return $this->_tag('thead',
+                       implode($this->_columns));
+  }
+
+  public function visitField($name, $value) {
+    $this->_columns []= $this->_tag('th', $name);
+    return $this;
+  }
+}
+
+?>
\ No newline at end of file
diff --git a/library/storm b/library/storm
index 08c073b2bfde86b0d4d4f4ed3ef8503543fa4506..8f8662dfdb89bfbd8c247791e2d844db7dfb7880 160000
--- a/library/storm
+++ b/library/storm
@@ -1 +1 @@
-Subproject commit 08c073b2bfde86b0d4d4f4ed3ef8503543fa4506
+Subproject commit 8f8662dfdb89bfbd8c247791e2d844db7dfb7880
diff --git a/public/opac/css/global.css b/public/opac/css/global.css
index 9aa44497b4d1c18d2158bf595299b4d05440b9a2..5162500395c9e155c8419ea1d735352dc49ab4d1 100644
--- a/public/opac/css/global.css
+++ b/public/opac/css/global.css
@@ -2532,6 +2532,11 @@ div.suggestion-achat-liste dl {
     border-top: 2px solid grey;
 }
 
+
+.abonne_suggestion-achat-add .help-text{
+    margin-bottom: 10px;
+}
+
 div.suggestion-achat-liste dt {
     float:left;
     clear:left;
diff --git a/public/opac/css/responsive.css b/public/opac/css/responsive.css
index 89d3212257f9b6cbcf3266891a69766afed1f640..05e716531cd18b493386716c6df92d9b82a345b3 100644
--- a/public/opac/css/responsive.css
+++ b/public/opac/css/responsive.css
@@ -1,76 +1,75 @@
 @media screen and (max-device-width: 1024px) {
-
     body * {
-	box-sizing: border-box;
-	white-space: normal !important;
+        box-sizing: border-box;
+        white-space: normal !important;
     }
 
 
     /** FORCED RULES **/
     iframe, 
     .ui-dialog {
-	width: 100% !important;
+        width: 100% !important;
     }
 
 
     .liste_vignettes dl * {
-	width: 100% !important;
-	clear: both;
-	padding: 0px !important;
-	margin: 0px !important;
-	float: left !important;
-	text-align: left !important;
+        width: 100% !important;
+        clear: both;
+        padding: 0px !important;
+        margin: 0px !important;
+        float: left !important;
+        text-align: left !important;
     }
 
     
     #my_vid {
-	width: 100% !important;
-	height: auto !important;
+        width: 100% !important;
+        height: auto !important;
     }
 
 
     #site_web_content {
-	width: 90% !important;
-	max-width: 90% !important;
-	min-width: 90% !important;
-	margin: 5% !important;
+        width: 90% !important;
+        max-width: 90% !important;
+        min-width: 90% !important;
+        margin: 5% !important;
     }
 
 
     #banniere,
     #header {
-	height: auto !important;
-	width: 100% !important;
+        height: auto !important;
+        width: 100% !important;
     }
 
     
     #menu_horizontal ,
     #header ,
     #header > * {
-	overflow: visible !important;
-	width: 100% !important;
+        overflow: visible !important;
+        width: 100% !important;
     }
 
 
     #header > * {
-	position: inherit !important;
+        position: inherit !important;
     }
 
 
     #menu_horizontal,
     #header div[class*="menu"] {
-	position: relative !important;
+        position: relative !important;
     }
 
 
     div[class*="menu"].show_menu > ul ul,
     div[class*="menu"].show_menu > ul li {
-	min-width: 0 !important;
+        min-width: 0 !important;
     }
 
 
     div[class*="menu"] li img {
-	display: none !important;
+        display: none !important;
     }
 
 
@@ -78,22 +77,22 @@
     div[class*="menu"]:not(.show_menu) > ul > li ,
     div[class*="menu"]:not(.show_menu) > ul > li > ul ,
     div[class*="menu"]:not(.show_menu) > ul > li > ul > li {
-	position: absolute !important;
-	top: 0 !important;
-	left: 0 !important;
-	margin: 0 !important;
-	padding: 0 !important;
+        position: absolute !important;
+        top: 0 !important;
+        left: 0 !important;
+        margin: 0 !important;
+        padding: 0 !important;
     }
 
 
     div[class*="menu"].show_menu > ul li {
-	margin: auto !important
+        margin: auto !important
     }
 
 
     div[class*="menu"] > ul > li {
-	display: block !important;
-	height: auto !important;
+        display: block !important;
+        height: auto !important;
     }
 
 
@@ -102,32 +101,32 @@
     #menu_horizontal,
     #header div[class*="menu"] ,
     div[class*="menu"] * {
-	display: block !important;
-	left: auto !important;
-	top: auto !important;
-	right: auto !important;
-	min-height: none !important;
+        display: block !important;
+        left: auto !important;
+        top: auto !important;
+        right: auto !important;
+        min-height: none !important;
     }
 
 
     #col_wrapper {
-	width: 100% !important;
-	max-width: 100% !important;
-	min-width: 100% !important;
+        width: 100% !important;
+        max-width: 100% !important;
+        min-width: 100% !important;
     }
 
 
     #col_wrapper > *  {
-	margin: 1% 0 !important;
-	width: 100% !important;
+        margin: 1% 0 !important;
+        width: 100% !important;
     }
 
 
     .footer,
     .layout-division,
     div[id^="col"][id*="Inner"] {
-	padding: 0 !important;
-	margin: 0 !important;
+        padding: 0 !important;
+        margin: 0 !important;
     }
 
 
@@ -139,25 +138,39 @@
     #site_web_wrapper,
     .layout-division ,
     #col_wrapper .boite > * {
-	width: 100% !important;
-	max-width: 100% !important;
-	min-width: 100% !important;
+        width: 100% !important;
+        max-width: 100% !important;
+        min-width: 100% !important;
     }
 
 
     #colGaucheInner, 
     #colDroiteInner, 
     #colMilieuInner {
-	min-height: auto !important;
+        min-height: auto !important;
     }
 
 
     /** DEFAULT RULES **/
+
+    #suggestion input[type="password"],
+    #suggestion input[type="text"],
+    #suggestion input[type="url"],
+    #suggestion textarea {
+        width: 100%;
+    }
+
     .siteWeb div#col_wrapper,
     #abonne_edit, 
     #abonne_edit > *, 
     #abonne_edit fieldset, 
     #abonne_edit fieldset td,
+
+    #suggestion,
+    #suggestion > *, 
+    #suggestion fieldset, 
+    #suggestion fieldset td,
+
     .filtre_recherche,
     .filtre_recherche > *,
     #colMilieuInner .contenuInner ,    
@@ -180,22 +193,28 @@
     .titre ,
     .col_gauche,
     .col_droite {
-	float: left;
-	max-height: auto;
-	min-height: 0;
-	top: auto;
-	left: auto;
-	right: auto;
-	bottom: auto;
-	overflow: hidden;
+        float: left;
+        max-height: auto;
+        min-height: 0;
+        top: auto;
+        left: auto;
+        right: auto;
+        bottom: auto;
+        overflow: hidden;
     }
 
 
     #site_web_content > *,
     .siteWeb div#col_wrapper,
-    #abonne_edit > *, 
+
+    #abonne_edit > *,
     #abonne_edit fieldset, 
     #abonne_edit fieldset td,
+
+    #suggestion > *,
+    #suggestion fieldset, 
+    #suggestion fieldset td,
+
     .resultat_recherche,
     .siteWeb,
     .footer,
@@ -211,174 +230,176 @@
     .resultat_recherche > div,
     .filtre_recherche,
     #col_wrapper .boite.conteneur_deux_colonnes {
-	width: 100%;
-	max-width: 100%;
-	min-width: 100%;
-	clear: both;
+        width: 100%;
+        max-width: 100%;
+        min-width: 100%;
+        clear: both;
     }
 
 
     #colMilieuInner .contenuInner ,    
     #col_wrapper .col_gauche .boite,
     #col_wrapper .col_droite .boite {
-	width: 98%;
-	max-width: 98%;
-	min-width: 98%;
+        width: 98%;
+        max-width: 98%;
+        min-width: 98%;
     }
 
 
 
-    #abonne_edit > *, 
+    #abonne_edit > *,
+    #suggestion > *, 
     .filtre_recherche > *,
     .resultat_recherche .notice_wrapper,
     #col_wrapper .boite,
     #col_wrapper .col_gauche,
     #col_wrapper .col_droite {
-	width: 49%;
-	max-width: 49%;
-	min-width: 49%;
-	clear: none;
+        width: 49%;
+        max-width: 49%;
+        min-width: 49%;
+        clear: none;
     }
 
 
-    #abonne_edit > *:nth-of-type(even), 
+    #abonne_edit > *:nth-of-type(even),
     .filtre_recherche > *:nth-of-type(even),
     .resultat_recherche .notice_wrapper:nth-of-type(even),
     #col_wrapper .boite:nth-of-type(even),
     .col_droite {
-	float: right;
-	clear: right;
+        float: right;
+        clear: right;
     }
 
 
-    #abonne_edit > *:nth-of-type(odd), 
+    #abonne_edit > *:nth-of-type(odd),
+    #suggestion > *:nth-of-type(odd), 
     .filtre_recherche > *:nth-of-type(odd),
     .resultat_recherche .notice_wrapper:nth-of-type(odd),
     #col_wrapper .boite:nth-of-type(odd) {
-	clear: left;
+        clear: left;
     }
 
 
     .colFlottant.layout-division {
-	display: none;
+        display: none;
     }
 
 
     #header > * ,
     #site_web_content > * {
-	float: left;
+        float: left;
     }
 
 
     .back_to_phone {
-	right: 0;
-	width: auto;
-	padding: 5px;
-	z-index: 1;
+        right: 0;
+        width: auto;
+        padding: 5px;
+        z-index: 1;
     }
 
 
     .titre {
-	height: auto;
-	max-height: none;
-	min-height: none;
+        height: auto;
+        max-height: none;
+        min-height: none;
     }
 
 
     .calendar .month_list > *{
-	display:inline-block;
+        display:inline-block;
     }
 
 
     .recherche_avancee #site_web_wrapper form.recherche_avancee select[name*="operateur"] {
-	width: 50px !important;
-	margin-top: 10px;
+        width: 50px !important;
+        margin-top: 10px;
     }
 
 
     .recherche_simple .boiteMilieu,
     .recherche_viewnotice #col_wrapper #colMilieuInner .contenuInner > * {
-	width: 100%;
-	float: left;
-	clear: both;
+        width: 100%;
+        float: left;
+        clear: both;
     }
 
 
     div.onglets_titre h2{
-	white-space: nowrap;
+        white-space: nowrap;
     }
 
 
     .onglets_titre > div > div {
-	float: left;
-	clear: both;
-	width: 100% !important;
+        float: left;
+        clear: both;
+        width: 100% !important;
     }
 
 
     table.exemplaires {
-	width: 100%;
-	display: table;
-	overflow: hidden;
-	float: left;
+        width: 100%;
+        display: table;
+        overflow: hidden;
+        float: left;
     }
 
 
     .nothumbnail {
-	overflow: hidden;
+        overflow: hidden;
     }
 
 
     table.photo_onglet {
-	width: 100%;
+        width: 100%;
     }
 
 
     table.photo_onglet * {
-	display: inline-block;
-	float: left;
-	width: 100%;
+        display: inline-block;
+        float: left;
+        width: 100%;
     }
 
 
     table.photo_onglet td.photo_onglet {
-	width: 50%;
+        width: 50%;
     }
 
 
     div[id*="set"] {
-	float: left;
-	width: 100%;
+        float: left;
+        width: 100%;
     }
 
 
     .liste_vignettes dl > * {
-	line-height: 1.5em;
+        line-height: 1.5em;
     }
 
     .liste_vignettes dl dt {
-	font-weight: 800;
+        font-weight: 800;
     }
 
 
     table.soustitre th:first-child, 
     table.panier_notices td:first-child {
-	width: auto;
+        width: auto;
     }
     
 
     /** MENU **/
     div:not(.show_menu)[class*="menu"],
     #menu_horizontal {
-	background: none;
-	height: auto;
-	padding: 0;
-	margin: 0;
+        background: none;
+        height: auto;
+        padding: 0;
+        margin: 0;
     }
 
     
     div[class*="menu"] * {
-	transition: none;
+        transition: none;
     }
 
 
@@ -387,15 +408,15 @@
 
 
     div[class*="menu"] > ul > li > a {
-	text-transform: uppercase;
+        text-transform: uppercase;
     }
 
 
     div[class*="menu"] > ul {
-	display: block;
-	position: absolute;
-	height: 0;
-	visibility: hidden;
+        display: block;
+        position: absolute;
+        height: 0;
+        visibility: hidden;
     }
 
 
@@ -403,30 +424,30 @@
     div[class*="menu"].show_menu > ul li,
     #menu_horizontal.show_menu > ul ul,
     #menu_horizontal.show_menu > ul li {
-	display: block;
-	position: relative;
-	min-width: auto;
-	width: auto;
-	float: left;
-	clear: both;
-	text-align: left;
-	left: 0;
-	top: 0;
-	border: none;
+        display: block;
+        position: relative;
+        min-width: auto;
+        width: auto;
+        float: left;
+        clear: both;
+        text-align: left;
+        left: 0;
+        top: 0;
+        border: none;
     }
 
 
     #menu_horizontal.show_menu > ul > li,
     div[class*="menu"].show_menu > ul > li {
-	float: left;
-	width: 100%;
-	border-bottom: 1px solid #efefef;
+        float: left;
+        width: 100%;
+        border-bottom: 1px solid #efefef;
     }
 
 
     #menu_horizontal.show_menu > ul > li:last-of-type,
     div[class*="menu"].show_menu > ul > li:last-of-type {
-	border: none;
+        border: none;
     }
 
 
@@ -438,7 +459,7 @@
     #menu_horizontal > ul li,
     #menu_horizontal > ul li a ,
     #menu_horizontal > ul li ul li a {
-	color: #efefef;
+        color: #efefef;
     }
 
 
@@ -448,18 +469,18 @@
     #menu_horizontal.show_menu > ul ul,
     #menu_horizontal.show_menu > ul li,
     #menu_horizontal.show_menu > ul li a {
-	background: none;	
-	height: auto;
+        background: none;   
+        height: auto;
     }
 
     
     div[class*="menu"].show_menu > ul li {
-	line-height: 2em;
+        line-height: 2em;
     }
 
 
     #menu_horizontal ul li ul {
-	border: none;
+        border: none;
     }
 
     
@@ -470,68 +491,68 @@
     div:not(.show_menu)[class*="menu"] li.selected_profil > a[href*="/"],
     #menu_horizontal:not(.show_menu) li.selected_profil > a[href*="/"] ,
     div:not(.boite)[class*="menu"]:after {
-	background-color: #333;
+        background-color: #333;
     }
 
 
     div[class*="menu"].show_menu > ul,
     #menu_horizontal.show_menu > ul{
-	visibility: visible;
-	width: auto;
-	height: auto;
-	font-size: 1em;
-	padding: 0 2%;
-	margin: 3em 0 0 0;
-	left: 0;
-	z-index: 101;
+        visibility: visible;
+        width: auto;
+        height: auto;
+        font-size: 1em;
+        padding: 0 2%;
+        margin: 3em 0 0 0;
+        left: 0;
+        z-index: 101;
     }
 
 
     div[class*="menu"] li.selected_profil > a[href*="/"]:only-child {
-	visibility: visible;
+        visibility: visible;
     }
 
 
     div:not(.show_menu)[class*="menu"] li.selected_profil > a[href*="/"]:only-child,
     #menu_horizontal:not(.show_menu) li.selected_profil > a[href*="/"]:only-child{
-	float: left;
-	line-height: 3em;
-	margin: 0 0 0 3em;
-	padding: 0 0.5em;
+        float: left;
+        line-height: 3em;
+        margin: 0 0 0 3em;
+        padding: 0 0.5em;
     }
 
 
     div[class*="menu"].show_menu li.selected_profil > a[href*="/"]:only-child,
     #menu_horizontal.show_menu li.selected_profil > a[href*="/"]:only-child {
-	border-left: 5px solid #00C000;
-	margin-left: -10px;
-	padding-left: 5px;
+        border-left: 5px solid #00C000;
+        margin-left: -10px;
+        padding-left: 5px;
     }
 
 
     div:not(.boite)[class*="menu"]:after {
-	content: '';
-	height: 3em;
-	width: 3em;
-	background: #333 url(../images/buttons/menu.png) no-repeat center center / 2em;
-	background-size: 32px 32px;
-	float: left;
-	cursor: pointer;
+        content: '';
+        height: 3em;
+        width: 3em;
+        background: #333 url(../images/buttons/menu.png) no-repeat center center / 2em;
+        background-size: 32px 32px;
+        float: left;
+        cursor: pointer;
     }
 
 
     div:not(.boite)[class*="menu"].show_menu:after {
-	background: #333 url(../images/buttons/close_menu.png) no-repeat center center / 2em;
+        background: #333 url(../images/buttons/close_menu.png) no-repeat center center / 2em;
     }
 
 
     #menu_horizontal a {
-    	background: none;
+        background: none;
     }
 
 
     #open_accessibility {
-	z-index: 1;
+        z-index: 1;
     }
 
     
@@ -539,7 +560,7 @@
 
     #colMilieuInner .contenuInner,
     #col_wrapper .boite {
-	margin: 0;
+        margin: 0;
     }
 
 
@@ -550,62 +571,62 @@
     .recherche_avancee #site_web_wrapper form.recherche_avancee td,
     .recherche_avancee #site_web_wrapper form.recherche_avancee select,
     .recherche_avancee #site_web_wrapper form.recherche_avancee input {
-	width: 100% !important;
-	clear: both;
-	float: left;
+        width: 100% !important;
+        clear: both;
+        float: left;
     }
 
 
     /** SEARCH RESULT **/
 
     .facette_outer {
-	margin: 10px 0 !important;
-	padding: 10px 0 !important;
+        margin: 10px 0 !important;
+        padding: 10px 0 !important;
     }
 
 
     /** RECORD **/
     
     table.exemplaires tr {
-	font-size: 1em;
-	line-height: 1.5em;
-	height: auto;
-	max-width: none !important;
-	min-width: 0 !important;
-	min-height: 2.5em;
-	white-space: normal !important;
-	text-align: left !important;
-	width: 25% !important;
-	display: inline-block !important;
-	margin-bottom: 10px !important;
-	padding-bottom: 10px !important;
-	border-bottom: 1px solid #333 !important;
+        font-size: 1em;
+        line-height: 1.5em;
+        height: auto;
+        max-width: none !important;
+        min-width: 0 !important;
+        min-height: 2.5em;
+        white-space: normal !important;
+        text-align: left !important;
+        width: 25% !important;
+        display: inline-block !important;
+        margin-bottom: 10px !important;
+        padding-bottom: 10px !important;
+        border-bottom: 1px solid #333 !important;
     }
 
 
     table.exemplaires tr:odd {
-	clear: left;
+        clear: left;
     }
 
 
     table.exemplaires tr > * {
-	display: block;
-	width: 100% !important;
-	max-width: none !important;
-	padding: 0 1%;
-	margin: 1% 0;
-	min-width: 0 !important;
-	white-space: nowrap !important;
-	overflow: hidden;
-	font-size: 1em;
-	text-align: left !important;
-	line-height: 1.5em;
-	height: 1.5em;	
+        display: block;
+        width: 100% !important;
+        max-width: none !important;
+        padding: 0 1%;
+        margin: 1% 0;
+        min-width: 0 !important;
+        white-space: nowrap !important;
+        overflow: hidden;
+        font-size: 1em;
+        text-align: left !important;
+        line-height: 1.5em;
+        height: 1.5em;  
     }
 
 
     table.exemplaires tr > th {
-	text-align: right !important;
+        text-align: right !important;
     }
 
 
@@ -615,69 +636,69 @@
 
 
     #dialog_reserver {
-	padding: 0 !important;
+        padding: 0 !important;
     }
 
 
     .recherche_viewnotice .boiteMilieu .blocs_notice .notice_bloc {
-	max-width: 100% !important;
+        max-width: 100% !important;
     }
 
 
     .recherche_viewnotice .boiteMilieu .contenuInner > * ,
     .recherche_viewnotice .boiteMilieu .blocs_notice > * {
-	float: left;
-	clear: both;
-	width: 100%;
-	min-width: 100%;
-	max-width: 100;
-	margin: 0 auto;
-	padding: 0;
-	position: inherit;
-	top: auto;
-	left: auto;
-	right: auto;
-	bottom: auto;
+        float: left;
+        clear: both;
+        width: 100%;
+        min-width: 100%;
+        max-width: 100;
+        margin: 0 auto;
+        padding: 0;
+        position: inherit;
+        top: auto;
+        left: auto;
+        right: auto;
+        bottom: auto;
     } 
 
 
     /** LEFT COL COLLAPSED **/
 
     #col_wrapper .colGauche .boite {
-	width: 49% !important;
-	min-width: 0 !important;
-	max-width: auto !important;
+        width: 49% !important;
+        min-width: 0 !important;
+        max-width: auto !important;
     }
 
 
     .facette_outer > div,
     #col_wrapper .colGauche .boite .contenu {
-	display: none !important;
+        display: none !important;
     }
 
 
     .facette_outer:before,
     #col_wrapper .colGauche .boite:before {
-	content: '';
-	display: block;
-	height: 2em;
-	width: 40px;
-	float: right;
-    	background-image: url(../images/buttons/down-chevron.png);
-    	background-position: center center;
-    	background-repeat: no-repeat;
+        content: '';
+        display: block;
+        height: 2em;
+        width: 40px;
+        float: right;
+        background-image: url(../images/buttons/down-chevron.png);
+        background-position: center center;
+        background-repeat: no-repeat;
     }
 
 
     .facette_outer.show_content:before,
     #col_wrapper .colGauche .show_content:before {
-    	background-image: url(../images/buttons/up-chevron.png);
+        background-image: url(../images/buttons/up-chevron.png);
     }
 
     
     .facette_outer.show_content > div ,
     #col_wrapper .colGauche .show_content .contenu {
-	display: block !important;
+        display: block !important;
     }
 }
 
@@ -686,12 +707,12 @@
 @media screen and (max-device-width: 580px) {
 
     #col_wrapper .colGauche .boite {
-	width: 100% !important;
+        width: 100% !important;
     }
 
 
     table.exemplaires tr {
-	width: 50% !important;
+        width: 50% !important;
     }
     
 
@@ -699,6 +720,10 @@
     #abonne_edit > *, 
     #abonne_edit fieldset, 
     #abonne_edit fieldset td,
+    #suggestion, 
+    #suggestion > *, 
+    #suggestion fieldset, 
+    #suggestion fieldset td,
     .filtre_recherche,
     .filtre_recherche > *,
     .resultat_recherche,
@@ -718,8 +743,8 @@
     #col_wrapper .col_gauche,
     #col_wrapper .col_droite ,
     #col_wrapper .boite {
-	width: 100%;
-	max-width: 100%;
-	min-width: 100%;
+        width: 100%;
+        max-width: 100%;
+        min-width: 100%;
     }
 }
\ No newline at end of file
diff --git a/tests/application/modules/opac/controllers/AbonneControllerSuggestionAchatTest.php b/tests/application/modules/opac/controllers/AbonneControllerSuggestionAchatTest.php
index 0ce15a72d9552f7ca53f525f4d4cd8616377e336..5c89eb7d15cf87d5eb72b21086e59b97d2132077 100644
--- a/tests/application/modules/opac/controllers/AbonneControllerSuggestionAchatTest.php
+++ b/tests/application/modules/opac/controllers/AbonneControllerSuggestionAchatTest.php
@@ -18,22 +18,34 @@
  * along with BOKEH; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
-require_once 'AbstractControllerTestCase.php';
 
 class AbonneControllerSuggestionAchatAddFormTest extends AbstractControllerTestCase {
+  protected $_storm_default_to_volatile = true;
+
   public function setUp() {
     parent::setUp();
-
+    Class_CosmoVar::newInstanceWithId('types_docs', ['liste' => '']);
     $this->fixture('Class_TypeDoc', ['id' => 6 ,
-    'label' => 'Blueray',
-    'famille_id' => Class_CodifTypeDoc::VIDEO]);
+                                     'label' => 'Blueray',
+                                     'famille_id' => Class_CodifTypeDoc::VIDEO]);
 
     $this->fixture('Class_Bib', ['id' => 11,
-    'libelle' => 'Bib de la plage']);
+                                 'libelle' => 'Bib de la plage']);
+
+
+    Class_Profil::getCurrentProfil()
+      ->setCfgModules(['abonne' => ['suggestion-achat-add' => ['help-text' => 'Entrez votre suggestion']]]);
+
 
     $this->dispatch('/opac/abonne/suggestion-achat-add', true);
   }
 
+
+  /** @test */
+  public function pageShouldContainsDivHelpTextWithEntrezVotreSuggestion() {
+    $this->assertXPathContentContains('//div[@class="help-text"]', 'Entrez votre suggestion');
+  }
+
   /** @test */
   public function pageTitleShouldBeSuggestionAchat() {
     $this->assertXPathContentContains('//title', 'Suggérer un achat');
@@ -105,29 +117,31 @@ class AbonneControllerSuggestionAchatAddFormTest extends AbstractControllerTestC
 }
 
 
+
+
+
 class AbonneControllerSuggestionAchatAddFormMultipleBibsTest extends AbstractControllerTestCase {
   public function setUp() {
     parent::setUp();
 
     $this->fixture('Class_Bib', ['id' => 11,
-    'libelle' => 'Bib de la plage']);
+                                 'libelle' => 'Bib de la plage']);
     $this->fixture('Class_Bib', ['id' => 12,
-    'libelle' => 'Bib de la plage 2']);
+                                 'libelle' => 'Bib de la plage 2']);
 
-    $this->fixture('Class_Users', [
-      'id' => 3,
-      'login' => 'test',
-      'password' => 'test',
-      'id_site' => 12,
-    ]);
+    $user = $this->fixture('Class_Users', [
+                                           'id' => 3,
+                                           'login' => 'test',
+                                           'password' => 'test',
+                                           'id_site' => 12,
+                                           ]);
 
-    $identity = new StdClass();
-    $identity->ID_USER = 3;
-    ZendAfi_Auth::getInstance()->getStorage()->write($identity);
+    ZendAfi_Auth::getInstance()->logUser($user);
 
     $this->dispatch('/opac/abonne/suggestion-achat-add', true);
   }
 
+
   /** @test */
   public function formShouldContainsSelectForLibrary() {
     $this->assertXPath('//form//select[@name="bib_id"]');
@@ -135,7 +149,7 @@ class AbonneControllerSuggestionAchatAddFormMultipleBibsTest extends AbstractCon
 
 
   /** @test */
-  public function LibrarySelectShouldContainBibDeLaPlage() {
+  public function librarySelectShouldContainBibDeLaPlage() {
     $this->assertXPath('//form//select[@name="bib_id"]//option[@value="11"][@label="Bib de la plage"]/following-sibling::option[@value="12"][@label="Bib de la plage 2"]');
   }
 
@@ -147,9 +161,234 @@ class AbonneControllerSuggestionAchatAddFormMultipleBibsTest extends AbstractCon
 }
 
 
+
+
+class AbonneControllerSuggestionAchatAddFormMultipleBibsAndKohaNotRestfulTest extends AbstractControllerTestCase {
+  public function setUp() {
+    parent::setUp();
+    $sigb_plage = $this->fixture('Class_IntBib',
+                                 [
+                                  'id' => 3,
+                                  'comm_params' => ['url_serveur' => 'http://plage.com/cgi-bin/koha/ilsdi.pl',
+                                                    'restful' => '0'],
+                                  'comm_sigb' => Class_IntBib::COM_KOHA
+                                 ]);
+
+    $this->fixture('Class_Bib', ['id' => 12,
+                                 'libelle' => 'Bib de la plage 2',
+                                 'int_bib' => $sigb_plage]);
+
+    $user = $this->fixture('Class_Users', [
+                                           'id' => 3,
+                                           'login' => 'test',
+                                           'password' => 'test',
+                                           'id_site' => 12,
+                                           'int_bib' => $sigb_plage,
+                                           ]);
+
+    ZendAfi_Auth::getInstance()->logUser($user);
+
+    $this->dispatch('/opac/abonne/suggestion-achat-add', true);
+  }
+
+
+  /** @test */
+  public function formShouldContainsTextAreaForCommentaire() {
+    $this->assertXPath('//form//textarea[@name="commentaire"]');
+  }
+
+
+  /** @test */
+  public function pageShouldNotContainsDivHelpText() {
+    $this->assertNotXPath('//div[@class="help-text"]');
+  }
+
+}
+
+
+
+
+abstract class AbonneControllerSuggestionAchatAddFormMultipleBibsAndKohaTestCase extends AbstractControllerTestCase {
+  protected
+    $_storm_default_to_volatile = true;
+
+  public function setUp() {
+    parent::setUp();
+
+
+    $sigb_plage = $this->fixture('Class_IntBib',
+                                 [
+                                  'id' => 3,
+                                  'comm_params' => ['url_serveur' => 'http://plage.com/cgi-bin/koha/ilsdi.pl',
+                                                    'restful' => '1'],
+                                  'comm_sigb' => Class_IntBib::COM_KOHA
+                                 ]);
+
+    $this->fixture('Class_Bib', ['id' => 11,
+                                 'libelle' => 'Bib de la plage',
+                                 'int_bib' => $sigb_plage]);
+
+    $this->fixture('Class_Bib', ['id' => 12,
+                                 'libelle' => 'Bib de la plage 2',
+                                 'int_bib' => $sigb_plage]);
+
+    $this->fixture('Class_Bib', ['id' => 14,
+                                 'libelle' => 'Bib de la montagne']);
+
+    $user = $this->fixture('Class_Users', [
+                                           'id' => 3,
+                                           'login' => 'test',
+                                           'password' => 'test',
+                                           'id_site' => 12,
+                                           'id_sigb' => 'azerty',
+                                           'int_bib' => $sigb_plage,
+                                           ]);
+
+    ZendAfi_Auth::getInstance()->logUser($user);
+
+    $this->mock_web_client = $this->mock();
+    $sigb_comm = Class_IntBib::find(3)->getSIGBComm();
+    $sigb_comm->setWebClient($this->mock_web_client);
+
+  }
+
+
+
+  public function tearDown() {
+    Class_IntBib::find(3)->getSIGBComm()->setWebClient(null);
+    parent::tearDown();
+  }
+
+}
+
+
+
+
+class AbonneControllerSuggestionAchatAddFormMultipleBibsAndKohaRestfulTest extends AbonneControllerSuggestionAchatAddFormMultipleBibsAndKohaTestCase {
+  public function setUp() {
+    parent::setup();
+
+    $this->dispatch('/opac/abonne/suggestion-achat-add', true);
+  }
+
+
+
+  /** @test */
+  public function formShouldContainsTextAreaForPatronReason() {
+    $this->assertXPath('//form//textarea[@name="PatronReason"]');
+  }
+
+
+  /** @test */
+  public function formShouldContainsInputForTitle() {
+    $this->assertXPath('//form//input[@name="Title"][@placeholder="ex: Harry Potter à l\'école des sorciers"]');
+  }
+
+
+  /** @test */
+  public function formShouldContainsInputForAuthor() {
+    $this->assertXPath('//form//input[@name="Author"][@placeholder="ex: Joanne Kathleen Rowling"]');
+  }
+
+
+  /** @test */
+  public function formShouldContainsInputForIsbn() {
+    $this->assertXPath('//form//input[@name="Isbn"][@placeholder="ex: 2-07-054127-4"]');
+  }
+
+
+  /** @test */
+  public function formShouldContainsInputForPublicationYear() {
+    $this->assertXPath('//form//input[@name="PublicationYear"][@placeholder="2015"]');
+  }
+}
+
+
+
+
+class AbonneControllerSuggestionAchatAddFormMultipleBibsAndKohaRestfulPostTest extends AbonneControllerSuggestionAchatAddFormMultipleBibsAndKohaTestCase {
+  public function setUp() {
+    parent::setUp();
+    $this->mock_web_client
+      ->whenCalled('open_url')
+      ->with('http://plage.com/cgi-bin/koha/ilsdi.pl?service=LookupPatron&id=azerty&id_type=cardnumber')
+      ->answers('<xml><id>234</id></xml>');
+
+
+    $this->postDispatch('/opac/abonne/suggestion-achat-add',
+                        ['Title' => 'Harry Potter',
+                         'Author' => 'J.K.Rowling',
+                         'Isbn' => '2-07-0541 27_4',
+                         'PatronReason' => 'Je veux le lire',
+                         'PublicationYear' => '2014',
+                         'submit' => 'Envoyer']);
+  }
+
+  /** @test */
+  public function dataShouldHaveBeenPosted() {
+    $this->assertTrue($this->mock_web_client->methodHasBeenCalled('postData'));
+  }
+
+
+  /** @test */
+  public function dataShouldBeJsonEncoded() {
+    $datas = json_decode($this->mock_web_client->getAttributesForLastCallOn('postData')[1]['data'],
+                         true);
+    $this->assertEquals(['title' => 'Harry Potter',
+                         'author' => 'J.K.Rowling',
+                         'isbn' => '2-07-0541 27_4',
+                         'patronreason' => 'Je veux le lire',
+                         'publicationyear' => '2014',
+                         'suggestedby' => '234'],
+                        $datas);
+  }
+}
+
+
+
+
+class AbonneControllerSuggestionAchatAddFormMultipleBibsAndKohaRestfulPostWrongDataTest extends AbonneControllerSuggestionAchatAddFormMultipleBibsAndKohaTestCase {
+  public function setUp() {
+    parent::setUp();
+
+    $this->postDispatch('/opac/abonne/suggestion-achat-add',
+                        ['Title' => '',
+                         'Author' => '',
+                         'Isbn' => '',
+                         'PatronReason' => '',
+                         'PublicationYear' => 'toto',
+                         'submit' => 'Envoyer']);
+  }
+
+
+  /** @test */
+  public function inputTitleShouldHaveErrorRequiredValue() {
+    $this->assertXPathContentContains('//input[@id="Title"]/following-sibling::ul/li',
+                                      'Une valeur est requise');
+  }
+
+
+  /** @test */
+  public function inputAuthorShouldHaveErrorRequiredValue() {
+    $this->assertXPathContentContains('//input[@id="Author"]/following-sibling::ul/li',
+                                      'Une valeur est requise');
+  }
+
+
+  /** @test */
+  public function inputPublicationYearShouldHaveErrorBeInt() {
+    $this->assertXPathContentContains('//input[@id="PublicationYear"]/following-sibling::ul/li',
+                                      "'toto' n'est pas un nombre entier");
+  }
+}
+
+
+
 abstract class AbonneControllerSuggestionAchatAddPostTestCase extends AbstractControllerTestCase {
-  protected $_suggestion;
-  protected $_mail;
+  protected
+    $_suggestion,
+    $_storm_default_to_volatile = true,
+    $_mail;
 
   protected function _loginHook($account) {
     $account->username     = 'Arnaud';
@@ -159,14 +398,15 @@ abstract class AbonneControllerSuggestionAchatAddPostTestCase extends AbstractCo
 
   public function setUp() {
     parent::setUp();
+    Class_CosmoVar::newInstanceWithId('types_docs', ['liste' => '']);
     $codif_type_doc=$this->fixture('Class_CodifTypeDoc', ['id' => 102,
-                                          'famille_id' => Class_CodifTypeDoc::LIVRE,
-                                          'bibliotheques' => '2;3',
-                                          'annexes' => '4;8',
-                                          'sections' => '9;10']);
+                                                          'famille_id' => Class_CodifTypeDoc::LIVRE,
+                                                          'bibliotheques' => '2;3',
+                                                          'annexes' => '4;8',
+                                                          'sections' => '9;10']);
 
-    $this->fixture('Class_TypeDoc', ['id'=>Class_TypeDoc::LIVRE,
-                                      'codif_type_doc' =>  $codif_type_doc,
+    $this->fixture('Class_TypeDoc', ['id' => Class_TypeDoc::LIVRE,
+                                     'codif_type_doc' =>  $codif_type_doc,
                                      'label'=> 'Livres Numériques']);
 
     Storm_Test_ObjectWrapper::onLoaderOfModel('Class_SuggestionAchat')
@@ -179,8 +419,9 @@ abstract class AbonneControllerSuggestionAchatAddPostTestCase extends AbstractCo
 }
 
 
-class AbonneControllerSuggestionAchatAddPostValidDataTest extends AbonneControllerSuggestionAchatAddPostTestCase {
 
+
+class AbonneControllerSuggestionAchatAddPostValidDataTest extends AbonneControllerSuggestionAchatAddPostTestCase {
   public function setUp() {
     parent::setUp();
 
@@ -262,7 +503,7 @@ class AbonneControllerSuggestionAchatAddPostValidDataTest extends AbonneControll
 
   /** @test */
   public function responseShouldRedirectToSuggestionAchatId66() {
-    $this->assertRedirectTo('/opac/abonne/suggestion-achat-add/id/66');
+    $this->assertRedirectTo('/opac/abonne/suggestion-achat');
   }
 
 
@@ -285,10 +526,9 @@ class AbonneControllerSuggestionAchatAddPostValidDataTest extends AbonneControll
 
 
   /** @test */
-  public function notificationShouldBeEmpty() {
-    $this->assertFalse(isset($_SESSION['FlashMessenger']));
+  public function saveShouldBeNotified() {
+    $this->assertFlashMessengerContentContains('Suggestion d\'achat enregistrée');
   }
-
 }
 
 
@@ -330,6 +570,7 @@ class AbonneControllerSuggestionAchatAddPostWithMailSuggestions extends AbonneCo
 
 
 class AbonneControllerSuggestionAchatAddPostValidDataButNoMailSentTest extends AbstractControllerTestCase {
+  protected $_storm_default_to_volatile = true;
   protected $_suggestion;
   protected $_mail;
 
@@ -337,8 +578,6 @@ class AbonneControllerSuggestionAchatAddPostValidDataButNoMailSentTest extends A
   public function setUp() {
     parent::setUp();
 
-    Class_SuggestionAchat::BeVolatile();
-
     Class_Users::getIdentity()->setMail('');
     Class_Profil::getPortail()->setMailSite('');
     Class_Profil::getCurrentProfil()->setMailSite('');
@@ -373,10 +612,13 @@ class AbonneControllerSuggestionAchatAddPostValidDataButNoMailSentTest extends A
 
 
 class AbonneControllerSuggestionAchatAddPostWrongDataTest extends AbstractControllerTestCase {
+  protected $_storm_default_to_volatile = true;
+
   public function setUp() {
     parent::setUp();
 
-    Class_Profil::getCurrentProfil()->setCfgModules(['index' => ['formulairecontact' => ['bib_selector' => 1]]]);
+    Class_Profil::getCurrentProfil()
+      ->setCfgModules(['index' => ['formulairecontact' => ['bib_selector' => 1]]]);
 
     $this->fixture('Class_Bib',
                    ['id' => 2,
@@ -423,6 +665,8 @@ class AbonneControllerSuggestionAchatAddPostWrongDataTest extends AbstractContro
 
 
 class AbonneControllerSuggestionAchatAddDataWithEmptyFieldsNotRequiredTest extends AbstractControllerTestCase {
+  protected $_storm_default_to_volatile = true;
+
   public function setUp() {
     parent::setUp();
 
@@ -474,6 +718,8 @@ class AbonneControllerSuggestionAchatAddWithIdTest extends AbstractControllerTes
 
 
 class AbonneControllerSuggestionAchatWithOutSuggestionTest extends AbstractControllerTestCase {
+  protected $_storm_default_to_volatile = true;
+
   public function setUp() {
     parent::setUp();
 
@@ -497,23 +743,25 @@ class AbonneControllerSuggestionAchatWithOutSuggestionTest extends AbstractContr
 
 
 class AbonneControllerSuggestionAchatWithOneSuggestionTest extends AbstractControllerTestCase {
+  protected $_storm_default_to_volatile = true;
+
   public function setUp() {
     parent::setUp();
 
     $user = $this->fixture('Class_Users',
-    ['id' => 1,
-    'login' => 'Tom',
-    'password' => 'pwd']);
+                           ['id' => 1,
+                            'login' => 'Tom',
+                            'password' => 'pwd']);
 
     ZendAfi_Auth::getInstance()->logUser($user);
 
 
     $suggestion = $this->fixture('Class_SuggestionAchat',
-    ['id' => 1,
-    'commentaire' => 'New edition is available.',
-    'description_url' => '',
-    'isbn' => '',
-    'type_doc_id' => Class_CodifTypeDoc::VIDEO]);
+                                 ['id' => 1,
+                                  'commentaire' => 'New edition is available.',
+                                  'description_url' => '',
+                                  'isbn' => '',
+                                  'type_doc_id' => Class_CodifTypeDoc::VIDEO]);
 
     $user->setSuggestionAchat([$suggestion])->save();
 
@@ -523,13 +771,246 @@ class AbonneControllerSuggestionAchatWithOneSuggestionTest extends AbstractContr
 
   /** @test */
   public function loggedUserShouldHaveOneSuggestion() {
-    $this->assertXPathContentContains('//dl/dt', 'Commentaire');
+    $this->assertXPathContentContains('//table[@class="tablesorter"]/thead/th', 'Commentaire');
   }
 
 
   /** @test */
   public function suggestionShouldHaveTypeDocDVD() {
-    $this->assertXPathContentContains('//dl//dd', 'DVD');
+    $this->assertXPathContentContains('//table/tbody/tr/td', 'DVD');
+  }
+}
+
+
+
+
+class AbonneControllerSuggestionAchatWithOneRestfulSuggestionTest
+  extends AbonneControllerSuggestionAchatAddFormMultipleBibsAndKohaTestCase {
+
+  public function setUp() {
+    parent::setUp();
+
+    $logger = $this->mock()
+                   ->whenCalled('log')->answers(true)
+
+                   ->whenCalled('logError')
+                   ->willDo(
+                            function($url, $message) {
+                              throw new RuntimeException($url . ' :: ' . $message);
+                            });
+
+    Class_WebService_SIGB_AbstractService::setLogger($logger);
+
+    $this->mock_web_client
+      ->whenCalled('open_url')
+      ->with('http://plage.com/cgi-bin/koha/ilsdi.pl?service=LookupPatron&id=azerty&id_type=cardnumber')
+      ->answers('<xml><id>234</id></xml>')
+
+      ->whenCalled('open_url')
+      ->with('http://plage.com/cgi-bin/koha/rest.pl/suggestions?suggestedby=234')
+      ->answers('[{
+      "date" : "2014-04-01 16:08:36",
+      "STATUS" : "ASKED",
+      "suggestionid" : "6197",
+      "branchcodemanagedby" : "",
+      "accepteddate" : "",
+      "borrnummanagedby" : "",
+      "emailmanagedby" : "",
+      "branchcodesuggestedby" : "IST",
+      "isbn" : "9782814101425 ",
+      "emailsuggestedby" : "",
+      "branchcode" : "IST",
+      "copyrightdate" : "0",
+      "budgetid" : "",
+      "reason" : null,
+      "ASKED" : 1,
+      "total" : "",
+      "surnamemanagedby" : "",
+      "branchnamesuggestedby" : "Test",
+      "price" : "",
+      "title" : "En piste ! : Créations en couture pour petits et grands Enfant",
+      "collectiontitle" : "",
+      "publicationyear" : "2012",
+      "itemtype" : "",
+      "place" : "",
+      "author" : "Laëtitia Gheno",
+      "suggesteddate" : "2013-11-14",
+      "currency" : "",
+      "borrnumsuggestedby" : "234",
+      "biblionumber" : "",
+      "categorycodesuggestedby" : "",
+      "manageddate" : "",
+      "acceptedby" : "",
+      "firstnamesuggestedby" : "",
+      "surnamesuggestedby" : "",
+      "publishercode" : "",
+      "suggestedby" : "234",
+      "rejecteddate" : null,
+      "firstnamemanagedby" : "",
+      "rejectedby" : null,
+      "quantity" : "0",
+      "note" : "D.L.",
+      "patronreason" : "Je veux le lire",
+      "categorydescriptionsuggestedby" : "",
+      "volumedesc" : null,
+      "mailoverseeing" : "0",
+      "managedby" : ""}]')
+                                  ->beStrict();
+
+    $this->fixture('Class_CodifAnnexe',
+                   ['id' => 15,
+                    'libelle' => 'Istres',
+                    'code' => 'IST']);
+
+
+    $this->dispatch('/opac/abonne/suggestion-achat', true);
+  }
+
+
+  public function tearDown() {
+    Class_WebService_SIGB_AbstractService::setLogger(null);
+    parent::tearDown();
+  }
+
+
+  /** @test */
+  public function titleShouldBePresent() {
+    $this->assertXPathContentContains('//td', 'En piste ! : Créations en couture pour petits et grands Enfant');
+  }
+
+
+  /** @test */
+  public function authorShouldBePrensent() {
+    $this->assertXPathContentContains('//td', 'Laëtitia Gheno');
+  }
+
+
+  /** @test */
+  public function publicationYearShouldBePresent() {
+    $this->assertXPathContentContains('//td', '2012');
+  }
+
+
+  /** @test */
+  public function libraryShouldBePresent() {
+    $this->assertXPathContentContains('//td', 'Istres');
+  }
+
+
+  /** @test */
+  public function suggestDateShouldBePresent() {
+    $this->assertXPathContentContains('//td', '2013-11-14');
+  }
+
+
+  /** @test */
+  public function patronReasonShouldBePresent() {
+    $this->assertXPathContentContains('//td', 'Je veux le lire');
+  }
+
+
+  /** @test */
+  public function statusShouldBePresent() {
+    $this->assertXPathContentContains('//td', 'En attente');
+  }
+}
+
+
+
+
+class AbonneControllerSuggestionAchatWithRestfulErrorTest
+  extends AbonneControllerSuggestionAchatAddFormMultipleBibsAndKohaTestCase {
+
+  public function setUp() {
+    parent::setUp();
+
+    $logger = $this->mock()
+                   ->whenCalled('log')->answers(true)
+
+                   ->whenCalled('logError')
+                   ->willDo(
+                            function($url, $message) {
+                              throw new RuntimeException($url . ' :: ' . $message);
+                            });
+
+    Class_WebService_SIGB_AbstractService::setLogger($logger);
+
+
+    $this->mock_web_client
+      ->whenCalled('open_url')
+      ->with('http://plage.com/cgi-bin/koha/ilsdi.pl?service=LookupPatron&id=azerty&id_type=cardnumber')
+      ->answers('<?xml version="1.0" encoding="UTF-8" ?>
+<LookupPatron>
+  <id>234</id>
+</LookupPatron>')
+
+      ->whenCalled('open_url')
+      ->with('http://plage.com/cgi-bin/koha/rest.pl/suggestions?suggestedby=234')
+      ->answers('[
+   "Forbidden. 178.16.171.35 is not allowed to use this service. Are you sure configuration variable \'authorizedips\' is correctly configured?"
+]');
+
+    $this->fixture('Class_CodifAnnexe',
+                   ['id' => 15,
+                    'libelle' => 'Istres',
+                    'code' => 'IST']);
+
+    $this->dispatch('/opac/abonne/suggestion-achat', true);
+  }
+
+
+  public function tearDown() {
+    Class_WebService_SIGB_AbstractService::setLogger(null);
+    parent::tearDown();
+  }
+
+
+  /** @test */
+  public function shouldNotDisplaySuggestionsList() {
+    $this->assertNotXPath('//div[@class="suggestion-achat-liste"]//table');
+  }
+
+
+  /** @test */
+  public function shouldDisplayWebserviceError() {
+    $this->assertXPathContentContains('//div',
+                                      'Forbidden. 178.16.171.35 is not allowed to use this service. Are you sure configuration variable \'authorizedips\' is correctly configured?');
   }
 }
+
+
+
+
+class ModulesControllerAbonneSuggestionAchatTest extends Admin_AbstractControllerTestCase {
+  public function setUp() {
+    parent::setUp();
+
+
+    Class_Profil::getCurrentProfil()
+      ->setCfgModules(['abonne' => ['suggestion-achat-add' => ['help-text' => 'Entrez votre suggestion']]]);
+
+    $this->dispatch('/admin/modules/abonne?id_profil=2&action1=suggestion-achat-add&type_module=abonne&config=site', true);
+  }
+
+  /** @test */
+  public function titleShouldBeProperty() {
+    $this->assertXPathContentContains('//h1', 'Propriétés du module : Suggestions d\'achat');
+  }
+
+
+  /** @test */
+  public function textareHelpTextShouldContainsEntrezVotreSuggestion() {
+    $this->assertXPathContentContains('//textarea[@name="help-text"]',
+                                      'Entrez votre suggestion');
+  }
+
+
+  /** @test */
+  public function textareHelpTextShouldBeCkeditor() {
+    $this->assertXPathContentContains('//script',
+                                      'CKEDITOR.replace(\'cke-help-text\'');
+  }
+}
+
+
 ?>
\ No newline at end of file
diff --git a/tests/library/Class/WebService/SIGB/CarthameTest.php b/tests/library/Class/WebService/SIGB/CarthameTest.php
index cf64d330ad0f721ed80feb8a762a1dafc0d0e9c6..80106799b59596bb06e71d3a75c9fde0a36696ea 100644
--- a/tests/library/Class/WebService/SIGB/CarthameTest.php
+++ b/tests/library/Class/WebService/SIGB/CarthameTest.php
@@ -686,7 +686,7 @@ class CarthameOperationsTest extends CarthameOperationTestCase {
   /** @test */
   public function supprimerReservationShouldReturnSuccessIfNoError() {
     $this->mock_web_client->whenCalled('open_url')
-                          ->with('http://server.domain/webservices/index.php?sigb=karvi&version=standalone&action=reserveCancel&resid=MillRes')
+                          ->with('http://server.domain/webservices/index.php?sigb=karvi&version=standalone&bibkey&action=reserveCancel&resid=MillRes')
                           ->answers('<?xml version="1.0"?>
                                         <root>
                                           <reservationCancel>
diff --git a/tests/library/Class/WebService/SIGB/KohaRestfulTest.php b/tests/library/Class/WebService/SIGB/KohaRestfulTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..70cf32095226be11b302afd63c5a8e3b8ee25eb8
--- /dev/null
+++ b/tests/library/Class/WebService/SIGB/KohaRestfulTest.php
@@ -0,0 +1,390 @@
+<?php
+/**
+ * Copyright (c) 2012-2014, 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 KohaRestfulTestCase extends ModelTestCase {
+  const BASE_URL = 'http://cat-aficg55.biblibre.com/cgi-bin/koha/';
+
+  protected
+    $_storm_default_to_volatile = true,
+    $mock_web_client,
+    $service;
+
+  public function setUp() {
+    parent::setUp();
+
+    Class_AdminVar::set('KOHA_MULTI_SITES', '');
+
+    $this->mock_web_client = $this->mock();
+
+    $logger = $this->mock()
+                   ->whenCalled('log')->answers(true)
+
+                   ->whenCalled('logError')
+                   ->willDo(function($url, $message) {
+                              throw new RuntimeException($url . ' :: ' . $message);
+                            });
+    Class_WebService_SIGB_AbstractService::setLogger($logger);
+
+    $params = ['url_serveur' => static::BASE_URL . 'ilsdi.pl',
+               'restful' => '1'];
+    $this->service = Class_WebService_SIGB_Koha::getService($params);
+    $this->service->setWebClient($this->mock_web_client);
+  }
+
+
+  public function tearDown() {
+    Class_WebService_SIGB_AbstractService::setLogger(null);
+    parent::tearDown();
+  }
+}
+
+
+
+
+class KohaRestfulSuggestionsOfUserWithKohaNotAllowedTest extends KohaRestfulTestCase {
+  public function setUp() {
+    parent::setUp();
+
+    $user = $this->fixture('Class_Users',
+                           ['id' => 34,
+                            'login' => 'harlock',
+                            'password' => 'arcadia',
+                            'idabon' => 'AO989IE']);
+
+    $this->mock_web_client
+      ->whenCalled('open_url')
+      ->with(static::BASE_URL . 'ilsdi.pl?service=LookupPatron&id=AO989IE&id_type=cardnumber')
+      ->answers('<?xml version="1.0" encoding="UTF-8" ?>
+<LookupPatron>
+  <message>Unauthorized IP address: 178.16.171.35.</message>
+  <code>NotAllowed</code>
+</LookupPatron>');
+    $this->response = $this->service->suggestionsOf($user);
+  }
+
+
+  /** @test */
+  public function shouldHaveError() {
+    $this->assertFalse($this->response['statut']);
+  }
+
+
+
+  /** @test */
+  public function errorShouldBeUnknown() {
+    $this->assertEquals('Échec de l\'authentification par le webservice',
+                        $this->response['erreur']);
+  }
+}
+
+
+
+
+class KohaRestfulSuggestionsOfUserWithForbiddenTest extends KohaRestfulTestCase {
+  public function setUp() {
+    parent::setUp();
+
+    $user = $this->fixture('Class_Users',
+                           ['id' => 34,
+                            'login' => 'harlock',
+                            'password' => 'arcadia',
+                            'idabon' => 'AO989IE']);
+
+    $this->mock_web_client
+      ->whenCalled('open_url')
+      ->with(static::BASE_URL . 'ilsdi.pl?service=LookupPatron&id=AO989IE&id_type=cardnumber')
+      ->answers('<?xml version="1.0" encoding="UTF-8" ?>
+<LookupPatron>
+  <id>234</id>
+</LookupPatron>')
+
+      ->whenCalled('open_url')
+      ->with(static::BASE_URL . 'rest.pl/suggestions?suggestedby=234')
+      ->answers('[
+   "Forbidden. 178.16.171.35 is not allowed to use this service. Are you sure configuration variable \'authorizedips\' is correctly configured?"
+]');
+
+    $this->response = $this->service->suggestionsOf($user);
+  }
+
+
+  /** @test */
+  public function shouldHaveError() {
+    $this->assertFalse($this->response['statut']);
+  }
+
+
+
+  /** @test */
+  public function errorShouldBeUnknown() {
+    $this->assertEquals('Échec de la connexion au webservice, le SIGB a répondu "[
+   "Forbidden. 178.16.171.35 is not allowed to use this service. Are you sure configuration variable \'authorizedips\' is correctly configured?"
+]"',
+                        $this->response['erreur']);
+  }
+}
+
+
+
+
+class KohaRestfulSuggestionsOfUserTest extends KohaRestfulTestCase {
+  public function setUp() {
+    parent::setUp();
+
+    $user = $this->fixture('Class_Users',
+                           ['id' => 34,
+                            'login' => 'harlock',
+                            'password' => 'arcadia',
+                            'idabon' => 'AO989IE']);
+
+    $this->fixture('Class_CodifAnnexe',
+                   ['id' => 15,
+                    'libelle' => 'Istres',
+                    'code' => 'IST']);
+
+    $this->mock_web_client
+      ->whenCalled('open_url')
+      ->with(static::BASE_URL . 'ilsdi.pl?service=LookupPatron&id=AO989IE&id_type=cardnumber')
+      ->answers('<id>32007</id>')
+
+      ->whenCalled('open_url')
+      ->with(static::BASE_URL . 'rest.pl/suggestions?suggestedby=32007')
+      ->answers(file_get_contents(__DIR__ . '/suggestions_32007.json'));
+
+    $this->suggestions = $this->service->suggestionsOf($user);
+  }
+
+
+  /** @test */
+  public function shouldHaveThreeSuggestions() {
+    $this->assertEquals(3, count($this->suggestions));
+  }
+
+
+  public function datas() {
+    return [[0,
+             'En piste ! : Créations en couture pour petits et grands Enfant',
+             'Laëtitia Gheno',
+             '',
+             'Istres',
+             '2013-11-14',
+             'D.L.',
+             'Disponible'],
+            [1,
+             'Un été couture made in France',
+             'Géraldine Debeauvais',
+             '',
+             'Istres',
+             '2013-12-12',
+             '',
+             'Disponible'],
+            [2,
+             'Couture pour enfants branchés ! Vêtements et accessoires de la naissance à 2 ans et plus',
+             'Marie-Eve Dollat',
+             '2012',
+             'Istres',
+             '2014-04-16',
+             '',
+             'Rejetée (Sujet largement couvert dans la collection)']];
+  }
+
+
+  /**
+   * @test
+   * @dataProvider datas
+   */
+  public function datasShouldBeImported($pos, $title, $author, $publication_year,
+                                        $library, $date, $note, $status) {
+    $this->assertEquals($title, $this->suggestions[$pos]->getTitle());
+    $this->assertEquals($author, $this->suggestions[$pos]->getAuthor());
+    $this->assertEquals($publication_year,
+                        $this->suggestions[$pos]->getPublicationYear());
+    $this->assertEquals($library, $this->suggestions[$pos]->getLibrary());
+    $this->assertEquals($date, $this->suggestions[$pos]->getDate());
+    $this->assertEquals($note, $this->suggestions[$pos]->getNote());
+    $this->assertEquals($status, $this->suggestions[$pos]->getStatus());
+  }
+}
+
+
+
+abstract class KohaRestfulSuggestTestCase extends KohaRestfulTestCase {
+  public function setUp() {
+    parent::setUp();
+
+    $user = $this->fixture('Class_Users',
+                           ['id' => 34,
+                            'login' => 'harlock',
+                            'password' => 'arcadia',
+                            'idabon' => 'AO989IE']);
+
+    $this->fixture('Class_CodifAnnexe',
+                   ['id' => 15,
+                    'libelle' => 'Istres',
+                    'code' => 'IST']);
+
+    $this->mock_web_client
+      ->whenCalled('open_url')
+      ->with(static::BASE_URL . 'ilsdi.pl?service=LookupPatron&id=AO989IE&id_type=cardnumber')
+      ->answers('<id>32007</id>')
+
+      ->whenCalled('postData')
+      ->with('http://cat-aficg55.biblibre.com/cgi-bin/koha/rest.pl/suggestions?',
+             ['data' => '{"suggestedby":"32007","title":"CommitStrip - Le Livre","author":"CommitStrip","isbn":"","patronreason":null,"publicationyear":""}'])
+      ->answers($this->_postAnswer())
+
+      ->beStrict();
+
+    $suggestion = new Class_WebService_SIGB_Suggestion();
+    $suggestion->updateAttributes(['Title' => 'CommitStrip - Le Livre',
+                                   'Author' => 'CommitStrip',
+                                   'User' => $user]);
+    $this->response = $this->service->suggest($suggestion);
+  }
+
+
+  abstract protected function _postAnswer();
+}
+
+
+
+class KohaRestfulSuccessfulSuggestTest extends KohaRestfulSuggestTestCase {
+  protected function _postAnswer() {
+    return '{
+   "date" : "2015-07-09 11:36:17",
+   "STATUS" : "ASKED",
+   "suggestionid" : "8824",
+   "accepteddate" : null,
+   "isbn" : null,
+   "branchcode" : null,
+   "copyrightdate" : null,
+   "budgetid" : null,
+   "reason" : null,
+   "total" : null,
+   "price" : null,
+   "title" : "CommitStrip - Le Livre",
+   "collectiontitle" : null,
+   "publicationyear" : "0",
+   "itemtype" : null,
+   "place" : null,
+   "author" : "CommitStrip",
+   "suggesteddate" : "2015-07-09",
+   "currency" : null,
+   "biblionumber" : null,
+   "manageddate" : null,
+   "acceptedby" : null,
+   "publishercode" : null,
+   "suggestedby" : "0",
+   "rejecteddate" : null,
+   "rejectedby" : null,
+   "quantity" : null,
+   "note" : null,
+   "patronreason" : null,
+   "volumedesc" : null,
+   "mailoverseeing" : "0",
+   "managedby" : null
+}';
+  }
+
+
+  /** @test */
+  public function shouldHaveNoError() {
+    $this->assertTrue($this->response['statut']);
+  }
+}
+
+
+
+class KohaRestfulEmptyResponseSuggestTest extends KohaRestfulSuggestTestCase {
+  protected function _postAnswer() {
+    return '';
+  }
+
+
+  /** @test */
+  public function shouldHaveError() {
+    $this->assertFalse($this->response['statut']);
+  }
+
+
+
+  /** @test */
+  public function errorShouldBeUnknown() {
+    $this->assertEquals('Échec de la suggestion, une erreur inconnue est survenue.',
+                        $this->response['erreur']);
+  }
+}
+
+
+
+class KohaRestfulSoftwareErrorResponseSuggestTest extends KohaRestfulSuggestTestCase {
+  protected function _postAnswer() {
+    return '<h1>Software error:</h1>
+<pre>Can\'t locate object method &quot;error&quot; via package &quot;Error executing run mode \'create_suggestion\': DBIx::Class::ResultSet::create(): Column \'suggestedby\' cannot be null at /home/koha/src/C4/Suggestions.pm line 450
+ at /usr/share/perl5/CGI/Application/Dispatch.pm line 707
+&quot; (perhaps you forgot to load &quot;Error executing run mode \'create_suggestion\': DBIx::Class::ResultSet::create(): Column \'suggestedby\' cannot be null at /home/koha/src/C4/Suggestions.pm line 450
+ at /usr/share/perl5/CGI/Application/Dispatch.pm line 707
+&quot;?) at /usr/share/perl5/CGI/Application/Dispatch.pm line 438.
+</pre>
+<p>
+For help, please send mail to the webmaster (<a href="mailto:support@server.com">support@server.com</a>), giving this error message
+and the time and date of the error.
+
+</p>';
+  }
+
+
+  /** @test */
+  public function shouldHaveError() {
+    $this->assertFalse($this->response['statut']);
+  }
+
+
+  /** @test */
+  public function errorShouldBeUnknown() {
+    $this->assertEquals('Échec de la suggestion, une erreur inconnue est survenue.',
+                        $this->response['erreur']);
+  }
+}
+
+
+
+class KohaRestfulJsonErrorSuggestTest extends KohaRestfulSuggestTestCase {
+  protected function _postAnswer() {
+    return '{
+   "error" : "Failed to parse data parameter: malformed JSON string, neither array, object, number, string or atom, at character offset 0 (before \"(end of string)\") at /usr/share/perl5/JSON.pm line 171.\n"
+}';
+  }
+
+
+  /** @test */
+  public function shouldHaveError() {
+    $this->assertFalse($this->response['statut']);
+  }
+
+
+  /** @test */
+  public function errorShouldBeKnown() {
+    $this->assertEquals('Échec de la suggestion, le webservice a répondu "Failed to parse data parameter: malformed JSON string, neither array, object, number, string or atom, at character offset 0 (before "(end of string)") at /usr/share/perl5/JSON.pm line 171."',
+                        $this->response['erreur']);
+  }
+}
\ No newline at end of file
diff --git a/tests/library/Class/WebService/SIGB/KohaTest.php b/tests/library/Class/WebService/SIGB/KohaTest.php
index 7900d422d6ad47c8d8b55cda3006fd0ab33d1aaf..ac39b69960b35497018a7118644410a9c0d32c9a 100644
--- a/tests/library/Class/WebService/SIGB/KohaTest.php
+++ b/tests/library/Class/WebService/SIGB/KohaTest.php
@@ -20,11 +20,14 @@
  */
 include_once('KohaFixtures.php');
 
-class KohaGetServiceTest extends PHPUnit_Framework_TestCase {
+class KohaGetServiceTest extends ModelTestCase {
+  protected $_storm_default_to_volatile = true;
+
   public function setUp() {
+    parent::setUp();
     Class_WebService_SIGB_Koha::reset();
     Class_AdminVar::newInstanceWithId('KOHA_MULTI_SITES', ['valeur' => '' ]);
-    $this->service = Class_WebService_SIGB_Koha::getService(array('url_serveur' => 'http://cat-aficg55.biblibre.com/cgi-bin/koha/ilsdi.pl'));
+    $this->service = Class_WebService_SIGB_Koha::getService(['url_serveur' => 'http://cat-aficg55.biblibre.com/cgi-bin/koha/ilsdi.pl']);
   }
 
 
@@ -41,14 +44,30 @@ class KohaGetServiceTest extends PHPUnit_Framework_TestCase {
                         $this->service->getServerRoot());
   }
 
+
+  /** @test */
+  public function shouldNotProvideSuggestions() {
+    $this->assertFalse($this->service->providesSuggestions());
+  }
+
+
+  /** @test */
+  public function withRestfulShouldProvideSuggestions() {
+    Class_WebService_SIGB_Koha::reset();
+    $params = ['url_serveur' => 'http://cat-aficg55.biblibre.com/cgi-bin/koha/ilsdi.pl',
+               'restful' => '1'];
+    $service = Class_WebService_SIGB_Koha::getService($params);
+    $this->assertTrue($service->providesSuggestions());
+  }
+
+
   /** @test */
   public function getServiceWithoutSchemeShouldAddHttpScheme() {
     Class_WebService_SIGB_Koha::reset();
-    $this->service = Class_WebService_SIGB_Koha::getService(array('url_serveur' => 'cat-aficg55.biblibre.com/cgi-bin/koha/ilsdi.pl'));
+    $this->service = Class_WebService_SIGB_Koha::getService(['url_serveur' => 'cat-aficg55.biblibre.com/cgi-bin/koha/ilsdi.pl']);
     $this->assertEquals('http://cat-aficg55.biblibre.com/cgi-bin/koha/ilsdi.pl',
                         $this->service->getServerRoot());
   }
-
 }
 
 
@@ -58,6 +77,7 @@ abstract class KohaTestCase extends ModelTestCase {
   protected $service;
 
   public function setUp() {
+    parent::setUp();
     Class_Profil::setCurrentProfil($this->fixture('Class_Profil',
                                                   ['id' => 1,
                                                    'libelle' => 'Actu']));
diff --git a/tests/library/Class/WebService/SIGB/suggestions_32007.json b/tests/library/Class/WebService/SIGB/suggestions_32007.json
new file mode 100644
index 0000000000000000000000000000000000000000..74421ddd913a37e84f4019a4c575f6fb852ee556
--- /dev/null
+++ b/tests/library/Class/WebService/SIGB/suggestions_32007.json
@@ -0,0 +1,146 @@
+[
+   {
+      "date" : "2014-04-01 16:08:36",
+      "STATUS" : "AVAILABLE",
+      "suggestionid" : "6197",
+      "branchcodemanagedby" : "MIR",
+      "accepteddate" : "2014-01-29",
+      "borrnummanagedby" : "811",
+      "emailmanagedby" : "mail@server.com",
+      "branchcodesuggestedby" : "IST",
+      "isbn" : "9782814101425 ",
+      "emailsuggestedby" : "mail@server.com",
+      "branchcode" : "IST",
+      "copyrightdate" : "0",
+      "budgetid" : "1557",
+      "reason" : null,
+      "AVAILABLE" : 1,
+      "total" : "0.000000",
+      "surnamemanagedby" : "TESTING",
+      "branchnamesuggestedby" : "Test",
+      "price" : "26.900000",
+      "title" : "En piste ! : Créations en couture pour petits et grands Enfant",
+      "collectiontitle" : "",
+      "publicationyear" : "0",
+      "itemtype" : "LIVR",
+      "place" : "",
+      "author" : "Laëtitia Gheno",
+      "suggesteddate" : "2013-11-14",
+      "currency" : "EUR",
+      "borrnumsuggestedby" : "32007",
+      "biblionumber" : "261517",
+      "categorycodesuggestedby" : "A",
+      "manageddate" : "2014-01-29",
+      "acceptedby" : "811",
+      "firstnamesuggestedby" : "Test",
+      "surnamesuggestedby" : "TEST",
+      "publishercode" : "",
+      "suggestedby" : "32007",
+      "rejecteddate" : null,
+      "firstnamemanagedby" : "Test",
+      "rejectedby" : null,
+      "quantity" : "0",
+      "note" : "D.L.",
+      "patronreason" : null,
+      "categorydescriptionsuggestedby" : "Adulte",
+      "volumedesc" : null,
+      "mailoverseeing" : "0",
+      "managedby" : "811"
+   },
+   {
+      "date" : "2014-05-05 15:42:42",
+      "STATUS" : "AVAILABLE",
+      "suggestionid" : "6360",
+      "branchcodemanagedby" : "MIR",
+      "accepteddate" : "2014-02-18",
+      "borrnummanagedby" : "811",
+      "emailmanagedby" : "mail@server.com",
+      "branchcodesuggestedby" : "IST",
+      "isbn" : "",
+      "emailsuggestedby" : "mail@server.com",
+      "branchcode" : "IST",
+      "copyrightdate" : "0",
+      "budgetid" : "952",
+      "reason" : null,
+      "AVAILABLE" : 1,
+      "total" : "0.000000",
+      "surnamemanagedby" : "TESTING",
+      "branchnamesuggestedby" : "Test",
+      "price" : "0.000000",
+      "title" : "Un été couture made in France",
+      "collectiontitle" : "",
+      "publicationyear" : "0",
+      "itemtype" : "LIVR",
+      "place" : "",
+      "author" : "Géraldine Debeauvais",
+      "suggesteddate" : "2013-12-12",
+      "currency" : "EUR",
+      "borrnumsuggestedby" : "32007",
+      "biblionumber" : "260846",
+      "categorycodesuggestedby" : "A",
+      "manageddate" : "2014-02-18",
+      "acceptedby" : "811",
+      "firstnamesuggestedby" : "Test",
+      "surnamesuggestedby" : "TESTING",
+      "publishercode" : "Tutti Frutti",
+      "suggestedby" : "32007",
+      "rejecteddate" : null,
+      "firstnamemanagedby" : "Test",
+      "rejectedby" : null,
+      "quantity" : "0",
+      "note" : "",
+      "patronreason" : null,
+      "categorydescriptionsuggestedby" : "Adulte",
+      "volumedesc" : null,
+      "mailoverseeing" : "0",
+      "managedby" : "811"
+   },
+   {
+      "date" : "2014-04-22 15:37:16",
+      "STATUS" : "REJECTED",
+      "suggestionid" : "7168",
+      "branchcodemanagedby" : "MIR",
+      "accepteddate" : null,
+      "borrnummanagedby" : "811",
+      "emailmanagedby" : "mail@server.com",
+      "branchcodesuggestedby" : "IST",
+      "isbn" : "",
+      "emailsuggestedby" : "mail@server.com",
+      "branchcode" : "IST",
+      "copyrightdate" : "0",
+      "budgetid" : "952",
+      "reason" : "Sujet largement couvert dans la collection",
+      "total" : "0.000000",
+      "surnamemanagedby" : "TESTING",
+      "branchnamesuggestedby" : "Test",
+      "REJECTED" : 1,
+      "price" : "0.000000",
+      "title" : "Couture pour enfants branchés ! Vêtements et accessoires de la naissance à 2 ans et plus",
+      "collectiontitle" : "",
+      "publicationyear" : "2012",
+      "itemtype" : "LIVR",
+      "place" : "",
+      "author" : " Marie-Eve Dollat",
+      "suggesteddate" : "2014-04-16",
+      "currency" : "EUR",
+      "borrnumsuggestedby" : "32007",
+      "biblionumber" : null,
+      "categorycodesuggestedby" : "A",
+      "manageddate" : "2014-04-22",
+      "acceptedby" : "0",
+      "firstnamesuggestedby" : "Test",
+      "surnamesuggestedby" : "TESTING",
+      "publishercode" : "",
+      "suggestedby" : "32007",
+      "rejecteddate" : "2014-04-22",
+      "firstnamemanagedby" : "Test",
+      "rejectedby" : "811",
+      "quantity" : "0",
+      "note" : "",
+      "patronreason" : null,
+      "categorydescriptionsuggestedby" : "Adulte",
+      "volumedesc" : null,
+      "mailoverseeing" : "0",
+      "managedby" : "811"
+   }
+]
diff --git a/tests/library/ZendAfi/View/Helper/ListeSuggestionAchatTest.php b/tests/library/ZendAfi/View/Helper/ListeSuggestionAchatTest.php
index 51e0a3cd7b533e8e56a168f0e32ea46f05aaec1c..cb5637334858b158af3a51f4fd64a8ff760a3b25 100644
--- a/tests/library/ZendAfi/View/Helper/ListeSuggestionAchatTest.php
+++ b/tests/library/ZendAfi/View/Helper/ListeSuggestionAchatTest.php
@@ -16,13 +16,13 @@
  *
  * 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 
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
 
 require_once 'library/ZendAfi/View/Helper/ViewHelperTestCase.php';
 
 class ListeSuggestionAchatWithSuggestionAchatTest extends ViewHelperTestCase {
-  
+
   protected $_tom;
   protected $_pharo_by_example;
 
@@ -32,8 +32,8 @@ class ListeSuggestionAchatWithSuggestionAchatTest extends ViewHelperTestCase {
     $this->_tom = Class_Users::newInstanceWithId(2,['nom' => 'Le',
                                                     'prenom' => 'Tom',
                                                     'mail' => 'leTom@afi-sa.fr']);
-    
-    $this->_pharo_by_example = 
+
+    $this->_pharo_by_example =
       Class_SuggestionAchat::newInstanceWithId(2)
       ->setDateCreation('2013-23-10')
       ->setTitre('Pharo By Example')
@@ -43,7 +43,7 @@ class ListeSuggestionAchatWithSuggestionAchatTest extends ViewHelperTestCase {
       ->setCommentaire('I need')
       ->setUser($this->_tom);
 
-  $this->_cuisiner_le_melon = 
+  $this->_cuisiner_le_melon =
       Class_SuggestionAchat::newInstanceWithId(5)
       ->setDateCreation('2013-21-10')
       ->setTitre('Cuisiner le Melon')
@@ -66,13 +66,13 @@ class ListeSuggestionAchatWithSuggestionAchatTest extends ViewHelperTestCase {
 
   /** @test **/
   public function tomShouldHavePharoByExampleInListSuggestionAchat() {
-    $this->assertXPathContentContains($this->_html, '//div/div[1]/dl//dd', 'Pharo By Example', $this->_html);
+    $this->assertXPathContentContains($this->_html, '//table/tbody/tr[1]/td', 'Pharo By Example', $this->_html);
   }
 
 
   /** @test **/
   public function tomShouldHaveCuisinerLeMelonInListSuggestionAchat() {
-    $this->assertXPathContentContains($this->_html, '//div/div[2]/dl//dd', 'Cuisiner le Melon', $this->_html);
+    $this->assertXPathContentContains($this->_html, '//table/tbody/tr[2]/td', 'Cuisiner le Melon', $this->_html);
   }
 }