diff --git a/code/test4.php b/code/test4.php
index d7924ed2f19707a83ab4da7801f81f7d9031332f..82a51817f5a42a21a8baf560b7ec26e5d491063e 100644
--- a/code/test4.php
+++ b/code/test4.php
@@ -7,54 +7,110 @@
  * @var $sl         \Zend\ServiceManager\ServiceLocatorInterface
  */
 
+/** @var \UnicaenTbl\Service\QueryGeneratorService $s */
+$s = $sl->get('UnicaenTbl\Service\QueryGenerator');
 
-/** @var \Application\Provider\Chargens\ChargensProvider $s */
-$s  = $sl->get('chargens');
 
-/** @var \Application\Service\Etape $se */
-$se = $sl->get('applicationEtape');
+//$p = $s->updateProcedures();
 
-$data = file_get_contents('/home/laurent/data.csv');
-$data = explode( "\n", $data );
 
-$sql = [];
+$s = $sl->get('applicationService');
 
-$thids = [
-    'fi' => 6,
-    'fa' => 7,
-    'fc' => 8,
-];
+$r = new \Application\Entity\Service\Recherche();
 
-foreach( $data as $d ){
-    if ($d != ''){
-        $d = explode( "\t", $d);
+$r->setIntervenant($sl->get('applicationIntervenant')->get(35424));
 
-        $code = trim($d[0]);
-        $e = [];
-        $e['fi'] = (int)trim($d[9]);
-        $e['fc'] = (int)trim($d[10]);
-        $e['fa'] = (int)trim($d[11]);
-        //var_dump($code, $fi, $fc, $fa);
+$d = $s->getExportPdfData($r);
 
-        $etape = $se->getRepo()->findOneBy([
-            'sourceCode' => $code,
-            'annee' => $se->getServiceContext()->getAnnee(),
-        ]);
+?>
+<table class="table table-bordered table-condensed">
+    <thead>
+    <tr>
+        <th>Intervenant</th>
+        <th>Statut intervenant</th>
+        <th>Grade</th>
+        <th>Structure d'enseignement</th>
+        <th>Type de formation</th>
+        <th>Formation ou établissement</th>
+        <th>Enseignement ou fonction référentielle</th>
+        <th>Service statutaire</th>
+        <th>Modification de service du</th>
+        <th>Total FI</th>
+        <th>Total FA</th>
+        <th>Total FC</th>
+        <th>Référentiel</th>
+        <th>Total HETD</th>
+        <th>Service (+/-) *</th>
+    </tr>
+    </thead>
+    <tbody>
+    <?php
+    foreach ($d as $di):
+        $s = 0;
 
-        if ($etape){
-            $etapeId = $etape->getId();
+        $ls = [
+            'structure'      => '------------',
+            'type-formation' => '------------',
+            'formation'      => '------------',
+            'enseignement'   => '------------',
+        ];
+        foreach ($di['services'] as $ds):
+            $s++;
 
-            foreach( $e as $ec => $eff ){
-                if ($eff > 0){
-                    $thid = $thids[$ec];
-                    $scenarioId = 1;
-                    $sql[] = "OSE_CHARGENS.INIT_SCENARIO_NOEUD_EFFECTIF($etapeId,$scenarioId,$thid, $eff, TRUE );";
-                }
+            if ($ls['formation'] != $ds['formation']) {
+                $ls['enseignement'] = '------------';
             }
-        }else{
-//            var_dump('étape non trouvée : '.$code);
-        }
-    }
-}
+            if ($ls['type-formation'] != $ds['type-formation']) {
+                $ls['formation']    = '------------';
+                $ls['enseignement'] = '------------';
+            }
+            if ($ls['structure'] != $ds['structure']) {
+                $ls['type-formation'] = '------------';
+                $ls['formation']      = '------------';
+                $ls['enseignement']   = '------------';
+            }
+            ?>
+            <tr>
+                <td><?php echo $s == 1 ? $di['nom'] : '' ?></td>
+                <td><?php echo $s == 1 ? $di['statut'] : '' ?></td>
+                <td><?php echo $s == 1 ? $di['grade'] : '' ?></td>
+                <td><?php echo $ls['structure'] != $ds['structure'] ? $ds['structure'] : '' ?></td>
+                <td><?php echo $ls['type-formation'] != $ds['type-formation'] ? $ds['type-formation'] : '' ?></td>
+                <td><?php echo $ls['formation'] != $ds['formation'] ? $ds['formation'] : '' ?></td>
+                <td><?php echo $ls['enseignement'] != $ds['enseignement'] ? $ds['enseignement'] : '' ?></td>
+
+                <td></td>
+                <td></td>
+                <td><?php echo \UnicaenApp\Util::formattedFloat($ds['fi']) ?></td>
+                <td><?php echo \UnicaenApp\Util::formattedFloat($ds['fa']) ?></td>
+                <td><?php echo \UnicaenApp\Util::formattedFloat($ds['fc']) ?></td>
+                <td><?php echo \UnicaenApp\Util::formattedFloat($ds['referentiel']) ?></td>
+                <td><?php echo \UnicaenApp\Util::formattedFloat($ds['total']) ?></td>
+                <td></td>
+            </tr>
+            <?php
+
+            $ls = $ds;
+
+        endforeach; ?>
+        <tr class="total">
+            <td>Total <?php echo $di['nom'] ?></td>
+            <td></td>
+            <td></td>
+            <td></td>
+            <td></td>
+            <td></td>
+            <td></td>
 
-echo implode( "<br />\n", $sql );
\ No newline at end of file
+            <td><?php echo \UnicaenApp\Util::formattedFloat($di['service-du']) ?></td>
+            <td><?php echo \UnicaenApp\Util::formattedFloat($di['modif-service-du']) ?></td>
+            <td><?php echo \UnicaenApp\Util::formattedFloat($di['fi']) ?></td>
+            <td><?php echo \UnicaenApp\Util::formattedFloat($di['fa']) ?></td>
+            <td><?php echo \UnicaenApp\Util::formattedFloat($di['fc']) ?></td>
+            <td><?php echo \UnicaenApp\Util::formattedFloat($di['referentiel']) ?></td>
+            <td><?php echo \UnicaenApp\Util::formattedFloat($di['total']) ?></td>
+            <td<?php if ($di['solde'] < 0) echo ' class="solde-negatif"' ?>><?php echo \UnicaenApp\Util::formattedFloat($di['solde']) ?></td>
+        </tr>
+    <?php endforeach; ?>
+    </tbody>
+</table>
diff --git a/composer.json b/composer.json
index 39832bf7c08b0fb1f364fa811d8b727077e47bda..54d59ca40b94f69aafd9ec95ba3c712db3e5ab9c 100755
--- a/composer.json
+++ b/composer.json
@@ -16,7 +16,8 @@
         "zendframework/zend-file":              ">=2.3",
         "mpdf/mpdf":                            "v5.7.2",
         "unicaen/unicaen-code":                 "dev-trunk as 1.0.1",
-        "unicaen/unicaen-import":               "dev-trunk as 1.0.6"
+        "unicaen/unicaen-import":               "dev-trunk as 1.0.6",
+        "unicaen/unicaen-tbl":                  "dev-trunk"
     },
     "require-dev": {
         "zendframework/zend-test":              ">=2.3",
diff --git a/composer.lock b/composer.lock
index b797cff6c9f0556149e5d7d2ab8e08da9568fc7b..ce4dffc5bdcf713c9b1529a375b6713e2e822c31 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,8 +4,8 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "hash": "fee35c1c24c0c32b1f8584f358fae7b1",
-    "content-hash": "deaa4e323f5fab2258aac73a9ac2acba",
+    "hash": "44be8cfa17f051728f09542f59d7214b",
+    "content-hash": "a2e4bcf2efac6a66dc6831bcc85c7a90",
     "packages": [
         {
             "name": "bjyoungblood/bjy-authorize",
@@ -1506,6 +1506,33 @@
             "description": "Bibliothèque utile lorsqu'on utilise un base de données Oracle",
             "time": "2017-01-17 11:13:51"
         },
+        {
+            "name": "unicaen/unicaen-tbl",
+            "version": "dev-trunk",
+            "source": {
+                "type": "svn",
+                "url": "https://svn.unicaen.fr/svn/UnicaenTbl",
+                "reference": "/trunk/@5"
+            },
+            "require": {
+                "unicaen/unicaen-app": "1.*"
+            },
+            "require-dev": {
+                "phpunit/phpunit": ">=5.6"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-0": {
+                    "UnicaenTbl": "src/",
+                    "UnicaenTblTest": "tests/"
+                },
+                "classmap": [
+                    "./Module.php"
+                ]
+            },
+            "description": "Module Unicaen de gestion de tableaux de bord Oracle",
+            "time": "2017-05-15 13:55:05"
+        },
         {
             "name": "zendframework/zend-authentication",
             "version": "2.4.11",
@@ -4981,7 +5008,8 @@
         "unicaen/unicaen-auth": 20,
         "bjyoungblood/bjy-authorize": 20,
         "unicaen/unicaen-code": 20,
-        "unicaen/unicaen-import": 20
+        "unicaen/unicaen-import": 20,
+        "unicaen/unicaen-tbl": 20
     },
     "prefer-stable": false,
     "prefer-lowest": false,
diff --git a/config/application.config.php b/config/application.config.php
index 71300789943b2fd11f3fdf3a1092a69ebd17330d..bf6bdcd39d4fa2920caa77b452948bdc8ee2b9f2 100755
--- a/config/application.config.php
+++ b/config/application.config.php
@@ -4,7 +4,7 @@ $env = getenv('APPLICATION_ENV') ?: 'production';
 
 $modules = [
     'ZfcBase', 'DoctrineModule', 'DoctrineORMModule', 'ZfcUser', 'ZfcUserDoctrineORM',
-    'UnicaenApp', 'UnicaenAuth', 'UnicaenImport',
+    'UnicaenApp', 'UnicaenAuth', 'UnicaenImport', 'UnicaenTbl',
     'Application'
 ];
 
diff --git a/config/autoload/unicaen-tbl.global.php b/config/autoload/unicaen-tbl.global.php
new file mode 100644
index 0000000000000000000000000000000000000000..cc5f06e7d113316712175a7445d9780aecc69bab
--- /dev/null
+++ b/config/autoload/unicaen-tbl.global.php
@@ -0,0 +1,8 @@
+<?php
+
+namespace UnicaenTbl;
+
+return [
+    'unicaen-tbl' => [
+    ],
+];
\ No newline at end of file
diff --git "a/data/Sql/Intervenant test existance Harp\303\250ge.sql" "b/data/Sql/Intervenant test existance Harp\303\250ge.sql"
index 1d8352e5a0d9a1b6252371e3dbbb93d34b1af935..e78b8b95c5549c89963a3edf4953d6a2dd7a4756 100644
--- "a/data/Sql/Intervenant test existance Harp\303\250ge.sql"	
+++ "b/data/Sql/Intervenant test existance Harp\303\250ge.sql"	
@@ -73,4 +73,8 @@ FROM
   LEFT JOIN chercheur@harpprod          ch                 ON ch.no_individu                 = individu.no_individu
   LEFT JOIN affectation_recherche@harpprod ar              ON ar.no_dossier_pers             = individu.no_individu
 WHERE
-  individu.no_individu = '44164'
\ No newline at end of file
+ individu.no_individu = 31731
+-- individu.nom_usuel like 'Aubry%';
+ ;
+ 
+ SELECT * from individu@harpprod where nom_usuel like 'AUBRY%'
diff --git a/module/Application/config/aaa_module.config.php b/module/Application/config/aaa_module.config.php
index 9f3852e5dc853eaad8804525295fbb12f3f3c11a..8ff240b1307da2187a432a99062fc6c8fbfdc6a4 100755
--- a/module/Application/config/aaa_module.config.php
+++ b/module/Application/config/aaa_module.config.php
@@ -147,6 +147,7 @@ return [
             'dbEvent'                       => Service\DbEventService::class,
             'UnicaenAuth\Service\Privilege' => Service\PrivilegeService::class,
             'assertionInformation'          => Assertion\InformationAssertion::class,
+            'tableauBord'                   => Service\TableauBordService::class,
         ],
         'factories'  => [
             'navigation'                  => Service\NavigationFactoryFactory::class,
@@ -204,12 +205,12 @@ return [
     ],
     'public_files'       => [
         'head_scripts'   => [
-            '010_jquery'   => 'vendor/jquery-1.11.3.min.js',
-            '020_jqueryui' => 'vendor/bootstrap-3.3.5/js/bootstrap.min.js',
-            '019_bootstrap'   => 'vendor/jquery-ui-1.11.4/jquery-ui.min.js',
+            '010_jquery'    => 'vendor/jquery-1.11.3.min.js',
+            '020_jqueryui'  => 'vendor/bootstrap-3.3.5/js/bootstrap.min.js',
+            '019_bootstrap' => 'vendor/jquery-ui-1.11.4/jquery-ui.min.js',
 
-//            '020_jqueryui' => 'vendor/jquery-ui-1.11.4/jquery-ui.min.js',
-//            '019_bootstrap'   => 'vendor/bootstrap-3.3.5/js/bootstrap.min.js',
+            //            '020_jqueryui' => 'vendor/jquery-ui-1.11.4/jquery-ui.min.js',
+            //            '019_bootstrap'   => 'vendor/bootstrap-3.3.5/js/bootstrap.min.js',
 
         ],
         'inline_scripts' => [
diff --git a/module/Application/config/service.config.php b/module/Application/config/service.config.php
index a5b40cfb6e89bfeed5f60c9bfbc86427fd1acfd4..dcfe5c381ff1f715bb0f6268c22803f0a4aada0d 100644
--- a/module/Application/config/service.config.php
+++ b/module/Application/config/service.config.php
@@ -39,6 +39,15 @@ return [
                             ],
                         ],
                     ],
+                    'export-pdf'               => [
+                        'type'    => 'Literal',
+                        'options' => [
+                            'route'    => '/export-pdf',
+                            'defaults' => [
+                                'action' => 'export-pdf',
+                            ],
+                        ],
+                    ],
                     'resume-refresh'           => [
                         'type'    => 'Literal',
                         'options' => [
@@ -302,6 +311,13 @@ return [
                         Privileges::ENSEIGNEMENT_EXPORT_CSV,
                     ],
                 ],
+                [
+                    'controller' => 'Application\Controller\Service',
+                    'action'     => ['export-pdf'],
+                    'privileges' => [
+                        Privileges::ENSEIGNEMENT_EXPORT_PDF,
+                    ],
+                ],
 
                 /* Référentiel */
                 [
diff --git a/module/Application/src/Application/Controller/ServiceController.php b/module/Application/src/Application/Controller/ServiceController.php
index 1df73865c45ce3074b72a8e678b7588d272bc38a..d5a1a58eb6173155974cfdce43772dadcdb84515 100644
--- a/module/Application/src/Application/Controller/ServiceController.php
+++ b/module/Application/src/Application/Controller/ServiceController.php
@@ -12,6 +12,8 @@ use Application\Processus\Traits\ValidationProcessusAwareTrait;
 use Application\Provider\Privilege\Privileges;
 use Application\Service\Traits\LocalContextAwareTrait;
 use Application\Service\Traits\RegleStructureValidationServiceAwareTrait;
+use Application\Service\Traits\TableauBordServiceAwareTrait;
+use UnicaenApp\Exporter\Pdf;
 use UnicaenApp\View\Model\CsvModel;
 use UnicaenApp\View\Model\MessengerViewModel;
 use Zend\Http\Request;
@@ -57,6 +59,7 @@ class ServiceController extends AbstractController
     use RechercheFormAwareTrait;
     use ValidationEnseignementProcessusAwareTrait;
     use RegleStructureValidationServiceAwareTrait;
+    use TableauBordServiceAwareTrait;
 
 
 
@@ -116,10 +119,9 @@ class ServiceController extends AbstractController
 
     public function exportAction()
     {
-        $role = $this->getServiceContext()->getSelectedIdentityRole();
+        $role        = $this->getServiceContext()->getSelectedIdentityRole();
         $intervenant = $role->getIntervenant() ?: $this->getEvent()->getParam('intervernant');
-        /* @var $intervenant Intervenant  */
-
+        /* @var $intervenant Intervenant */
 
 
         $this->initFilters();
@@ -155,6 +157,44 @@ class ServiceController extends AbstractController
 
 
 
+    public function exportPdfAction()
+    {
+        $role        = $this->getServiceContext()->getSelectedIdentityRole();
+        $intervenant = $role->getIntervenant() ?: $this->getEvent()->getParam('intervernant');
+        /* @var $intervenant Intervenant */
+
+
+        $this->initFilters();
+        if (!$intervenant) {
+            $this->rechercheAction();
+            $recherche = $this->getServiceService()->loadRecherche();
+        } else {
+            $recherche = new Recherche;
+            $recherche->setTypeVolumeHoraire($this->getServiceTypeVolumehoraire()->getPrevu());
+            $recherche->setEtatVolumeHoraire($this->getServiceEtatVolumeHoraire()->getSaisi());
+        }
+
+        $variables = [
+            'typeIntervenant' => $recherche->getTypeIntervenant(),
+            'structure'       => $recherche->getStructureAff(),
+            'data'            => $this->getServiceService()->getExportPdfData($recherche),
+        ];
+
+        $exp = $this->pdf()
+            ->setOrientationPaysage(true)
+            ->setFormat('A3')
+            ->setHeaderTitle('État des services prévisionnels au titre de l\'année universitaire ' . $this->getServiceContext()->getAnnee())
+            ->setMarginBottom(25)
+            ->setMarginTop(25);
+//        $exp->setFooterTitle('FooterTitle');
+        $exp->addBodyScript('application/service/export-pdf.phtml', false, $variables);
+        $fileName = 'Listing des services - ' . date('dmY') . '.pdf';
+
+        $exp->export($fileName, Pdf::DESTINATION_BROWSER_FORCE_DL);
+    }
+
+
+
     /**
      * Totaux de services et de référentiel par intervenant.
      *
@@ -162,9 +202,9 @@ class ServiceController extends AbstractController
      */
     public function resumeAction()
     {
-        $role = $this->getServiceContext()->getSelectedIdentityRole();
+        $role        = $this->getServiceContext()->getSelectedIdentityRole();
         $intervenant = $role->getIntervenant() ?: $this->getEvent()->getParam('intervernant');
-        /* @var $intervenant Intervenant  */
+        /* @var $intervenant Intervenant */
 
         $canAddService = $this->isAllowed(Privileges::getResourceId(Privileges::ENSEIGNEMENT_EDITION));
         $annee         = $this->getServiceContext()->getAnnee();
@@ -324,10 +364,13 @@ class ServiceController extends AbstractController
         $this->initFilters();
         $errors   = [];
         $services = $this->params()->fromQuery('services');
+//        $intervenants = [];
+//        $this->getServiceTableauBord()->desactiver();
         if ($services) {
             $services = explode(',', $services);
             foreach ($services as $sid) {
                 $service = $this->getServiceService()->get($sid);
+//                $intervenants[$service->getIntervenant()->getId()] = $service->getIntervenant();
                 $service->setTypeVolumeHoraire($this->getServiceTypeVolumeHoraire()->getRealise());
                 if ($this->isAllowed($service, Privileges::ENSEIGNEMENT_EDITION)) {
                     try {
@@ -338,6 +381,11 @@ class ServiceController extends AbstractController
                 }
             }
         }
+//
+//        foreach( $intervenants as $id => $intervenant ){
+//            $this->getServiceTableauBord()->calculerTous($intervenant);
+//        }
+//        $this->getServiceTableauBord()->activer();
 
         return compact('errors');
     }
@@ -379,8 +427,8 @@ class ServiceController extends AbstractController
                     $this->getServiceService()->delete($service);
                 }*/
             } catch (\Exception $e) {
-                $e        = DbException::translate($e);
-                $this->flashMessenger()->addErrorMessage( $e->getMessage() );
+                $e = DbException::translate($e);
+                $this->flashMessenger()->addErrorMessage($e->getMessage());
             }
         }
 
@@ -466,7 +514,7 @@ class ServiceController extends AbstractController
         $typeVolumeHoraire = $this->getServiceTypeVolumeHoraire()->getByCode($this->params()->fromRoute('type-volume-horaire-code', 'PREVU'));
 
         $rsv = $this->getServiceRegleStructureValidation()->getBy($typeVolumeHoraire, $intervenant);
-        if ($rsv && $rsv->getMessage()){
+        if ($rsv && $rsv->getMessage()) {
             $this->flashMessenger()->addInfoMessage($rsv->getMessage());
         }
 
diff --git a/module/Application/src/Application/Form/Service/RechercheForm.php b/module/Application/src/Application/Form/Service/RechercheForm.php
index 6ce18092e640cce7885b9f29d10549481091a1df..3e6094954ff1b2e4fcddead33555fe8267a5d529 100644
--- a/module/Application/src/Application/Form/Service/RechercheForm.php
+++ b/module/Application/src/Application/Form/Service/RechercheForm.php
@@ -209,7 +209,10 @@ class RechercheForm extends AbstractForm implements EntityManagerAwareInterface
         $this->addActionButton('submit-resume', 'Afficher (résumé)', $this->getUrl('service/resume'), true);
         $this->addActionButton('submit-details', 'Afficher (détails)', $this->getUrl('service'));
         if ($this->getServiceAuthorize()->isAllowed(Privileges::getResourceId(Privileges::ENSEIGNEMENT_EXPORT_CSV))) {
-            $this->addActionButton('submit-export', 'Exporter (CSV)', $this->getUrl('service/export'));
+            $this->addActionButton('submit-export-csv', 'Exporter (CSV)', $this->getUrl('service/export'));
+        }
+        if ($this->getServiceAuthorize()->isAllowed(Privileges::getResourceId(Privileges::ENSEIGNEMENT_EXPORT_PDF))) {
+            $this->addActionButton('submit-export-pdf', 'Exporter (PDF)', $this->getUrl('service/export-pdf'));
         }
     }
 
diff --git a/module/Application/src/Application/Provider/Privilege/Privileges.php b/module/Application/src/Application/Provider/Privilege/Privileges.php
index c1435fb6d57d615c57d1bea46accc3c4e915eb6b..12aec1392631caca8cdae33dc2ba0c44c9de39e6 100755
--- a/module/Application/src/Application/Provider/Privilege/Privileges.php
+++ b/module/Application/src/Application/Provider/Privilege/Privileges.php
@@ -67,6 +67,7 @@ class Privileges extends \UnicaenAuth\Provider\Privilege\Privileges {
     const ENSEIGNEMENT_DEVALIDATION                  = 'enseignement-devalidation';
     const ENSEIGNEMENT_EDITION                       = 'enseignement-edition';
     const ENSEIGNEMENT_EXPORT_CSV                    = 'enseignement-export-csv';
+    const ENSEIGNEMENT_EXPORT_PDF                    = 'enseignement-export-pdf';
     const ENSEIGNEMENT_EXTERIEUR                     = 'enseignement-exterieur';
     const ENSEIGNEMENT_VALIDATION                    = 'enseignement-validation';
     const ENSEIGNEMENT_VISUALISATION                 = 'enseignement-visualisation';
diff --git a/module/Application/src/Application/Service/TableauBordService.php b/module/Application/src/Application/Service/TableauBordService.php
new file mode 100755
index 0000000000000000000000000000000000000000..b0a9b00f996b06fbd3b17574e54fabd532d7dd01
--- /dev/null
+++ b/module/Application/src/Application/Service/TableauBordService.php
@@ -0,0 +1,140 @@
+<?php
+
+namespace Application\Service;
+
+use Application\Entity\Db\Intervenant as IntervenantEntity;
+use Application\Entity\Db\Annee as AnneeEntity;
+
+
+/**
+ * Description of TableauBordService
+ *
+ * @author LECLUSE Laurent <laurent.lecluse at unicaen.fr>
+ */
+class TableauBordService extends AbstractService
+{
+    const PKG_AGREMENT                = 'OSE_AGREMENT';
+    const PKG_CLOTURE_REALISE         = 'OSE_CLOTURE_REALISE';
+    const PKG_CONTRAT                 = 'OSE_CONTRAT';
+    const PKG_DOSSIER                 = 'OSE_DOSSIER';
+    const PKG_FORMULE                 = 'OSE_FORMULE';
+    const PKG_PAIEMENT                = 'OSE_PAIEMENT';
+    const PKG_PIECE_JOINTE            = 'OSE_PIECE_JOINTE';
+    const PKG_PIECE_JOINTE_DEMANDE    = 'OSE_PIECE_JOINTE_DEMANDE';
+    const PKG_PIECE_JOINTE_FOURNIE    = 'OSE_PIECE_JOINTE_FOURNIE';
+    const PKG_SERVICE                 = 'OSE_SERVICE';
+    const PKG_SERVICE_REFERENTIEL     = 'OSE_SERVICE_REFERENTIEL';
+    const PKG_SERVICE_SAISIE          = 'OSE_SERVICE_SAISIE';
+    const PKG_VALIDATION_ENSEIGNEMENT = 'OSE_VALIDATION_ENSEIGNEMENT';
+    const PKG_VALIDATION_REFERENTIEL  = 'OSE_VALIDATION_REFERENTIEL';
+    const PKG_WORKFLOW                = 'OSE_WORKFLOW';
+
+    const PACKAGES = [
+        self::PKG_AGREMENT,
+        self::PKG_CLOTURE_REALISE,
+        self::PKG_CONTRAT,
+        self::PKG_DOSSIER,
+        self::PKG_FORMULE,
+        self::PKG_PAIEMENT,
+        self::PKG_PIECE_JOINTE,
+        self::PKG_PIECE_JOINTE_DEMANDE,
+        self::PKG_PIECE_JOINTE_FOURNIE,
+        self::PKG_SERVICE,
+        self::PKG_SERVICE_REFERENTIEL,
+        self::PKG_SERVICE_SAISIE,
+        self::PKG_VALIDATION_ENSEIGNEMENT,
+        self::PKG_VALIDATION_REFERENTIEL,
+        self::PKG_WORKFLOW,
+    ];
+
+
+
+    public function calculer($packageName, IntervenantEntity $intervenant, $withDeps = false, $withSucs = true)
+    {
+        if (!in_array($packageName, self::PACKAGES)) {
+            throw new \Exception('Package non valide');
+        }
+
+        $deps = $withDeps ? 'true' : 'false';
+        $sucs = $withSucs ? 'true' : 'false';
+        $this->exec("BEGIN OSE_EVENT.CALCULER(:package, :intervenant, $deps, $sucs); END;", [
+            'package'     => $packageName,
+            'intervenant' => $intervenant->getId(),
+        ]);
+
+        return $this;
+    }
+
+
+
+    /**
+     * @todo ATTENTION : la hiérarchie des packages n'est pas prise en compte!!!
+     *
+     * @param IntervenantEntity $intervenant
+     *
+     * @return $this
+     */
+    public function calculerTous(IntervenantEntity $intervenant)
+    {
+        foreach (self::PACKAGES as $package) {
+            $this->calculer($package, $intervenant, false, false);
+        }
+
+        return $this;
+    }
+
+
+
+    public function calculerTout($packageName, AnneeEntity $annee = null, $withDeps = false, $withSucs = true)
+    {
+        if (!in_array($packageName, self::PACKAGES)) {
+            throw new \Exception('Package non valide');
+        }
+
+        $deps = $withDeps ? 'true' : 'false';
+        $sucs = $withSucs ? 'true' : 'false';
+        if ($annee) {
+            $this->exec("BEGIN OSE_EVENT.CALCULER_TOUT(:package, :annee, $deps, $sucs); END;", [
+                'package' => $packageName,
+                'annee'   => $annee->getId(),
+            ]);
+        } else {
+            $this->exec("BEGIN OSE_EVENT.CALCULER_TOUT(:package, NULL, $deps, $sucs); END;", [
+                'package' => $packageName,
+            ]);
+        }
+
+        return $this;
+    }
+
+
+
+    public function activer()
+    {
+        $this->exec("BEGIN OSE_EVENT.SET_ACTIF(TRUE); END;");
+
+        return $this;
+    }
+
+
+
+    public function desactiver()
+    {
+        $this->exec("BEGIN OSE_EVENT.SET_ACTIF(FALSE); END;");
+
+        return $this;
+    }
+
+
+
+    /**
+     * @param       $sql
+     * @param array $params
+     *
+     * @return \Doctrine\DBAL\Driver\Statement
+     */
+    protected function exec($sql, array $params = [])
+    {
+        return $this->getEntityManager()->getConnection()->executeQuery($sql, $params);
+    }
+}
\ No newline at end of file
diff --git a/module/Application/src/Application/Service/Traits/TableauBordServiceAwareTrait.php b/module/Application/src/Application/Service/Traits/TableauBordServiceAwareTrait.php
new file mode 100755
index 0000000000000000000000000000000000000000..57a7a53f233844d42828074f66237d2efccc85bf
--- /dev/null
+++ b/module/Application/src/Application/Service/Traits/TableauBordServiceAwareTrait.php
@@ -0,0 +1,59 @@
+<?php
+
+namespace Application\Service\Traits;
+
+use Application\Service\TableauBordService;
+use Application\Module;
+use RuntimeException;
+
+/**
+ * Description of TableauBordServiceAwareTrait
+ *
+ * @author UnicaenCode
+ */
+trait TableauBordServiceAwareTrait
+{
+    /**
+     * @var TableauBordService
+     */
+    private $serviceTableauBord;
+
+
+
+
+
+    /**
+     * @param TableauBordService $serviceTableauBord
+     * @return self
+     */
+    public function setServiceTableauBord( TableauBordService $serviceTableauBord )
+    {
+        $this->serviceTableauBord = $serviceTableauBord;
+        return $this;
+    }
+
+
+
+    /**
+     * @return TableauBordService
+     * @throws RuntimeException
+     */
+    public function getServiceTableauBord()
+    {
+        if (empty($this->serviceTableauBord)){
+            $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->serviceTableauBord = $serviceLocator->get('tableauBord');
+        }
+        return $this->serviceTableauBord;
+    }
+}
\ No newline at end of file
diff --git a/module/Application/view/application/service/export-pdf.phtml b/module/Application/view/application/service/export-pdf.phtml
new file mode 100644
index 0000000000000000000000000000000000000000..d83fc2d87948058aff3abf0fae7a4766c23a12ec
--- /dev/null
+++ b/module/Application/view/application/service/export-pdf.phtml
@@ -0,0 +1,274 @@
+<?php
+/**
+ * @var $structure       \Application\Entity\Db\Structure
+ * @var $typeIntervenant \Application\Entity\Db\TypeIntervenant
+ * @var $data            array
+ */
+
+?>
+<style>
+    body {
+        font-family: ubuntu, arial, sans-serif;
+    }
+
+    .entete {
+        font-size: 6pt;
+        font-weight: bold;
+    }
+
+    .sign-cell {
+        padding: 15pt;
+        width: 50%;
+    }
+
+    .signature {
+        border-style: solid;
+        border-width: 1px;
+        padding: 15pt;
+        width: 100%;
+    }
+
+    .signature-titre {
+        font-weight: bold;
+        text-align: center;
+    }
+
+    .signature-personne {
+        text-align: center;
+    }
+
+    .data {
+        font-size: 7pt;
+        border-collapse: collapse;
+    }
+
+    .data thead th {
+        background-color: royalblue;
+        color:white;
+    }
+
+    .total td {
+        background-color:mediumblue;
+        color:white;
+    }
+
+    .total td.solde_negatif {
+        background-color: lightpink;
+        color:darkred;
+        border-right-width: 2;
+        border-right-style: solid;
+    }
+
+    .c1 {
+        border-left-width: 2;
+        border-left-style: solid;
+    }
+
+    .c5 {
+        border-right-width: 2;
+        border-right-style: solid;
+    }
+
+    .c7 {
+        border-right-width: 2;
+        border-right-style: solid;
+    }
+
+    .c9 {
+        border-right-width: 2;
+        border-right-style: solid;
+    }
+
+    .c13 {
+        border-right-width: 2;
+        border-right-style: solid;
+    }
+
+    .c14 {
+        border-right-width: 2;
+        border-right-style: solid;
+    }
+
+    .c15 {
+        border-right-width: 2;
+        border-right-style: solid;
+    }
+
+    .data:last-child {
+        border-bottom-width: 2;
+        border-bottom-style: solid;
+    }
+
+</style>
+
+<table style="width:100%" class="entete">
+    <tr>
+        <td style="width: 85%">
+            <table>
+                <tr>
+                    <td>Composante d'affectation</td>
+                    <td><?php echo $structure ? $structure : 'Toutes' ?></td>
+                </tr>
+                <tr>
+                    <td>Type d'intervenant</td>
+                    <td><?php echo $typeIntervenant ? $typeIntervenant : 'Tous' ?></td>
+                </tr>
+            </table>
+        </td>
+        <td>*<br/>&nbsp;</td>
+        <td>
+            "service +" : Total heures complémentaires (HETD)<br/>
+            "Service -" : Heures sous-service (HETD)
+        </td>
+    </tr>
+</table>
+
+
+<table class="data" cellpadding="3">
+    <thead>
+    <tr>
+        <th class="c1">Intervenant</th>
+        <th class="c2">Statut intervenant</th>
+        <th class="c3">Grade</th>
+        <th class="c4">Structure d'enseignement</th>
+        <th class="c5">Type de formation</th>
+        <th class="c6">Formation ou établissement</th>
+        <th class="c7">Enseignement ou fonction référentielle</th>
+        <th class="c8">Service statutaire</th>
+        <th class="c9">Modification de service du</th>
+        <th class="c10">Total FI</th>
+        <th class="c11">Total FA</th>
+        <th class="c12">Total FC</th>
+        <th class="c13">Référentiel</th>
+        <th class="c14">Total HETD</th>
+        <th class="c15">Service (+/-) *</th>
+    </tr>
+    </thead>
+    <tbody>
+    <?php
+    foreach ($data as $di):
+        $s = 0;
+
+        $ls = [
+            'structure'      => '------------',
+            'type-formation' => '------------',
+            'formation'      => '------------',
+            'enseignement'   => '------------',
+        ];
+        foreach ($di['services'] as $ds):
+            $s++;
+
+            if ($ls['formation'] != $ds['formation']) {
+                $ls['enseignement'] = '------------';
+            }
+            if ($ls['type-formation'] != $ds['type-formation']) {
+                $ls['formation']    = '------------';
+                $ls['enseignement'] = '------------';
+            }
+            if ($ls['structure'] != $ds['structure']) {
+                $ls['type-formation'] = '------------';
+                $ls['formation']      = '------------';
+                $ls['enseignement']   = '------------';
+            }
+            ?>
+            <tr>
+                <td class="c1"><?php echo $s == 1 ? $di['nom'] : '' ?></td>
+                <td class="c2"><?php echo $s == 1 ? $di['statut'] : '' ?></td>
+                <td class="c3"><?php echo $s == 1 ? $di['grade'] : '' ?></td>
+                <td class="c4"><?php echo $ls['structure'] != $ds['structure'] ? $ds['structure'] : '' ?></td>
+                <td class="c5"><?php echo $ls['type-formation'] != $ds['type-formation'] ? $ds['type-formation'] : '' ?></td>
+                <td class="c6"><?php echo $ls['formation'] != $ds['formation'] ? $ds['formation'] : '' ?></td>
+                <td class="c7"><?php echo $ls['enseignement'] != $ds['enseignement'] ? $ds['enseignement'] : '' ?></td>
+
+                <td class="c8"></td>
+                <td class="c9"></td>
+                <td class="c10"><?php echo \UnicaenApp\Util::formattedFloat($ds['fi']) ?></td>
+                <td class="c11"><?php echo \UnicaenApp\Util::formattedFloat($ds['fa']) ?></td>
+                <td class="c12"><?php echo \UnicaenApp\Util::formattedFloat($ds['fc']) ?></td>
+                <td class="c13"><?php echo \UnicaenApp\Util::formattedFloat($ds['referentiel']) ?></td>
+                <td class="c14"><?php echo \UnicaenApp\Util::formattedFloat($ds['total']) ?></td>
+                <td class="c15"></td>
+            </tr>
+            <?php
+
+            $ls = $ds;
+
+        endforeach; ?>
+        <tr class="total">
+            <td class="c1">Total <?php echo $di['nom'] ?></td>
+            <td class="c2"></td>
+            <td class="c3"></td>
+            <td class="c4"></td>
+            <td class="c5"></td>
+            <td class="c6"></td>
+            <td class="c7"></td>
+
+            <td class="c8"><?php echo \UnicaenApp\Util::formattedFloat($di['service-du']) ?></td>
+            <td class="c9"><?php echo \UnicaenApp\Util::formattedFloat($di['modif-service-du']) ?></td>
+            <td class="c10"><?php echo \UnicaenApp\Util::formattedFloat($di['fi']) ?></td>
+            <td class="c11"><?php echo \UnicaenApp\Util::formattedFloat($di['fa']) ?></td>
+            <td class="c12"><?php echo \UnicaenApp\Util::formattedFloat($di['fc']) ?></td>
+            <td class="c13"><?php echo \UnicaenApp\Util::formattedFloat($di['referentiel']) ?></td>
+            <td class="c14"><?php echo \UnicaenApp\Util::formattedFloat($di['total']) ?></td>
+            <td class="<?php echo ($di['solde'] < 0) ? 'solde_negatif' : 'c15' ?>"><?php echo \UnicaenApp\Util::formattedFloat($di['solde']) ?></td>
+        </tr>
+    <?php endforeach; ?>
+    </tbody>
+</table>
+
+
+<table style="width:100%">
+    <tr>
+        <td class="sign-cell">
+            <table class="signature">
+                <tr>
+                    <td class="signature-titre">Attestation de l'exactitude réglementaire des services mentionnés sur le
+                        présent document
+                    </td>
+                </tr>
+                <tr>
+                    <td class="signature-personne">Pour le Président et par délégation,<br/>le Directeur administratif de la
+                        composante :
+                    </td>
+                </tr>
+                <tr>
+                    <td>Date :</td>
+                </tr>
+                <tr>
+                    <td>&nbsp;</td>
+                </tr>
+                <tr>
+                    <td>Signature :</td>
+                </tr>
+                <tr>
+                    <td>&nbsp;</td>
+                </tr>
+            </table>
+        </td>
+        <td class="sign-cell">
+            <table class="signature">
+                <tr>
+                    <td class="signature-titre">Le conseil de la composante et les directeurs des unités de recherche
+                        consultés
+                    </td>
+                </tr>
+                <tr>
+                    <td class="signature-personne">Pour le Président et par délégation,<br/> le Directeur de la composante :
+                    </td>
+                </tr>
+                <tr>
+                    <td>Date :</td>
+                </tr>
+                <tr>
+                    <td>&nbsp;</td>
+                </tr>
+                <tr>
+                    <td>Signature :</td>
+                </tr>
+                <tr>
+                    <td>&nbsp;</td>
+                </tr>
+            </table>
+        </td>
+    </tr>
+</table>
\ No newline at end of file