diff --git a/FEATURES/59187 b/FEATURES/59187
new file mode 100644
index 0000000000000000000000000000000000000000..c53c5b2f5fe8018a99490f44fd40c38b7aec5135
--- /dev/null
+++ b/FEATURES/59187
@@ -0,0 +1,10 @@
+        '59187' =>
+            ['Label' => $this->_('[Explo] Redmine : pouvoir uploader des fichiers dans les tickets back office'),
+             'Desc' => '',
+             'Image' => '',
+             'Video' => '',
+             'Category' => '',
+             'Right' => function($feature_description, $user) {return true;},
+             'Wiki' => '',
+             'Test' => '',
+             'Date' => '2017-09-28'],
\ No newline at end of file
diff --git a/VERSIONS_WIP/59187 b/VERSIONS_WIP/59187
new file mode 100644
index 0000000000000000000000000000000000000000..0a50e0f9959e23f073d37537e987e2fdb769e05e
--- /dev/null
+++ b/VERSIONS_WIP/59187
@@ -0,0 +1 @@
+ - ticket #59187 : [Explo] Redmine : pouvoir uploader des fichiers dans les tickets back office
\ No newline at end of file
diff --git a/application/modules/admin/controllers/RedmineController.php b/application/modules/admin/controllers/RedmineController.php
index d6a04c54a70d5db032d799b365dbc6fa1d01c127..a6dc51e07e5406fc71a4795bb55a0717e2a38597 100644
--- a/application/modules/admin/controllers/RedmineController.php
+++ b/application/modules/admin/controllers/RedmineController.php
@@ -107,18 +107,32 @@ class Admin_RedmineController extends ZendAfi_Controller_Action {
       ->setService($service);
 
     $this->view->form = $form = ZendAfi_Form_Redmine_Issue::newWithIssue($issue, $service);
-    if ($this->_request->isPost()
-        && $form->isValid($this->_request->getPost())) {
-      $issue->updateAttributes($form->getValues());
 
-      if ($service->createIssue($issue)) {
-        $this->_helper->notify($this->_('Demande enregistrée'));
-        $this->_redirectToIndex();
-        return;
-      }
+    if (!$this->_request->isPost())
+      return;
+
+    if (!$form->isValid($this->_request->getPost()))
+      return $this->_helper->notify($this->_('Erreur lors de l\'enregistrement'));
+
+    $issue->updateAttributes($form->getValues());
+
+    if (!$response = $service->createIssue($issue))
+      return $this->_helper->notify($this->_('Erreur lors de la création du ticket'));
 
-      $this->_helper->notify($this->_('Erreur lors de l\'enregistrement'));
+    if(!$response instanceof SimpleXMLElement)
+      return $this->_helper->notify($this->_('Erreur lors de la création du ticket'));
+
+    if($issue_id = $response->id->__toString()) {
+      $service->attachToIssue($issue->setid($issue_id));
+      $this->_helper->notify($this->_('Demande %s créée', $issue_id));
+      return $this->_redirect(Class_Url::absolute(['module' => 'admin',
+                                                   'controller' => 'redmine',
+                                                   'action' => 'edit-issue',
+                                                   'id' => $issue_id,
+                                                   'id_lib' => $this->_getParam('id_lib')]));
     }
+
+    $this->_helper->notify($this->_('Erreur lors de la création du ticket'));
   }
 
 
@@ -153,13 +167,55 @@ class Admin_RedmineController extends ZendAfi_Controller_Action {
         && $form->isValid($this->_request->getPost())) {
       $issue->updateAttributes($form->getValues());
       $service->updateIssue($issue);
+      $service->attachToIssue($issue);
 
       $this->_helper->notify($this->_('Demande #%s enregistrée', $issue->getid()));
-      $this->_redirectToIndex();
+      $this->_redirectToReferer();
     }
   }
 
 
+  public function uploadFileAction() {
+    if (!$this->_request->isPost())
+      return $this->_jsonError($this->_('La requête doit être de type POST'));
+
+    $library = Class_Bib::find($this->_getParam('id_lib', 0));
+    $service = new Class_WebService_Redmine($library);
+
+    if (null !== $message = $service->validate())
+      return $this->_jsonError($this->_('Le service Redmine est invalide.'));
+
+    if(!$data = $this->_getParam('data'))
+      return $this->_jsonError($this->_('La pièce jointe est invalide.'));
+
+    if(false !== ($pos = strpos($data, ",")))
+      $data = substr($data, $pos + 1);
+
+    if(!$data = base64_decode($data))
+      return $this->_jsonError($this->_('La pièce jointe est invalide.'));
+
+    if (!$response = $service->uploadFile($data))
+      return $this->_jsonError($this->_('L\'ajout de pièce jointe a échoué.'));
+
+    $decoded_response = json_decode($response, true);
+    if(!isset($decoded_response['upload']['token']))
+      return $this->_jsonError($this->_('La pièce jointe est invalide.'));
+
+    if(!preg_match('/[^.]$/', $decoded_response['upload']['token']))
+      return $this->_jsonError($this->_('L\'ajout de la pièce jointe a échoué car la clé reçue "%s" est invalide.',
+                                        $decoded_response['upload']['token']));
+
+    return $this->_helper->json($decoded_response);
+  }
+
+
+  protected function _jsonError($message) {
+    return $this->_helper->json(['status' => 'error',
+                                 'message' => $message,
+                                 'params' => $this->_request->getParams()]);
+  }
+
+
   protected function withResponseDo($data, $call_back) {
     $error_message = $this->view->getHelper('Redmine_AccountStatus')->connectionFail();
 
diff --git a/application/modules/admin/views/scripts/redmine/edit-issue.phtml b/application/modules/admin/views/scripts/redmine/edit-issue.phtml
index 970664867c8a6c99a93ae75aa30030548fdd6baa..275987e2a3aafe9528940ec209bf65f73c78ac2e 100644
--- a/application/modules/admin/views/scripts/redmine/edit-issue.phtml
+++ b/application/modules/admin/views/scripts/redmine/edit-issue.phtml
@@ -1,5 +1,6 @@
 <div class="form">
   <fieldset>
+   <legend><?php echo $this->_('Titre');?></legend>
     <table>
       <tr>
         <td></td>
@@ -18,6 +19,15 @@
       </tr>
     </table>
   </fieldset>
+  <fieldset>
+    <legend><?php echo $this->_('Pièces jointes');?></legend>
+    <table>
+      <tr>
+        <td></td>
+        <td class="gauche"><?php echo $this->redmine_IssueAttachments($this->issue); ?></td>
+      </tr>
+     </table>
+  </fieldset>
   <fieldset>
     <legend><?php echo $this->_('Historique');?></legend>
     <table>
diff --git a/application/modules/admin/views/scripts/redmine/index.phtml b/application/modules/admin/views/scripts/redmine/index.phtml
index 1f5d91622606c386b3c642aad0c8226a7f31b743..ebe8cf6ae2d692798b08116aec44825bb865bfaa 100644
--- a/application/modules/admin/views/scripts/redmine/index.phtml
+++ b/application/modules/admin/views/scripts/redmine/index.phtml
@@ -1,5 +1,4 @@
 <?php
-
 if (!$this->libraries) {
   echo $this->getHelper('Redmine_Header')->shouldSelectLib($this->user);
   return;
diff --git a/library/Class/Entity.php b/library/Class/Entity.php
index d6ad0498a27ac1601434968b69988e9e81ddc62e..7b3e2df6eaff7306c30f84670d04372569cb9a44 100644
--- a/library/Class/Entity.php
+++ b/library/Class/Entity.php
@@ -46,6 +46,11 @@ class Class_Entity {
   }
 
 
+  public function __construct($attributes = []) {
+    $this->updateAttributes($attributes);
+  }
+
+
   public function get($name, $default=null) {
     return array_key_exists($name, $this->_attribs) ?
       $this->_attribs[$name] : $default;
diff --git a/library/Class/ScriptLoader.php b/library/Class/ScriptLoader.php
index e1c1c57c05f607a5ca01bd65add06dc7515b9a00..a84ce07447cb828ba3e1e7f5bbf3dbc8178c3808 100644
--- a/library/Class/ScriptLoader.php
+++ b/library/Class/ScriptLoader.php
@@ -813,7 +813,7 @@ class Class_ScriptLoader {
     return $this->_addSearchInput('.main > .modules',
                                   'input_content_menu',
                                   $label,
-                                  'table, thead, th , .form, .form *, center, center *, br, .bouton, a *, a, img, h1, h3, h3 + div , .error, h3 + div *, .soustitre, .soustitre *, tr *, #progressbar, #progressbar *, button');
+                                  'table, thead, th ,table th,table thead *, .form, .form *, center, center *, br, .bouton, a *, a, img, h1, h3, h3 + div , .error, h3 + div *, h2, h2 + *, div > h2, .soustitre, .soustitre *, tr *, #progressbar, #progressbar *, button');
   }
 
 
diff --git a/library/Class/WebService/Redmine.php b/library/Class/WebService/Redmine.php
index daa11a004ac154787da22d2b59b08fa2076791c7..89c41bab2b3117bea6b1facaf465967e778b1087 100644
--- a/library/Class/WebService/Redmine.php
+++ b/library/Class/WebService/Redmine.php
@@ -84,6 +84,11 @@ class Class_WebService_Redmine extends Class_WebService_Abstract {
   }
 
 
+  protected function _getAttachmentApi() {
+    return $this->getClient()->api('attachment');
+  }
+
+
   protected function getIssueStatusApi() {
     return $this->getClient()->api('issue_status');
   }
@@ -198,7 +203,22 @@ class Class_WebService_Redmine extends Class_WebService_Abstract {
 
   public function updateIssue($issue) {
     return $this->getIssueApi()
-                ->update($issue->getid(), $issue->getUpdateParams());
+         ->update($issue->getid(), $issue->getUpdateParams());
+  }
+
+
+  public function attachToIssue($issue) {
+    if(!$issue)
+      return null;
+
+    if(!$token = $issue->gettoken())
+      return null;
+
+    return $this->getIssueApi()
+         ->attach($issue->getid(),
+                  ['token' => $token,
+                   'filename' => $issue->getfilename(),
+                   'content_type' => $issue->getfiletype()]);
   }
 
 
@@ -206,7 +226,7 @@ class Class_WebService_Redmine extends Class_WebService_Abstract {
     if (!$this->isValid() || !$ticket)
       return new Class_WebService_Redmine_Issue();
 
-    $data = $this->getIssueApi()->show($ticket, ['include' => 'journals']);
+    $data = $this->getIssueApi()->show($ticket, ['include' => 'attachments,journals']);
     $issue = Class_WebService_Redmine_Issue::newWith(isset($data['issue']) ? $data['issue'] : []);
     $issue->setService($this);
 
@@ -360,6 +380,12 @@ class Class_WebService_Redmine extends Class_WebService_Abstract {
   }
 
 
+  public function uploadFile($json) {
+    return $this->_getAttachmentApi()
+                ->upload($json);
+  }
+
+
   protected function getCustomOptions($id) {
     $options = [];
     foreach ($this->getCustomFields() as $field) {
diff --git a/library/Class/WebService/Redmine/Issue.php b/library/Class/WebService/Redmine/Issue.php
index a415ab2e3a76a3553cf54662caebe9f2ac0af73a..a3a1c911f760ed6bb9805282c1d5b95e6a53d982 100644
--- a/library/Class/WebService/Redmine/Issue.php
+++ b/library/Class/WebService/Redmine/Issue.php
@@ -25,9 +25,7 @@ class Class_WebService_Redmine_Issue extends Class_Entity {
 
   public static function newWith($data) {
     $instance = new static();
-    $instance->updateAttributes($data);
-
-    return $instance;
+    return $instance->updateAttributes($data);
   }
 
 
@@ -55,8 +53,6 @@ class Class_WebService_Redmine_Issue extends Class_Entity {
   }
 
 
-
-
   public function getTechnicalInformations() {
     $datas = [$this->_('Url : ') . Class_Url::rootUrl() . Class_Url::baseUrl(),
               $this->_('Version : ') . BOKEH_RELEASE_NUMBER . ' (' . BOKEH_VERSION . ')',
@@ -138,6 +134,21 @@ class Class_WebService_Redmine_Issue extends Class_Entity {
   }
 
 
+  public function renderAttachment($view, $attachment) {
+    if(!$attachment->getnew_value())
+      return $view->tag('del',
+                        $this->_('Pièce jointe : "%s"', $attachment->getold_value()));
+
+    $show_url = sprintf('%s/attachments/download/%s/%s',
+                   Class_AdminVar::get('REDMINE_SERVER_URL'),
+                   $attachment->getname(),
+                   $attachment->getnew_value());
+
+    return $view->tagAnchor($show_url,
+                            $this->_('Pièce jointe : "%s"', $attachment->getnew_value()), ['target' => '_blank']);
+  }
+
+
   protected function withServiceDo($closure) {
     return ($service = $this->getService()) ? $closure($service) : null;
   }
diff --git a/library/Class/WebService/Redmine/Issues.php b/library/Class/WebService/Redmine/Issues.php
index afb87dfb44a12d5b6250f11012464198e86694f6..872a56d619b77fd451dff0a7cfabdce654ef150e 100644
--- a/library/Class/WebService/Redmine/Issues.php
+++ b/library/Class/WebService/Redmine/Issues.php
@@ -60,6 +60,11 @@ class Class_WebService_Redmine_Issues extends Storm_Collection {
   }
 
 
+  public function selectActionNeeded() {
+    return $this->select(function($issue) { return $issue->getStatusId() == Class_WebService_Redmine_Workflow_Afibre::QUESTION_CLIENT;});
+  }
+
+
   public function selectLibraryId($id_bib) {
     return new Class_WebService_Redmine_Issues(
                $this->select(
diff --git a/library/Class/WebService/Redmine/Workflow/Afibre.php b/library/Class/WebService/Redmine/Workflow/Afibre.php
index 963aee819d990a67e20b6fdc64009bd521859870..b298a4442ee2e14e01dfdc7a2d3b774a85029e76 100644
--- a/library/Class/WebService/Redmine/Workflow/Afibre.php
+++ b/library/Class/WebService/Redmine/Workflow/Afibre.php
@@ -66,6 +66,10 @@ class Class_WebService_Redmine_Workflow_Afibre extends  Class_WebService_Redmine
   public function getNumberOfIssuesNotification() {
     $issues = Class_WebService_Redmine_Issues::forUserFromCache(Class_Users::getIdentity());
 
-    return count($issues->select(function($issue) { return $issue->getStatusId() == self::QUESTION_CLIENT; }));
+    return count($issues
+                 ->select(function($issue)
+                                 {
+                                   return $issue->getStatusId() == self::QUESTION_CLIENT;
+                                 }));
   }
 }
\ No newline at end of file
diff --git a/library/ZendAfi/Form/Redmine/Issue.php b/library/ZendAfi/Form/Redmine/Issue.php
index 4c902d8afdce9eb379a4cdeccc07d63976f6d1bb..396ceb1dd78d9100691717acdf5dfaee915abf5b 100644
--- a/library/ZendAfi/Form/Redmine/Issue.php
+++ b/library/ZendAfi/Form/Redmine/Issue.php
@@ -23,8 +23,13 @@
 class ZendAfi_Form_Redmine_Issue extends ZendAfi_Form {
   protected
     $_issue,
-    $_status = [], $_priorities = [], $_modules = [],
-    $_default_priority, $_default_module, $_default_contact, $_default_customer;
+    $_status = [],
+    $_priorities = [],
+    $_modules = [],
+    $_default_priority,
+    $_default_module,
+    $_default_contact,
+    $_default_customer;
 
 
   public static function newWithIssue($issue, $service) {
@@ -65,6 +70,37 @@ class ZendAfi_Form_Redmine_Issue extends ZendAfi_Form {
 
 
   protected function initInputs() {
+
+    Class_ScriptLoader::getInstance()
+      ->addOPACScript('file_uploader.js')
+      ->addJqueryReady(sprintf('$("#attachment").file_uploader("%s");',
+                               Class_Url::relative(['module' => 'admin',
+                                                    'controller' => 'redmine',
+                                                    'action' => 'upload-file',
+                                                    'id_lib' => Class_Url::getParam('id_lib')])));
+
+    $this
+      ->addElement('file',
+                   'attachment',
+                   ['label' => $this->_('Pièce jointe'),
+                    'destination' => PATH_TEMP])
+
+      ->addElement('hidden',
+                   'token')
+
+      ->addElement('hidden',
+                   'filename')
+
+      ->addElement('hidden',
+                   'filetype')
+
+      ->addElement('info',
+                   'attachment_error',
+                   ['value' => '',
+                    'id' => 'attachment_error',
+                    'class' => 'error',
+                    'style' => 'display: none;']);
+
     if (!$this->_issue->getid()) {
       $this
         ->addElement('text',
@@ -77,7 +113,7 @@ class ZendAfi_Form_Redmine_Issue extends ZendAfi_Form {
         ->addElement('textarea',
                      'technical_informations',
                      ['label' => $this->_('Informations techniques'),
-                      'rows' => 4,
+                      'rows' => 6,
                       'cols' => 70,
                       'required' => false,
                       'readonly' => 'readonly',
@@ -94,7 +130,11 @@ class ZendAfi_Form_Redmine_Issue extends ZendAfi_Form {
                       'value' => '',
                       'placeholder' => $this->_('Merci de préciser les différentes étapes pour reproduire le problème rencontré, l\'adresse de la page, si il faut être connecté avec un compte particulier')])
 
-        ->addDisplayGroup(['subject', 'description', 'technical_informations'],
+        ->addDisplayGroup(['subject',
+                           'description',
+                           'technical_informations',
+                           'attachment',
+                           'attachment_error'],
                           'common',
                           ['legend' => ''])
         ;
@@ -103,8 +143,12 @@ class ZendAfi_Form_Redmine_Issue extends ZendAfi_Form {
 
     if ($this->_issue->getid()) {
       $this
-        ->addElement('textarea', 'notes', ['rows' => 5, 'cols' => 75])
-        ->addDisplayGroup(['notes'], 'default', ['legend' => $this->_('Nouvelle note')]);
+        ->addElement('textarea', 'notes', [
+                                           'label' => $this->_('Note'),
+                                           'rows' => 5, 'cols' => 75])
+        ->addDisplayGroup(['notes',
+                           'attachment',
+                           'attachment_error'], 'default', ['legend' => $this->_('Nouvelle note')]);
     }
 
 
@@ -136,8 +180,11 @@ class ZendAfi_Form_Redmine_Issue extends ZendAfi_Form {
                        'rows' => 2, 'cols' => 50,
                        'value' => $this->_issue->getContact() ? $this->_issue->getContact() : $this->getDefaultContact()])
 
-
-         ->addDisplayGroup(['customer', 'status_id', 'priority', 'module', 'contact'],
+         ->addDisplayGroup(['customer',
+                            'status_id',
+                            'priority',
+                            'module',
+                            'contact'],
                            'properties',
                            ['legend' => $this->_('Propriétés')]);
 
@@ -177,9 +224,9 @@ class ZendAfi_Form_Redmine_Issue extends ZendAfi_Form {
       return;
 
     if ($library->hasMail() || $library->hasTelephone())
-        return implode(' / ', array_filter([$library->getLibelle(),
-                                            $library->getMail(),
-                                            $library->getTelephone()]));
+      return implode(' / ', array_filter([$library->getLibelle(),
+                                          $library->getMail(),
+                                          $library->getTelephone()]));
   }
 
 
diff --git a/library/ZendAfi/View/Helper/Admin/FrontNav.php b/library/ZendAfi/View/Helper/Admin/FrontNav.php
index 04ef2e194d737375990e69e6965bc556e67dca11..50ac3b126cc8b0f1c342568ac3ed4090dc7e687f 100644
--- a/library/ZendAfi/View/Helper/Admin/FrontNav.php
+++ b/library/ZendAfi/View/Helper/Admin/FrontNav.php
@@ -67,15 +67,30 @@ class ZendAfi_View_Helper_Admin_FrontNav extends ZendAfi_View_Helper_BaseHelper
 
   protected function _myAccount() {
     $id = Class_Users::getIdentity()->getId();
+    $name = Class_Users::getNomAff($id);
+    $anchors = [$this->_tag('li',
+                            $this->view->tagAnchor(['module' => 'admin',
+                                                    'controller' => 'users',
+                                                    'action' => 'edit',
+                                                    'id' => $id],
+                                                   $name,
+                                                   ['title' => $this->_('Accéder à la page de modification de mon compte administrateur'),
+                                                    'data-popup' => 'true'])),
+                $this->_tag('li', $this->view->tagAnchor($this->view->url(['module' => 'admin',
+                                                                           'controller' => 'auth',
+                                                                           'action' => 'logout'], null, true),
+                                                         $this->_('Se déconnecter')
+                                                         . Class_Admin_Skin::current()->renderMenuIconOn('logout',
+                                                                                                         $this->view,
+                                                                                                         ['alt' => 'logout',
+                                                                                                          'style' => 'filter: invert(1);']),
+                                                         ['title' => $this->_('Se déconnecter du compte : %s', $name)]))];
+
     return $this->_tag('div',
-                       $this->view->tagAnchor(['module' => 'admin',
-                                               'controller' => 'users',
-                                               'action' => 'edit',
-                                               'id' => $id],
-                                              $this->_('Utilisateur courant : %s', Class_Users::getNomAff($id)),
-                                              ['title' => $this->_('Accéder à la page de modification de mon compte administrateur'),
-                                               'data-popup' => 'true']),
-                       ['class' => 'admin_menu_title']);
+                       $this->_('Utilisateur courant'),
+                       ['class' => 'admin_menu_title'])
+
+      . $this->_tag('ul', implode($anchors));
   }
 
 
@@ -227,6 +242,16 @@ class ZendAfi_View_Helper_Admin_FrontNav extends ZendAfi_View_Helper_BaseHelper
                                                                       'home')),
                                      ['title' => $this->_('Accéder à l\'interface d\'administration')])];
 
+    if(Class_AdminVar::isRedmineEnabled())
+      $links [] = $this->view->tagAnchor($this->view->url(['module' => 'admin',
+                                                           'controller' => 'redmine',
+                                                           'action' => 'index'], null, true),
+                                         Class_Admin_Skin::current()->renderMenuIconOn('redmine',
+                                                                                       $this->view,
+                                                                                       ['alt' => 'redmine'])
+                                         . $this->_('Assistance (%d)', Class_WebService_Redmine_Workflow::current()->getNumberOfIssuesNotification()),
+                                         ['title' => $this->_('Accéder à l\'assistance')]);
+
     if($this->_isAllowed('cms', 'index'))
       $links[] = $this->view->tagAnchor(Class_Url::absolute('/admin/cms/'),
                                         $this->_('Articles') .
diff --git a/library/ZendAfi/View/Helper/Button.php b/library/ZendAfi/View/Helper/Button.php
index fb43bb5933316da333dda0e6ef12ab1ad7232212..f4c518a3e736df311c11891fa3b295796ceb525b 100644
--- a/library/ZendAfi/View/Helper/Button.php
+++ b/library/ZendAfi/View/Helper/Button.php
@@ -50,7 +50,7 @@ class ZendAfi_View_Helper_Button extends ZendAfi_View_Helper_BaseHelper {
       return $this;
 
     $button->setAttribs(array_merge($button->getAttribs(),
-                                    ['onclick' => sprintf('window.location.href = \'%s\';return false;',
+                                    ['onclick' => sprintf('window.location.href = \'%s\';',
                                                           $button->getUrl())]));
     return $this;
   }
diff --git a/library/ZendAfi/View/Helper/Redmine/Header.php b/library/ZendAfi/View/Helper/Redmine/Header.php
index df6834e6b25eb2ff89045d2ce26813cb1bd236dd..d833b574a68c1e3205de8bd8f152c81c98576468 100644
--- a/library/ZendAfi/View/Helper/Redmine/Header.php
+++ b/library/ZendAfi/View/Helper/Redmine/Header.php
@@ -104,8 +104,9 @@ class ZendAfi_View_Helper_Redmine_Header extends ZendAfi_View_Helper_BaseHelper
                                ->setUrl($this->view->url(['module' => 'admin',
                                                           'controller' => 'bib',
                                                           'action' => 'edit',
-                                                          'id' => $library->getId(),
-                                                          'backUrl' => $this->view->url()], null ,true) . '#fieldset-redmine')
+                                                          'id' => $library->getId()], null ,true)
+                                        . '?backUrl=' . $this->view->url()
+                                        . '#fieldset-redmine')
                                ->setAttribs(['class' => 'library_redmine_account',
                                              'title' => $title]));
   }
diff --git a/library/ZendAfi/View/Helper/Redmine/IssueAttachments.php b/library/ZendAfi/View/Helper/Redmine/IssueAttachments.php
new file mode 100644
index 0000000000000000000000000000000000000000..7602fe5bd84f66bd735d3a826e3912cc487f02c6
--- /dev/null
+++ b/library/ZendAfi/View/Helper/Redmine/IssueAttachments.php
@@ -0,0 +1,39 @@
+<?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 ZendAfi_View_Helper_Redmine_IssueAttachments extends ZendAfi_View_Helper_BaseHelper {
+  protected $_issue;
+
+  public function Redmine_IssueAttachments($issue) {
+    if (!$issue || (!$attachements = $issue->getattachments()))
+      return $this->_('Aucune pièce jointe');
+
+    $html = [];
+    foreach($attachements as $attachment)
+      $html [] = $this->_tag('li',
+                             $issue->renderAttachment($this->view, (new Class_Entity($attachment))
+                                                      ->setnew_value($attachment['filename'])
+                                                      ->setname($attachment['id'])));
+
+    return $this->_tag('ul', implode($html));
+  }
+}
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/Redmine/IssueJournal.php b/library/ZendAfi/View/Helper/Redmine/IssueJournal.php
index 2b1a65b6fcf9c67033a3f1ca646f8b3a8dc50c44..518e56cebcbbbdba725118db44e49786346176af 100644
--- a/library/ZendAfi/View/Helper/Redmine/IssueJournal.php
+++ b/library/ZendAfi/View/Helper/Redmine/IssueJournal.php
@@ -95,6 +95,9 @@ class ZendAfi_View_Helper_Redmine_IssueJournal extends ZendAfi_View_Helper_BaseH
 
 
   protected function renderDetail($detail) {
+    if('attachment' == $detail['property'])
+      return $this->_tag('li', $this->_issue->renderAttachment($this->view,
+                                                               new Class_Entity($detail)));
     if ('relation' == $detail['property'])
       return $this->_tag('li', $this->labelFromCode($detail['name'],
                                                     isset($detail['old_value']) ? $detail['old_value'] : null,
@@ -107,7 +110,7 @@ class ZendAfi_View_Helper_Redmine_IssueJournal extends ZendAfi_View_Helper_BaseH
       return $this->_tag('li', $this->getChangeLabel($this->customFrom($detail['name']),
                                                      $detail['old_value'], $detail['new_value']));
 
-    return '';
+    return $this->_tag('li', implode(' ', $detail));
   }
 
 
diff --git a/library/ZendAfi/View/Helper/Redmine/Issues.php b/library/ZendAfi/View/Helper/Redmine/Issues.php
index 85d8bc4f5c64fc8e35a62a8263c1317b6ff29bdf..97a3097d407c3e51bf9256b15a6242fdba5db39f 100644
--- a/library/ZendAfi/View/Helper/Redmine/Issues.php
+++ b/library/ZendAfi/View/Helper/Redmine/Issues.php
@@ -29,9 +29,16 @@ class ZendAfi_View_Helper_Redmine_Issues extends ZendAfi_View_Helper_BaseHelper
     if (!Class_AdminVar::isRedmineEnabled() || !$issues)
       return '';
 
-    return
-      $this->renderIssues($library, $issues->selectNotClosed(), $this->_('Demandes en cours'))
-      . $this->renderIssues($library, $issues->selectClosed(), $this->_('Demandes fermées'));
+    $script_loader = Class_ScriptLoader::getInstance()
+      ->addSearchInputToContent($this->_('Chercher'))
+      ->addJQueryReady('$(\'#issues_list\').accordion({heightStyle: \'content\'});');
+
+(new Class_Admin_Skin)->renderJQueryCssOn($script_loader);
+return $this->_tag('div',
+                   $this->renderIssues($library, $issues->selectActionNeeded(), $this->_('Demandes auxquelles je dois répondre'))
+                   . $this->renderIssues($library, $issues->selectNotClosed(), $this->_('Demandes en cours'))
+                   . $this->renderIssues($library, $issues->selectClosed(), $this->_('Demandes fermées')),
+                   ['id' => 'issues_list']);
   }
 
 
@@ -56,19 +63,20 @@ class ZendAfi_View_Helper_Redmine_Issues extends ZendAfi_View_Helper_BaseHelper
       return strftime('%x', strtotime($model->getcreated_on()));
     };
 
-    return $this->_tag('h3', $label)
-      . $this->view->tagModelTable($issues,
-                                   [$this->_('Numéro'), $this->_('Sujet'),
-                                    $this->_('Statut'), $this->_('Créée le')],
+    return $this->_tag('h2', $label . $this->_tag('small', count($issues), ['style' => 'margin-left: 1em;']))
+      . $this->_tag('div',
+                    $this->view->tagModelTable($issues,
+                                               [$this->_('Numéro'), $this->_('Sujet'),
+                                                $this->_('Statut'), $this->_('Créée le')],
 
-                                   ['id', 'subject', 'status', 'created_on'],
+                                               ['id', 'subject', 'status', 'created_on'],
 
-                                   [$editAction],
+                                               [$editAction],
 
-                                   'issues-' . $library->getId(),
+                                               'issues-' . $library->getId(),
                                    null,
 
-                                   ['status' => $status_renderer,
-                                    'created_on' => $date_renderer]);
+                                               ['status' => $status_renderer,
+                                                'created_on' => $date_renderer]));
   }
 }
\ No newline at end of file
diff --git a/public/admin/skins/bokeh74/form.css b/public/admin/skins/bokeh74/form.css
index 46148525ef829da91d7a27b842611e9839cc0fae..09f121a05d1697b96cc2fc177ae3f3151ec96ebd 100644
--- a/public/admin/skins/bokeh74/form.css
+++ b/public/admin/skins/bokeh74/form.css
@@ -158,3 +158,8 @@ body .ui-tabs .ui-tabs-nav > .ui-tabs-active > a.modified,
 body .ui-tabs .ui-tabs-nav > .ui-state-default > a.modified {
     color: var(--error-text);
 }
+
+.admin-form [readonly="readonly"] {
+    cursor: default;
+    background-color: var(--main-background);
+}
diff --git a/public/admin/skins/bokeh74/jquery.css b/public/admin/skins/bokeh74/jquery.css
index 5455929e9dd8641c58f19ef72194c7e12529de36..8f300d7762b2e7d0ea5ae7148c7e463d4f851792 100644
--- a/public/admin/skins/bokeh74/jquery.css
+++ b/public/admin/skins/bokeh74/jquery.css
@@ -59,7 +59,8 @@ body .ui-tabs .ui-tabs-nav > .ui-tabs-active > a {
 }
 
 .ui-dialog .zend_form,
-.ui-dialog fieldset {
+.ui-dialog fieldset,
+.ui-dialog .ui-dialog-content {
     margin: 0;
     padding: 0;
     text-align:center;
@@ -69,7 +70,6 @@ body .ui-tabs .ui-tabs-nav > .ui-tabs-active > a {
     margin-right: 10px;
 }
 
-
 .ui-dialog fieldset td.gauche {
     text-align: left;
 }
@@ -150,4 +150,41 @@ body .ui-dialog .show_drag_and_drop {
 body .ui-tabs a.errors.ui-tabs-anchor {
     color: white;
     background: var(--error-text);
-}
\ No newline at end of file
+}
+
+body .ui-progressbar .ui-progressbar-value {
+    background : var(--success-background);
+    margin: 0;
+
+}
+
+body .ui-progressbar {
+    height: 1em;
+}
+
+body .ui-accordion .ui-accordion-header {
+    padding: 1ex 1em 1ex 2em;
+    margin: 0.5ex 0;
+}
+
+body .ui-accordion .ui-accordion-header a {
+    color: inherit;
+    background: none;
+}
+
+body .ui-accordion .ui-accordion-header {
+    color: var(--button);
+    background-color: var(--button-background);
+}
+
+body .ui-accordion .ui-accordion-header:hover,
+body .ui-accordion .ui-accordion-header.ui-state-active {
+    color: var(--button-highlight);
+    background-color: var(--button-background-highlight);
+}
+
+body .ui-accordion .ui-accordion-content {
+    padding: 1ex 1em;
+    margin: 0;
+    background-color: var(--main-background);
+}
diff --git a/public/opac/java/form_to_tabs/form_to_tabs.js b/public/opac/java/form_to_tabs/form_to_tabs.js
index 0ad150cce3c8888aa68c19ddef51229090f3280a..fb3b271709bbbaa27f59131021323e0f471103a5 100644
--- a/public/opac/java/form_to_tabs/form_to_tabs.js
+++ b/public/opac/java/form_to_tabs/form_to_tabs.js
@@ -21,29 +21,28 @@
 (function ( $ ) {
   $.fn.form_to_tabs = function() {
     var form = $(this);
-    var tabs = $('<ul></ul>');
-    var no_legend = $('<div></div>');
     var form_fieldsets = form.find('fieldset');
 
-    if(1 >= form_fieldsets.length)
+    if(0 == form_fieldsets.length)
       return false;
 
+    var tabs = $('<ul></ul>');
+    var no_legend = $('<div></div>');
+
     form_fieldsets.each(function(index, element) {
       var fieldset = $(element);
-      //fieldset.attr('id', 'tab'+index)
       var legend = fieldset.find('legend');
 
-      if(1 > legend.length) {
-        no_legend.append(fieldset.clone());
-        fieldset.remove();
-        return;
+      if(0 == legend.length) {
+        fieldset.appendTo(no_legend);
+        return true;
       }
 
       var tab_link = $('<a>' + legend.text() +'</a>');
       tab_link.attr('href', '#' + fieldset.attr('id'));
       
       if (fieldset.find('.errors').length > 0)
-	tab_link.addClass('errors');
+	      tab_link.addClass('errors');
 
       
       tabs.append($('<li></li>').append(tab_link));
diff --git a/public/opac/java/search_input/search_input.js b/public/opac/java/search_input/search_input.js
index d359045af535a78e88c446871073fb7e3f889c55..3bec72fb4c23d680e64a883127417d9505ed5ea6 100644
--- a/public/opac/java/search_input/search_input.js
+++ b/public/opac/java/search_input/search_input.js
@@ -22,7 +22,7 @@
   $.fn.search_input = function(options) {
     if ($('head').find('link[href*="search_input.css"]').length < 1) {
       $('head').append('<link media="screen" href="' 
-		       + baseUrl + '/public/opac/java/search_input/search_input.css" rel="stylesheet" type="text/css"></link>');
+		                   + baseUrl + '/public/opac/java/search_input/search_input.css" rel="stylesheet" type="text/css"></link>');
     }
 
     var default_option_id = 'default_search_input_id';
@@ -31,8 +31,8 @@
 
     if(undefined == options)
       options = {id : default_input_id,
-		 label : default_input_label,
-		 fixed_display : ''};
+		             label : default_input_label,
+		             fixed_display : ''};
 
     if(undefined == options.id)
       options.id = default_input_id;
@@ -52,11 +52,11 @@
     var onSearchInputChange = function(searchText) {
       
       var resetAll = function() {
-	html.find('*').removeClass(not_found_class);
+	      html.find('*').removeClass(not_found_class);
       }
       
       if (searchText == "" || searchText == '*') {
-	return resetAll();
+	      return resetAll();
       }
 
       var accentsTidy = function(s){
@@ -75,9 +75,9 @@
       };
       
       var highlightItems = function(elements) {
-	resetAll();
-	html.find('*').not(elements).not(default_fixed_display + options.fixed_display).addClass(not_found_class);
-	html.find(elements).parentsUntil(html).removeClass(not_found_class);
+	      resetAll();
+	      html.find('*').not(elements).not(default_fixed_display + options.fixed_display).addClass(not_found_class);
+	      html.find(elements).parentsUntil(html).removeClass(not_found_class).show();
       }
 
       searchText = accentsTidy(searchText);
@@ -87,19 +87,19 @@
       var reg_exps = [];
 
       $.each(searchText, function(index, term) {
-	var reg = new RegExp('\\b' + term, 'gi');
-	reg_exps.push(reg);
+	      var reg = new RegExp('\\b' + term, 'gi');
+	      reg_exps.push(reg);
       });
 
       var matches = html.find('*').contents().filter(function() {
-	if(this.nodeType != 3)
-	  return false;
+	      if(this.nodeType != 3)
+	        return false;
 
-	for(var index in reg_exps)
+	      for(var index in reg_exps)
       	  if(!reg_exps[index].test(accentsTidy(this.nodeValue)))
-	    return false;
+	          return false;
 
-	return true;
+	      return true;
       });
 
       highlightItems(matches);
@@ -107,15 +107,15 @@
 
 
     var search_input = html.prepend("<div class='search_input'>" +
-				    "<form>" + 
-				    "<label for='" + options.id + "'>" + options.label + "</label>" +
-				    "<input type='text' name='search_input' id='" + options.id +"'></input>" +
-				    "</form>" +
-				    "</div>")
-      .find('input')
-      .keyup(function(event){
-	onSearchInputChange($(this).val());
-      })
-      .end();
+				                            "<form>" + 
+				                            "<label for='" + options.id + "'>" + options.label + "</label>" +
+				                            "<input type='text' name='search_input' id='" + options.id +"'></input>" +
+				                            "</form>" +
+				                            "</div>")
+        .find('input')
+        .keyup(function(event){
+	        onSearchInputChange($(this).val());
+        })
+        .end();
   }
 } (jQuery));
diff --git a/public/opac/js/file_uploader.js b/public/opac/js/file_uploader.js
new file mode 100644
index 0000000000000000000000000000000000000000..bfd89a389d12b5f61f0946bdeafc963de7139d21
--- /dev/null
+++ b/public/opac/js/file_uploader.js
@@ -0,0 +1,49 @@
+(function ( $ ) {
+  $.fn.file_uploader = function(url) {
+    var input_file = $(this);
+    $(input_file).change(function(event) {
+      postAjax(event);
+    });
+
+    var postAjax = function(event) {
+      var image_preview = input_file.closest('tr').find('img');
+      input_file.closest('form').find('#attachment_error').hide();
+      if(0 == image_preview.length) {
+        input_file.closest('td').append('<img style="display: block; width: 500px; margin: 1ex 0;"></img>')
+        image_preview = input_file.closest('tr').find('img');
+      }
+
+      var file = null,
+          is_image = null;
+
+      if((!(file = event.target.files[0])) ||
+         (!(is_image = file.type.match(/image.*/)))) {
+        image_preview.hide();
+      }
+
+      var reader = new FileReader();
+
+      reader.onload = function(e) {
+        var file_content = e.target.result;
+        if(is_image) {
+          var image = new Image();
+          image.src = file_content;
+          image_preview.attr('src', file_content);
+          image_preview.show();
+        }
+        $.post(url,
+               {data: file_content,
+                processData: false},
+               function(data) {
+                 if('message' in data)
+                   return input_file.closest('form').find('#attachment_error').show().text(data.message);
+
+                 input_file.closest('form').find('#token').attr('value', data.upload.token);
+                 input_file.closest('form').find('#filename').attr('value', file.name);
+                 input_file.closest('form').find('#filetype').attr('value', file.type);
+               });
+      };
+      reader.readAsDataURL(file);
+    };
+  }
+} (jQuery));
diff --git a/tests/application/modules/admin/controllers/RedmineControllerTest.php b/tests/application/modules/admin/controllers/RedmineControllerTest.php
index 2be95ef46d10ddc69e2b74f6a0cb30089121240a..8fc8aab752b9f33ce46d06d934da9cbcde9c5f9c 100644
--- a/tests/application/modules/admin/controllers/RedmineControllerTest.php
+++ b/tests/application/modules/admin/controllers/RedmineControllerTest.php
@@ -294,7 +294,7 @@ class Admin_RedmineControllerIndexTest extends Admin_RedmineControllerWithApiTes
 
   /** @test */
   public function anchorToEditBibsShouldBePresent() {
-    $this->assertXPath('//div[@class="modules"]//button[contains(@onclick, "admin/bib/edit/id/1/backUrl/")]');
+    $this->assertXPath('//div[@class="modules"]//button[contains(@onclick, "admin/bib/edit/id/1?backUrl=")]');
   }
 
 
@@ -433,10 +433,10 @@ abstract class Admin_RedmineControllerFixtureAbstractTest extends Admin_RedmineC
     parent::setUp();
 
     $redmine_api = $this->mock()
-                        ->whenCalled('show')->with('34247', ['include' => 'journals'])
+                        ->whenCalled('show')->with('34247', ['include' => 'attachments,journals'])
                         ->answers(RedmineFixtures::issue34247WithJournals())
 
-                        ->whenCalled('show')->with('34248', ['include' => 'journals'])
+                        ->whenCalled('show')->with('34248', ['include' => 'attachments,journals'])
                         ->answers(RedmineFixtures::issue34248WithJournals())
 
                         ->whenCalled('update')->answers('hfg')
@@ -449,9 +449,26 @@ abstract class Admin_RedmineControllerFixtureAbstractTest extends Admin_RedmineC
     $redmine_api_priority = $this->mock()
                                  ->whenCalled('all')->answers(RedmineFixtures::supportPriority());
 
+    $redmine_api_attachment = $this->mock()
+
+                                   ->whenCalled('upload')
+                                   ->with('image content')
+                                   ->answers('{"upload":{"token":"7167.ed1ccdb093229ca1bd0b043618d88743"}}')
+
+                                   ->whenCalled('upload')
+                                   ->with('image invalide')
+                                   ->answers('<html>ERROR 500</html>')
+
+                                   ->whenCalled('upload')
+                                   ->with('token invalide')
+                                   ->answers('{"upload":{"token":"7167."}}')
+
+                                   ->beStrict();
+
     $redmine_client = $this->mock()
                            ->whenCalled('api')->with('issue')->answers($redmine_api)
                            ->whenCalled('api')->with('issue_status')->answers($redmine_api_status)
+                           ->whenCalled('api')->with('attachment')->answers($redmine_api_attachment)
                            ->beStrict();
 
     Class_WebService_Redmine::setClient($redmine_client);
@@ -483,7 +500,7 @@ class Admin_RedmineControllerEditIssue34247Test extends Admin_RedmineControllerF
             ['//ul//li', 'Priorité client changé de Normale à Urgente'],
             ['//td','test-support'],
             ['//td', '07/01/2016 à 09:30:26'],
-
+            ['//td//a', 'Pièce jointe : "proof.jpg"']
     ];
   }
 
@@ -636,7 +653,7 @@ class Admin_RedmineControllerPostEditIssue34247Test extends Admin_RedmineControl
     parent::setUp();
 
     $redmine_api = $this->mock()
-                        ->whenCalled('show')->with('34247', ['include' => 'journals'])
+                        ->whenCalled('show')->with('34247', ['include' => 'attachments,journals'])
                         ->answers(RedmineFixtures::issue34247WithJournals())
 
                         ->whenCalled('update')->answers('hfg')
@@ -726,13 +743,14 @@ class Admin_RedmineControllerAddIssueTest extends Admin_RedmineControllerFixture
 
 
   public function data_form() {
-    return [ ['//form'],
+    return [['//form'],
             ['//input[@id="subject"]'],
             ['//select[@id="priority"]//option[@value="Normale"][@selected]'],
             ['//select[@id="module"]'],
             ['//textarea[@id="description"]'],
             ['//textarea[@id="technical_informations"][@readonly][contains(text(), "Url :")]'],
-            ['//textarea[@id="contact"]']];
+            ['//textarea[@id="contact"]'],
+            ['//input[@type="file"]']];
   }
 
 
@@ -743,4 +761,105 @@ class Admin_RedmineControllerAddIssueTest extends Admin_RedmineControllerFixture
   public function formShouldContains($tag) {
     $this->assertXPath($tag, $this->_response->getBody());
   }
-}
\ No newline at end of file
+}
+
+
+
+
+
+class Admin_RedmineControllerUploadFileTest extends Admin_RedmineControllerFixtureAbstractTest{
+
+  /** @test */
+  public function shouldReturnJsonResponse() {
+    $this->postDispatch('admin/redmine/upload-file/id_lib/1', ['data' => base64_encode('image content')]);
+    $this->assertEquals('{"upload":{"token":"7167.ed1ccdb093229ca1bd0b043618d88743"}}', $this->_response->getBody());
+  }
+
+
+  /** @test */
+  public function shouldReturnErrorMessageInJsonBecauseContainsHTML() {
+    $this->postDispatch('admin/redmine/upload-file/id_lib/1', ['data' => base64_encode('image invalide')]);
+    $this->assertContains('{"status":"error","message":"La pi\u00e8ce jointe est invalide.",', $this->_response->getBody());
+  }
+
+
+  /** @test */
+  public function shouldReturnErrorMessageInJsonBecauseTokenDoesntMatch() {
+    $this->postDispatch('admin/redmine/upload-file/id_lib/1', ['data' => base64_encode('token invalide')]);
+    $this->assertContains('{"status":"error","message":"L\'ajout de la pi\u00e8ce jointe a \u00e9chou\u00e9 car la cl\u00e9 re\u00e7ue \"7167.\" est invalide."', $this->_response->getBody());
+  }
+}
+
+
+
+
+class Admin_RedmineControllerPostEditIssue34247WithAttachmentTest extends Admin_RedmineControllerWithApiTestCase {
+  protected $_update_params;
+
+  public function setUp() {
+    parent::setUp();
+
+    $redmine_api = $this->mock()
+
+                        ->whenCalled('show')
+                        ->with('34247', ['include' => 'attachments,journals'])
+                        ->answers(RedmineFixtures::issue34247WithJournals())
+
+                        ->whenCalled('update')
+                        ->with(34247,
+                               ['status_id' => 5,
+                                'custom_fields' => [['id' => 5,
+                                                     'value' => 'Normale'],
+                                                    ['id' => 37,
+                                                     'value' => ''],
+                                                    ['id' => 43,
+                                                     'value' => ''],
+                                                    ['id' => 38,
+                                                     'value' => 'Bug logiciel']],
+                               'notes' => 'add proof'])
+                        ->answers(true)
+
+                        ->whenCalled('all')
+                        ->with(['project_id' => 123])
+                        ->answers(RedmineFixtures::supportStatus())
+
+                        ->whenCalled('attach')
+                        ->with(34247,
+                               ['token' => '7167.ed1ccdb093229ca1bd0b043618d88743',
+                                'filename' => 'proof.png',
+                                'content_type' => 'image/png'])
+                        ->answers(true)
+
+                        ->beStrict();
+
+    $redmine_client = $this->mock()
+                           ->whenCalled('api')
+                           ->answers($redmine_api);
+
+    Class_WebService_Redmine::setClient($redmine_client);
+
+    $this->postDispatch('admin/redmine/edit-issue/id_lib/1/id/34247',
+                        ['status_id' => '5',
+                         'priority' => 'Normale',
+                         'notes' => 'add proof',
+                         'module' => '',
+                         'contact' => '',
+                         'token' => '7167.ed1ccdb093229ca1bd0b043618d88743',
+                         'filename' => 'proof.png',
+                         'filetype' => 'image/png']);
+
+    $this->_update_params = $redmine_api->getAttributesForLastCallOn('update')[1];
+  }
+
+
+  /** @test */
+  public function issue34247ShouldHaveBeenUpdated() {
+    $this->assertFlashMessengerContentContains('Demande #34247 enregistrée');
+  }
+
+
+  /** @test */
+  public function shouldRedirectToReferer() {
+    $this->assertRedirect();
+  }
+}
diff --git a/tests/fixtures/RedmineFixtures.php b/tests/fixtures/RedmineFixtures.php
index 475493334017a00665de29e7338bc9bf005a55b2..5bab9f300c192019c13ba59da5569c81b8682bd0 100644
--- a/tests/fixtures/RedmineFixtures.php
+++ b/tests/fixtures/RedmineFixtures.php
@@ -58,33 +58,33 @@ class RedmineFixtures {
   public static function sandreIssues() {
     return ['issues' => [
                          ['id' => 34246,
-                           'project' => ['id' => 56,
-                                         'name' => 'Développement Bokeh AFI-OPAC 2.0'],
-                           'tracker' => ['id' => 2,
-                                         'name' => 'Développement'],
-                           'status' => ['id' => 7 ,
-                                        'name' => 'En développement'],
-                           'priority' => ['id' => 4,
-                                          'name' => 'Normal'],
-                           'author' => ['id' => 207,
-                                        'name' => 'gloas'],
-                           'assigned_to' => ['id' => 207,
-                                             'name' => 'gloas'],
-                           'subject' => 'Charte graphique back-office',
-                           'description' => 'un ticket redmine',
-                           'done_ratio' => 30,
-                           'custom_fields' => [ ['id' => 37,
-                                                 'name' => 'Module Portail',
-                                                 'value' => ''],
-                                               ['id' => 5 ,
-                                                'name' => 'Priorité client',
-                                                'value' => 'Normale'],
-                                               ['id' => 11,
-                                                'name' => 'Phase',
-                                                'value' => '']],
-                           'created_on' => '2015-12-04T09:19:11Z',
-                           'updated_on' => '2015-12-04T09:25:42Z',
-                           'story_points' => ''],
+                          'project' => ['id' => 56,
+                                        'name' => 'Développement Bokeh AFI-OPAC 2.0'],
+                          'tracker' => ['id' => 2,
+                                        'name' => 'Développement'],
+                          'status' => ['id' => 7 ,
+                                       'name' => 'En développement'],
+                          'priority' => ['id' => 4,
+                                         'name' => 'Normal'],
+                          'author' => ['id' => 207,
+                                       'name' => 'gloas'],
+                          'assigned_to' => ['id' => 207,
+                                            'name' => 'gloas'],
+                          'subject' => 'Charte graphique back-office',
+                          'description' => 'un ticket redmine',
+                          'done_ratio' => 30,
+                          'custom_fields' => [ ['id' => 37,
+                                                'name' => 'Module Portail',
+                                                'value' => ''],
+                                              ['id' => 5 ,
+                                               'name' => 'Priorité client',
+                                               'value' => 'Normale'],
+                                              ['id' => 11,
+                                               'name' => 'Phase',
+                                               'value' => '']],
+                          'created_on' => '2015-12-04T09:19:11Z',
+                          'updated_on' => '2015-12-04T09:25:42Z',
+                          'story_points' => ''],
 
                          static::issue34247(),
                          static::issue34248()],
@@ -166,131 +166,115 @@ class RedmineFixtures {
   public static function issue34247WithJournals() {
     return
       [ 'issue' =>
-          [ 'id' => 34247,
-                 'project' => [ 'id' => 214,
-                                     'name' => 'Support Bokeh AFI-OPAC 2.0',
-                                     ],
-                 'tracker' => [ 'id' => 12,
-                                     'name' => 'Demande d\'assistance',
-                                     ],
-                 'status' => [ 'id' => 2,
-                                    'name' => 'Affecté au dév.',
-                                    ],
-                 'priority' => [ 'id' => 5,
-                                      'name' => 'Haut',
-                                      ],
-                 'author' => [ 'id' => 207,
-                                    'name' => 'gloas',
-                                    ],
-                 'assigned_to' => [ 'id' => 207,
-                                         'name' => 'gloas',
-                                         ],
-                 'subject' => 'reindexation des champs personnalisés ',
-                 'description' => 'Url de l\'anomalie : http://web.afi-sa.net/miop-test.net/admin/custom-fields/edit/id/1
+       [ 'id' => 34247,
+        'project' => [ 'id' => 214,
+                      'name' => 'Support Bokeh AFI-OPAC 2.0',
+        ],
+        'tracker' => [ 'id' => 12,
+                      'name' => 'Demande d\'assistance',
+        ],
+        'status' => [ 'id' => 2,
+                     'name' => 'Affecté au dév.',
+        ],
+        'priority' => [ 'id' => 5,
+                       'name' => 'Haut',
+        ],
+        'author' => [ 'id' => 207,
+                     'name' => 'gloas',
+        ],
+        'assigned_to' => [ 'id' => 207,
+                          'name' => 'gloas',
+        ],
+        'subject' => 'reindexation des champs personnalisés ',
+        'description' => 'Url de l\'anomalie : http://web.afi-sa.net/miop-test.net/admin/custom-fields/edit/id/1
 
                  Étapes pour parvenir au bug :
                  * indexer un champs personnalisé
                  * les facettes des notices des articles qui ont une valeur de paramétrée pour ce champ personnalisé ne sont pas mises à jour.
                  ',
-                 'done_ratio' => 20,
-                 'spent_hours' => 0,
-                 'custom_fields' => [  [ 'id' => 43,
-                                              'name' => 'Personne à contacter',
-                                              'value' => 'Nom / prénom / email / téléphone',
-                                              ],
-                                       [ 'id' => 42,
-                                              'name' => 'Pris en charge par',
-                                              'value' => '',
-                                              ],
-                                       [ 'id' => 37,
-                                              'name' => 'Module Portail',
-                                              'value' => 'Recherche',
-                                              ],
-                                       [ 'id' => 5,
-                                              'name' => 'Priorité client',
-                                              'value' => 'Normale',
-                                              ],
-                                       [ 'id' => 1,
-                                              'name' => 'Client',
-                                              'value' => '',
-                                              ],
-                                       [ 'id' => 46,
-                                              'name' => 'Relancé le',
-                                              'value' => '',
-                                              ],
-                                       ],
-                 'created_on' => '2015-09-29T10:01:49Z',
-                 'updated_on' => '2015-12-02T13:37:49Z',
-                 'journals' => [  [ 'id' => 149465,
-                                         'user' => [ 'id' => 1198,
-                                                          'name' => 'test-support',
-                                                          ],
-                                         'notes' => '',
-                                         'created_on' => '2016-01-07T08:30:26Z',
-                                         'details' => [  [ 'property' => 'relation',
-                                                                      'name' => 'copied_from',
-                                                                      'new_value' => '35800',
-                                                                      ],
-                                                         ],
-                                         ],
-                                  [ 'id' => 149517,
-                                         'user' => [ 'id' => 92,
-                                                          'name' => 'other',
-                                                          ],
-                                         'notes' => 'Pris en charge par le developpement',
-                                         'created_on' => '2016-01-07T09:38:13Z',
-                                         'details' => [  [ 'property' => 'attr',
-                                                                      'name' => 'status_id',
-                                                                      'old_value' => '1',
-                                                                      'new_value' => '2',
-                                                                      ],
-                                                         [ 'property' => 'attr',
-                                                                      'name' => 'done_ratio',
-                                                                      'old_value' => '0',
-                                                                      'new_value' => '20',
-                                                                      ],
-                                                         ],
-                                         ],
-                                  [ 'id' => 149608,
-                                         'user' => [ 'id' => 92,
-                                                          'name' => 'dev',
-                                                          ],
-                                         'notes' => '',
-                                         'created_on' => '2016-01-07T11:10:00Z',
-                                         'details' => [  [ 'property' => 'relation',
-                                                                      'name' => 'copied_to',
-                                                                      'old_value' => '35831',
-                                                                      ],
-                                                         ],
-                                         ],
-                                  [ 'id' => 149610,
-                                         'user' => [ 'id' => 92,
-                                                          'name' => 'dev',
-                                                          ],
-                                         'notes' => '',
-                                         'created_on' => '2016-01-07T11:10:04Z',
-                                         'details' => [  [ 'property' => 'relation',
-                                                                      'name' => 'blocks',
-                                                                      'new_value' => '35831',
-                                                                      ],
-                                                         ],
-                                         ],
-                                  [ 'id' => 149612,
-                                         'user' => [ 'id' => 1198,
-                                                          'name' => 'test-support',
-                                                          ],
-                                         'notes' => '',
-                                         'created_on' => '2016-01-07T11:12:45Z',
-                                         'details' => [  [ 'property' => 'cf',
-                                                                      'name' => '5',
-                                                                      'old_value' => 'Normale',
-                                                                      'new_value' => 'Urgente',
-                                                                      ],
-                                                         ],
-                                         ],
-                                  ],
-                 ],
-];
+        'done_ratio' => 20,
+        'spent_hours' => 0,
+        'custom_fields' => [  [ 'id' => 43,
+                               'name' => 'Personne à contacter',
+                               'value' => 'Nom / prénom / email / téléphone',
+           ],
+                            [ 'id' => 42,
+                             'name' => 'Pris en charge par',
+                             'value' => '',
+                            ],
+                            [ 'id' => 37,
+                             'name' => 'Module Portail',
+                             'value' => 'Recherche',
+                            ],
+                            [ 'id' => 5,
+                             'name' => 'Priorité client',
+                             'value' => 'Normale',
+                            ],
+                            [ 'id' => 1,
+                             'name' => 'Client',
+                             'value' => '',
+                            ],
+                            [ 'id' => 46,
+                             'name' => 'Relancé le',
+                             'value' => '',
+                            ],
+        ],
+        'created_on' => '2015-09-29T10:01:49Z',
+        'updated_on' => '2015-12-02T13:37:49Z',
+        'journals' => [['id' => 149465,
+                        'user' => [ 'id' => 1198,
+                                   'name' => 'test-support'],
+                        'notes' => '',
+                        'created_on' => '2016-01-07T08:30:26Z',
+                        'details' => [['property' => 'relation',
+                                       'name' => 'copied_from',
+                                       'new_value' => '35800']]],
+                       ['id' => 149517,
+                        'user' => ['id' => 92,
+                                   'name' => 'other'],
+                        'notes' => 'Pris en charge par le developpement',
+                        'created_on' => '2016-01-07T09:38:13Z',
+                        'details' => [['property' => 'attr',
+                                       'name' => 'status_id',
+                                       'old_value' => '1',
+                                       'new_value' => '2'],
+                                      ['property' => 'attr',
+                                       'name' => 'done_ratio',
+                                       'old_value' => '0',
+                                       'new_value' => '20']]],
+                       ['id' => 149608,
+                        'user' => ['id' => 92,
+                                   'name' => 'dev'],
+                        'notes' => '',
+                        'created_on' => '2016-01-07T11:10:00Z',
+                        'details' => [['property' => 'relation',
+                                       'name' => 'copied_to',
+                                       'old_value' => '35831']]],
+                       ['id' => 149610,
+                        'user' => ['id' => 92,
+                                   'name' => 'dev'],
+                        'notes' => '',
+                        'created_on' => '2016-01-07T11:10:04Z',
+                        'details' => [['property' => 'relation',
+                                       'name' => 'blocks',
+                                       'new_value' => '35831']]],
+                       ['id' => 149612,
+                        'user' => ['id' => 1198,
+                                   'name' => 'test-support'],
+                        'notes' => '',
+                        'created_on' => '2016-01-07T11:12:45Z',
+                        'details' => [['property' => 'cf',
+                                       'name' => '5',
+                                       'old_value' => 'Normale',
+                                       'new_value' => 'Urgente']]],
+                       ['id' => 249465,
+                        'user' => ['id' => 1198,
+                                   'name' => 'test-support'],
+                        'notes' => '',
+                        'created_on' => '2016-01-07T08:30:26Z',
+                        'details' => [['property' => 'attachment',
+                                       'name' => '456789',
+                                       'new_value' => 'proof.jpg']]]]]];
   }