diff --git a/VERSIONS_WIP/51538 b/VERSIONS_WIP/51538
new file mode 100644
index 0000000000000000000000000000000000000000..324c170bdfbab59cf366e3a77506271910a988b0
--- /dev/null
+++ b/VERSIONS_WIP/51538
@@ -0,0 +1 @@
+ - ticket #51538 : Administration : Ajout de la possibilité de spécifier les jours de lancement des batchs
\ No newline at end of file
diff --git a/VERSIONS_WIP/61993 b/VERSIONS_WIP/61993
new file mode 100644
index 0000000000000000000000000000000000000000..cac3abf2ea2e8ce4810c26daf2686dce8d956ee9
--- /dev/null
+++ b/VERSIONS_WIP/61993
@@ -0,0 +1 @@
+ - ticket #61993 : Les icones d'administration en front cachent moins les textes
\ No newline at end of file
diff --git a/VERSIONS_WIP/63069 b/VERSIONS_WIP/63069
new file mode 100644
index 0000000000000000000000000000000000000000..046a87024a55ed8a091bf568f98229de0e91bca9
--- /dev/null
+++ b/VERSIONS_WIP/63069
@@ -0,0 +1 @@
+ - ticket #63069 : Ajout d'un batch permettant moissonner un calendrier externe automatiquement
\ No newline at end of file
diff --git a/VERSIONS_WIP/64069 b/VERSIONS_WIP/64069
new file mode 100644
index 0000000000000000000000000000000000000000..918294510c2edd0147f7c43c8043cb3c31eebc1d
--- /dev/null
+++ b/VERSIONS_WIP/64069
@@ -0,0 +1,2 @@
+ - ticket #64069: Administration : amélioration de la fonction d'ajout d'une boîte depuis l'interface publique.
+ 
\ No newline at end of file
diff --git a/VERSIONS_WIP/64071 b/VERSIONS_WIP/64071
new file mode 100644
index 0000000000000000000000000000000000000000..cc963af57e159809a3368777b1f3a13cd1926e94
--- /dev/null
+++ b/VERSIONS_WIP/64071
@@ -0,0 +1 @@
+ - ticket #64071 : Menu d'administration : lien Accueil renommé en Accès Pro
\ No newline at end of file
diff --git a/VERSIONS_WIP/64073 b/VERSIONS_WIP/64073
new file mode 100644
index 0000000000000000000000000000000000000000..1b12e34be432b110655ba336eb1cd7de206f1eb1
--- /dev/null
+++ b/VERSIONS_WIP/64073
@@ -0,0 +1 @@
+ - ticket #64073 : Nouvelle version stable : lien vers infos de version et documentation en haut de page de l'accueil de l'administration
\ No newline at end of file
diff --git a/application/modules/admin/controllers/BatchController.php b/application/modules/admin/controllers/BatchController.php
index d51f363ebfc604184d3383fe2aef0593283ae16f..fc774d80779c828e4f82c96667e3fa075a578e3d 100644
--- a/application/modules/admin/controllers/BatchController.php
+++ b/application/modules/admin/controllers/BatchController.php
@@ -23,20 +23,89 @@ class Admin_BatchController extends ZendAfi_Controller_Action {
 
   public function getPlugins() {
     return ['ZendAfi_Controller_Plugin_ResourceDefinition_Batch',
-            'ZendAfi_Controller_Plugin_Manager_Manager'];
+            'ZendAfi_Controller_Plugin_Manager_Batch'];
+  }
+
+
+  public function indexAction() {
+    parent::indexAction();
+    $this->view->definitions = Class_Batch::getAvailableBatchDefinitions();
+  }
+
+
+  public function activateAction() {
+    if ((!$type = $this->_getParam('id'))
+        || !Class_Batch::isAvailableType($type))
+      return $this->_redirectToIndex();
+
+    Class_Batch::newInstance(['type' => $type])
+      ->save();
+
+    $this->_helper->notify('Tâche activée');
+    $this->_redirectToIndex();
+  }
+
+
+  public function deleteAction() {
+    if ((!$type = $this->_getParam('id'))
+        || (!$batch = Class_Batch::findFirstBy(['type' => $type]))
+        || !$batch->isDeletable())
+      return $this->_redirectToIndex();
+
+    $batch->delete();
+
+    $this->_helper->notify('Tâche désactivée');
+    $this->_redirectToIndex();
+  }
+
+
+  public function planAction() {
+    if (!Class_Users::isCurrentUserSuperAdmin()
+        || (!$type = $this->_getParam('id'))
+        || !$batch = Class_Batch::findFirstBy(['type' => $type]))
+      return $this->_redirectToIndex();
+
+    $this->view->titre = $this->_('Planifier la tâche "%s"', $batch->getLibelle());
+    $form = (new ZendAfi_Form_Admin_Batch())
+      ->setAction($this->view->url(['module' => 'admin',
+                                    'controller' => 'batch',
+                                    'action' => 'plan',
+                                    'id' => $type],
+                                   null, true));
+    $form->populate($batch->getRawAttributes());
+    $this->view->form = $form;
+
+    if (!$this->_request->isPost()
+        || !$form->isValid($this->_request->getPost()))
+      return;
+
+    $batch->setPickDay($form->getValue('pick_day'))
+          ->save();
+
+    $this->_helper->notify('Planification de la tâche modifiée');
+    $this->_redirectClose('/admin/batch');
   }
 
 
   public function runAction() {
-    Class_Batch::find($this->_getParam('id'))->run();
+    if ((!$batch = Class_Batch::findFirstBy(['type' => $this->_getParam('id')]))
+        || !$batch->isManuallyRunnable())
+      return $this->_redirectToIndex();
+
+    $batch->run();
+
     $this->_helper->notify($this->_('Tâche executée'));
-    $this->_redirect('/admin/batch');
+    $this->_redirectToIndex();
   }
 
 
   public function runAjaxAction() {
-    $batch = Class_Batch::find($this->_getParam('id'));
-    $this->view->titre = $this->view->_('Exécution du traitement "%s"', $batch->getLibelle());
+    if ((!$batch = Class_Batch::findFirstBy(['type' => $this->_getParam('id')]))
+        || !$batch->isManuallyRunnable())
+      return $this->_redirectToIndex();
+
+    $this->view->titre = $this->view->_('Exécution du traitement "%s"',
+                                        $batch->getLibelle());
     $this->view->batch = $batch;
   }
 
@@ -47,5 +116,3 @@ class Admin_BatchController extends ZendAfi_Controller_Action {
       ->runStep($this->_request->getParams()));
   }
 }
-
-?>
\ No newline at end of file
diff --git a/application/modules/admin/controllers/ExternalAgendasController.php b/application/modules/admin/controllers/ExternalAgendasController.php
index 2398e0110a99fc46a8957a2e43809b1ffb4a21f0..0c78b90ddca93cff18bed8e96406b38e20e30bb8 100644
--- a/application/modules/admin/controllers/ExternalAgendasController.php
+++ b/application/modules/admin/controllers/ExternalAgendasController.php
@@ -23,7 +23,7 @@
 class Admin_ExternalAgendasController extends ZendAfi_Controller_Action {
   public function getPlugins() {
     return ['ZendAfi_Controller_Plugin_ResourceDefinition_ExternalAgenda',
-            'ZendAfi_Controller_Plugin_Manager_Manager'];
+            'ZendAfi_Controller_Plugin_Manager_ExternalAgenda'];
   }
 
 
@@ -32,17 +32,9 @@ class Admin_ExternalAgendasController extends ZendAfi_Controller_Action {
       return $this->_redirectToIndex();
 
     $this->view->titre = $this->_('Moissonnage des évènements de l\'agenda "%s"', $agenda->getLibelle());
-    $agenda->import($this);
-  }
-
-
-  public function visitNewEvents($events) {
-    $this->view->new_events = $events;
-  }
-
-
-  public function visitUpdatedEvents($events) {
-    $this->view->updated_events = $events;
+    $results = $agenda->import();
+    $this->view->new_events = $results['new'];
+    $this->view->updated_events = $results['update'];
   }
 
 
diff --git a/application/modules/admin/views/scripts/batch/add.phtml b/application/modules/admin/views/scripts/batch/add.phtml
deleted file mode 100644
index dc46f2831c7f803cf1fe92106a4a72f2e9d8c066..0000000000000000000000000000000000000000
--- a/application/modules/admin/views/scripts/batch/add.phtml
+++ /dev/null
@@ -1 +0,0 @@
-<?php echo $this->renderForm($this->form); ?>
\ No newline at end of file
diff --git a/application/modules/admin/views/scripts/batch/edit.phtml b/application/modules/admin/views/scripts/batch/edit.phtml
deleted file mode 100644
index dc46f2831c7f803cf1fe92106a4a72f2e9d8c066..0000000000000000000000000000000000000000
--- a/application/modules/admin/views/scripts/batch/edit.phtml
+++ /dev/null
@@ -1 +0,0 @@
-<?php echo $this->renderForm($this->form); ?>
\ No newline at end of file
diff --git a/application/modules/admin/views/scripts/batch/index.phtml b/application/modules/admin/views/scripts/batch/index.phtml
index 827623b90f929a01db9c0cb3cb413c1136d47289..6bc950081245e673621100acbb82f313c88f21b0 100644
--- a/application/modules/admin/views/scripts/batch/index.phtml
+++ b/application/modules/admin/views/scripts/batch/index.phtml
@@ -1,40 +1,17 @@
 <?php
-echo $this->Button_New((new Class_Entity())
-                       ->setText($this->_('Ajouter une tâche')));
-
-$id_placeholder = 'MODEL_ID';
-
-$delete_url = $this->url(['action' => 'delete',
-                          'id' => $id_placeholder]);
-
-$run_url = $this->url(['action' => 'run',
-                       'id' => $id_placeholder]);
-
-$run_ajax_url = $this->url(['action' => 'run-ajax',
-                            'id' => $id_placeholder]);
-
-echo $this->tagModelTable(
-  $this->batchs,
-  [$this->_('Libelle'), $this->_('Dernière exécution')],
-  ['Libelle', 'last_run'],
-  [
-    function($batch) use ($id_placeholder, $delete_url) {
-      if(!$batch->isDeletable())
-        return '';
-
-      return $this->tagAnchor(str_replace($id_placeholder, $batch->getId(), $delete_url),
-                              $this->boutonIco('type=del'));
-    },
-
-    function($batch) use ($id_placeholder, $run_url, $run_ajax_url) {
-      if(!$batch->isManuallyRunnable())
-        return '';
-
-      $url = $batch->isAjaxRunnable() ? $run_ajax_url : $run_url;
-
-      return $this->tagAnchor(str_replace($id_placeholder, $batch->getId(), $url),
-                              $this->boutonIco('type=test', 'bulle=Lancer'));
-    }
-  ],
-  'batchs');
-?>
+$description = (new Class_TableDescription('batchs'))
+  ->addColumn($this->_('Libellé'), function($model) { return $model->getLabel(); })
+  ->addColumn($this->_('Planification'),
+              function($model)
+              {
+                return (new Class_Repeat_WeekDays())->humanReadable($model->getPickDay());
+              })
+  ->addColumn($this->_('Dernière exécution'), function($model) { return $model->getLastRun(); })
+  ->addRowAction(function($batch)
+                 {
+                   return $this->renderPluginsActions($batch);
+                 })
+  ;
+
+echo $this->renderTable($description, $this->definitions, ['sorter' => true])
+  ;
diff --git a/application/modules/admin/views/scripts/batch/plan.phtml b/application/modules/admin/views/scripts/batch/plan.phtml
new file mode 100644
index 0000000000000000000000000000000000000000..c52ca489f905555642d9f8210fc3130ba4abfdcd
--- /dev/null
+++ b/application/modules/admin/views/scripts/batch/plan.phtml
@@ -0,0 +1 @@
+<?php echo $this->renderForm($this->form); ?>
diff --git a/application/modules/admin/views/scripts/external-agendas/index.phtml b/application/modules/admin/views/scripts/external-agendas/index.phtml
index e79537bceb9b075979f778070a7cccca1b942f59..be3fca0d36c35381ce3ac65ffd9a4351a5fecd9c 100644
--- a/application/modules/admin/views/scripts/external-agendas/index.phtml
+++ b/application/modules/admin/views/scripts/external-agendas/index.phtml
@@ -15,9 +15,15 @@ $number_of_events = function($model, $attrib)
 
 $ical_url = function($model, $attrib)
 {
+  $part = $model->getUrl();
+  if (strlen($model->getUrl()) >40) {
+    $parts = explode('/',$part);
+    $part=reset($parts).'//.../'.end($parts);
+  }
+
   return $this->tagAnchor($model->getUrl(),
-                          $model->getUrl(),
-                          ['target' => '_blank']);
+                          $part,
+                          ['title' => $model->getUrl(),'target' => '_blank']);
 };
 
 $category = function($model, $attribs) {
@@ -28,27 +34,15 @@ $category = function($model, $attribs) {
                           Class_ArticleCategorie::find($cat_id)->getLibelle());
 };
 
-echo $this->tagModelTable($this->agendas,
-
-                          [$this->_('Libellé'),
-                           $this->_('Nombre d\'événements'),
-                           $this->_('URL'),
-                           $this->_('Categorie')],
-
-                          ['label',
-                           'number-of-events',
-                           'url',
-                           'category'],
-
-                          [ ['action' => 'import', 'content' => $this->boutonIco('type=test',
-                                                                                 'bulle='. $this->_('Moissonner'))],
-                            ['action' => 'edit', 'content' => $this->boutonIco('type=edit')],
-                            ['action' => 'delete', 'content' => $this->boutonIco('type=del')],
-                            ],
-
-                          'agendas',
-                          null,
-
-                          ['number-of-events' => $number_of_events,
-                           'url' => $ical_url,
-                           'category' => $category]);
+$description = (new Class_TableDescription('agendas'))
+  ->addColumn($this->_('Libellé'), 'label')
+  ->addColumn($this->_('Nombre d\'événements'), $number_of_events)
+  ->addColumn($this->_('URL'), $ical_url)
+  ->addColumn($this->_('Categorie'), $category)
+  ->addColumn($this->_('MAJ auto.'), function($model)
+              {
+                return $model->autoharvest ? $this->_('Oui') : $this->_('Non');
+              })
+  ->addRowAction(function($model) { return $this->renderPluginsActions($model); });
+
+echo $this->renderTable($description, $this->agendas, ['sorter' => true]);
diff --git a/application/modules/admin/views/scripts/index/index.phtml b/application/modules/admin/views/scripts/index/index.phtml
index a421300cb6622fe1106f8893334deb2debe79403..37af2474069050a7c3a5db645c521ee990731952 100644
--- a/application/modules/admin/views/scripts/index/index.phtml
+++ b/application/modules/admin/views/scripts/index/index.phtml
@@ -1,3 +1,31 @@
+<?php
+$skin = Class_Admin_Skin::current();
+?>
+<h2 style="display:inline;border:none">
+  <?php
+  Class_ScriptLoader::getInstance()
+  ->addInlineStyle('
+#learn_more_7_10 {
+  background-color:var(--bokeh-event);
+  padding:10px;
+  text-transform:uppercase;
+}
+#learn_more_7_10:hover {
+  background-color:var(--bokeh-event-highlight);
+}
+');
+  echo $skin->renderMenuIconOn('tag', $this,
+                               ['style' => 'vertical-align:middle'])
+    . ' '
+    . $this->_('Nouvelle version');
+
+  $button = (new Class_Entity())->setText($this->_('Découvrir les nouveautés de la version 7.10'))
+                                ->setAttribs(['id' => 'learn_more_7_10',
+                                              'onclick' => 'window.open(\'http://wiki.bokeh-library-portal.org/index.php?title=7.10.0\'); return false']);
+  echo $this->Button($button);
+  ?>
+</h2>
+
 <h2 class="toggle_video">
   <?php
   Class_ScriptLoader::getInstance()->addJQueryReady('$(".toggle_video").click(function() {$(this).toggleClass("on");$(this).next().toggle();})');
diff --git a/application/modules/opac/views/scripts/head.phtml b/application/modules/opac/views/scripts/head.phtml
index af83377af4715b1ed92979c5a5b9ea17fd5a3fd6..701b2380ee1db6304708accf4919b8b5bee57061 100644
--- a/application/modules/opac/views/scripts/head.phtml
+++ b/application/modules/opac/views/scripts/head.phtml
@@ -36,7 +36,6 @@
                                           'division-five',
                                           'reload_module'])
                         ->addJQueryReady('
-                                         autoHideShowConfigurationModule();
                                          initializeNoticeMurAnimation();
                                          initializeImgHover();
                                          initializePopups();
diff --git a/cosmogramme/sql/patch/patch_334.php b/cosmogramme/sql/patch/patch_334.php
new file mode 100644
index 0000000000000000000000000000000000000000..8bd70b3464b6f10eb20e53ede87e273dd7626526
--- /dev/null
+++ b/cosmogramme/sql/patch/patch_334.php
@@ -0,0 +1,8 @@
+<?php
+try{
+  Zend_Db_Table_Abstract::getDefaultAdapter()
+    ->query('alter table external_agenda add column autoharvest tinyint not null default 0');
+  Zend_Db_Table_Abstract::getDefaultAdapter()
+    ->query('alter table external_agenda add key autoharvest(autoharvest)');
+} catch(Exception $e) {}
+?>
diff --git a/cosmogramme/sql/patch/patch_335.php b/cosmogramme/sql/patch/patch_335.php
new file mode 100644
index 0000000000000000000000000000000000000000..12fae2847321c1efe7d84f2e782a1b1fcb823f48
--- /dev/null
+++ b/cosmogramme/sql/patch/patch_335.php
@@ -0,0 +1,13 @@
+<?php
+$adapter = Zend_Db_Table_Abstract::getDefaultAdapter();
+$week_days = new Class_Repeat_WeekDays();
+
+try {
+  $adapter->query('select pick_day from batchs limit 1');
+} catch (Exception $e) {
+  $adapter->query('ALTER TABLE `batchs` ADD COLUMN `pick_day` VARCHAR(255) NOT NULL DEFAULT "' . $week_days->allDaysSerialized() . '";');
+  $adapter->query('update `batchs` set `pick_day`="' . $week_days->saturdaySerialized() . '" where type="' . Class_Batch_ArteVOD::TYPE . '";');
+  $adapter->query('update `batchs` set `pick_day`="' . $week_days->sundaySerialized() . '" where type="' . Class_Batch_Cyberlibris::TYPE . '";');
+  $adapter->query('update `batchs` set `pick_day`="' . $week_days->sundaySerialized() . '" where type="' . Class_Batch_Jamendo::TYPE . '";');
+}
+?>
\ No newline at end of file
diff --git a/library/Class/Batch.php b/library/Class/Batch.php
index c8469a79541add4601be117ac6e713acb645594c..71ebf92bd7d8ed36464f43457f589a0510b097a8 100644
--- a/library/Class/Batch.php
+++ b/library/Class/Batch.php
@@ -20,7 +20,6 @@
  */
 
 class Class_BatchLoader extends Storm_Model_Loader {
-
   public function findAllWithDefaults($params = []) {
     if(! Class_Batch::findFirstBy(['type' => Class_Batch_NoveltyFacet::TYPE]))
       Class_Batch::newInstance(['type' => Class_Batch_NoveltyFacet::TYPE])->save();
@@ -41,7 +40,8 @@ class Class_BatchLoader extends Storm_Model_Loader {
                         Class_Batch_AutocompleteRecordAuthor::TYPE => new Class_Batch_AutocompleteRecordAuthor(),
                         Class_Batch_BuildSiteMap::TYPE => new Class_Batch_BuildSiteMap(),
                         Class_Batch_PremierChapitre::TYPE => new Class_Batch_PremierChapitre(),
-                        Class_Batch_NoveltyFacet::TYPE => new Class_Batch_NoveltyFacet()]);
+                        Class_Batch_NoveltyFacet::TYPE => new Class_Batch_NoveltyFacet(),
+                        Class_Batch_ExternalAgenda::TYPE => new Class_Batch_ExternalAgenda]);
   }
 
 
@@ -64,7 +64,10 @@ class Class_BatchLoader extends Storm_Model_Loader {
 
 
   public function getKnownType($type) {
-    return Class_Batch::getKnownTypes()[$type];
+    $known_types = Class_Batch::getKnownTypes();
+    return array_key_exists($type, $known_types)
+      ? $known_types[$type]
+      : null;
   }
 
 
@@ -90,7 +93,9 @@ class Class_BatchLoader extends Storm_Model_Loader {
 
 
   public function getBatchLibelle($type) {
-    return Class_Batch::getKnownType($type)->getLabel();
+    return ($model = Class_Batch::getKnownType($type))
+      ? $model->getLabel()
+      : '';
   }
 
 
@@ -104,15 +109,65 @@ class Class_BatchLoader extends Storm_Model_Loader {
     return $result;
   }
 
+
+  public function isAvailableType($type) {
+    return array_key_exists($type, $this->getAvailableType());
+  }
+
+
+  public function getAvailableBatchDefinitions() {
+    $result = [];
+    $types = Class_Batch::getKnownTypes();
+    foreach($types as $type => $batch) {
+      if ($batch->isEnabled())
+        $result[$type] = new Class_Batch_Definition($batch);
+    }
+
+    return $result;
+  }
+
+
+  public function getDefaultPickDayFor($type) {
+    $week_days = new Class_Repeat_WeekDays();
+
+    if (Class_Batch_ArteVOD::TYPE == $type)
+      return $week_days->saturdaySerialized();
+
+    return in_array($type, [Class_Batch_Cyberlibris::TYPE,
+                            Class_Batch_Jamendo::TYPE])
+      ? $week_days->sundaySerialized()
+      : $week_days->allDaysSerialized();
+
+  }
 }
 
 
+
+
 class Class_Batch extends Storm_Model_Abstract {
+  use Trait_TimeSource;
+
   protected $_table_name = 'batchs';
   protected $_loader_class = 'Class_BatchLoader';
   protected $_default_attribute_values = ['type'=> '',
+                                          'pick_day' => '',
                                           'last_run' => ''];
 
+  public function beforeSave() {
+    $this->_ensureDefaultPickDay();
+  }
+
+
+  protected function _ensureDefaultPickDay() {
+    if (!$this->isNew())
+      return;
+
+    if (!$this->getPickDay()) {
+      $pick_day = $this->getLoader()->getDefaultPickDayFor($this->getType());
+      $this->setPickDay($pick_day);
+    }
+  }
+
 
   public function getLibelle() {
     return $this->withBatchDo(function($batch) { return $batch->getLabel(); },
@@ -165,7 +220,10 @@ class Class_Batch extends Storm_Model_Abstract {
 
 
   public function isManuallyRunnable() {
-    return $this->getType() != Class_Batch_Cyberlibris::TYPE;
+    return !in_array($this->getType(),
+                     [Class_Batch_Cyberlibris::TYPE,
+                      Class_Batch_ArteVOD::TYPE,
+                      Class_Batch_Jamendo::TYPE]);
   }
 
 
@@ -175,4 +233,21 @@ class Class_Batch extends Storm_Model_Abstract {
                      Class_Batch_AutocompleteRecordAuthor::TYPE,
                      Class_Batch_IndexRessourcesNumeriques::TYPE]);
   }
+
+
+  public function setPickDay($value) {
+    if (is_array($value))
+      $value = (new Class_Repeat_WeekDays())->serialize($value);
+
+    return parent::_set('pick_day', $value);
+  }
+
+
+  public function shouldRun() {
+    $now = $this->getCurrentTime();
+    $today = date('w', $now);
+
+    return in_array($today,
+                    (new Class_Repeat_WeekDays())->unserialize($this->getPickDay()));
+  }
 }
diff --git a/library/Class/Batch/Abstract.php b/library/Class/Batch/Abstract.php
index 32e6cb1f6f747a8065c47c1c6674fb999dd054ad..788a8d5ac15e35b4b835b261f36d3477e0ef2d03 100644
--- a/library/Class/Batch/Abstract.php
+++ b/library/Class/Batch/Abstract.php
@@ -45,6 +45,11 @@ class Class_Batch_Abstract {
 
 
   public function getModel() {
-    return Class_Batch::findFirstBy(['type' => static::TYPE]);
+    return Class_Batch::findFirstBy(['type' => $this->getType()]);
+  }
+
+
+  public function getType() {
+    return static::TYPE;
   }
 }
\ No newline at end of file
diff --git a/library/Class/Batch/Definition.php b/library/Class/Batch/Definition.php
new file mode 100644
index 0000000000000000000000000000000000000000..0a84103377e642a283d2b697949214e15eae9b34
--- /dev/null
+++ b/library/Class/Batch/Definition.php
@@ -0,0 +1,75 @@
+<?php
+/**
+ * Copyright (c) 2012-2017, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+class Class_Batch_Definition {
+  use Trait_Translator;
+
+  protected
+    $_type,
+    $_model;
+
+  public function __construct($type) {
+    $this->_type = $type;
+    $this->_model = $type->getModel();
+  }
+
+
+  public function __call($name, $params) {
+    $map = ['getPickDay' => '',
+            'isDeletable' => false,
+            'isManuallyRunnable' => false,
+            'isAjaxRunnable' => false];
+
+    if (array_key_exists($name, $map))
+      return $this->_model
+        ? call_user_func_array([$this->_model, $name], $params)
+        : $map[$name];
+
+    throw new RuntimeException('Call to undefined method '. get_class($this) . '::' . $name);
+  }
+
+
+  public function isActive() {
+    return null !== $this->_model;
+  }
+
+
+  public function getLabel() {
+    return $this->_type->getLabel();
+  }
+
+
+  public function getId() {
+    return $this->_type->getType();
+  }
+
+
+  public function getLastRun() {
+    if (!$this->isActive())
+      return $this->_('Aucune');
+
+    return ('0000-00-00 00:00:00' == ($last_run = $this->_model->getLastRun()))
+      ? $this->_('Aucune')
+      : $last_run;
+  }
+
+}
diff --git a/library/Class/Batch/ExternalAgenda.php b/library/Class/Batch/ExternalAgenda.php
new file mode 100644
index 0000000000000000000000000000000000000000..f69be445238fefb3c91fce7d23ad003fe11e7cae
--- /dev/null
+++ b/library/Class/Batch/ExternalAgenda.php
@@ -0,0 +1,34 @@
+<?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_Batch_ExternalAgenda extends Class_Batch_Abstract {
+  const TYPE = 'EXTERNAL_AGENDA';
+
+  public function getLabel() {
+    return $this->_('Moissonner les agendas externes');
+  }
+
+  public function run() {
+    Class_ExternalAgenda::harvest($this->getLogger());
+  }
+}
+?>
\ No newline at end of file
diff --git a/library/Class/Batch/PremierChapitre.php b/library/Class/Batch/PremierChapitre.php
index c5b151595e7c80cedd275b403f26dd52c548b53e..14a54aba38d8c947c7ed8c50558c50556b1d8da0 100644
--- a/library/Class/Batch/PremierChapitre.php
+++ b/library/Class/Batch/PremierChapitre.php
@@ -40,7 +40,7 @@ class Class_Batch_PremierChapitre extends Class_Batch_Abstract {
 
     $contenu = date('H:i:s')." ".$this->_('Le référentiel a bien été mise à jour')."\n";
     if (!$data = $pc_ws->getDatafile()) {
-      $this->content = $contenu . 
+      $this->content = $contenu .
                           $this->_('Une erreur est survenue')."\n".
                           $this->_('le référentiel n\'a pas pu être téléchargé')."\n".
                           $this->_('Veuillez réessayer ultérieurement')."\n";
@@ -86,7 +86,12 @@ class Class_Batch_PremierChapitre extends Class_Batch_Abstract {
                     '* '.$this->_plural($data['total'],'aucune oeuvre n\'a été traitée','%d oeuvre a été traitée','%d oeuvres ont été traitées',$data['total'])."\n";
     if ($data['add']) $contenu .= '* '.$this->_plural($data['add'],'','%d a été ajoutée','%d ont été ajoutées',$data['add'])."\n";
     if ($data['del']) $contenu .= '* '.$this->_plural($data['del'],'','%d a été supprimée','%d ont été supprimées',$data['del'])."\n";
-       
+
     $this->content = $contenu;
   }
+
+
+  public function isEnabled() {
+    return Class_AdminVar::isPremierChapitreEnabled();
+  }
 }
\ No newline at end of file
diff --git a/library/Class/Cosmogramme/Integration/PhaseBatchs.php b/library/Class/Cosmogramme/Integration/PhaseBatchs.php
index 4386ec6685d8d75be0ad75446de11625ed083e1f..e59cc2b5b251523c0b4df432cb7d04ee12120448 100644
--- a/library/Class/Cosmogramme/Integration/PhaseBatchs.php
+++ b/library/Class/Cosmogramme/Integration/PhaseBatchs.php
@@ -60,6 +60,13 @@ class Class_Cosmogramme_Integration_PhaseBatchs
 
 
   protected function _runOne($batch) {
+    if (!$batch->shouldRun()) {
+      $this->_log->success($this->_('La tâche %s n\'est pas plannifiée aujourd\'hui',
+                                    $batch->getLibelle()));
+      $this->_chrono->startOnFile();
+      return;
+    }
+
     $this->_log->success($batch->getLibelle());
     $this->_setData('pointeur_reprise', $batch->getId());
 
@@ -70,7 +77,7 @@ class Class_Cosmogramme_Integration_PhaseBatchs
 
     } catch (Exception $e) {
       $this->_log->error($this->_('Erreur lors de l\'execution du batch %s',
-                                     $batch->getLibelle()));
+                                  $batch->getLibelle()));
       $this->_log->error($e->getMessage());
       $this->_log->error($e->getTraceAsString());
     }
diff --git a/library/Class/DigitalResource/Batch.php b/library/Class/DigitalResource/Batch.php
index 698e5885f70f5f7d9e344d78725edc5f5bf91d1e..341777fb34e20789a335a3cddd2089cd3ca41a3b 100644
--- a/library/Class/DigitalResource/Batch.php
+++ b/library/Class/DigitalResource/Batch.php
@@ -37,4 +37,9 @@ class Class_DigitalResource_Batch extends Class_Batch_RessourceNumerique{
   public function isEnabled() {
     return $this->_config->isEnabled();
   }
-}
+
+
+  public function getType() {
+    return get_class($this);
+  }
+}
\ No newline at end of file
diff --git a/library/Class/ExternalAgenda.php b/library/Class/ExternalAgenda.php
index 9816b744e7e5507fd3651945c6d44327f55b8533..ada348c13beea5ca555dee3b77937e297cc2cefb 100644
--- a/library/Class/ExternalAgenda.php
+++ b/library/Class/ExternalAgenda.php
@@ -20,6 +20,19 @@
  */
 
 
+class Class_ExternalAgendaLoader extends Storm_Model_Loader {
+
+  public function harvest($logger) {
+    foreach (Class_ExternalAgenda::findAllBy(['autoharvest' => 1]) as $agenda) {
+      $results = $agenda->import();
+      $logger->log($agenda->getLabel().":\n");
+      $logger->log($agenda->_("Nombre d\'événements créés : %s\n",count($results['new'])));
+      $logger->log($agenda->_("Nombre d\'événements mis à jour : %s\n",count($results['update'])));
+    }
+  }
+}
+
+
 class Class_ExternalAgenda extends Storm_Model_Abstract {
   use Trait_Translator;
 
@@ -30,6 +43,7 @@ class Class_ExternalAgenda extends Storm_Model_Abstract {
                             'location' => ['model' => 'Class_Lieu',
                                            'referenced_in' => 'id_lieu']];
 
+  protected $_loader_class = 'Class_ExternalAgendaLoader';
 
   public function getLibelle() {
     return $this->getLabel();
@@ -43,16 +57,13 @@ class Class_ExternalAgenda extends Storm_Model_Abstract {
   }
 
 
-  public function import($logger) {
+  public function import() {
     $service = new Class_WebService_ICalendar();
     $events = $service->import($this);
-
-    $logger->visitNewEvents($events->select('isNew'));
-    $logger->visitUpdatedEvents($events->reject('isNew'));
-
+    $results['new'] = $events->select('isNew');
+    $results['update'] = $events->reject('isNew');
     $events->eachDo('save');
-
-    return $events;
+    return $results;
   }
 
 
diff --git a/library/Class/Repeat/WeekDays.php b/library/Class/Repeat/WeekDays.php
new file mode 100644
index 0000000000000000000000000000000000000000..db54e22796959f730a2ab2b615f42c003c7e67ad
--- /dev/null
+++ b/library/Class/Repeat/WeekDays.php
@@ -0,0 +1,94 @@
+<?php
+/**
+ * Copyright (c) 2012-2017, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+class Class_Repeat_WeekDays {
+  use Trait_Translator;
+
+  const SEPARATOR = ';';
+
+  protected $_days;
+
+  public function __construct() {
+    $this->_days = ['1' => $this->_('lundi'),
+                    '2' => $this->_('mardi'),
+                    '3' => $this->_('mercredi'),
+                    '4' => $this->_('jeudi'),
+                    '5' => $this->_('vendredi'),
+                    '6' => $this->_('samedi'),
+                    '0' => $this->_('dimanche')];
+  }
+
+
+  public function allDaysSerialized() {
+    return implode(static::SEPARATOR, array_keys($this->_days));
+  }
+
+
+  public function saturdaySerialized() {
+    return '6';
+  }
+
+
+  public function sundaySerialized() {
+    return '0';
+  }
+
+
+  public function allDays() {
+    return $this->_days;
+  }
+
+
+  public function unserialize($value) {
+    $values = explode(static::SEPARATOR, $value);
+    return array_filter($values,
+                        function($item)
+                        {
+                          return $item !== null && $item !== '';
+                        });
+  }
+
+
+  public function serialize($value) {
+    return implode(static::SEPARATOR, $value);
+  }
+
+
+  public function humanReadable($value) {
+    $values = $this->unserialize($value);
+
+    if (!$values)
+      return $this->_('Aucune');
+
+    if (count($values) == count($this->_days))
+      return $this->_('Tous les jours');
+
+    $days = [];
+    foreach($this->_days as $k => $v) {
+      if (in_array($k, $values))
+        $days[] = substr($v, 0, 3);
+      continue;
+    }
+
+    return implode(', ', $days);
+  }
+}
\ No newline at end of file
diff --git a/library/ZendAfi/Acl/AdminControllerRoles.php b/library/ZendAfi/Acl/AdminControllerRoles.php
index 6913a8aa1dda39ff7f898ab70e8cf11cd2697c9d..8b7b1921877fb6b33d2e03bb54938ead62c03a5e 100644
--- a/library/ZendAfi/Acl/AdminControllerRoles.php
+++ b/library/ZendAfi/Acl/AdminControllerRoles.php
@@ -90,6 +90,7 @@ class ZendAfi_Acl_AdminControllerRoles extends Zend_Acl {
     $this->add(new Zend_Acl_Resource('print'));
     $this->add(new Zend_Acl_Resource('external-agendas'));
     $this->add(new Zend_Acl_Resource('systeme'));
+    $this->add(new Zend_Acl_Resource('batch'));
 
     //Roles
     $this->addRole(new Zend_Acl_Role('invite'));
@@ -159,6 +160,7 @@ class ZendAfi_Acl_AdminControllerRoles extends Zend_Acl {
     $this->deny('modo_portail','users');
     $this->deny('modo_portail','usergroup');
     $this->deny('modo_portail','systeme');
+    $this->deny('modo_portail','batch');
 
     $this->allow('modo_portail');
     $this->allow('admin_portail');
diff --git a/library/ZendAfi/Controller/Plugin/Manager/Batch.php b/library/ZendAfi/Controller/Plugin/Manager/Batch.php
new file mode 100644
index 0000000000000000000000000000000000000000..801abe1a1db8946b9cb93e7bcf309bf0f17fc560
--- /dev/null
+++ b/library/ZendAfi/Controller/Plugin/Manager/Batch.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ * Copyright (c) 2012-2017, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+class ZendAfi_Controller_Plugin_Manager_Batch extends ZendAfi_Controller_Plugin_Manager_Manager {
+  public function getActions($model) {
+    return [
+            ['url' => '#',
+             'icon' => 'help',
+             'label' => $this->_('Tâche système non désactivable'),
+             'condition' => function($model)
+              {
+                return !$model->isDeletable() && $model->isActive();
+              },
+             'anchorOptions' => ['onclick' => 'return false;']],
+
+            ['url' => '/admin/batch/activate/id/%s',
+             'icon' => 'hide',
+             'label' => $this->_('Activer la tâche'),
+             'condition' => function($model) {
+                return Class_Users::isCurrentUserSuperAdmin()
+                && !$model->isActive();
+             }],
+
+            ['url' => '/admin/batch/delete/id/%s',
+             'icon' => 'show',
+             'label' => $this->_('Désactiver la tâche'),
+             'condition' => function($model)
+              {
+                return $model->isDeletable();
+              },
+             'anchorOptions' => ['onclick' => 'return confirm(\''
+                                 . str_replace(['\'', '"'], '\\\'',
+                                               $this->_('Etes-vous sur de vouloir désactiver cette tâche ?'))
+                                 . '\')']],
+
+            ['url' => '/admin/batch/plan/id/%s',
+             'icon' => 'calendar',
+             'label' => $this->_('Plannifier la tâche'),
+             'condition' => function($model) {
+                return Class_Users::isCurrentUserSuperAdmin()
+                && $model->isActive();
+             },
+             'anchorOptions' => ['data-popup' => 'true']],
+
+
+            ['url' => '/admin/batch/run/id/%s',
+             'icon' => 'test',
+             'label' => $this->_('Lancer manuellement'),
+             'condition' => function($model)
+              {
+                return $model->isManuallyRunnable() && (!$model->isAjaxRunnable());
+              }],
+
+            ['url' => '/admin/batch/run-ajax/id/%s',
+             'icon' => 'test',
+             'label' => $this->_('Lancer'),
+             'condition' => function($model)
+              {
+                return $model->isManuallyRunnable() && $model->isAjaxRunnable();
+              }]];
+  }
+
+
+  protected function _canEdit($model) {
+    return Class_Users::isCurrentUserSuperAdmin();
+  }
+}
\ No newline at end of file
diff --git a/library/ZendAfi/Controller/Plugin/Manager/ExternalAgenda.php b/library/ZendAfi/Controller/Plugin/Manager/ExternalAgenda.php
new file mode 100644
index 0000000000000000000000000000000000000000..3a92d345d0fa282a0c7c9529b7b546b149396525
--- /dev/null
+++ b/library/ZendAfi/Controller/Plugin/Manager/ExternalAgenda.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Copyright (c) 2012-2017, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+class ZendAfi_Controller_Plugin_Manager_ExternalAgenda extends ZendAfi_Controller_Plugin_Manager_Manager {
+  public function getActions($model) {
+    return [
+            ['url' => '/admin/external-agendas/import/id/%s',
+             'icon' => 'test',
+             'label' => $this->_('Moissonner')
+            ],
+            ['url' => '/admin/external-agendas/edit/id/%s',
+             'icon' => 'edit',
+             'label' => $this->_('Modifier'),
+             'anchorOptions' => ['data-popup' => 'true']],
+            ['url' => '/admin/external-agendas/delete/id/%s',
+             'label' => $this->_('Supprimer'),
+             'icon' => 'delete',
+             'anchorOptions' => ['data-popup' => 'true']]
+            ];
+  }
+}
\ No newline at end of file
diff --git a/library/ZendAfi/Controller/Plugin/ResourceDefinition/Batch.php b/library/ZendAfi/Controller/Plugin/ResourceDefinition/Batch.php
index 319f2646d50bb3888a75ba8336a727637c02f1a7..e4e223efe849f3a45cdae4ac79be40f844369f5e 100644
--- a/library/ZendAfi/Controller/Plugin/ResourceDefinition/Batch.php
+++ b/library/ZendAfi/Controller/Plugin/ResourceDefinition/Batch.php
@@ -28,10 +28,12 @@ class ZendAfi_Controller_Plugin_ResourceDefinition_Batch extends ZendAfi_Control
                         'order' => 'type',
                         'findAll' => 'findAllWithDefaults'],
 
-            'messages' => ['successful_add' => $this->_('Tâche ajoutée'),
+            'messages' => ['successful_save' => $this->_('Tâche sauvegardée'),
+                           'successful_add' => $this->_('Tâche ajoutée'),
                            'successful_delete' => $this->_('Tâche supprimée')],
 
             'actions' => ['add' => ['title' => $this->_('Nouvelle Tâche')],
+                          'edit' => ['title' => $this->_('Modifier la tâche')],
                           'index' => ['title' => $this->_('Tâches')]],
 
             'after_add' => function() {$this->_redirect('/admin/batch');},
diff --git a/library/ZendAfi/Form/Admin/Batch.php b/library/ZendAfi/Form/Admin/Batch.php
index 8bc12c09edbb6dadcddaf34a93e8194343b96bc4..3c7d6d024bf14226a40063bb104b8ae68eb4d2bf 100644
--- a/library/ZendAfi/Form/Admin/Batch.php
+++ b/library/ZendAfi/Form/Admin/Batch.php
@@ -25,12 +25,11 @@ class ZendAfi_Form_Admin_Batch extends ZendAfi_Form {
     parent::init();
 
     $this
-      ->setAttrib('data-disable-onchange', 'true')
+      ->setAttrib('id', 'batch_plan')
+      ->addElement('weekDays',
+                   'pick_day',
+                   ['label' => $this->_('Lancer tous les')]);
 
-      ->addElement('select', 'type',
-                   ['multiOptions' => Class_Batch::getAvailableType(),
-                    'required' => true])
-
-      ->addDisplayGroup(['type'], 'ajout_tache', []);
+    $this->addUniqDisplayGroup('batch');
   }
 }
diff --git a/library/ZendAfi/Form/Admin/ExternalAgenda.php b/library/ZendAfi/Form/Admin/ExternalAgenda.php
index bef1b8f0ce6ba0f0ae432b0d0409b96e5f0251c3..295cf12deba7661f7a46cc610fd7cb4be7fba2a8 100644
--- a/library/ZendAfi/Form/Admin/ExternalAgenda.php
+++ b/library/ZendAfi/Form/Admin/ExternalAgenda.php
@@ -38,6 +38,10 @@ class ZendAfi_Form_Admin_ExternalAgenda extends ZendAfi_Form {
                     'required' => true,
                     'allowEmpty' => false,
                     'title' => $this->_('Le flux doit être au format iCalendar')])
+      ->addElement('checkbox',
+                   'autoharvest',
+                   ['label' => $this->_('Moissonnage automatique'),
+                    ])
 
       ->addElement('comboCategories',
                    'cat_id',
@@ -52,7 +56,7 @@ class ZendAfi_Form_Admin_ExternalAgenda extends ZendAfi_Form {
                    ['label' => $this->_('Lieu'),
                     'multiOptions' => ['0' => $this->_('Aucun')] + Class_Lieu::getAllLibelles()]);
 
-    $elements = ['label', 'url', 'cat_id', 'id_lieu'];
+    $elements = ['label', 'url','autoharvest', 'cat_id', 'id_lieu'];
 
     if (Class_AdminVar::isWorkFlowEnabled()) {
       $this->addElement('radio', 'status',
diff --git a/library/ZendAfi/Form/Element/WeekDays.php b/library/ZendAfi/Form/Element/WeekDays.php
new file mode 100644
index 0000000000000000000000000000000000000000..4fbe72d00d7cc0d701e1051047598af17d923aca
--- /dev/null
+++ b/library/ZendAfi/Form/Element/WeekDays.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Copyright (c) 2012-2017, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+class ZendAfi_Form_Element_WeekDays extends Zend_Form_Element_MultiCheckbox {
+  public function __construct($spec, $options=null) {
+    parent::__construct($spec, $options);
+    $this
+      ->setMultiOptions((new Class_Repeat_WeekDays())->allDays())
+      ->setSeparator(' ');
+  }
+
+
+  public function setValue($value) {
+    return is_string($value)
+      ? parent::setValue((new Class_Repeat_WeekDays())->unserialize($value))
+      : parent::setValue($value);
+  }
+}
diff --git a/library/ZendAfi/View/Helper/Accueil/Kiosque.php b/library/ZendAfi/View/Helper/Accueil/Kiosque.php
index 70e98f3a8cff8136fc153a5e636bbafad2c384e4..c59660584b3c19555026ba4cfa435d291d9c47dd 100644
--- a/library/ZendAfi/View/Helper/Accueil/Kiosque.php
+++ b/library/ZendAfi/View/Helper/Accueil/Kiosque.php
@@ -69,20 +69,17 @@ class ZendAfi_View_Helper_Accueil_Kiosque extends ZendAfi_View_Helper_Accueil_Ba
     $this->contenu =  (in_array($this->preferences['style_liste'], ['mur', 'vignettes', 'chrono']))
       ? $this->getKiosqueHtml()
       : $this->getKiosqueIFrame();
-    $this->contenu = $this->getChangeKiosqueData() . $this->contenu;
+    $this->contenu = $this->contenu;
 
     return $this->getHtmlArray();
   }
 
 
-  public function getAddEditLinks() {
-    if (!Class_Users::isCurrentUserCanAccesBackend())
-      return '';
-
+  public function getEditLink() {
     if (!($this->preferences['id_catalogue'] && ($catalogue = Class_Catalogue::find($this->preferences['id_catalogue']))))
       return '';
 
-    $edit_link =  $this->view->tagAnchor($this->view->url(['module' => 'admin',
+    return  $this->view->tagAnchor($this->view->url(['module' => 'admin',
                                                            'controller' => 'catalogue',
                                                            'action' => 'edit',
                                                            'id_catalogue' => $this->preferences['id_catalogue']]),
@@ -91,10 +88,17 @@ class ZendAfi_View_Helper_Accueil_Kiosque extends ZendAfi_View_Helper_Accueil_Ba
                                                               ['title' => $this->view->_('Modifier le domaine : %s', htmlspecialchars($catalogue->getLibelle()))]),
                                          ['data-popup' => 'true']);
 
+  }
+
+
+  public function getAddLink() {
+    if (!($this->preferences['id_catalogue'] && ($catalogue = Class_Catalogue::find($this->preferences['id_catalogue']))))
+      return null;
+
     if (!$domaine_parent = $catalogue->getDomaineParent())
-      return $edit_link;
+      return null;
 
-    $add_link = $this->view->tagAnchor($this->view->url(['module' => 'admin',
+    return $this->view->tagAnchor($this->view->url(['module' => 'admin',
                                                          'controller' => 'catalogue',
                                                          'action' => 'add',
                                                          'id_catalogue' => $domaine_parent->getId(),
@@ -102,15 +106,23 @@ class ZendAfi_View_Helper_Accueil_Kiosque extends ZendAfi_View_Helper_Accueil_Ba
                                        Class_Admin_Skin::current()
                                          ->renderActionIconOn('add', $this->view, ['title' => $this->view->_('Afficher un nouveau domaine')]),
                                        ['data-popup' => 'true']);
-
-    return $edit_link.$add_link;
   }
 
 
-  public function getChangeKiosqueData() {
+  protected function _extendedActions() {
     if (!Class_Users::isCurrentUserCanAccesBackend())
-      return '<div style="display:none"></div>';
+      return null;
+
+    return [
+            function() { return $this->getChangeKiosqueData(); },
+            function() { return $this->getAddLink(); },
+            function() { return $this->getEditLink(); }
+    ];
+  }
 
+
+
+  public function getChangeKiosqueData() {
     $id_panier = isset($this->preferences['id_panier'])
       ? $this->preferences['id_panier']
       : 0;
@@ -126,17 +138,12 @@ class ZendAfi_View_Helper_Accueil_Kiosque extends ZendAfi_View_Helper_Accueil_Ba
                         'id_module' => $this->id_module
                         ],null,true);
 
-    return
-      $this->_tag('div',
-                  $this->getAddEditLinks() .
-                  $this->view->tagAnchor($change_kiosque_selection_url,
-                                         $this->view->tagImg(Class_Admin_Skin::current()
-                                                             ->getIconUrl('icons',
-                                                                          'domains'),
-                                                             ['title' => $this->view->_('Choisir un autre domaine')]),
-                                         ['data-popup'=>'true']),
-                  ['class' => 'change_kiosque_data configuration_module']);
-
+    return $this->view->tagAnchor($change_kiosque_selection_url,
+                                  $this->view->tagImg(Class_Admin_Skin::current()
+                                                      ->getIconUrl('icons',
+                                                                   'domains'),
+                                                      ['title' => $this->view->_('Choisir un autre domaine')]),
+                                  ['data-popup'=>'true']);
   }
 
 
diff --git a/library/ZendAfi/View/Helper/Accueil/Library.php b/library/ZendAfi/View/Helper/Accueil/Library.php
index 738d2067ab05fa1b9623f181854d72fb94928555..e33d0ab06dc9e8805d3bde3805d5d55de1f5aaed 100644
--- a/library/ZendAfi/View/Helper/Accueil/Library.php
+++ b/library/ZendAfi/View/Helper/Accueil/Library.php
@@ -344,4 +344,4 @@ class ZendAfi_View_Helper_Accueil_Library extends ZendAfi_View_Helper_Accueil_Ba
                                           ]);
   }
 
-}
+}
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/Accueil/MenuVertical.php b/library/ZendAfi/View/Helper/Accueil/MenuVertical.php
index 6f98639b9a02ae46f1c782abfad377768a6e970f..24c4dc6b2a2b7ac39650f0832aaf62e80a4b0edc 100644
--- a/library/ZendAfi/View/Helper/Accueil/MenuVertical.php
+++ b/library/ZendAfi/View/Helper/Accueil/MenuVertical.php
@@ -85,11 +85,16 @@ class ZendAfi_View_Helper_Accueil_MenuVertical extends ZendAfi_View_Helper_Accue
       : $this->_getContentAsOldHtml($config);
 
     $this->titre = $titre;
-    $this->contenu = $this->_editMenu() . $contenu;
+    $this->contenu =  $contenu;
     return $this->getHtmlArray();
   }
 
 
+  protected function _extendedActions() {
+    return [function() { return $this->_editMenu(); }];
+  }
+
+
   protected function _editMenu() {
     return $this->view->tagEditMenu($this->_menu_id, $this->_menu_id_profil);
   }
diff --git a/library/ZendAfi/View/Helper/Admin/ContentNav.php b/library/ZendAfi/View/Helper/Admin/ContentNav.php
index a3999e2a70ba6d0a6b32c73c42309fdd54a63af1..85a7bc95df7b73aacf5144ca28ebd3ae5a08c374 100644
--- a/library/ZendAfi/View/Helper/Admin/ContentNav.php
+++ b/library/ZendAfi/View/Helper/Admin/ContentNav.php
@@ -138,7 +138,7 @@ class ZendAfi_View_Helper_Admin_ContentNav extends ZendAfi_View_Helper_BaseHelpe
                    [['cosmogramme', $this->_('Accès à Cosmogramme'), '/cosmogramme',
                      ['target' => '_blank'], $is_admin],
 
-                    ['batches', $this->_('Batchs'), '/admin/batch', [], $is_admin],
+                    ['batches', $this->_('Batchs'), '/admin/batch'],
                     ['variables', $this->_('Variables'), '/admin/index/adminvar', [], $is_admin],
 
                     ['webservice_tests', $this->_('Test des web-services'), '/admin/systeme/webservices',
diff --git a/library/ZendAfi/View/Helper/Admin/FrontNav.php b/library/ZendAfi/View/Helper/Admin/FrontNav.php
index da9f0cac0bbb0a47b89cc71cd773864c83330560..04ef2e194d737375990e69e6965bc556e67dca11 100644
--- a/library/ZendAfi/View/Helper/Admin/FrontNav.php
+++ b/library/ZendAfi/View/Helper/Admin/FrontNav.php
@@ -221,7 +221,7 @@ class ZendAfi_View_Helper_Admin_FrontNav extends ZendAfi_View_Helper_BaseHelper
 
   protected function _adminLinks() {
     $links = [$this->view->tagAnchor(Class_Url::absolute('/admin'),
-                                     $this->_('Accueil') .
+                                     $this->_('Accès pro.') .
                                      $this->view->tagImg(Class_Admin_Skin::current()
                                                          ->getIconUrl('icons',
                                                                       'home')),
diff --git a/library/ZendAfi/View/Helper/FonctionsAdmin.php b/library/ZendAfi/View/Helper/FonctionsAdmin.php
index 01d131763eb2510a9508306ab92a5c182e451be2..8edcbcd89944885cb3bf0cf54aae32c2f9be3c47 100644
--- a/library/ZendAfi/View/Helper/FonctionsAdmin.php
+++ b/library/ZendAfi/View/Helper/FonctionsAdmin.php
@@ -34,18 +34,22 @@ class ZendAfi_View_Helper_FonctionsAdmin extends ZendAfi_View_Helper_BaseHelper
     $this->division = $division;
     $this->_current_skin = Class_Admin_Skin::current();
 
-    if (!Class_Users::isCurrentUserCanConfigFront())
-      return '';
-
-    return ($actions = trim($this->_extended($extended_actions) . ' '
-                            . $this->_config() . ' '
-                            . $this->_versions() . ' '
-                            . $this->_add() . ' '
-                            . $this->_delete())) ?
-      $this->_tag('div', $actions,
-                  ['class' => 'configuration_module',
-                   'style' => 'text-align:right']) :
-      '';
+    $actions = [$this->_extended($extended_actions)];
+
+    if (Class_Users::isCurrentUserCanConfigFront())
+      $actions = array_merge($actions,
+                             [$this->_config(),
+                              $this->_versions(),
+                              $this->_add(),
+                              $this->_delete()]);
+
+    $html = trim(implode(' ', array_filter($actions)));
+
+    return $html
+      ? $this->_tag('div', $html,
+                    ['class' => 'configuration_module',
+                     'style' => 'text-align:right'])
+      : '';
   }
 
 
@@ -137,7 +141,7 @@ class ZendAfi_View_Helper_FonctionsAdmin extends ZendAfi_View_Helper_BaseHelper
 
     $url = $this->view->url(['module' => 'admin',
                              'controller' => 'widget',
-                             'action' => 'add',
+                             'action' => 'add-from-template',
                              'after' => $this->id_module,
                              'division' => $this->division,
                              'id_profil' => $this->_getIdProfil()],
diff --git a/library/ZendAfi/View/Helper/RenderWidgetTemplates.php b/library/ZendAfi/View/Helper/RenderWidgetTemplates.php
index e4c5cf47e6e777b937c215815366f068c4b782a8..076fa1514b6f5240c80f7f6baa548afa40d977a1 100644
--- a/library/ZendAfi/View/Helper/RenderWidgetTemplates.php
+++ b/library/ZendAfi/View/Helper/RenderWidgetTemplates.php
@@ -21,7 +21,6 @@
 
 
 class ZendAfi_View_Helper_RenderWidgetTemplates extends ZendAfi_View_Helper_BaseHelper {
-
   public function renderWidgetTemplates($templates) {
     Class_ScriptLoader::getInstance()
       ->addJQueryReady('var widget = $(".widget_templates");'
@@ -63,10 +62,7 @@ class ZendAfi_View_Helper_RenderWidgetTemplates extends ZendAfi_View_Helper_Base
                                     'controller' => 'widget',
                                     'action' => 'add',
                                     'template' => $section_key,
-                                    'template_no' => $template_index,
-                                    'id_profil' => Class_Profil::getCurrentProfil()->getId()],
-                                   null,
-                                   true);
+                                    'template_no' => $template_index]);
     return
       $this->_tag('a',
                   $this->_tag('h4', $template['title']) .
diff --git a/library/digital_resources/Lekiosk/tests/LeKioskTest.php b/library/digital_resources/Lekiosk/tests/LeKioskTest.php
index a9944472cf241ed5467fdfcf4f9bba0dcee0fcf9..989189ca42c981be5f9f4c1a22fc3869d7e7b41c 100644
--- a/library/digital_resources/Lekiosk/tests/LeKioskTest.php
+++ b/library/digital_resources/Lekiosk/tests/LeKioskTest.php
@@ -454,8 +454,6 @@ class LeKioskRenderAlbumFromRecordTest extends LekioskServiceTestCase {
 
 
 
-
-
 class LekioskAdminUserGroupControllerRessourcesNumeriquesTest extends Admin_AbstractControllerTestCase {
   protected $_storm_default_to_volatile = true;
 
@@ -500,18 +498,21 @@ class LekioskAdminUserGroupControllerRessourcesNumeriquesTest extends Admin_Abst
 class LekioskBatchIndexTest extends Admin_AbstractControllerTestCase {
   protected $_storm_default_to_volatile = true;
 
-
-  public function setUp() {
-    parent::setUp();
+  /** @test */
+  public function whenActiveLekioskBatchShouldBePresent() {
     LekioskAdminVars::activate();
-    $this->dispatch('/admin/batch/add', true);
+    $this->dispatch('/admin/batch', true);
+    $this->assertXPathContentContains('//td',
+                                      'Moissonner catalogue Lekiosk');
   }
 
 
   /** @test */
-  public function lekioskBatchShouldBePresent() {
-    $this->assertXPathContentContains('//form//select//option[@value="Lekiosk_Batch"]',
-                                      'Moissonner catalogue Lekiosk');
+  public function whenNotActiveLekioskBatchShouldNotBePresent() {
+    LekioskAdminVars::deactivate();
+    $this->dispatch('/admin/batch', true);
+    $this->assertNotXPathContentContains('//td',
+                                         'Moissonner catalogue Lekiosk');
   }
 }
 
diff --git a/public/admin/css/front_nav.css b/public/admin/css/front_nav.css
new file mode 100644
index 0000000000000000000000000000000000000000..20d17cf5b70547f15f61130bfcb5cdc4c4482c8c
--- /dev/null
+++ b/public/admin/css/front_nav.css
@@ -0,0 +1,232 @@
+
+.menu_admin_front * {
+    box-sizing: content-box;
+    font-family: arial, sans-serif;
+}
+
+.menu_admin_front .form select,
+.menu_admin_front > div {
+    background-color: var(--widget-background);
+}
+
+.menu_admin_front .admin_menu_title,
+.menu_admin_front .form select,
+.menu_admin_front label {
+    color: var(--main-text);
+}
+
+.menu_admin_front a {
+    color: var(--anchor);
+}
+
+.menu_admin_front .form select {
+    border: 1px solid var(--border-highlight);
+}
+
+.menu_admin_front > div {
+    box-shadow: 1px 1px 5px var(--widget-shadow);
+}
+
+.menu_admin_front {
+    font-size: 12px;
+    position: fixed;
+    top: 0;
+    left: 0;
+    z-index: 102;
+}
+
+.menu_admin_front > button,
+.menu_admin_front > div {
+    transition: all 0.4s;
+}
+
+.menu_admin_front > div {
+    overflow: hidden;
+    width: 300px;
+}
+
+.menu_admin_front.hidden > div {
+    margin-left: -300px;
+    position: absolute;
+}
+
+.menu_admin_front > button {
+    margin: 0;
+    white-space: nowrap;
+}
+
+.menu_admin_front:not(.hidden) > button > img {
+    transform: rotate(45deg);
+}
+
+.menu_admin_front .amdin_menu_title,
+.menu_admin_front form tr,
+.menu_admin_front a {
+    display: block;
+    line-height: 2em;
+}
+
+.menu_admin_front a img {
+    float: right;
+    vertical-align: middle;
+    padding-right: 1.5em;
+}
+
+.menu_admin_front ul,
+.menu_admin_front li {
+    margin: 0 0 0 0.2em;
+    padding: 0 0 0 0.2em;
+    list-style: none;
+}
+
+.menu_admin_front [class*="deactivate"] {
+    display: none;
+}
+
+.menu_admin_front fieldset {
+    padding: 0;
+    margin: 0;
+}
+
+.menu_admin_front .form td {
+    display: inline-block;
+    text-align: left !important;
+}
+
+.menu_admin_front form + .boutons {
+    display: none;
+}
+
+.menu_admin_front .form {
+    text-align: left;
+}
+
+.menu_admin_front .form * {
+    display: block;
+}
+
+.menu_admin_front .form select {
+    display: inline;
+    height: 2em;
+    width: 270px;
+}
+
+#site_web_wrapper[data-show_admin_icons="true"] a[href*="/admin"] {
+    display: inline-block !important;
+}
+
+
+.menu_admin_front a[href$="/admin"] img {
+    filter: invert(1);
+}
+
+
+#site_web_wrapper[data-show_admin_icons="true"] .configuration_module {
+    z-index: 101;
+    display: block !important;
+    position: absolute;
+    right: 10px;
+    top: 10px;
+}
+
+#site_web_wrapper .footer select[onchange],
+#site_web_wrapper .footer a[href*="/admin"],
+#site_web_wrapper .admin_tools_lock,
+#site_web_wrapper .configuration_module,
+#site_web_wrapper a[href*="/admin"] {
+    display: none !important;
+}
+
+
+#site_web_wrapper a[href*="/admin"]  {
+    z-index: 101;
+    background-color: transparent !important;
+    margin: 0 !important;
+    border: 2px solid transparent !important;
+    left: 0;
+    padding: 1px !important;
+    opacity: 0.4;
+}
+
+
+#site_web_wrapper a[href*="/admin"],
+#site_web_wrapper a[href*="/admin"] img {
+    height: 16px !important;
+    width: 16px !important;
+}
+
+
+#site_web_wrapper a[href*="/admin"] img {
+    margin: 0 !important;
+    padding: 0 !important;
+    border-radius: 0 !important;
+    vertical-align: top;
+    left: auto !important;
+    top: auto !important;
+    position: static !important;
+}
+
+
+#site_web_wrapper #menu_horizontal:hover a[href*="/admin"], 
+#site_web_wrapper .boite:hover a[href*="/admin"] {
+    opacity: 1 !important;
+}
+
+
+#site_web_wrapper .boite:hover .configuration_module {
+    height: 20px;
+    background-color: var(--line-highlight);
+}
+
+
+#site_web_wrapper a[href*="/admin"]:hover {
+    border-color: black !important;
+    background-color: white !important;
+}
+
+.menu_admin_front a:hover, 
+.menu_admin_front a:focus {
+    text-decoration: underline;
+}
+
+.menu_admin_front > div {
+    padding-bottom: 1em;
+}
+
+.menu_admin_front .admin_menu_title {
+    font-size: 1.17em;
+    margin: 1em 0 1em 0;
+    font-weight: bold;
+}
+
+.menu_admin_front .admin_menu_title label {
+    font-weight: bold;
+}
+
+
+a[class*="edit_"]:not(.edit_profil) {
+    position: absolute;
+}
+
+.configuration_module a.edit_menu {
+    position: static;
+}
+
+
+.menu_horizontal > a.edit_menu:focus,
+.menu_horizontal > a.edit_menu {
+    left: auto !important;
+    right: 0;
+}
+
+
+
+div.menu_vertical ul a.edit_menu,
+#menu_horizontal ul a.edit_menu {
+    left: -1em !important;
+}
+
+article header .edit_article,
+section .edit_library {
+    top: 2ex;
+}
\ No newline at end of file
diff --git a/public/admin/js/onload_utils.js b/public/admin/js/onload_utils.js
index 22580fd778e9083d37e68c9e4570a7b513d98231..696095416f11c87c76fb55e50f6d9380f4a50c4c 100644
--- a/public/admin/js/onload_utils.js
+++ b/public/admin/js/onload_utils.js
@@ -70,34 +70,6 @@ var setupAnchorsTarget = function() {
 }
 
 
-var autoHideShowConfigurationModule = function() {
-  autoHideShowTagOnParentHover('.configuration_module', 'div.boite');
-  autoHideShowTagOnParentHover('a[class^="edit_"]', 'div.boite');
-  autoHideShowTagOnParentHover('a[class^="edit_"]', 'div.menu_horizontal');
-  autoHideShowTagOnParentHover('.select_kiosque_form', 'div.boite');
-  autoHideShowTagOnParentHover('.newsadd', 'div.boite');
-  autoHideShowTagOnParentHover('.default_filters', 'div.boite');
-}
-
-
-var autoHideShowTagOnParentHover = function (child_selector, parent_selector) {
-  hide_selector = parent_selector + ' ' + child_selector;
-  $(hide_selector).hide();
-  $(child_selector).parents(parent_selector).hover(
-    function() {
-      $(this).find(child_selector).fadeIn();
-    },
-
-    function() {
-      if (!$(this).find('select').is(":focus")) 
-				$(parent_selector).find(child_selector).fadeOut();
-    }
-  );
-  
-}
-
-
-
 var initializeImgHover = function() {
   var images = $('img[data-hover]');
   images.each(function(index, element) {
diff --git a/public/admin/skins/bokeh72/front_nav.css b/public/admin/skins/bokeh72/front_nav.css
index 7055fa7b95c0d948cf3677fafebe7b7100d39b42..0f2066cd19c0ea1be164ee7b70381382586e6d9c 100644
--- a/public/admin/skins/bokeh72/front_nav.css
+++ b/public/admin/skins/bokeh72/front_nav.css
@@ -1,143 +1 @@
-.menu_admin_front * {
-    box-sizing: content-box;
-    font-family: arial, sans-serif;
-}
-
-.menu_admin_front .form select,
-.menu_admin_front > div {
-    background-color: var(--widget-background);
-}
-
-.menu_admin_front .admin_menu_title,
-.menu_admin_front .form select,
-.menu_admin_front label {
-    color: var(--main-text);
-}
-
-.menu_admin_front a {
-    color: var(--anchor);
-}
-
-.menu_admin_front .form select {
-    border: 1px solid var(--border-highlight);
-}
-
-.menu_admin_front > div {
-    box-shadow: 1px 1px 5px var(--widget-shadow);
-}
-
-.menu_admin_front {
-    position: fixed;
-    top: 0;
-    left: 0;
-    z-index: 102;
-}
-
-.menu_admin_front > button,
-.menu_admin_front > div {
-    transition: all 0.4s;
-}
-
-.menu_admin_front > div {
-    overflow: hidden;
-    width: 300px;
-}
-
-.menu_admin_front.hidden > div {
-    margin-left: -300px;
-    position: absolute;
-}
-
-.menu_admin_front > button {
-    margin: 0;
-    white-space: nowrap;
-}
-
-.menu_admin_front:not(.hidden) > button > img {
-    transform: rotate(45deg);
-}
-
-.menu_admin_front .admin_menu_title,
-.menu_admin_front form tr,
-.menu_admin_front a {
-    display: block;
-    line-height: 2em;
-}
-
-.menu_admin_front a img {
-    float: right;
-    vertical-align: middle;
-    padding-right: 1.5em;
-}
-
-.menu_admin_front ul,
-.menu_admin_front li {
-    margin: 0 0 0 0.2em;
-    padding: 0 0 0 0.2em;
-    list-style: none;
-}
-
-.menu_admin_front [class*="deactivate"] {
-    display: none;
-}
-
-.menu_admin_front fieldset {
-    padding: 0;
-    margin: 0;
-}
-
-.menu_admin_front .form td {
-    display: inline-block;
-    text-align: left !important;
-}
-
-.menu_admin_front form + .boutons {
-    display: none;
-}
-
-.menu_admin_front .form {
-    text-align: left;
-}
-
-.menu_admin_front .form * {
-    display: block;
-}
-
-.menu_admin_front .form select {
-    display: inline;
-    height: 2em;
-    width: 270px;
-}
-
-#site_web_wrapper[data-show_admin_icons="true"] a[href*="/admin"] {
-    display: inline-block !important;
-}
-
-
-#site_web_wrapper[data-show_admin_icons="true"] .configuration_module {
-    display: block !important;
-}
-
-#site_web_wrapper .footer select[onchange],
-#site_web_wrapper .footer a[href*="/admin"],
-#site_web_wrapper .admin_tools_lock,
-#site_web_wrapper .configuration_module,
-#site_web_wrapper a[href*="/admin"] {
-    display: none !important;
-    opacity: 1 !important;
-}
-
-.menu_admin_front a:hover, 
-.menu_admin_front a:focus {
-    text-decoration: underline;
-}
-
-.menu_admin_front a img {
-    height: 18px;
-}
-
-.menu_admin_front .admin_menu_title {
-    font-size: 1.17em;
-    margin: 1em 0 1em 0;
-    font-weight: bold;
-}
+@import url('../../css/front_nav.css');
\ No newline at end of file
diff --git a/public/admin/skins/bokeh74/front_nav.css b/public/admin/skins/bokeh74/front_nav.css
index 5214189aa087316a706a9c2df78e359cf4b71949..0f2066cd19c0ea1be164ee7b70381382586e6d9c 100644
--- a/public/admin/skins/bokeh74/front_nav.css
+++ b/public/admin/skins/bokeh74/front_nav.css
@@ -1,155 +1 @@
-.menu_admin_front * {
-    box-sizing: content-box;
-    font-family: arial, sans-serif;
-}
-
-.menu_admin_front .form select,
-.menu_admin_front > div {
-    background-color: var(--widget-background);
-}
-
-.menu_admin_front .admin_menu_title,
-.menu_admin_front .form select,
-.menu_admin_front label {
-    color: var(--main-text);
-}
-
-.menu_admin_front a {
-    color: var(--anchor);
-}
-
-.menu_admin_front .form select {
-    border: 1px solid var(--border-highlight);
-}
-
-.menu_admin_front > div {
-    box-shadow: 1px 1px 5px var(--widget-shadow);
-}
-
-.menu_admin_front {
-    font-size: 12px;
-    position: fixed;
-    top: 0;
-    left: 0;
-    z-index: 102;
-}
-
-.menu_admin_front > button,
-.menu_admin_front > div {
-    transition: all 0.4s;
-}
-
-.menu_admin_front > div {
-    overflow: hidden;
-    width: 300px;
-}
-
-.menu_admin_front.hidden > div {
-    margin-left: -300px;
-    position: absolute;
-}
-
-.menu_admin_front > button {
-    margin: 0;
-    white-space: nowrap;
-}
-
-.menu_admin_front:not(.hidden) > button > img {
-    transform: rotate(45deg);
-}
-
-.menu_admin_front .amdin_menu_title,
-.menu_admin_front form tr,
-.menu_admin_front a {
-    display: block;
-    line-height: 2em;
-}
-
-.menu_admin_front a img {
-    float: right;
-    vertical-align: middle;
-    padding-right: 1.5em;
-}
-
-.menu_admin_front ul,
-.menu_admin_front li {
-    margin: 0 0 0 0.2em;
-    padding: 0 0 0 0.2em;
-    list-style: none;
-}
-
-.menu_admin_front [class*="deactivate"] {
-    display: none;
-}
-
-.menu_admin_front fieldset {
-    padding: 0;
-    margin: 0;
-}
-
-.menu_admin_front .form td {
-    display: inline-block;
-    text-align: left !important;
-}
-
-.menu_admin_front form + .boutons {
-    display: none;
-}
-
-.menu_admin_front .form {
-    text-align: left;
-}
-
-.menu_admin_front .form * {
-    display: block;
-}
-
-.menu_admin_front .form select {
-    display: inline;
-    height: 2em;
-    width: 270px;
-}
-
-#site_web_wrapper[data-show_admin_icons="true"] a[href*="/admin"] {
-    display: inline-block !important;
-}
-
-.menu_admin_front a img {
-    height: 18px;
-}
-
-.menu_admin_front a[href$="/admin"] img {
-    filter: invert(1);
-}
-
-#site_web_wrapper[data-show_admin_icons="true"] .configuration_module {
-    display: block !important;
-}
-
-#site_web_wrapper .footer select[onchange],
-#site_web_wrapper .footer a[href*="/admin"],
-#site_web_wrapper .admin_tools_lock,
-#site_web_wrapper .configuration_module,
-#site_web_wrapper a[href*="/admin"] {
-    display: none !important;
-    opacity: 1 !important;
-}
-
-.menu_admin_front a:hover, 
-.menu_admin_front a:focus {
-    text-decoration: underline;
-}
-
-.menu_admin_front > div {
-    padding-bottom: 1em;
-}
-
-.menu_admin_front .admin_menu_title {
-    font-size: 1.17em;
-    margin: 1em 0 1em 0;
-    font-weight: bold;
-}
-
-.menu_admin_front .admin_menu_title label {
-    font-weight: bold;
-}
+@import url('../../css/front_nav.css');
\ No newline at end of file
diff --git a/public/admin/skins/retro/front_nav.css b/public/admin/skins/retro/front_nav.css
index d1f11a3ed337e56b39be10f735ff0b508b2c81db..b8ebbecc18cf630d087dc490c15ad84ba7997137 100644
--- a/public/admin/skins/retro/front_nav.css
+++ b/public/admin/skins/retro/front_nav.css
@@ -1,3 +1,5 @@
+@import url('../../css/front_nav.css');
+
 @font-face{
     font-family:minecraft;
     src:url(Minecraft.ttf) format("truetype");
@@ -23,138 +25,4 @@
 
 .menu_admin_front > div > ul > li {
     margin-top: 1em;
-}
-
-.menu_admin_front .admin_menu_title,
-.menu_admin_front .form select,
-.menu_admin_front label {
-    color: var(--main-text);
-}
-
-.menu_admin_front a {
-    color: var(--anchor);
-}
-
-.menu_admin_front .form select {
-    border: 1px solid var(--border-highlight);
-}
-
-.menu_admin_front > div {
-    box-shadow: 1px 1px 5px var(--widget-shadow);
-}
-
-.menu_admin_front {
-    position: fixed;
-    top: 0;
-    left: 0;
-    z-index: 102;
-}
-
-.menu_admin_front > button,
-.menu_admin_front > div {
-    transition: all 0.4s;
-}
-
-.menu_admin_front > div {
-    overflow: hidden;
-    width: 300px;
-}
-
-.menu_admin_front.hidden > div {
-    margin-left: -300px;
-    position: absolute;
-}
-
-.menu_admin_front > button {
-    margin: 0;
-    white-space: nowrap;
-}
-
-.menu_admin_front:not(.hidden) > button > img {
-    transform: rotate(45deg);
-}
-
-.menu_admin_front .admin_menu_title,
-.menu_admin_front form tr,
-.menu_admin_front a {
-    display: block;
-    line-height: 2em;
-}
-
-.menu_admin_front a img {
-    float: right;
-    vertical-align: middle;
-    padding-right: 1.5em;
-}
-
-.menu_admin_front ul,
-.menu_admin_front li {
-    margin: 0;
-    padding: 0 0.2em 0 0.2em;
-    list-style: none;
-}
-
-.menu_admin_front [class*="deactivate"] {
-    display: none;
-}
-
-.menu_admin_front fieldset {
-    padding: 0;
-    margin: 0;
-}
-
-.menu_admin_front .form td {
-    display: inline-block;
-    text-align: left !important;
-}
-
-.menu_admin_front form + .boutons {
-    display: none;
-}
-
-.menu_admin_front .form {
-    text-align: left;
-}
-
-.menu_admin_front .form * {
-    display: block;
-}
-
-.menu_admin_front .form select {
-    height: 2em;
-    width: 270px;
-}
-
-#site_web_wrapper[data-show_admin_icons="true"] a[href*="/admin"] {
-    display: inline-block !important;
-}
-
-
-#site_web_wrapper[data-show_admin_icons="true"] .configuration_module {
-    display: block !important;
-}
-
-#site_web_wrapper .footer select[onchange],
-#site_web_wrapper .footer a[href*="/admin"],
-#site_web_wrapper .admin_tools_lock,
-#site_web_wrapper .configuration_module,
-#site_web_wrapper a[href*="/admin"] {
-    display: none !important;
-    opacity: 1 !important;
-}
-
-.menu_admin_front a:hover, 
-.menu_admin_front a:focus {
-    text-decoration: underline;
-}
-
-.menu_admin_front a[href$="/admin"] img {
-    height: 18px;
-    filter: invert(1);
-}
-
-.menu_admin_front .admin_menu_title {
-    font-size: 1.17em;
-    margin: 1em 0 1em 0;
-    font-weight: bold;
-}
+}
\ No newline at end of file
diff --git a/public/opac/css/global.css b/public/opac/css/global.css
index 481e0d4a31a825b4ef07bcfb4432874bf43ccbda..b14fcc8a308b32e159d5c4dda54316b5e321c274 100644
--- a/public/opac/css/global.css
+++ b/public/opac/css/global.css
@@ -35,13 +35,6 @@ a {
 
 
 /* Boites bannière*/
-.configuration_module {
-    z-index: 101;
-    position: relative; 
-    height: 0px;
-    float: right;
-    cursor:pointer;
-}
 
 .select_kiosque_form {
     margin-right:25px;
@@ -412,9 +405,6 @@ table.calendar_table td {
     position: relative;
 }
 
-ul.menuGauche {
-    overflow: hidden;
-}
 
 ul.menuGauche li {
     white-space: nowrap;
@@ -976,10 +966,6 @@ ul.view-raw-rss li {
     margin-top: 10px;
 }
 
-.edit_menu  {
-    left: 0;
-    top: 0;
-}
 
 .edit_album {
     float: right;
@@ -1070,7 +1056,6 @@ ul.view-raw-rss li {
 article,
 .colContenu,
 .kiosque .titre,
-.kiosque .contenu,
 .boite.kiosque {
     position: relative;
 }
@@ -3175,6 +3160,10 @@ a.loan-export {
     padding: 0 20px;
 }
 
+.boite.library section {
+    position: relative;
+}
+
 .dilicom-action {
     padding: 5px;
     margin: 10px; 
@@ -3563,70 +3552,4 @@ th.actions {
 .boutons {
     text-align: center;
     padding: 1em;
-}
-
-a.newsadd,
-a.default_filters,
-a[class*="edit_"]:not(.edit_profil) {
-    position: absolute;
-}
-
-a.newsadd,
-a.default_filters,
-.configuration_module a,
-a[class*="edit_"]:not(.edit_profil):focus,
-a[class*="edit_"]:not(.edit_profil) {
-    display: inline-block;
-    margin: 0 !important;
-    padding: 0 !important;
-    left: 0;
-    top: 0;
-    z-index: 101;
-    background-color: transparent !important;
-    margin: 0 !important;
-    padding: 1px !important;
-    height: auto !important;
-    width: auto !important;
-    border: 2px solid transparent !important;
-}
-
-a.newsadd:hover,
-a.default_filters:hover,
-.configuration_module a:hover,
-a[class*="edit_"]:not(.edit_profil):hover {
-    border-color: black !important;
-    background-color: white !important;
-}
-
-a.newsadd img,
-a.default_filters img,
-.configuration_module a img,
-a[class*="edit_"] img {
-    height: 16px !important;
-    width: 16px !important;
-    margin: 0 !important;
-    padding: 0 !important;
-    border-radius: 0 !important;
-    vertical-align: middle;
-}
-
-.edit_profil {
-    margin: 0 5px;
-}
-
-.configuration_module + a.edit_menu:focus,
-.configuration_module + a.edit_menu,
-a.newsadd,
-a.newsadd:focus,
-a.default_filters,
-a.default_filters:focus {
-    top: auto;
-    left: auto;
-    right: 80px !important;
-}
-
-.menu_horizontal > a.edit_menu:focus,
-.menu_horizontal > a.edit_menu {
-    left: auto;
-    right: 0;
 }
\ No newline at end of file
diff --git a/public/opac/js/digital_connectors.js b/public/opac/js/digital_connectors.js
index f70e8c199721b8b3a40e315cc4dcd86f4165ffd5..f9f924330f6e67a29266047614030fb5dff9f879 100644
--- a/public/opac/js/digital_connectors.js
+++ b/public/opac/js/digital_connectors.js
@@ -258,5 +258,58 @@
     "desc": "Orphea Studio vous propose des offres de gestion de contenus multimédias adaptées à vos problématiques métiers",
     "features": ["HARVEST", "SSO"], 
     "sales_contact": {"url": "https://www.orphea.com/contact", "name":"Orphéa", "mail":"info@orphea.com"}
+  },
+    
+  "MEDIAPART": {
+    "label" : "Médiapart", 
+    "enabled": "PROVIDER",
+    "url" : "https://www.mediapart.fr", 
+    "image_url" : "http://bokeh-library-portal.org/userfiles/media/ressources_numeriques/logo_mediapart.png", 
+    "desc": "Mediapart est un journal d'information numérique, indépendant et participatif.",
+    "features": [], 
+    "sales_contact": {"mail" : "",
+		      "name" : "",
+		      "url" : "https://www.mediapart.fr"}
+  },
+  
+  "UNIVERSALIS": {
+    "label" : "Universalis", 
+    "enabled": "PROVIDER",
+    "url" : "http://www.universalis-edu.com/", 
+    "image_url" : "http://bokeh-library-portal.org/userfiles/media/ressources_numeriques/logo_universalis.jpg", 
+    "desc": "Encyclopédie francophone proposant des contenus couvrant tous les domaines de la connaissance illustrés par de nombreux médias.",
+    "features": [], 
+    "sales_contact": {"mail" : "",
+		      "name" : "",
+		      "url" : "http://www.encyclopaedia-universalis.fr/bibliotheques-et-entreprises/universalis-fr/"}
+		      
+  },
+  
+  "REFERENCES": {
+    "label" : "Références par Indexpresse", 
+    "enabled": "PROVIDER",
+    "url" : "http://www.references-indexpresse.com", 
+    "image_url" : "http://bokeh-library-portal.org/userfiles/media/ressources_numeriques/logo_references.png", 
+    "desc": "Références est le moteur de recherche dédié aux revues et magazines français « grand public ».",
+    "features": [], 
+    "sales_contact": {"mail" : "",
+		      "name" : "",
+		      "url" : "http://www.indexpresse.fr/project/references/"}
+		      
+  },
+  
+  "SCIENCESENLIGNE": {
+    "label" : "Sciences en ligne", 
+    "enabled": "PROVIDER",
+    "url" : "http://www.sciences-en-ligne.com", 
+    "image_url" : "http://bokeh-library-portal.org/userfiles/media/ressources_numeriques/logo_sciencesenligne.png", 
+    "desc": "Ressources encyclopédique scientifique et technique, en français.",
+    "features": [], 
+    "sales_contact": {"mail" : "",
+		      "name" : "",
+		      "url" : "http://www.sciences-en-ligne.com/comm/documentaliste-bibliothecaire-mediatheques/"}
+
+		      
+
   }
 }
diff --git a/public/opac/js/widget_templates/agenda_mur.jpg b/public/opac/js/widget_templates/agenda_mur.jpg
index bef7277c397c56c332f30b88b2e1d01f3c81bd25..ae2ede2213622ac326ff8b2cb49cee4b9bf77c32 100644
Binary files a/public/opac/js/widget_templates/agenda_mur.jpg and b/public/opac/js/widget_templates/agenda_mur.jpg differ
diff --git a/public/opac/js/widget_templates/agenda_simple.jpg b/public/opac/js/widget_templates/agenda_simple.jpg
index 3e9ad690978a0fb70a94bb5410f560edc4092b6b..3400a24da5a5ac57ca4bbdfa803218ebae2b70ef 100644
Binary files a/public/opac/js/widget_templates/agenda_simple.jpg and b/public/opac/js/widget_templates/agenda_simple.jpg differ
diff --git a/public/opac/js/widget_templates/article_diaporama.jpg b/public/opac/js/widget_templates/article_diaporama.jpg
index a4d873c5e6f91a9e608bf74371522587d28583c5..f204d27f526c3f22f27bf709c69fa9380b9d22c0 100644
Binary files a/public/opac/js/widget_templates/article_diaporama.jpg and b/public/opac/js/widget_templates/article_diaporama.jpg differ
diff --git a/public/opac/js/widget_templates/article_diaporama_boutons.jpg b/public/opac/js/widget_templates/article_diaporama_boutons.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..5616d34cf39e7cf30e266e1a7874eb7802aa5494
Binary files /dev/null and b/public/opac/js/widget_templates/article_diaporama_boutons.jpg differ
diff --git a/public/opac/js/widget_templates/article_diaporama_vignette.jpg b/public/opac/js/widget_templates/article_diaporama_vignette.jpg
index 7735d9cb00b42d82e2c7a12f3647af4d3fc3ce1f..b5f24cd1a537a003a10231d0f6dd2fb6a9ae7627 100644
Binary files a/public/opac/js/widget_templates/article_diaporama_vignette.jpg and b/public/opac/js/widget_templates/article_diaporama_vignette.jpg differ
diff --git a/public/opac/js/widget_templates/articles_diaporama.jpg b/public/opac/js/widget_templates/articles_diaporama.jpg
deleted file mode 100644
index 08682293b1a7cb1f7df4c2ac3acbd37b8c89ec2c..0000000000000000000000000000000000000000
Binary files a/public/opac/js/widget_templates/articles_diaporama.jpg and /dev/null differ
diff --git a/public/opac/js/widget_templates/boite_bibliotheque.jpg b/public/opac/js/widget_templates/boite_bibliotheque.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..99377bdc7f616a8ec2c859539871b5b2c063e0a5
Binary files /dev/null and b/public/opac/js/widget_templates/boite_bibliotheque.jpg differ
diff --git a/public/opac/js/widget_templates/domaines.jpg b/public/opac/js/widget_templates/domaines.jpg
index 4b2b524ebd1b4c51fa3196799092786587f7442a..43a7d63df72170895827170576c803c731f3038c 100644
Binary files a/public/opac/js/widget_templates/domaines.jpg and b/public/opac/js/widget_templates/domaines.jpg differ
diff --git a/public/opac/js/widget_templates/kiosque_barre_horizontale.jpg b/public/opac/js/widget_templates/kiosque_barre_horizontale.jpg
index a48eb463c9c8faf991a40786e20a48c905ec8514..1682458e20a6b4c0b1b03f7ed8c9659b3847fb7e 100644
Binary files a/public/opac/js/widget_templates/kiosque_barre_horizontale.jpg and b/public/opac/js/widget_templates/kiosque_barre_horizontale.jpg differ
diff --git a/public/opac/js/widget_templates/langue.jpg b/public/opac/js/widget_templates/langue.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..b492dd1efc672416c82b35d63a5346c2df01cdf8
Binary files /dev/null and b/public/opac/js/widget_templates/langue.jpg differ
diff --git a/public/opac/js/widget_templates/lettre_information.jpg b/public/opac/js/widget_templates/lettre_information.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..f6a8773162f905f7ee2b2b686a9769d0fe41857f
Binary files /dev/null and b/public/opac/js/widget_templates/lettre_information.jpg differ
diff --git a/public/opac/js/widget_templates/login.jpg b/public/opac/js/widget_templates/login.jpg
index e713d9935e90051e9aaa67086152af9c2e150bad..c43c368ae329cc4ea84c57efe79a58f30638964c 100644
Binary files a/public/opac/js/widget_templates/login.jpg and b/public/opac/js/widget_templates/login.jpg differ
diff --git a/public/opac/js/widget_templates/menu_vertical.jpg b/public/opac/js/widget_templates/menu_vertical.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..3cc934c5bc8f532de252266989bbd666d649b6b0
Binary files /dev/null and b/public/opac/js/widget_templates/menu_vertical.jpg differ
diff --git a/public/opac/js/widget_templates/nuage_tags.jpg b/public/opac/js/widget_templates/nuage_tags.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..e783f2a47b45320b6270ac66947e8a1df60bfae7
Binary files /dev/null and b/public/opac/js/widget_templates/nuage_tags.jpg differ
diff --git a/public/opac/js/widget_templates/recherche.jpg b/public/opac/js/widget_templates/recherche.jpg
index 02ada8019b874844bd5158ba6ac37b789d215255..703603d2e3fdd4e02dddd72977dca4387cf1b08f 100644
Binary files a/public/opac/js/widget_templates/recherche.jpg and b/public/opac/js/widget_templates/recherche.jpg differ
diff --git a/public/opac/js/widget_templates/rss.jpg b/public/opac/js/widget_templates/rss.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..c2bf4c7b6692dbcc28eb1cdb0003780bea7b07a5
Binary files /dev/null and b/public/opac/js/widget_templates/rss.jpg differ
diff --git a/public/opac/js/widget_templates/sitotheque.jpg b/public/opac/js/widget_templates/sitotheque.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..d2c015fad2a5497ab3701a07477befeecadab507
Binary files /dev/null and b/public/opac/js/widget_templates/sitotheque.jpg differ
diff --git a/public/opac/js/widget_templates/widget_templates.css b/public/opac/js/widget_templates/widget_templates.css
index 605ed7d747c18340359c5858cb893f04647e133d..d25a8741850f9306d59c13c4d628c4520118881f 100644
--- a/public/opac/js/widget_templates/widget_templates.css
+++ b/public/opac/js/widget_templates/widget_templates.css
@@ -1,17 +1,51 @@
+.widget_templates.ui-accordion .ui-accordion-header {
+    padding: 1em 2em;
+    margin-bottom: 2px;
+    font-weight: bold;
+}
+
+.widget_templates.ui-accordion .ui-accordion-header,
+.widget_templates a h4 {
+    color: var(--button);
+    background-color: var(--button-background);
+}
+
+.widget_templates.ui-accordion .ui-accordion-header:hover,
+.widget_templates.ui-accordion .ui-accordion-header.ui-state-active,
+.widget_templates a:hover h4 {
+    color: var(--button-highlight);
+    background-color: var(--button-background-highlight);
+}
+
 .widget_templates a {
-  display: inline-block;
-  width: 50%;
-  transition: all .2s ease-in-out;
+    display: inline-block;
+    transition: all .2s ease-in-out;
+    box-shadow: 0px 0px 5px var(--widget-shadow);
+    text-align: center;
+    border-radius: 5px;
+    margin: 0.5%;
+}
+
+
+.widget_templates a {
+    width: 32%;    
+}
+
+
+.widget_templates a img {
+    width: 100%;
 }
 
 .widget_templates a h4 {
-  color: #333333;
-  font-weight: normal;
-  text-align: center;
-  text-transform: uppercase;
+    font-weight: normal;
+    text-transform: uppercase;
+    margin: 0;
+    padding: 1em;
+    border-radius: 5px 5px 0 0;
+    white-space: nowrap;
 }
 
 .widget_templates a:hover {
-  opacity: 0.8;
-  transform: scale(1.1);
-}
\ No newline at end of file
+    box-shadow: 0px 0px 15px var(--widget-shadow);
+    transform: scale(1.02);
+}
diff --git a/public/opac/js/widget_templates/widget_templates.json b/public/opac/js/widget_templates/widget_templates.json
index 3e609b25e3855d5e0eef238e2e27b14ea53a2dbb..a939603c921181a8fa2b38c8ac1e40018a678a61 100755
--- a/public/opac/js/widget_templates/widget_templates.json
+++ b/public/opac/js/widget_templates/widget_templates.json
@@ -36,7 +36,7 @@
 
         {
           "title": "Diaporama avec boutons",
-          "icon": "articles_diaporama.jpg",
+          "icon": "article_diaporama_boutons.jpg",
 	  "type": "NEWS",
           "configuration": {
             "style_liste": "diaporama_navigation",
@@ -211,16 +211,9 @@
       ]
     },
 
-    "advanced": {
-      "title": "Avancé",
+    "Recherche": {
+      "title": "Recherche",      
       "templates": [
-        {
-          "title": "Boite d'authentification",
-	  "type": "LOGIN",
-          "icon": "login.jpg",
-          "configuration": {}
-        },
-
         {
           "title": "Boite de recherche",
           "icon": "recherche.jpg",
@@ -232,10 +225,10 @@
           }
         },
 
-        {
-          "title": "Boite 2 colonnes",
-          "icon": "boite_2colonnes.jpg",
-	  "type": "CONTENEUR_DEUX_COLONNES",
+          {
+          "title": "Nuage de tags",
+          "icon": "nuage_tags.jpg",
+	  "type": "TAGS",
           "configuration": {}
         },
 
@@ -247,6 +240,62 @@
         }
 
       ]
+    },
+
+
+
+    "advanced": {
+      "title": "Avancé",
+      "templates": [
+        {
+          "title": "Boite d'authentification",
+	  "type": "LOGIN",
+          "icon": "login.jpg",
+          "configuration": {}
+        },
+
+        {
+          "title": "Boite 2 colonnes",
+          "icon": "boite_2colonnes.jpg",
+	  "type": "CONTENEUR_DEUX_COLONNES",
+          "configuration": {}
+        },
+
+        {
+          "title": "Boite RSS",
+          "icon": "rss.jpg",
+	  "type": "RSS",
+          "configuration": {}
+        },
+
+        {
+          "title": "Boite Bibliothèque",
+          "icon": "boite_bibliotheque.jpg",
+	  "type": "LIBRARY",
+          "configuration": {}
+        },
+
+        {
+          "title": "Boite Menu Vertical",
+          "icon": "menu_vertical.jpg",
+	  "type": "MENU_VERTICAL",
+          "configuration": {}
+        },
+
+        {
+          "title": "Boite Newsletter",
+          "icon": "lettre_information.jpg",
+	  "type": "NEWSLETTERS",
+          "configuration": {}
+        },
+
+        {
+          "title": "Boite Langue",
+          "icon": "langue.jpg",
+	  "type": "LANGUE",
+          "configuration": {}
+        }
+      ]
     }
   }
 }
diff --git a/tests/application/modules/admin/controllers/BatchControllerTest.php b/tests/application/modules/admin/controllers/BatchControllerTest.php
index bfd78004098037b925b467c6140081fa181fd835..3750b2bc44d7e0e0ec6cc3d797b9b7c04f3e3e83 100644
--- a/tests/application/modules/admin/controllers/BatchControllerTest.php
+++ b/tests/application/modules/admin/controllers/BatchControllerTest.php
@@ -28,27 +28,84 @@ abstract class BatchControllerTestCase extends AbstractControllerTestCase {
     $_storm_default_to_volatile = true,
     $_batch_import;
 
+  protected function _loginHook($account) {
+    $account->ROLE_LEVEL = ZendAfi_Acl_AdminControllerRoles::SUPER_ADMIN;
+  }
+
   public function setUp() {
     parent::setUp();
 
     RessourcesNumeriquesFixtures::activateTypo3();
     RessourcesNumeriquesFixtures::activateVodeclic();
-    RessourcesNumeriquesFixtures::deactivateArteVod();
+    RessourcesNumeriquesFixtures::activateArteVod();
+    RessourcesNumeriquesFixtures::activateCyberlibris();
     RessourcesNumeriquesFixtures::deactivateToutApprendre();
     RessourcesNumeriquesFixtures::deactivateNumilog();
+
     $this->_batch_import = $this->fixture('Class_Batch',
                                           ['id' => 3,
                                            'type' => 'IMPORT_TYPO3',
+                                           'pick_day' => '5;6',
                                            'last_run' => '2012-05-01 10:23:00']);
   }
 }
 
 
 
+class BatchControllerWithoutAdminAccountTest extends BatchControllerTestCase {
+  protected function _loginHook($account) {
+    $account->ROLE_LEVEL = ZendAfi_Acl_AdminControllerRoles::MODO_PORTAIL;
+  }
+
+
+  /** @test */
+  public function shouldBeRedirectedToOpac() {
+    $this->dispatch('/admin/batch', true);
+    $this->assertRedirectTo('/opac/index/index/id_profil/1');
+  }
+}
+
+
+
+class BatchControllerWithAdminPortalTest extends BatchControllerTestCase {
+  protected function _loginHook($account) {
+    $account->ROLE_LEVEL = ZendAfi_Acl_AdminControllerRoles::ADMIN_PORTAIL;
+  }
+
+
+  public function setUp() {
+    parent::setUp();
+    $this->dispatch('/admin/batch', true);
+  }
+
+
+  /** @test */
+  public function planLinkShouldNotBePresent() {
+    $this->assertNotXPath('//a[contains(@href, "/batch/plan/id/")]');
+  }
+}
+
+
 
 class BatchControllerWithBatchInDb extends BatchControllerTestCase {
   public function setUp() {
     parent::setUp();
+
+    $this->fixture('Class_Batch',
+                   ['id' => 4,
+                    'type' => Class_Batch_PanierUser::TYPE,
+                    'pick_day' => '1;2;3;4;5;6;0']);
+
+    $this->fixture('Class_Batch',
+                   ['id' => 5,
+                    'type' => Class_Batch_AvisNotice::TYPE,
+                    'pick_day' => '']);
+
+    $this->fixture('Class_Batch',
+                   ['id' => 6,
+                    'type' => Class_Batch_AutocompleteRecordTitle::TYPE,
+                    'pick_day' => '0']);
+
     $this->dispatch('/admin/batch', true);
   }
 
@@ -62,129 +119,182 @@ class BatchControllerWithBatchInDb extends BatchControllerTestCase {
 
   /** @test */
   public function batchNoveltyCouldNotBeDelete() {
-    $this->assertNotXPath('//a[contains(@href, "batch/delete/id/' . Class_Batch::findFirstBy(['type' => Class_Batch_NoveltyFacet::TYPE])->getId() . '")]', $this->_response->getBody());
+    $this->assertNotXPath('//a[contains(@href, "batch/delete/id/' . Class_Batch_NoveltyFacet::TYPE . '")]');
   }
 
 
   /** @test */
-  public function tableShouldContainsMoissonnageArteVod() {
-    $this->assertXPathContentContains('//tbody//tr[1]//td',
+  public function tableShouldContainsTypo3() {
+    $this->assertXPathContentContains('//tbody//td',
                                       Class_Batch::getBatchLibelle('IMPORT_TYPO3'));
   }
 
 
   /** @test */
-  public function buttonShouldLinkToAdd() {
-    $this->assertXPath('//button[contains(@onclick, "batch/add")]');
+  public function tableShouldContainsTypo3PickDay() {
+    $this->assertXPathContentContains('//tbody//td', 'ven, sam');
+  }
+
+
+  /** @test */
+  public function tableShouldContainsAllDays() {
+    $this->assertXPathContentContains('//tbody//td', 'Tous les jours');
+  }
+
+
+  /** @test */
+  public function tableShouldContainsNeverEver() {
+    $this->assertXPathContentContains('//tbody//td', 'Aucune');
+  }
+
+
+  /** @test */
+  public function tableShouldContainsOneSundayOnly() {
+    $this->assertXPathCount('//tbody//td[text()="dim"]', 1);
   }
 
 
   /** @test */
-  public function batchActionShouldDeleteMyTask() {
+  public function deleteLinkShouldBePresent() {
     $this->assertXPath('//a[contains(@href, "batch/delete")]');
   }
 
 
   /** @test */
-  public function batchActionShouldRunMyTask() {
+  public function runLinkShouldBePresent() {
     $this->assertXPath('//a[contains(@href, "batch/run")]');
   }
+
+
+  /** @test */
+  public function activateLinkShouldBePresent() {
+    $this->assertXPath('//a[contains(@href, "/batch/activate")]');
+  }
+
+
+  /** @test */
+  public function planLinkShouldBePresent() {
+    $this->assertXPath('//a[contains(@href, "batch/plan/id")]');
+  }
 }
 
 
 
 
-class BatchControllerAddTest extends BatchControllerTestCase {
-  public function setUp() {
-    parent::setUp();
-    $this->dispatch('/admin/batch/add', true);
+class BatchControllerActivateTest extends BatchControllerTestCase {
+  protected function _expectNotSave() {
+    $this->onLoaderOfModel('Class_Batch')
+         ->whenCalled('save')
+         ->willDo(function()
+                  {
+                    throw new RuntimeException('Save called on Class_Batch');
+                  });
   }
 
 
   /** @test */
-  public function selectElementBatchShouldBePresent() {
-    $this->assertXPath('//select[@name="type"]');
+  public function withoutIdShouldRedirectWithoutAdding() {
+    $this->_expectNotSave();
+    $this->dispatch('/admin/batch/activate', true);
+    $this->assertRedirectTo('/admin/batch/index');
   }
 
 
-  public function datas() {
-    return [['MOISSONNAGE_VODECLIC', 'Moissonner catalogue Vodeclic', true],
-            ['MOISSONNAGE_ARTEVOD', 'Moissonner catalogue ArteVOD', false],
-            ['MOISSONNAGE_NUMILOG', 'Moissonner catalogue Numilog', false],
-            ['MOISSONNAGE_TOUTAPPRENDRE', 'Moissonner catalogue Tout apprendre', false],
-            ['AUTOCOMPLETE_RECORD_TITLE', 'Indexer les titres de notice pour l\'autocompletion', true],
-            ['AUTOCOMPLETE_RECORD_AUTHOR', 'Indexer les auteurs de notice pour l\'autocompletion', true],
-            ['BUILD_SITE_MAP', 'Régénère le sitemap XML', true],
-            ['NOVELTY_FACET', 'Supprimer les facettes de nouveauté périmées', true]];
+  /** @test */
+  public function withUnknownIdShouldRedirectWithoutAdding() {
+    $this->_expectNotSave();
+    $this->dispatch('/admin/batch/activate/id/UNKNOWN_TYPE', true);
+    $this->assertRedirectTo('/admin/batch/index');
   }
 
 
+  /** @test */
+  public function withUnavailableIdShouldRedirectWithoutAdding() {
+    $this->_expectNotSave();
+    $this->dispatch('/admin/batch/activate/id/IMPORT_TYPO3', true);
+    $this->assertRedirectTo('/admin/batch/index');
+  }
+
+
+  public function datas() {
+    return [
+            [Class_Batch_Vodeclic::TYPE, '1;2;3;4;5;6;0'],
+            [Class_Batch_ArteVOD::TYPE, '6'],
+            [Class_Batch_Cyberlibris::TYPE, '0'],
+    ];
+  }
+
   /**
    * @test
    * @dataProvider datas
    */
-  public function selectElementShouldBePresent($value, $label, $should_be_present){
-    $path = sprintf('//select[@name="type"]/option[@value="%s"][@label="%s"][not(@selected)]',
-                    $value, $label);
+  public function shouldAddWithDays($type, $days) {
+    $this->dispatch('/admin/batch/activate/id/' . $type, true);
+    $this->assertNotNull($batch = Class_Batch::findFirstBy(['type' => $type]));
+    $this->assertEquals($days, $batch->getPickDay());
+  }
+}
+
+
 
-    $should_be_present
-      ? $this->assertXPath($path, $this->_response->getBody())
-      : $this->assertNotXPath($path, $this->_response->getBody());
+class BatchControllerPlanWithoutSysadminTest extends BatchControllerTestCase {
+  protected function _loginHook($account) {
+    $account->ROLE_LEVEL = ZendAfi_Acl_AdminControllerRoles::ADMIN_PORTAIL;
   }
 
 
   /** @test */
-  public function submitButtonShouldNotBeDisabled() {
-    $this->assertNotXPath('//button[contains(@class, "validate")][@disabled]');
+  public function shouldRedirect() {
+    $this->dispatch('/admin/batch/plan/id/IMPORT_TYPO3', true);
+    $this->assertRedirectTo('/admin/batch/index');
   }
 }
 
 
 
-class BatchControllerAddWithNumilogAndToutApprendreTest extends BatchControllerTestCase {
+class BatchControllerPlanWithSysadminTest extends BatchControllerTestCase {
+  protected function _loginHook($account) {
+    $account->ROLE_LEVEL = ZendAfi_Acl_AdminControllerRoles::SUPER_ADMIN;
+  }
+
+
   public function setUp() {
     parent::setUp();
-    RessourcesNumeriquesFixtures::activateNumilog();
-    RessourcesNumeriquesFixtures::activateToutApprendre();
-    $this->dispatch('/admin/batch/add', true);
+    $this->dispatch('/admin/batch/plan/id/IMPORT_TYPO3', true);
   }
 
 
   /** @test */
-  public function selectElementShouldContainsMoissonnageNumilog(){
-    $this->assertXPath('//select[@name="type"]/option[@value="MOISSONNAGE_NUMILOG"][@label="Moissonner catalogue Numilog"][not(@selected)]', $this->_response->getBody());
+  public function pickDayShouldBePresent() {
+    $this->assertXPath('//input[@type="checkbox"][@name="pick_day[]"]');
   }
+}
 
 
-  /** @test */
-  public function selectElementShouldContainsMoissonnageToutApprendre(){
-    $this->assertXPath('//select[@name="type"]/option[@value="MOISSONNAGE_TOUTAPPRENDRE"][@label="Moissonner catalogue Tout Apprendre"][not(@selected)]', $this->_response->getBody());
-  }
 
-  /** @test */
-  public function selectElementShouldContainsIndexerRessourcesNumeriques(){
-    $this->assertXPath('//select[@name="type"]/option[@value="INDEX_RESSOURCES_NUMERIQUES"][@label="Indexer les ressources numériques"][not(@selected)]', $this->_response->getBody());
+class BatchControllerPlanWithSysadminPostTest extends BatchControllerTestCase {
+  protected function _loginHook($account) {
+    $account->ROLE_LEVEL = ZendAfi_Acl_AdminControllerRoles::SUPER_ADMIN;
   }
-}
-
 
 
-class BatchControllerAddPostTest extends BatchControllerTestCase {
   public function setUp() {
     parent::setUp();
-    $this->postDispatch('/admin/batch/add',
-                        ['type' => 'MOISSONNAGE_VODECLIC'], true);
+    $this->postDispatch('/admin/batch/plan/id/IMPORT_TYPO3',
+                        ['pick_day' => ['3', '6']]);
   }
 
 
   /** @test */
-  public function batchShouldBeCreated() {
-    $this->assertNotNull(Class_Batch::findFirstBy(['type' => 'MOISSONNAGE_VODECLIC']));
+  public function batchPickDayShouldBeCome3and6() {
+    $this->assertEquals('3;6',
+                        Class_Batch::findFirstBy(['type' => 'IMPORT_TYPO3'])
+                        ->getPickDay());
   }
 
 
   /** @test */
-  public function clicValiderButtonShouldRedirectToAdminBatch(){
+  public function shouldRedirectToIndex() {
     $this->assertRedirectTo('/admin/batch');
   }
 }
@@ -195,15 +305,14 @@ class BatchControllerRunMoissonnageVodeclicTest extends BatchControllerTestCase
   public function setUp() {
     parent::setUp();
 
-    $this->mock_batch = Storm_Test_ObjectWrapper::mock()
-      ->whenCalled('run')->answers(true);
+    $this->mock_batch = $this->mock()->whenCalled('run')->answers(true);
 
     $this->fixture('Class_Batch', ['id' => 6, 'type' => 'MOCKED']);
-    Storm_Test_ObjectWrapper::onLoaderOfModel('Class_Batch')
-      ->whenCalled('getKnownType')->with('MOCKED')
-      ->answers($this->mock_batch);
+    $this->onLoaderOfModel('Class_Batch')
+         ->whenCalled('getKnownType')->with('MOCKED')
+         ->answers($this->mock_batch);
 
-    $this->dispatch('/admin/batch/run/id/6', true);
+    $this->dispatch('/admin/batch/run/id/MOCKED', true);
   }
 
 
@@ -226,20 +335,22 @@ class BatchControllerRunMoissonnageVodeclicTest extends BatchControllerTestCase
 class BatchControllerRunAjaxAutocompleteTest extends BatchControllerTestCase {
   public function setUp() {
     parent::setUp();
-    $this->fixture('Class_Batch', ['id' => 42, 'type' => 'AUTOCOMPLETE_RECORD_TITLE']);
+    $this->fixture('Class_Batch',
+                   ['id' => 42,
+                    'type' => Class_Batch_AutocompleteRecordTitle::TYPE]);
     $this->dispatch('/admin/batch', true);
   }
 
 
   /** @test */
   public function batchActionShouldRunAjaxMyTask() {
-    $this->assertXPath('//a[contains(@href, "batch/run-ajax/id/42")]');
+    $this->assertXPath('//a[contains(@href, "batch/run-ajax/id/' . Class_Batch_AutocompleteRecordTitle::TYPE . '")]');
   }
 
 
   /** @test */
   public function batchActionShouldNotRunSimpleMyTask() {
-    $this->assertNotXPath('//a[contains(@href, "batch/run/id/42")]');
+    $this->assertNotXPath('//a[contains(@href, "batch/run/id/' . Class_Batch_AutocompleteRecordTitle::TYPE . '")]');
   }
 }
 
@@ -248,23 +359,14 @@ class BatchControllerRunAjaxAutocompleteTest extends BatchControllerTestCase {
 class BatchControllerRunMoissonnageOrpheaTest extends BatchControllerTestCase {
   protected $_web_client;
 
-
-  public function tearDown() {
-    Storm_Model_Loader::defaultToDb();
-    parent::tearDown();
-  }
-
-
   public function setUp() {
     parent::setUp();
 
-    Storm_Model_Loader::defaultToVolatile();
-    $this->_web_client = Storm_Test_ObjectWrapper::mock()
-    ->whenCalled('open_url')->answers('');
+    $this->_web_client = $this->mock()->whenCalled('open_url')->answers('');
 
     $this->batch_orphea = $this->fixture('Class_Batch',
                                          ['id' => 4,
-                                          'type' => 'MOISSONNAGE_ORPHEA',
+                                          'type' => Class_Batch_Orphea::TYPE,
                                           'last_run' => '2012-05-01 10:23:00']);
 
     Class_WebService_BibNumerique_Orphea::setDefaultHttpClient($this->_web_client);
@@ -298,7 +400,7 @@ class BatchControllerRunMoissonnageOrpheaTest extends BatchControllerTestCase {
 
     ->beStrict();
 
-    $this->dispatch('/admin/batch/run/id/4', true);
+    $this->dispatch('/admin/batch/run/id/' . Class_Batch_Orphea::TYPE, true);
   }
 
 
@@ -311,19 +413,9 @@ class BatchControllerRunMoissonnageOrpheaTest extends BatchControllerTestCase {
 
 
 class BatchControllerIndexOrpheaTest extends BatchControllerTestCase {
-
-
-  public function tearDown() {
-    Storm_Model_Loader::defaultToDb();
-    parent::tearDown();
-  }
-
-
   public function setUp() {
     parent::setUp();
 
-    Storm_Model_Loader::defaultToVolatile();
-
     $this->fixture('Class_Album',
                    ['id' => 1,
                     'titre' => 'Orphea Album',
@@ -350,8 +442,6 @@ class BatchControllerIndexWithCyberlibrisTest extends BatchControllerTestCase {
   public function setUp() {
     parent::setUp();
 
-    RessourcesNumeriquesFixtures::activateCyberlibris();
-
     $this->fixture('Class_Batch',
                    ['id' => 1001528,
                     'type' => Class_Batch_Cyberlibris::TYPE]);
@@ -368,12 +458,12 @@ class BatchControllerIndexWithCyberlibrisTest extends BatchControllerTestCase {
 
   /** @test */
   public function cyberlibrisShouldNotBeRunnable() {
-    $this->assertNotXpath('//a[contains(@href, "batch/run/id/1001528")]');
+    $this->assertNotXpath('//a[contains(@href, "batch/run/id/' . Class_Batch_Cyberlibris::TYPE . '")]');
   }
 
 
   /** @test */
   public function cyberlibrisShouldNotBeAjaxRunnable() {
-    $this->assertNotXpath('//a[contains(@href, "batch/run-ajax/id/1001528")]');
+    $this->assertNotXpath('//a[contains(@href, "batch/run-ajax/id/' . Class_Batch_Cyberlibris::TYPE . '")]');
   }
-}
\ No newline at end of file
+}
diff --git a/tests/application/modules/admin/controllers/WidgetControllerTest.php b/tests/application/modules/admin/controllers/WidgetControllerTest.php
index 6ce32e882af155694d9567db3de0c737c3b7d37b..8f102ffd0b6e2efb4e5f47ecf149aad5106f6add 100644
--- a/tests/application/modules/admin/controllers/WidgetControllerTest.php
+++ b/tests/application/modules/admin/controllers/WidgetControllerTest.php
@@ -1574,7 +1574,7 @@ class WidgetControllerParentLoginDispatchTest extends WidgetControllerLoginInPar
   /** @test */
   public function addWidgetLinkShouldUseParentProfil() {
     $this->dispatch('/opac/index/index/id_profil/6', true);
-    $this->assertXpath('//div//a[contains(@href, "admin/widget/add/after/2/division/4/id_profil/2")]');
+    $this->assertXpath('//div//a[contains(@href, "admin/widget/add-from-template/after/2/division/4/id_profil/2")]');
   }
 
 
@@ -1959,7 +1959,7 @@ class WidgetControllerLibrarySimpleDispatchTest extends WidgetControllerDispatch
 
 
 
-class WidgetControllerAddActionLinkTest extends WidgetControllerWidgetConfigurationTestCase {
+class WidgetControllerAddFromTemplateActionLinkTest extends WidgetControllerWidgetConfigurationTestCase {
   public function setUp() {
     $this->_type_module = 'LOGIN';
     parent::setUp();
@@ -1969,24 +1969,27 @@ class WidgetControllerAddActionLinkTest extends WidgetControllerWidgetConfigurat
 
   /** @test */
   public function linkAddWidgetShouldBePresent() {
-    $this->assertXPath('//a[contains(@href, "admin/widget/add/after/6/division/3/id_profil/5")]');
+    $this->assertXPath('//a[contains(@href, "admin/widget/add-from-template/after/6/division/3/id_profil/5")]');
   }
 }
 
 
 
 
-class WidgetControllerAddActionDispatchTest extends WidgetControllerWidgetConfigurationTestCase {
+class WidgetControllerAddFromTemplateAfterModuleInDivisionThreeActionDispatchTest extends WidgetControllerWidgetConfigurationTestCase {
   public function setUp() {
     parent::setUp();
-    $this->dispatch('/admin/widget/add/after/6/division/3/id_profil/5', true);
+    $this->dispatch('/admin/widget/add-from-template/after/6/division/3/id_profil/5', true);
   }
 
 
   /** @test */
-  public function submitButtonShouldBePresent() {
-    $this->assertXpath('//button[@type="submit"]');
+  public function addWidgetLinkShouldContainsAfterSixDivisionThreeIdProfilFive() {
+    $this->assertXPathContentContains('//div[@class="widget_templates"]//div/a[contains(@href, "admin/widget/add/after/6/division/3/id_profil/5/template/articles/template_no/3")]/h4',
+                                      'Diaporama',
+                                      $this->_response->getBody());
   }
+
 }
 
 
@@ -2110,7 +2113,7 @@ class WidgetControllerAddActionEmptyPostDispatchTest extends WidgetControllerWid
 class WidgetControllerWidgetAddFromTemplateTest extends WidgetControllerWidgetConfigurationTestCase {
   public function setUp() {
     parent::setUp();
-    $this->dispatch('admin/widget/add-from-template',  true);
+    $this->dispatch('admin/widget/add-from-template/id_profil/2',  true);
   }
 
 
@@ -2128,7 +2131,7 @@ class WidgetControllerWidgetAddFromTemplateTest extends WidgetControllerWidgetCo
 
   /** @test */
   public function articlesSectionShouldContainsDiaporamaWithUrlAddWidgetTemplateArticlesZero() {
-    $this->assertXPathContentContains('//div[@class="widget_templates"]//div/a[contains(@href, "admin/widget/add/template/articles/template_no/3/id_profil/2")]/h4',
+    $this->assertXPathContentContains('//div[@class="widget_templates"]//div/a[contains(@href, "admin/widget/add/id_profil/2/template/articles/template_no/3")]/h4',
                                       'Diaporama');
   }
 
diff --git a/tests/application/modules/opac/controllers/IndexControllerTest.php b/tests/application/modules/opac/controllers/IndexControllerTest.php
index 6cc02bf3081c8e0524369dc54917d22644809e37..ef742d323110e7a997b7afd9040392a7afdbc3d4 100644
--- a/tests/application/modules/opac/controllers/IndexControllerTest.php
+++ b/tests/application/modules/opac/controllers/IndexControllerTest.php
@@ -787,7 +787,7 @@ class IndexControllerWithBibAdminLoggedTest extends AbstractControllerTestCase {
 
   /** @test */
   public function linkToAdminHomeShouldBeInMenu() {
-    $this->assertXPathContentContains('//body/div//ul/li/ul/li/a', 'Accueil');
+    $this->assertXPathContentContains('//body/div//ul/li/ul/li/a', 'Accès pro.');
   }
 
 
diff --git a/tests/db/UpgradeDBTest.php b/tests/db/UpgradeDBTest.php
index 501402b0624aa23fd30a723b1ec5a595c4fa1f26..ecf28c4294d7ad4df8183a7aca38c8d6d792be2e 100644
--- a/tests/db/UpgradeDBTest.php
+++ b/tests/db/UpgradeDBTest.php
@@ -177,6 +177,12 @@ abstract class UpgradeDBTestCase extends PHPUnit_Framework_TestCase {
   }
 
 
+  protected function assertFieldDefault($table, $column, $default, $message='') {
+    return $this->assertField($table, $column, $default, 'Default', $message);
+  }
+
+
+
   protected function assertField($table, $column, $expected, $field, $message = '') {
     try {
       $fields = [];
@@ -1658,4 +1664,73 @@ class UpgradeDB_333_Test extends UpgradeDBTestCase {
     $album = $this->query('select url_origine from album where id=' . static::$album_id)->fetch();
     $this->assertEquals(['url_origine' => 'https://export.1dtouch.com/oai'], $album);
   }
+}
+
+
+
+
+class UpgradeDB_334_Test extends UpgradeDBTestCase {
+  public function prepare() {
+    try {
+      $this->query('ALTER TABLE external_agenda DROP column autoharvest');
+    }
+    catch (Exception $e) {
+    }
+  }
+
+
+
+  /** @test */
+  public function columnAutoharvestShouldBePresent() {
+    $this->assertColumn('external_agenda','autoharvest');
+  }
+}
+
+
+
+
+class UpgradeDB_335_Test extends UpgradeDBTestCase {
+  public function prepare() {
+    try {
+      $this->query('alter table `batchs` drop `pick_day`');
+    } catch(Exception $e) {}
+
+    foreach([Class_Batch_ArteVOD::TYPE,
+             Class_Batch_Cyberlibris::TYPE,
+             Class_Batch_Jamendo::TYPE,
+             Class_Batch_PanierUser::TYPE]
+            as $type)
+      if (!$this->fetchBatchByType($type))
+        $this->query('insert into batchs(type, last_run) values("' . $type . '", "")');
+  }
+
+
+  protected function fetchBatchByType($type) {
+    return $this->query('select * from batchs where type="' . $type . '"')
+                ->fetch();
+  }
+
+
+  /** @test */
+  public function pickDayDefaultShouldBeAllWeekDays() {
+    $this->assertFieldDefault('batchs', 'pick_day', '1;2;3;4;5;6;0');
+  }
+
+
+  public function datas() {
+    return [[Class_Batch_ArteVOD::TYPE, '6'],
+            [Class_Batch_Cyberlibris::TYPE, '0'],
+            [Class_Batch_Jamendo::TYPE, '0'],
+            [Class_Batch_PanierUser::TYPE, '1;2;3;4;5;6;0'],
+    ];
+  }
+
+  /**
+   * @test
+   * @dataProvider datas
+   */
+  public function batchShouldHaveTypedPickDay($type, $pick_day) {
+    $batch = $this->fetchBatchByType($type);
+    $this->assertEquals($pick_day, $batch['pick_day']);
+  }
 }
\ No newline at end of file
diff --git a/tests/library/Class/Cosmogramme/Integration/PhaseBatchsTest.php b/tests/library/Class/Cosmogramme/Integration/PhaseBatchsTest.php
index 6506350642719bfbaa3db99830525f858d59cfb2..1da13472e240efd5ae2f2ddfde5590bd4bee0993 100644
--- a/tests/library/Class/Cosmogramme/Integration/PhaseBatchsTest.php
+++ b/tests/library/Class/Cosmogramme/Integration/PhaseBatchsTest.php
@@ -32,8 +32,12 @@ abstract class PhaseBatchsTestCase extends Class_Cosmogramme_Integration_PhaseTe
 
 
   protected function _prepareFixtures() {
+    $time = new TimeSourceForTest('2017-08-29');
+    Class_Batch::setTimeSource($time); // tuesday for pick_day
+
     $this->fixture('Class_Batch',
                    ['id' => 34,
+                    'pick_day' => '2',
                     'type' => 'TestingTest']);
 
     $this->_batch = $this->mock();
@@ -42,9 +46,20 @@ abstract class PhaseBatchsTestCase extends Class_Cosmogramme_Integration_PhaseTe
       ->whenCalled('run')->answers(true)
       ->whenCalled('setLogger')->answers($this->_batch);
 
+    $this->_not_runnable = $this->fixture('Class_Batch',
+                                          ['id' => 99,
+                                           'pick_day' => '3',
+                                           'type' => 'TestingNotRunnableTest']);
+
+    $this->_not_runnable_batch = $this->mock();
+    $this->_not_runnable_batch
+      ->whenCalled('getLabel')->answers('Testing Not Runnable Batch');
+
+
     $this
       ->onLoaderOfModel('Class_Batch')
-      ->whenCalled('getKnownType')->with('TestingTest')->answers($this->_batch);
+      ->whenCalled('getKnownType')->with('TestingTest')->answers($this->_batch)
+      ->whenCalled('getKnownType')->with('TestingNotRunnableTest')->answers($this->_not_runnable_batch);
   }
 
 
@@ -61,6 +76,7 @@ abstract class PhaseBatchsTestCase extends Class_Cosmogramme_Integration_PhaseTe
 
 
   public function tearDown() {
+    Class_Batch::setTimeSource(null);
     Zend_Registry::set('httpClient', $this->_registry_http_client);
     parent::tearDown();
   }
@@ -125,6 +141,12 @@ class PhaseBatchsCronRunTest extends PhaseBatchsTestCase {
   }
 
 
+  /** @test */
+  public function shouldDisplayNotRunnableBatchisNotPlanned() {
+    $this->assertLogContains('La tâche Testing Not Runnable Batch n\'est pas plannifiée aujourd\'hui');
+  }
+
+
   /**
    * @test
    * @see http://forge.afi-sa.fr/issues/28103
@@ -147,11 +169,13 @@ class PhaseBatchsCronRunWithLoggerTest extends PhaseBatchsTestCase {
   protected function _prepareFixtures() {
     $this->fixture('Class_Batch',
                    ['id' => 33,
-                    'type' => 'ThrowingBatch']);
+                    'type' => 'ThrowingBatch',
+                    'pick_day' => '1;2;3;4;5;6;0']);
 
     $this->fixture('Class_Batch',
                    ['id' => 34,
-                    'type' => 'TestingTest']);
+                    'type' => 'TestingTest',
+                    'pick_day' => '1;2;3;4;5;6;0']);
 
     $this->_batch = new Class_Cosmogramme_Integration_PhaseTestingBatch();
     $throwing = $this->mock();
diff --git a/tests/library/ZendAfi/View/Helper/Accueil/KiosqueTest.php b/tests/library/ZendAfi/View/Helper/Accueil/KiosqueTest.php
index a8c69d0746da0dae16f5a25104118c42de312ebf..e1ef547edbcc43141c530bafd4ee9e4962070631 100644
--- a/tests/library/ZendAfi/View/Helper/Accueil/KiosqueTest.php
+++ b/tests/library/ZendAfi/View/Helper/Accueil/KiosqueTest.php
@@ -303,9 +303,6 @@ class ZendAfi_View_Helper_Accueil_KiosqueRequetesAsRedacteurTest extends ZendAfi
   public function setUp() {
     parent::setUp();
 
-//    Storm_Test_ObjectWrapper::onLoaderOfModel('Class_PanierNotice')
-//      ->whenCalled('findAllBy')
-//      ->answers([$this->panier_films, $this->panier_livres]);
 
     $redacteur = Class_Users::newInstanceWithId(54)
       ->beModoBib()
@@ -324,7 +321,7 @@ class ZendAfi_View_Helper_Accueil_KiosqueRequetesAsRedacteurTest extends ZendAfi
 
   /** @test **/
   public function boiteKiosqueWithAdminLoggedShouldContainsLinkToChange() {
-    $this->assertXPath($this->_html, '//div[@class="boite kiosque"]//div[@class="change_kiosque_data configuration_module"]/a[contains(@href,"admin/modules/kiosque-change-data")]');
+    $this->assertXPath($this->_html, '//div[@class="boite kiosque"]//div[@class="configuration_module"]/a[contains(@href,"admin/modules/kiosque-change-data")]');
   }
 
 
diff --git a/tests/library/ZendAfi/View/Helper/Accueil/RechSimpleTest.php b/tests/library/ZendAfi/View/Helper/Accueil/RechSimpleTest.php
index 6493d12660c8ffc7f3c5f3421fa9e5fb8583a223..6930764b9755e868c0bc070c4bb6ad7f08300710 100644
--- a/tests/library/ZendAfi/View/Helper/Accueil/RechSimpleTest.php
+++ b/tests/library/ZendAfi/View/Helper/Accueil/RechSimpleTest.php
@@ -82,7 +82,7 @@ class ZendAfi_View_Helper_Accueil_RechSimpleWithAdminTest extends ZendAfi_View_H
 
   /** @test */
   public function addBlockActionShouldBePresent() {
-    $this->assertLocalXPath('//a[contains(@href, "/admin/widget/add/after/1/division/1/id_profil/2")]');
+    $this->assertLocalXPath('//a[contains(@href, "/admin/widget/add-from-template/after/1/division/1/id_profil/2")]');
   }
 
 
diff --git a/tests/scenarios/ExternalAgendas/ExternalAgendasBatchTest.php b/tests/scenarios/ExternalAgendas/ExternalAgendasBatchTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..0bf5fd171e1a76e42500c3a3ddfb6470ce40f450
--- /dev/null
+++ b/tests/scenarios/ExternalAgendas/ExternalAgendasBatchTest.php
@@ -0,0 +1,104 @@
+<?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 Class_Batch_ExternalAgendasBatchTestCase extends ModelTestCase {
+  protected
+    $_storm_default_to_volatile = true,
+    $_log = '',
+    $_debug_log = '';
+
+  public function setUp() {
+    parent::setUp();
+  }
+
+  public function getLogger() {
+    return $this->logger = $this->mock()
+                                ->whenCalled('log')
+                                ->willDo(
+                                         function($message, $target = '') {
+                                           if ($target == 'debug') {
+                                             $this->_debug_log .= $message . "\n";
+                                             return;
+                                           }
+                                           $this->_log .= $message;
+                                         });
+  }
+}
+
+
+
+class Class_Batch_ExternalAgendasBatchSimpleTest extends Class_Batch_ExternalAgendasBatchTestCase {
+  protected $_batch;
+
+  public function setUp() {
+    parent::setUp();
+
+
+    $this->valleiry = $this->fixture('Class_Bib',
+                                     ['id' => 1,
+                                      'libelle' => 'Valleiry']);
+
+    $events_category = $this->fixture('Class_ArticleCategorie',
+                                            ['id' => 1,
+                                             'libelle' => 'Events',
+                                             'bib' => $this->valleiry]);
+
+    $this->fixture('Class_ExternalAgenda',
+                   ['id' => 1,
+                    'label' => 'Personal Agenda',
+                    'url' => 'http://my.server.com/calendar.ics',
+                    'autoharvest' => 0,
+                    'status' => Class_Article::STATUS_VALIDATED,
+                    'category' => $events_category]);
+
+    $this->fixture('Class_ExternalAgenda',
+                   ['id' => 34,
+                    'label' => 'Extra Agenda',
+                    'url' => 'http://external.agenda.com/export?type=ics',
+                    'category' => $events_category,
+                    'id_lieu' => 0,
+                    'autoharvest' => 1,
+                    'status' => Class_Article::STATUS_VALIDATED]);
+
+    Class_WebService_ICalendar::setDefaultHttpClient($this->mock()
+                                                     ->whenCalled('open_url')
+                                                     ->with('http://external.agenda.com/export?type=ics')
+                                                     ->answers(file_get_contents(__DIR__.'/ical-event-second.ics')));
+
+    $this->_batch = new Class_Batch_ExternalAgenda();
+    $this->_batch->setLogger($this->getLogger());
+    $this->_batch->run();
+  }
+
+
+  /** @test */
+  public function labelShouldBeHarvestExternalAgenda() {
+    $this->assertEquals('Moissonner les agendas externes', $this->_batch->getLabel());
+  }
+
+
+  /** @test */
+  public function logShouldDisplayNumberOfCreatedEvents() {
+    $this->assertEquals("Extra Agenda:\nNombre d\'événements créés : 4\nNombre d\'événements mis à jour : 0\n",$this->_log);
+
+  }
+}
diff --git a/tests/scenarios/ExternalAgendas/ExternalAgendasTest.php b/tests/scenarios/ExternalAgendas/ExternalAgendasTest.php
index 6d7f510e48b7e4c454f7db1f6d2810f1eb8b3f44..3d45ce45151c0d5be99a0ee9b567a5bd2c4dc373 100644
--- a/tests/scenarios/ExternalAgendas/ExternalAgendasTest.php
+++ b/tests/scenarios/ExternalAgendas/ExternalAgendasTest.php
@@ -338,6 +338,13 @@ class ExternalAgendasAdminEditWithWorkflowTest extends ExternalAgendasAdminTestC
   }
 
 
+  /** @test */
+  public function checkboxAutomaticHarvestShouldBePresent() {
+    $this->assertXPathContentContains('//form//label[@for="autoharvest"]','Moissonnage automatique');
+    $this->assertXPath('//form//input[@type="checkbox"][@name="autoharvest"]');
+  }
+
+
   /** @test */
   public function titleShouldBeAjouterUnNouvelAgenda() {
     $this->assertXPathContentContains('//h1', 'Modifier un agenda');