diff --git a/code/test6.php b/code/test6.php
index 4969b3b7215e7958d66ec7cb873d8a3039c5338c..93a0c5bfeb474766af77d3b2211cf1d51dfe22da 100644
--- a/code/test6.php
+++ b/code/test6.php
@@ -23,14 +23,13 @@ $sep->forcerTauxMixite($ep, 0.5, 0.5,0);
 
 //var_dump($ep);
 
+$epid = 45788;
 
+/* @var \Application\Entity\Db\ElementPedagogique $ep */
+$ep = $sl->get('applicationElementPedagogique')->get($epid);
 
-$fn = '/home/laurent/test/test.txt';
-$data = 'salut';
+$tis = $ep->getTypesInterventionPossibles();
 
-mkdir( dirname($fn));
-chmod( dirname($fn), 0777);
-$r = file_put_contents($fn, $data);
-chmod($fn, 0777);
-
-var_dump(realpath($fn));
\ No newline at end of file
+foreach( $tis as $ti ){
+    var_dump($ti->getCode());
+}
\ No newline at end of file
diff --git a/module/Application/config/offre-formation.config.php b/module/Application/config/offre-formation.config.php
index 549305266b94ebbe71512794a8a7bed9c3c31fa2..0225b67ec4c6d713c5c4a99098f0aa58146ad472 100644
--- a/module/Application/config/offre-formation.config.php
+++ b/module/Application/config/offre-formation.config.php
@@ -91,6 +91,18 @@ return [
                                     'defaults'    => ['action' => 'getPeriode'],
                                 ],
                             ],
+                            'volume-horaire'   => [
+                                'type'    => 'Segment',
+                                'options' => [
+                                    'route'       => '/volume-horaire/:elementPedagogique',
+                                    'constraints' => [
+                                        'elementPedagogique' => '[0-9]*',
+                                    ],
+                                    'defaults'    => [
+                                        'action'     => 'volume-horaire',
+                                    ],
+                                ],
+                            ],
                         ],
                     ],
                     'etape'   => [
@@ -231,6 +243,14 @@ return [
                         Privileges::ODF_ELEMENT_VISUALISATION,
                         Privileges::ENSEIGNEMENT_EDITION,
                     ],
+                ],
+                [
+                    'controller' => 'Application\Controller\OffreFormation\ElementPedagogique',
+                    'action'     => ['volume-horaire'],
+                    'privileges' => [
+                        Privileges::ODF_ELEMENT_VH_VISUALISATION,
+                        Privileges::ODF_ELEMENT_VH_EDITION,
+                    ],
 
                 ],
                 [
@@ -264,6 +284,7 @@ return [
                 'Etape'              => [],
                 'CentreCoutEp'       => [],
                 'ElementModulateur'  => [],
+                'VolumeHoraireEns'   => [],
             ],
         ],
         'rule_providers'     => [
@@ -294,6 +315,11 @@ return [
                         'resources'  => ['Etape', 'Structure', 'ElementPedagogique'],
                         'assertion'  => 'AssertionOffreDeFormation',
                     ],
+                    [
+                        'privileges' => Privileges::ODF_ELEMENT_VH_EDITION,
+                        'resources'  => ['Etape', 'Structure', 'ElementPedagogique','VolumeHoraireEns','TypeIntervention'],
+                        'assertion'  => 'AssertionOffreDeFormation',
+                    ],
                 ],
             ],
         ],
@@ -303,9 +329,11 @@ return [
             'Application\Controller\OffreFormation'                    => Controller\OffreFormationController::class,
             'Application\Controller\OffreFormation\Etape'              => Controller\OffreFormation\EtapeController::class,
             'Application\Controller\OffreFormation\Modulateur'         => Controller\OffreFormation\ModulateurController::class,
-            'Application\Controller\OffreFormation\ElementPedagogique' => Controller\OffreFormation\ElementPedagogiqueController::class,
             'Application\Controller\OffreFormation\EtapeCentreCout'    => Controller\OffreFormation\EtapeCentreCoutController::class,
         ],
+        'factories' => [
+            'Application\Controller\OffreFormation\ElementPedagogique' => Controller\OffreFormation\Factory\ElementPedagogiqueControllerFactory::class,
+        ],
     ],
     'service_manager' => [
         'invokables' => [
@@ -335,6 +363,9 @@ return [
             Form\OffreFormation\TauxMixite\TauxMixiteForm::class     => Form\OffreFormation\TauxMixite\TauxMixiteForm::class,
             Form\OffreFormation\TauxMixite\TauxMixiteFieldset::class => Form\OffreFormation\TauxMixite\TauxMixiteFieldset::class,
         ],
+        'factories' => [
+            Form\OffreFormation\VolumeHoraireEns::class => Form\OffreFormation\Factory\VolumeHoraireEnsFormFactory::class,
+        ],
     ],
     'view_helpers'    => [
         'invokables' => [
diff --git a/module/Application/config/type-intervention.config.php b/module/Application/config/type-intervention.config.php
index 17d7eebdf6e53e9bd4176f70c2edd6e0158cc71d..6e8f90bba0501a9964b29207e8d2a08d67a861e2 100644
--- a/module/Application/config/type-intervention.config.php
+++ b/module/Application/config/type-intervention.config.php
@@ -111,6 +111,11 @@ return [
         ],
     ],
     'bjyauthorize'    => [
+        'resource_providers' => [
+            'BjyAuthorize\Provider\Resource\Config' => [
+                'TypeIntervention' => [],
+            ],
+        ],
         'guards' => [
             PrivilegeController::class => [
                 [
diff --git a/module/Application/config/volume-horaire.config.php b/module/Application/config/volume-horaire.config.php
index 30289b74461968678a6df424167de0c0a163ca0c..5f0a30db1b6add3a4fdd5f914d0817395519dba6 100644
--- a/module/Application/config/volume-horaire.config.php
+++ b/module/Application/config/volume-horaire.config.php
@@ -8,7 +8,7 @@ use UnicaenAuth\Guard\PrivilegeController;
 return [
     'router'          => [
         'routes' => [
-            'volume-horaire'             => [
+            'volume-horaire' => [
                 'type'          => 'Literal',
                 'options'       => [
                     'route'    => '/volume-horaire',
@@ -68,26 +68,27 @@ return [
     ],
     'controllers'     => [
         'invokables' => [
-            'Application\Controller\VolumeHoraire'            => Controller\VolumeHoraireController::class,
+            'Application\Controller\VolumeHoraire' => Controller\VolumeHoraireController::class,
         ],
     ],
     'service_manager' => [
         'invokables' => [
-            'ApplicationVolumeHoraire'                => Service\VolumeHoraire::class,
-            'ApplicationVolumeHoraireReferentiel'     => Service\VolumeHoraireReferentiel::class,
-            'ApplicationTypeVolumeHoraire'            => Service\TypeVolumeHoraire::class,
-            'ApplicationEtatVolumeHoraire'            => Service\EtatVolumeHoraire::class,
+            'ApplicationVolumeHoraire'            => Service\VolumeHoraire::class,
+            'ApplicationVolumeHoraireEns'         => Service\VolumeHoraireEnsService::class,
+            'ApplicationVolumeHoraireReferentiel' => Service\VolumeHoraireReferentiel::class,
+            'ApplicationTypeVolumeHoraire'        => Service\TypeVolumeHoraire::class,
+            'ApplicationEtatVolumeHoraire'        => Service\EtatVolumeHoraire::class,
         ],
     ],
     'view_helpers'    => [
         'invokables' => [
-            'volumeHoraireListe'            => View\Helper\VolumeHoraire\Liste::class,
+            'volumeHoraireListe' => View\Helper\VolumeHoraire\Liste::class,
         ],
     ],
     'form_elements'   => [
         'invokables' => [
-            'VolumeHoraireSaisie'                            => Form\VolumeHoraire\Saisie::class,
-            'VolumeHoraireSaisieMultipleFieldset'            => Form\VolumeHoraire\SaisieMultipleFieldset::class, // Nécessite plusieurs instances
+            'VolumeHoraireSaisie'                 => Form\VolumeHoraire\Saisie::class,
+            'VolumeHoraireSaisieMultipleFieldset' => Form\VolumeHoraire\SaisieMultipleFieldset::class, // Nécessite plusieurs instances
         ],
     ],
 ];
diff --git a/module/Application/src/Application/Assertion/OffreDeFormationAssertion.php b/module/Application/src/Application/Assertion/OffreDeFormationAssertion.php
index c1d03e198e4c8d76344865b71b1ee987265133a5..0aa5f11d2b46ff3ab16b3778d046a26a7cc9029f 100644
--- a/module/Application/src/Application/Assertion/OffreDeFormationAssertion.php
+++ b/module/Application/src/Application/Assertion/OffreDeFormationAssertion.php
@@ -2,6 +2,8 @@
 
 namespace Application\Assertion;
 
+use Application\Entity\Db\TypeIntervention;
+use Application\Entity\Db\VolumeHoraireEns;
 use Application\Provider\Privilege\Privileges;
 use Application\Entity\Db\CentreCoutEp;
 use Application\Entity\Db\ElementModulateur;
@@ -41,6 +43,8 @@ class OffreDeFormationAssertion extends AbstractAssertion
                         return $this->assertElementPedagogiqueSaisieModulateurs($role, $entity);
                     case Privileges::ODF_TAUX_MIXITE_EDITION:
                         return $this->assertElementPedagogiqueSaisieTauxMixite($role, $entity);
+                    case Privileges::ODF_ELEMENT_VH_EDITION:
+                        return $this->assertElementPedagogiqueSaisieVH($role, $entity);
                 }
             break;
             case $entity instanceof Etape:
@@ -53,6 +57,8 @@ class OffreDeFormationAssertion extends AbstractAssertion
                         return $this->assertEtapeSaisieModulateurs($role, $entity);
                     case Privileges::ODF_TAUX_MIXITE_EDITION:
                         return $this->assertEtapeSaisieTauxMixite($role, $entity);
+                    case Privileges::ODF_ELEMENT_VH_EDITION:
+                        return $this->assertEtapeSaisieVH($role, $entity);
                 }
             break;
             case $entity instanceof Structure:
@@ -62,6 +68,7 @@ class OffreDeFormationAssertion extends AbstractAssertion
                     case Privileges::ODF_CENTRES_COUT_EDITION:
                     case Privileges::ODF_MODULATEURS_EDITION:
                     case Privileges::ODF_TAUX_MIXITE_EDITION:
+                    case Privileges::ODF_ELEMENT_VH_EDITION:
                         return $this->assertStructureSaisie($role, $entity);
                 }
             break;
@@ -77,6 +84,18 @@ class OffreDeFormationAssertion extends AbstractAssertion
                         return $this->assertElementModulateurSaisieModulateurs($role, $entity);
                 }
             break;
+            case $entity instanceof VolumeHoraireEns:
+                switch ($privilege) {
+                    case Privileges::ODF_ELEMENT_VH_EDITION:
+                        return $this->assertVolumeHoraireEnsSaisieVH($role, $entity);
+                }
+            break;
+            case $entity instanceof TypeIntervention:
+                switch ($privilege) {
+                    case Privileges::ODF_ELEMENT_VH_EDITION:
+                        return $this->assertTypeInterventionSaisieVH($role, $entity);
+                }
+            break;
         }
 
         return true;
@@ -150,6 +169,40 @@ class OffreDeFormationAssertion extends AbstractAssertion
 
 
 
+    /* ---- Volumes horaires d'enseigneement ---- */
+    protected function assertEtapeSaisieVH(Role $role, Etape $etape)
+    {
+        return $this->assertStructureSaisie($role, $etape->getStructure())
+            && $etape->getElementPedagogique()->count() > 0;
+    }
+
+
+
+    protected function assertElementPedagogiqueSaisieVH(Role $role, ElementPedagogique $elementPedagogique)
+    {
+        return $this->assertStructureSaisie($role, $elementPedagogique->getStructure());
+    }
+
+
+
+    protected function assertTypeInterventionSaisieVH(Role $role, TypeIntervention $typeIntervention)
+    {
+        return true;
+    }
+
+
+
+    protected function assertVolumeHoraireEnsSaisieVH(Role $role, VolumeHoraireEns $volumeHoraireEns)
+    {
+        return $this->asserts([
+            $volumeHoraireEns->getSource() ? $this->assertSourceSaisie($volumeHoraireEns->getSource()) : true,
+            $volumeHoraireEns->getElementPedagogique() ? $this->assertElementPedagogiqueSaisieVH($role, $volumeHoraireEns->getElementPedagogique()) : true,
+            $volumeHoraireEns->getTypeIntervention() ? $this->assertTypeInterventionSaisieVH($role, $volumeHoraireEns->getTypeIntervention()) : true,
+        ]);
+    }
+
+
+
     /* ---- Modulateurs ---- */
     protected function assertEtapeSaisieModulateurs(Role $role, Etape $etape)
     {
diff --git a/module/Application/src/Application/Controller/OffreFormation/ElementPedagogiqueController.php b/module/Application/src/Application/Controller/OffreFormation/ElementPedagogiqueController.php
index 94e208cb0223c26e818c7db3cbe0de774e3eb455..56945f94262d1db5e5e352e8c71d6a2a436f32b7 100644
--- a/module/Application/src/Application/Controller/OffreFormation/ElementPedagogiqueController.php
+++ b/module/Application/src/Application/Controller/OffreFormation/ElementPedagogiqueController.php
@@ -3,10 +3,17 @@
 namespace Application\Controller\OffreFormation;
 
 use Application\Controller\AbstractController;
+use Application\Entity\Db\ElementPedagogique;
+use Application\Entity\Db\VolumeHoraireEns;
+use Application\Filter\FloatFromString;
 use Application\Form\OffreFormation\Traits\ElementPedagogiqueSaisieAwareTrait;
 use Application\Exception\DbException;
+use Application\Form\OffreFormation\Traits\VolumeHoraireEnsFormAwareTrait;
+use Application\Provider\Privilege\Privileges;
 use Application\Service\Traits\ElementPedagogiqueAwareTrait;
 use Application\Service\Traits\ContextAwareTrait;
+use Application\Service\Traits\VolumeHoraireEnsServiceAwareTrait;
+
 
 /**
  * Description of ElementPedagogiqueController
@@ -18,6 +25,8 @@ class ElementPedagogiqueController extends AbstractController
     use ElementPedagogiqueAwareTrait;
     use ContextAwareTrait;
     use ElementPedagogiqueSaisieAwareTrait;
+    use VolumeHoraireEnsFormAwareTrait;
+    use VolumeHoraireEnsServiceAwareTrait;
 
 
 
@@ -28,7 +37,7 @@ class ElementPedagogiqueController extends AbstractController
             \Application\Entity\Db\VolumeHoraire::class,
         ]);
         $element = $this->getEvent()->getParam('elementPedagogique');
-        $title   = "Enseignement";
+        $title   = $element->getLibelle() . ' (' . $element->getCode() . ')';
 
         return compact('element', 'title');
     }
@@ -75,8 +84,8 @@ class ElementPedagogiqueController extends AbstractController
             throw new \RuntimeException('L\'identifiant n\'est pas bon ou n\'a pas été fourni');
         }
 
-        $title  = "Suppression d'enseignement";
-        $form = $this->makeFormSupprimer(function()use($element){
+        $title = "Suppression d'enseignement";
+        $form  = $this->makeFormSupprimer(function () use ($element) {
             $this->getServiceElementPedagogique()->delete($element);
         });
 
@@ -143,7 +152,7 @@ class ElementPedagogiqueController extends AbstractController
             if (!$etape) {
                 $extra .= sprintf('<span class="element-rech etape" title="%s">%s</span>', "Formation", $item['LIBELLE_ETAPE']);
             }
-            $extra .= "Année" !== $item['LIBELLE_PE'] ? sprintf('<span class="element-rech periode" title="%s">%s</span>', "Période", $item['LIBELLE_PE']) : null;
+            $extra               .= "Année" !== $item['LIBELLE_PE'] ? sprintf('<span class="element-rech periode" title="%s">%s</span>', "Période", $item['LIBELLE_PE']) : null;
             $template            = sprintf('<span class="element-rech extra">{extra}</span><span class="element-rech element" title="%s">{label}</span>', "Enseignement");
             $result[$item['ID']] = [
                 'id'       => $item['ID'],
@@ -174,4 +183,64 @@ class ElementPedagogiqueController extends AbstractController
         return new \Zend\View\Model\JsonModel($result);
     }
 
+
+
+    public function volumeHoraireAction()
+    {
+        $this->em()->getFilters()->enable('historique')->init([
+            \Application\Entity\Db\VolumeHoraireEns::class,
+        ]);
+
+        $title = 'Volumes horaires';
+
+        /** @var ElementPedagogique $element */
+        $element = $this->getEvent()->getParam('elementPedagogique');
+
+        $ev         = $element->getVolumeHoraireEns();
+        $existsVhes = [];
+        foreach ($ev as $vhe) {
+            $existsVhes[$vhe->getTypeIntervention()->getId()] = $vhe;
+        }
+
+        $saisie = $this->params()->fromPost('vhes');
+
+        $tis = $element->getTypesInterventionPossibles();
+        foreach ($tis as $typeIntervention) {
+            if (!isset($existsVhes[$typeIntervention->getId()])) {
+                $vhe = $this->getServiceVolumeHoraireEns()->newEntity($element, $typeIntervention);
+            } else {
+                $vhe = $existsVhes[$typeIntervention->getId()];
+            }
+
+            if ($this->isAllowed($vhe, Privileges::ODF_ELEMENT_VH_EDITION)) {
+                if (isset($saisie[$vhe->getTypeIntervention()->getId()]['heures'])) {
+                    $heures = FloatFromString::run($saisie[$vhe->getTypeIntervention()->getId()]['heures']);
+                } else {
+                    $heures = null;
+                }
+                if (isset($saisie[$vhe->getTypeIntervention()->getId()]['groupes'])) {
+                    $groupes = FloatFromString::run($saisie[$vhe->getTypeIntervention()->getId()]['groupes']);
+                } else {
+                    $groupes = null;
+                }
+                try {
+                    $this->getServiceVolumeHoraireEns()->changeHeuresGroupes($vhe, $heures, $groupes);
+                } catch (\Exception $e) {
+                    $this->flashMessenger()->addErrorMessage(DbException::translate($e)->getMessage());
+                }
+            }
+
+            if (!$vhe->estNonHistorise()){
+                $vhe = $this->getServiceVolumeHoraireEns()->newEntity($element, $typeIntervention);
+            }
+
+            $vhes[$typeIntervention->getId()] = $vhe;
+        }
+
+        $form = $this->getFormOffreFormationVolumeHoraireEns();
+        $form->setAttribute('action', $this->url()->fromRoute('of/element/volume-horaire', ['elementPedagogique' => $element->getId()]));
+        $form->build($vhes);
+
+        return compact('title', 'vhes', 'form');
+    }
 }
diff --git a/module/Application/src/Application/Controller/OffreFormation/EtapeController.php b/module/Application/src/Application/Controller/OffreFormation/EtapeController.php
index 55e0df4013d9b1cefe77106e9e42cc9529cd69a5..6d5b52c5c238179ad1734c8c959d60a13849043a 100644
--- a/module/Application/src/Application/Controller/OffreFormation/EtapeController.php
+++ b/module/Application/src/Application/Controller/OffreFormation/EtapeController.php
@@ -95,7 +95,7 @@ class EtapeController extends AbstractController
             ElementPedagogique::class,
         ]);
         $etape        = $this->getEvent()->getParam('etape');
-        $title        = 'Formation';
+        $title        = $etape.' ('.$etape->getCode().')';
         $serviceEtape = $this->getServiceEtape();
 
         return compact('etape', 'title', 'serviceEtape');
diff --git a/module/Application/src/Application/Controller/OffreFormation/Factory/ElementPedagogiqueControllerFactory.php b/module/Application/src/Application/Controller/OffreFormation/Factory/ElementPedagogiqueControllerFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..4c64bf96ba28b9af598ba3cdc6f0e60da9142379
--- /dev/null
+++ b/module/Application/src/Application/Controller/OffreFormation/Factory/ElementPedagogiqueControllerFactory.php
@@ -0,0 +1,36 @@
+<?php
+
+namespace Application\Controller\OffreFormation\Factory;
+
+use Application\Form\OffreFormation\VolumeHoraireEnsForm;
+use Zend\Mvc\Controller\ControllerManager as ContainerInterface;
+use Application\Controller\OffreFormation\ElementPedagogiqueController;
+
+
+
+/**
+ * Description of ElementPedagogiqueControllerFactory
+ *
+ * @author LECLUSE Laurent <laurent.lecluse at unicaen.fr>
+ */
+class ElementPedagogiqueControllerFactory
+{
+
+    /**
+     * @param ContainerInterface $container
+     * @param string             $requestedName
+     * @param array|null         $options
+     *
+     * @return ElementPedagogiqueController
+     */
+    public function __invoke(ContainerInterface $container, $requestedName, $options = null)
+    {
+        $container = $container->getServiceLocator();
+
+        $controller = new ElementPedagogiqueController;
+        $controller->setServiceLocator($container);
+        $controller->setFormOffreFormationVolumeHoraireEns($container->get('FormElementManager')->get(VolumeHoraireEnsForm::class));
+
+        return $controller;
+    }
+}
\ No newline at end of file
diff --git a/module/Application/src/Application/Entity/Db/ElementPedagogique.php b/module/Application/src/Application/Entity/Db/ElementPedagogique.php
index a07c895e3f51717aac1d8bd480eda252be418270..ce8d69677c639617ccd058ced9b4250fdaf01f3b 100644
--- a/module/Application/src/Application/Entity/Db/ElementPedagogique.php
+++ b/module/Application/src/Application/Entity/Db/ElementPedagogique.php
@@ -110,6 +110,11 @@ class ElementPedagogique implements HistoriqueAwareInterface, AnneeAwareInterfac
      */
     protected $elementModulateur;
 
+    /**
+     * @var \Doctrine\Common\Collections\Collection
+     */
+    protected $volumeHoraireEns;
+
     /**
      * haschanged
      *
@@ -576,6 +581,46 @@ class ElementPedagogique implements HistoriqueAwareInterface, AnneeAwareInterfac
 
 
 
+    /**
+     * Add volumeHoraireEns
+     *
+     * @param VolumeHoraireEns $volumeHoraireEns
+     *
+     * @return ElementPedagogique
+     */
+    public function addVolumeHoraireEns(VolumeHoraireEns $volumeHoraireEns)
+    {
+        $this->volumeHoraireEns[] = $volumeHoraireEns;
+
+        return $this;
+    }
+
+
+
+    /**
+     * Remove volumeHoraireEns
+     *
+     * @param VolumeHoraireEns $volumeHoraireEns
+     */
+    public function removeVolumeHoraireEns(VolumeHoraireEns $volumeHoraireEns)
+    {
+        $this->volumeHoraireEns->removeElement($volumeHoraireEns);
+    }
+
+
+
+    /**
+     * Get volumeHoraireEns
+     *
+     * @return \Doctrine\Common\Collections\Collection|VolumeHoraireEns[]
+     */
+    public function getVolumeHoraireEns()
+    {
+        return $this->volumeHoraireEns;
+    }
+
+
+
     /**
      * Add service
      *
@@ -728,6 +773,26 @@ class ElementPedagogique implements HistoriqueAwareInterface, AnneeAwareInterfac
 
 
 
+    /**
+     * @return TypeIntervention[]
+     */
+    public function getTypesInterventionPossibles()
+    {
+        if (!$this->getId()) return [];
+
+        $sql = 'SELECT type_intervention_id FROM V_ELEMENT_TYPE_INTERV_POSSIBLE WHERE element_pedagogique_id = :element';
+        $res = $this->getEntityManager()->getConnection()->fetchAll($sql, ['element' => $this->getId()]);
+
+        $ids = [];
+        foreach( $res as $r ){
+            $ids[] = (int)$r['TYPE_INTERVENTION_ID'];
+        }
+
+        return $this->getEntityManager()->getRepository(TypeIntervention::class)->findBy(['id' => $ids], ['ordre' => 'ASC']);
+    }
+
+
+
     /**
      * Returns the string identifier of the Resource
      *
diff --git a/module/Application/src/Application/Entity/Db/Mapping/Application.Entity.Db.ElementPedagogique.dcm.xml b/module/Application/src/Application/Entity/Db/Mapping/Application.Entity.Db.ElementPedagogique.dcm.xml
index 483fb0adfff6d9394d727063f0efcaccc6781a85..50be9eaa5af24d34956b204e160a67b49300b8b4 100644
--- a/module/Application/src/Application/Entity/Db/Mapping/Application.Entity.Db.ElementPedagogique.dcm.xml
+++ b/module/Application/src/Application/Entity/Db/Mapping/Application.Entity.Db.ElementPedagogique.dcm.xml
@@ -88,6 +88,11 @@
                 <cascade-all/>
             </cascade>
         </one-to-many>
+        <one-to-many field="volumeHoraireEns" target-entity="Application\Entity\Db\VolumeHoraireEns" mapped-by="elementPedagogique">
+            <cascade>
+                <cascade-all/>
+            </cascade>
+        </one-to-many>
         <many-to-many field="typeIntervention" target-entity="Application\Entity\Db\TypeIntervention">
             <join-table name="V_ELEMENT_TYPE_INTERVENTION">
                 <join-columns>
diff --git a/module/Application/src/Application/Entity/Db/Mapping/Application.Entity.Db.VolumeHoraireEns.dcm.xml b/module/Application/src/Application/Entity/Db/Mapping/Application.Entity.Db.VolumeHoraireEns.dcm.xml
index 998b7557be0de50a30dbfcd2444201fbf6fdfa85..922beb7db82a365f97895e390e496f64e1db138e 100644
--- a/module/Application/src/Application/Entity/Db/Mapping/Application.Entity.Db.VolumeHoraireEns.dcm.xml
+++ b/module/Application/src/Application/Entity/Db/Mapping/Application.Entity.Db.VolumeHoraireEns.dcm.xml
@@ -17,6 +17,7 @@
       <generator strategy="SEQUENCE"/>
     </id>
     <field name="heures" type="float" column="HEURES" precision="126" scale="0" nullable="false"/>
+    <field name="groupes" type="float" column="GROUPES" precision="126" scale="0" nullable="true"/>
     <field name="histoCreation" type="datetime" column="HISTO_CREATION" nullable="false"/>
     <field name="histoDestruction" type="datetime" column="HISTO_DESTRUCTION" nullable="true"/>
     <field name="histoModification" type="datetime" column="HISTO_MODIFICATION" nullable="false"/>
diff --git a/module/Application/src/Application/Entity/Db/TypeIntervention.php b/module/Application/src/Application/Entity/Db/TypeIntervention.php
index 0eedea324153fdc90e7a5a7936794db71e1d7ff5..3ade5c78b7c3745fef481a6bc6109240fca0e658 100644
--- a/module/Application/src/Application/Entity/Db/TypeIntervention.php
+++ b/module/Application/src/Application/Entity/Db/TypeIntervention.php
@@ -4,11 +4,12 @@ namespace Application\Entity\Db;
 
 use UnicaenApp\Entity\HistoriqueAwareInterface;
 use UnicaenApp\Entity\HistoriqueAwareTrait;
+use Zend\Permissions\Acl\Resource\ResourceInterface;
 
 /**
  * TypeIntervention
  */
-class TypeIntervention implements HistoriqueAwareInterface
+class TypeIntervention implements HistoriqueAwareInterface, ResourceInterface
 {
     use HistoriqueAwareTrait;
 
@@ -396,4 +397,16 @@ class TypeIntervention implements HistoriqueAwareInterface
         return $this;
     }
 
+
+
+    /**
+     * Returns the string identifier of the Resource
+     *
+     * @return string
+     */
+    public function getResourceId()
+    {
+        return 'TypeIntervention';
+    }
+
 }
diff --git a/module/Application/src/Application/Entity/Db/VolumeHoraireEns.php b/module/Application/src/Application/Entity/Db/VolumeHoraireEns.php
index 731b65c1313c61d8bf225d6ed518983762aa8a36..9887ad8de9f97f84f32c3b314fed898c246a33a0 100644
--- a/module/Application/src/Application/Entity/Db/VolumeHoraireEns.php
+++ b/module/Application/src/Application/Entity/Db/VolumeHoraireEns.php
@@ -5,16 +5,16 @@ namespace Application\Entity\Db;
 use Application\Entity\Db\Traits\ElementPedagogiqueAwareTrait;
 use Application\Entity\Db\Traits\SourceAwareTrait;
 use Application\Entity\Db\Traits\TypeInterventionAwareTrait;
-use Doctrine\ORM\Mapping as ORM;
 use UnicaenApp\Entity\HistoriqueAwareInterface;
 use UnicaenApp\Entity\HistoriqueAwareTrait;
 use UnicaenImport\Entity\Db\Interfaces\ImportAwareInterface;
 use UnicaenImport\Entity\Db\Traits\ImportAwareTrait;
+use Zend\Permissions\Acl\Resource\ResourceInterface;
 
 /**
  * VolumeHoraireEns
  */
-class VolumeHoraireEns implements HistoriqueAwareInterface, ImportAwareInterface
+class VolumeHoraireEns implements HistoriqueAwareInterface, ImportAwareInterface, ResourceInterface
 {
     use HistoriqueAwareTrait;
     use ImportAwareTrait;
@@ -31,6 +31,11 @@ class VolumeHoraireEns implements HistoriqueAwareInterface, ImportAwareInterface
      */
     protected $heures;
 
+    /**
+     * @var float
+     */
+    protected $groupes;
+
 
 
     /**
@@ -45,6 +50,18 @@ class VolumeHoraireEns implements HistoriqueAwareInterface, ImportAwareInterface
 
 
 
+    /**
+     * Get heures
+     *
+     * @return float
+     */
+    public function getHeures()
+    {
+        return $this->heures;
+    }
+
+
+
     /**
      * Set heures
      *
@@ -62,13 +79,37 @@ class VolumeHoraireEns implements HistoriqueAwareInterface, ImportAwareInterface
 
 
     /**
-     * Get heures
-     *
      * @return float
      */
-    public function getHeures()
+    public function getGroupes()
     {
-        return $this->heures;
+        return $this->groupes;
+    }
+
+
+
+    /**
+     * @param float $groupes
+     *
+     * @return VolumeHoraireEns
+     */
+    public function setGroupes($groupes)
+    {
+        $this->groupes = $groupes;
+
+        return $this;
+    }
+
+
+
+    /**
+     * Returns the string identifier of the Resource
+     *
+     * @return string
+     */
+    public function getResourceId()
+    {
+        return 'VolumeHoraireEns';
     }
 
-}
+}
\ No newline at end of file
diff --git a/module/Application/src/Application/Filter/FloatFromString.php b/module/Application/src/Application/Filter/FloatFromString.php
index a1633d07c5a8208a99a61f434588ec411a0f2854..e231d4e2ac03170e032dd0fbf83bee4cfe6df8ab 100644
--- a/module/Application/src/Application/Filter/FloatFromString.php
+++ b/module/Application/src/Application/Filter/FloatFromString.php
@@ -11,6 +11,8 @@ class FloatFromString extends AbstractFilter
 
     public function filter($value)
     {
+        if ($value === '') return null;
+
         $value = preg_replace("/[^0-9,\.-]/","",$value);
         $value = str_replace(',','.',$value);
         $value = floatval($value);
@@ -26,6 +28,6 @@ class FloatFromString extends AbstractFilter
             self::$instance = new self;
         }
 
-        return self::$instance->filter($value);
+        return self::$instance->filter($value );
     }
 }
\ No newline at end of file
diff --git a/module/Application/src/Application/Form/OffreFormation/Factory/VolumeHoraireEnsFormFactory.php b/module/Application/src/Application/Form/OffreFormation/Factory/VolumeHoraireEnsFormFactory.php
new file mode 100755
index 0000000000000000000000000000000000000000..072769f87ac4484d22b08c976538d5d8a51a4d04
--- /dev/null
+++ b/module/Application/src/Application/Form/OffreFormation/Factory/VolumeHoraireEnsFormFactory.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace Application\Form\OffreFormation\Factory;
+
+use Zend\ServiceManager\ServiceLocatorInterface as ContainerInterface;
+use Application\Form\OffreFormation\VolumeHoraireEnsForm;
+
+
+
+/**
+ * Description of VolumeHoraireEnsFormFactory
+ *
+ * @author LECLUSE Laurent <laurent.lecluse at unicaen.fr>
+ */
+class VolumeHoraireEnsFormFactory
+{
+
+    /**
+     * @param ContainerInterface $container
+     * @param string             $requestedName
+     * @param array|null         $options
+     *
+     * @return VolumeHoraireEnsForm
+     */
+    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
+    {
+        $formOffreFormationVolumeHoraireEns = new VolumeHoraireEnsForm;
+        /* Injectez vos dépendances ICI */
+
+        return $formOffreFormationVolumeHoraireEns;
+    }
+}
\ No newline at end of file
diff --git a/module/Application/src/Application/Form/OffreFormation/Traits/VolumeHoraireEnsFormAwareTrait.php b/module/Application/src/Application/Form/OffreFormation/Traits/VolumeHoraireEnsFormAwareTrait.php
new file mode 100755
index 0000000000000000000000000000000000000000..c4610caab6157bd01ed85024b61035cc02248642
--- /dev/null
+++ b/module/Application/src/Application/Form/OffreFormation/Traits/VolumeHoraireEnsFormAwareTrait.php
@@ -0,0 +1,46 @@
+<?php
+
+namespace Application\Form\OffreFormation\Traits;
+
+use Application\Form\OffreFormation\VolumeHoraireEnsForm;
+use RuntimeException;
+
+/**
+ * Description of VolumeHoraireEnsFormAwareTrait
+ *
+ * @author UnicaenCode
+ */
+trait VolumeHoraireEnsFormAwareTrait
+{
+    /**
+     * @var VolumeHoraireEnsForm
+     */
+    protected $formOffreFormationVolumeHoraireEns;
+
+
+
+    /**
+     * @param VolumeHoraireEnsForm $formOffreFormationVolumeHoraireEns
+     *
+     * @return self
+     */
+    public function setFormOffreFormationVolumeHoraireEns( VolumeHoraireEnsForm $formOffreFormationVolumeHoraireEns )
+    {
+        $this->formOffreFormationVolumeHoraireEns = $formOffreFormationVolumeHoraireEns;
+
+        return $this;
+    }
+
+
+
+    /**
+     * Retourne un nouveau formulaire ou fieldset systématiquement, sauf si ce dernier a été fourni manuellement.
+     *
+     * @return VolumeHoraireEnsForm
+     * @throws RuntimeException
+     */
+    public function getFormOffreFormationVolumeHoraireEns()
+    {
+        return $this->formOffreFormationVolumeHoraireEns;
+    }
+}
\ No newline at end of file
diff --git a/module/Application/src/Application/Form/OffreFormation/VolumeHoraireEnsForm.php b/module/Application/src/Application/Form/OffreFormation/VolumeHoraireEnsForm.php
new file mode 100755
index 0000000000000000000000000000000000000000..dae6fc2726165570b124bb7558d6b4caf0a74dd7
--- /dev/null
+++ b/module/Application/src/Application/Form/OffreFormation/VolumeHoraireEnsForm.php
@@ -0,0 +1,89 @@
+<?php
+
+namespace Application\Form\OffreFormation;
+
+use Application\Entity\Db\VolumeHoraireEns;
+use Application\Filter\StringFromFloat;
+use Zend\Form\Form;
+use Zend\InputFilter\InputFilterProviderInterface;
+
+
+/**
+ * Description of VolumeHoraireEnsForm
+ *
+ * @author LECLUSE Laurent <laurent.lecluse at unicaen.fr>
+ */
+class VolumeHoraireEnsForm extends Form implements InputFilterProviderInterface
+{
+
+    public function init()
+    {
+
+        /* Ajoutez vos éléments de formulaire ici */
+
+        $this->add([
+            'name'       => 'submit',
+            'type'       => 'Submit',
+            'attributes' => [
+                'value' => 'Enregistrer',
+                'class' => 'btn btn-primary',
+            ],
+        ]);
+    }
+
+
+
+    /**
+     * @param VolumeHoraireEns[] $vhes
+     */
+    public function build(array $vhes)
+    {
+        foreach ($vhes as $vhe) {
+            $this->add([
+                'name'       => $this->getElementName($vhe, 'heures'),
+                'type'       => 'Text',
+                'attributes' => [
+                    'value' => StringFromFloat::run($vhe->getHeures(), false),
+                ],
+            ]);
+
+            $this->add([
+                'name'       => $this->getElementName($vhe, 'groupes'),
+                'type'       => 'Text',
+                'attributes' => [
+                    'value' => StringFromFloat::run($vhe->getGroupes(), false),
+                ],
+            ]);
+        }
+    }
+
+
+
+    public function getElement( VolumeHoraireEns $volumeHoraireEns, $type)
+    {
+        return $this->get($this->getElementName($volumeHoraireEns, $type));
+    }
+
+
+
+    private function getElementName(VolumeHoraireEns $volumeHoraireEns, $type)
+    {
+        return 'vhes['.$volumeHoraireEns->getTypeIntervention()->getId().']['.$type.']';
+    }
+
+
+
+    /**
+     * Should return an array specification compatible with
+     * {@link Zend\InputFilter\Factory::createInputFilter()}.
+     *
+     * @return array
+     */
+    public function getInputFilterSpecification()
+    {
+        return [
+            /* Filtres et validateurs */
+        ];
+    }
+
+}
\ No newline at end of file
diff --git a/module/Application/src/Application/Provider/Privilege/Privileges.php b/module/Application/src/Application/Provider/Privilege/Privileges.php
index a8f5c4128e56e91ebf78de31e4234fec09e2e194..30df0a00d4b0ea7ac3032b5c0766ec3666dae042 100755
--- a/module/Application/src/Application/Provider/Privilege/Privileges.php
+++ b/module/Application/src/Application/Provider/Privilege/Privileges.php
@@ -107,6 +107,8 @@ class Privileges extends \UnicaenAuth\Provider\Privilege\Privileges {
     const MOTIF_NON_PAIEMENT_VISUALISATION           = 'motif-non-paiement-visualisation';
     const ODF_CENTRES_COUT_EDITION                   = 'odf-centres-cout-edition';
     const ODF_ELEMENT_EDITION                        = 'odf-element-edition';
+    const ODF_ELEMENT_VH_EDITION                     = 'odf-element-vh-edition';
+    const ODF_ELEMENT_VH_VISUALISATION               = 'odf-element-vh-visualisation';
     const ODF_ELEMENT_VISUALISATION                  = 'odf-element-visualisation';
     const ODF_ETAPE_EDITION                          = 'odf-etape-edition';
     const ODF_ETAPE_VISUALISATION                    = 'odf-etape-visualisation';
@@ -137,6 +139,9 @@ class Privileges extends \UnicaenAuth\Provider\Privilege\Privileges {
     const REFERENTIEL_VISUALISATION                  = 'referentiel-visualisation';
     const TYPE_INTERVENTION_EDITION                  = 'type-intervention-edition';
     const TYPE_INTERVENTION_VISUALISATION            = 'type-intervention-visualisation';
+    const UNICAEN_TBL_ACTUALISATION                  = 'unicaen-tbl-actualisation';
+    const UNICAEN_TBL_ADMIN                          = 'unicaen-tbl-admin';
+    const UNICAEN_TBL_UPDATE_ACTUPROC                = 'unicaen-tbl-update-actuproc';
     const WORKFLOW_DEPENDANCES_EDITION               = 'workflow-dependances-edition';
     const WORKFLOW_DEPENDANCES_VISUALISATION         = 'workflow-dependances-visualisation';
 
diff --git a/module/Application/src/Application/Service/Traits/VolumeHoraireEnsServiceAwareTrait.php b/module/Application/src/Application/Service/Traits/VolumeHoraireEnsServiceAwareTrait.php
new file mode 100644
index 0000000000000000000000000000000000000000..f6f6eec2bf71ebfa884fa690e9372a3ac93c8e23
--- /dev/null
+++ b/module/Application/src/Application/Service/Traits/VolumeHoraireEnsServiceAwareTrait.php
@@ -0,0 +1,59 @@
+<?php
+
+namespace Application\Service\Traits;
+
+use Application\Service\VolumeHoraireEnsService;
+use Application\Module;
+use RuntimeException;
+
+/**
+ * Description of VolumeHoraireEnsAwareTrait
+ *
+ * @author UnicaenCode
+ */
+trait VolumeHoraireEnsServiceAwareTrait
+{
+    /**
+     * @var VolumeHoraireEnsService
+     */
+    private $serviceVolumeHoraireEns;
+
+
+
+
+
+    /**
+     * @param VolumeHoraireEnsService $serviceVolumeHoraireEns
+     * @return self
+     */
+    public function setServiceVolumeHoraireEns( VolumeHoraireEnsService $serviceVolumeHoraireEns )
+    {
+        $this->serviceVolumeHoraireEns = $serviceVolumeHoraireEns;
+        return $this;
+    }
+
+
+
+    /**
+     * @return VolumeHoraireEnsService
+     * @throws RuntimeException
+     */
+    public function getServiceVolumeHoraireEns()
+    {
+        if (empty($this->serviceVolumeHoraireEns)){
+        $serviceLocator = Module::$serviceLocator;
+        if (! $serviceLocator) {
+            if (!method_exists($this, 'getServiceLocator')) {
+                throw new RuntimeException('La classe ' . get_class($this) . ' n\'a pas accès au ServiceLocator.');
+            }
+
+            $serviceLocator = $this->getServiceLocator();
+            if (method_exists($serviceLocator, 'getServiceLocator')) {
+                $serviceLocator = $serviceLocator->getServiceLocator();
+            }
+        }
+        $this->serviceVolumeHoraireEns = $serviceLocator->get('ApplicationVolumeHoraireEns');
+        }
+        return $this->serviceVolumeHoraireEns;
+    }
+}
\ No newline at end of file
diff --git a/module/Application/src/Application/Service/VolumeHoraireEnsService.php b/module/Application/src/Application/Service/VolumeHoraireEnsService.php
new file mode 100644
index 0000000000000000000000000000000000000000..dd45831fb5abe1c3baff5efa5786dbcf1179f6a6
--- /dev/null
+++ b/module/Application/src/Application/Service/VolumeHoraireEnsService.php
@@ -0,0 +1,105 @@
+<?php
+
+namespace Application\Service;
+
+use Application\Entity\Db\VolumeHoraireEns;
+use Application\Service\Traits\SourceAwareTrait;
+use Application\Entity\Db\ElementPedagogique as ElementPedagogiqueEntity;
+use Application\Entity\Db\TypeIntervention as TypeInterventionEntity;
+
+
+/**
+ * Description of VolumeHoraireEnsService
+ *
+ * @author Laurent LÉCLUSE <laurent.lecluse at unicaen.fr>
+ *
+ * @method VolumeHoraireEns get($id)
+ * @method VolumeHoraireEns[] getList(\Doctrine\ORM\QueryBuilder $qb = null, $alias = null)
+ */
+class VolumeHoraireEnsService extends AbstractEntityService
+{
+    use SourceAwareTrait;
+
+
+
+    /**
+     * retourne la classe des entités
+     *
+     * @return string
+     * @throws RuntimeException
+     */
+    public function getEntityClass()
+    {
+        return VolumeHoraireEns::class;
+    }
+
+
+
+    /**
+     * Retourne l'alias d'entité courante
+     *
+     * @return string
+     */
+    public function getAlias()
+    {
+        return 'vhe';
+    }
+
+
+
+    /**
+     * Retourne une nouvelle entité, initialisée avec les bons paramètres
+     *
+     * @return \Application\Entity\Db\VolumeHoraireEns
+     */
+    public function newEntity(ElementPedagogiqueEntity $elementPedagogique = null, TypeInterventionEntity $typeIntervention = null)
+    {
+        /** @var VolumeHoraireEns $entity */
+        $entity = parent::newEntity();
+
+        // toutes les entités créées ont OSE pour source!!
+        $entity->setSource($this->getServiceSource()->getOse());
+
+        if ($elementPedagogique) {
+            $entity->setElementPedagogique($elementPedagogique);
+        }
+
+        if ($typeIntervention) {
+            $entity->setTypeIntervention($typeIntervention);
+        }
+
+        return $entity;
+    }
+
+
+
+    public function changeHeuresGroupes(VolumeHoraireEns $volumeHoraireEns, $heures, $groupes)
+    {
+        $changed  = false;
+        $toDelete = false;
+
+        if ($volumeHoraireEns->getHeures() !== $heures) {
+            if ($heures !== null) {
+                $volumeHoraireEns->setHeures($heures);
+            } else {
+                $toDelete = true;
+            }
+            $changed = true;
+        }
+
+        if ($volumeHoraireEns->getGroupes() !== $groupes) {
+            $volumeHoraireEns->setGroupes($groupes);
+            $changed = true;
+        }
+
+        if ($changed) {
+            if ($toDelete) {
+                $this->delete($volumeHoraireEns);
+            } else {
+                $this->save($volumeHoraireEns);
+            }
+        }
+
+        return $this;
+    }
+}
\ No newline at end of file
diff --git a/module/Application/view/application/intervenant/fiche.phtml b/module/Application/view/application/intervenant/fiche.phtml
index d7111bb55748b3883a218f7683ce80448cd2dfdb..a8ae25ca0325af598e4aae4e0bf9b8f5e252886a 100644
--- a/module/Application/view/application/intervenant/fiche.phtml
+++ b/module/Application/view/application/intervenant/fiche.phtml
@@ -9,13 +9,11 @@ $urlRefresh = $this->url('workflow/feuille-de-route-refresh', ['intervenant' =>
 ?>
     <script>
         $(function () {
-
             $('#feuille-de-route-refresh').popAjax({
                 change: function (event, popAjax) {
                     window.location.reload();
                 }
             });
-
         });
     </script>
     <hr/>
diff --git a/module/Application/view/application/offre-formation/element-pedagogique/voir.phtml b/module/Application/view/application/offre-formation/element-pedagogique/voir.phtml
index 822b4e2452d9def907f31ec01a7e4f8f325553a1..084faa52be31537a45ea90e2ba99616426a605d8 100644
--- a/module/Application/view/application/offre-formation/element-pedagogique/voir.phtml
+++ b/module/Application/view/application/offre-formation/element-pedagogique/voir.phtml
@@ -1,5 +1,21 @@
-<h3><?php echo $element ?> <small><?php echo $element->getCode() ?></small></h3>
+<?php
 
-<?php echo $this->elementPedagogique($element) ?>
+use Application\Provider\Privilege\Privileges;
 
-<br /><?php //foreach( $changements as $changement ) { echo $this->differentielLigne( $changement ); } ?>
+$tabs = [
+    [
+        'id'      => 'fiche',
+        'label'   => 'Fiche',
+        'content' => (string)$this->elementPedagogique($element),
+    ],
+];
+
+if ($this->isAllowed(Privileges::getResourceId(Privileges::ODF_ELEMENT_VH_VISUALISATION))) {
+    $tabs[] = [
+        'id'    => 'volume-horaire-ens',
+        'label' => '<span class="glyphicon glyphicon-time"></span> Volumes horaires',
+        'url'   => $this->url('of/element/volume-horaire', ['elementPedagogique' => $element->getId()]),
+    ];
+}
+
+echo $this->tabajax($tabs);
diff --git a/module/Application/view/application/offre-formation/element-pedagogique/volume-horaire.phtml b/module/Application/view/application/offre-formation/element-pedagogique/volume-horaire.phtml
new file mode 100644
index 0000000000000000000000000000000000000000..dd9f255838b393689689ff7160e26f88230d03b4
--- /dev/null
+++ b/module/Application/view/application/offre-formation/element-pedagogique/volume-horaire.phtml
@@ -0,0 +1,60 @@
+<?php
+
+use Application\Entity\Db\VolumeHoraireEns;
+use Application\Filter\StringFromFloat;
+use Application\Form\OffreFormation\VolumeHoraireEnsForm;
+
+/**
+ * @var $this             \Application\View\Renderer\PhpRenderer
+ * @var $vhes             VolumeHoraireEns[]
+ * @var $form             VolumeHoraireEnsForm
+ */
+
+?>
+<style>
+    .edition-volume-horaire-ens .source {
+        white-space: nowrap;
+    }
+
+    .edition-volume-horaire-ens td input {
+        width: 100%;
+    }
+
+</style>
+<?php echo $this->form()->openTag($form); ?>
+<table class="table table-bordered table-condensed table-hover edition-volume-horaire-ens" style="margin-top: 2px">
+    <thead>
+    <tr>
+        <th>&nbsp;</th>
+        <th>Heures</th>
+        <th>Groupes</th>
+        <th>Source</th>
+    </tr>
+    </thead>
+    <tbody>
+    <?php foreach ($vhes as $vhe):
+        $canEdit = $this->isAllowed($vhe, Application\Provider\Privilege\Privileges::ODF_ELEMENT_VH_EDITION);
+
+        if ($canEdit) {
+            $heures  = $this->formText($form->getElement($vhe,'heures'));
+            $groupes = $this->formText($form->getElement($vhe, 'groupes'));
+        } else {
+            $heures  = StringFromFloat::run($vhe->getHeures(), false);
+            $groupes = StringFromFloat::run($vhe->getGroupes(), false);
+        }
+
+        ?>
+        <tr>
+            <td><abbr title="<?php echo $vhe->getTypeIntervention()->getLibelle() ?>"><?php echo $vhe->getTypeIntervention() ?></abbr></td>
+            <td><?php echo $heures ?></td>
+            <td><?php echo $groupes ?></td>
+            <td class="source"><?php echo $vhe->getId() ? $vhe->getSource() : 'Non existant' ?></td>
+        </tr>
+    <?php endforeach; ?>
+    </tbody>
+</table>
+<?php if ($form): ?>
+    <?php echo $this->formSubmit($form->get('submit')); ?>
+<?php endif; ?>
+<?php echo $this->form()->closeTag() ?>
+<?php echo $this->messenger()->addCurrentMessagesFromFlashMessenger() ?>
diff --git a/module/Application/view/application/offre-formation/etape/voir.phtml b/module/Application/view/application/offre-formation/etape/voir.phtml
index 691a8f651ba340bd3a4b8cec0132e0c211dc49d9..14dd9408e877f7817ed694802c6650dc84977762 100644
--- a/module/Application/view/application/offre-formation/etape/voir.phtml
+++ b/module/Application/view/application/offre-formation/etape/voir.phtml
@@ -2,13 +2,6 @@
 
 use Application\Provider\Privilege\Privileges;
 
-?>
-<h3><?php echo $etape ?>
-    <small><?php echo $etape->getCode() ?></small>
-</h3>
-
-<?php
-
 /* @var $serviceEtape \Application\Service\Etape */
 
 $tabs = [