Commit edaab5ca authored by Antony Le Courtes's avatar Antony Le Courtes
Browse files

Optimisation pour la reconduction des centres coûts (Utilisation d'une vue et...

Optimisation pour la reconduction des centres coûts (Utilisation d'une vue et insert sql au lieu de doctrine)
parent 7b3af5e3
Loading
Loading
Loading
Loading
+145 −0
Original line number Diff line number Diff line
@@ -6828,6 +6828,50 @@
        ),
      ),
    ),
    'FORMULE_TEST_STRUCTURE' => 
    array (
      'name' => 'FORMULE_TEST_STRUCTURE',
      'temporary' => false,
      'logging' => true,
      'commentaire' => 'sequence=FTEST_STRUCTURE_ID_SEQ;',
      'sequence' => 'FTEST_STRUCTURE_ID_SEQ',
      'columns' => 
      array (
        'ID' => 
        array (
          'name' => 'ID',
          'type' => 'NUMBER',
          'length' => 0,
          'scale' => '0',
          'precision' => NULL,
          'nullable' => false,
          'default' => NULL,
          'commentaire' => NULL,
        ),
        'LIBELLE' => 
        array (
          'name' => 'LIBELLE',
          'type' => 'VARCHAR2',
          'length' => 80,
          'scale' => NULL,
          'precision' => NULL,
          'nullable' => false,
          'default' => NULL,
          'commentaire' => NULL,
        ),
        'UNIVERSITE' => 
        array (
          'name' => 'UNIVERSITE',
          'type' => 'NUMBER',
          'length' => 0,
          'scale' => '0',
          'precision' => 1,
          'nullable' => false,
          'default' => '0',
          'commentaire' => NULL,
        ),
      ),
    ),
    'FORMULE_TEST_VOLUME_HORAIRE' => 
    array (
      'name' => 'FORMULE_TEST_VOLUME_HORAIRE',
@@ -19818,6 +19862,16 @@
        0 => 'ID',
      ),
    ),
    'FORMULE_TEST_STRUCTURE_PK' => 
    array (
      'name' => 'FORMULE_TEST_STRUCTURE_PK',
      'table' => 'FORMULE_TEST_STRUCTURE',
      'index' => 'FORMULE_TEST_STRUCTURE_PK',
      'columns' => 
      array (
        0 => 'ID',
      ),
    ),
    'FORMULE_TEST_VOLUME_HORAIRE_PK' => 
    array (
      'name' => 'FORMULE_TEST_VOLUME_HORAIRE_PK',
@@ -31430,6 +31484,36 @@ END UNICAEN_TBL;',
  ),
  'BddAdmin\\Ddl\\DdlView' => 
  array (
    'NEWVIEW' => 
    array (
      'name' => 'NEWVIEW',
      'definition' => 'CREATE OR REPLACE FORCE VIEW NEWVIEW AS
WITH t AS (
SELECT
  e.id                etape_id,
  ep.id               element_pedagogique_id,
  ccep.centre_cout_id centre_cout_id,
  ccep.type_heures_id type_heures_id,
  ep.annee_id         annee_id,
  ep.code             code
FROM
  etape                     e
  JOIN source               s ON s.importable = 0
  JOIN element_pedagogique ep ON ep.etape_id = e.id AND ep.histo_destruction IS NULL
  JOIN centre_cout_ep    ccep ON ccep.element_pedagogique_id = ep.id AND ccep.histo_destruction IS NULL AND ccep.source_id = s.id
WHERE
  e.histo_destruction IS NULL
)
SELECT
  t."ETAPE_ID",t."ELEMENT_PEDAGOGIQUE_ID",t."CENTRE_COUT_ID",t."TYPE_HEURES_ID",t."ANNEE_ID",t."CODE",
  ep.id new_element_pedagogique_id,
  ccep.id new_centre_cout_ep_id,
  ccep.histo_destruction
FROM
  t
  JOIN element_pedagogique ep ON ep.annee_id = t.annee_id + 1 AND ep.code = t.code AND ep.histo_destruction IS NULL
  LEFT JOIN centre_cout_ep ccep ON ccep.element_pedagogique_id = ep.id AND ccep.centre_cout_id = t.centre_cout_id AND ccep.type_heures_id = t.type_heures_id',
    ),
    'V_AGREMENT_EXPORT_CSV' => 
    array (
      'name' => 'V_AGREMENT_EXPORT_CSV',
@@ -35681,6 +35765,37 @@ FROM
  privilege p
  JOIN categorie_privilege cp ON cp.id = p.categorie_id
  LEFT JOIN statuts_roles sr ON sr.privilege_id = p.id',
    ),
    'V_RECONDUCTION_CENTRE_COUT' => 
    array (
      'name' => 'V_RECONDUCTION_CENTRE_COUT',
      'definition' => 'CREATE OR REPLACE FORCE VIEW V_RECONDUCTION_CENTRE_COUT AS
WITH t AS (
SELECT
  e.id                etape_id,
  e.libelle           etape_libelle,
  e.code              etape_code,
  ep.id               element_pedagogique_id,
  ccep.centre_cout_id centre_cout_id,
  ccep.type_heures_id type_heures_id,
  ep.annee_id         annee_id,
  ep.code             code
FROM
  etape                     e
  JOIN source               s ON s.importable = 0
  JOIN element_pedagogique ep ON ep.etape_id = e.id AND ep.histo_destruction IS NULL
  LEFT JOIN centre_cout_ep    ccep ON ccep.element_pedagogique_id = ep.id AND ccep.histo_destruction IS NULL AND ccep.source_id = s.id
WHERE
  e.histo_destruction IS NULL
)
SELECT
  t."ETAPE_ID",t."ETAPE_LIBELLE", t."ETAPE_CODE", t."ELEMENT_PEDAGOGIQUE_ID",t."CENTRE_COUT_ID",t."TYPE_HEURES_ID",t."ANNEE_ID",t."CODE",
  ep.id new_element_pedagogique_id,
  ccep.id new_centre_cout_ep_id
FROM
  t
  LEFT JOIN element_pedagogique ep ON ep.annee_id = t.annee_id + 1 AND ep.code = t.code AND ep.histo_destruction IS NULL
  LEFT JOIN centre_cout_ep ccep ON ccep.element_pedagogique_id = ep.id AND ccep.centre_cout_id = t.centre_cout_id AND ccep.type_heures_id = t.type_heures_id',
    ),
    'V_REF_INTERVENANT' => 
    array (
@@ -43872,6 +43987,16 @@ WHERE
        2 => 'ETAT_VOLUME_HORAIRE_ID',
      ),
    ),
    'FORMULE_TEST_STRUCTURE__UN' => 
    array (
      'name' => 'FORMULE_TEST_STRUCTURE__UN',
      'table' => 'FORMULE_TEST_STRUCTURE',
      'index' => 'FORMULE_TEST_STRUCTURE__UN',
      'columns' => 
      array (
        0 => 'LIBELLE',
      ),
    ),
    'FORMULE__UN' => 
    array (
      'name' => 'FORMULE__UN',
@@ -48410,6 +48535,26 @@ END;',
        0 => 'ID',
      ),
    ),
    'FORMULE_TEST_STRUCTURE_PK' => 
    array (
      'name' => 'FORMULE_TEST_STRUCTURE_PK',
      'unique' => true,
      'table' => 'FORMULE_TEST_STRUCTURE',
      'columns' => 
      array (
        0 => 'ID',
      ),
    ),
    'FORMULE_TEST_STRUCTURE__UN' => 
    array (
      'name' => 'FORMULE_TEST_STRUCTURE__UN',
      'unique' => true,
      'table' => 'FORMULE_TEST_STRUCTURE',
      'columns' => 
      array (
        0 => 'LIBELLE',
      ),
    ),
    'FORMULE_TEST_VOLUME_HORAIRE_PK' => 
    array (
      'name' => 'FORMULE_TEST_VOLUME_HORAIRE_PK',
+15 −45
Original line number Diff line number Diff line
@@ -211,9 +211,6 @@ class OffreFormationController extends AbstractController
    public function reconductionCentreCoutAction()
    {
        $this->initFilterHistorique();
        $anneeN            = $this->getServiceContext()->getAnnee();
        $anneeN1           = $this->getServiceContext()->getAnneeSuivante();
        $fromPost          = false;
        $etapesReconduites = [];
        [$structure, $niveau, $etape] = $this->getParams();

@@ -225,41 +222,13 @@ class OffreFormationController extends AbstractController
        $this->getServiceStructure()->finderByRole($role, $qb);
        $structures = $this->getServiceStructure()->getList($qb);


        //Récupération de toutes les étapes éligibles à la reconduction des coûts
        if (!empty($structure)) {
            $etapesReconduitesResult = $this->getServiceEtape()->getEtapeReconduit($structure);
            $codesEtapesWithoutCC = [];
            if ($etapesReconduitesResult) {
                foreach ($etapesReconduitesResult as $etape) {
                    if ($etape->getAnnee()->getLibelle() == $this->getServiceContext()->getAnnee()->getLibelle()) {
                        $epWithCc = $this->getServiceElementPedagogique()->countEpWithCc($etape);
                        if(empty($epWithCc))
                        {
                            $codesEtapesWithoutCC[] = $etape->getCode();
                        }
                        $etapesReconduites[$etape->getCode()]['N']['etape']    = $etape;
                        $etapesReconduites[$etape->getCode()]['N']['epWithCc'] = $epWithCc;
                    } else {
                        $epWithCc = $this->getServiceElementPedagogique()->countEpWithCc($etape);
                        $etapesReconduites[$etape->getCode()]['N1']['etape']    = $etape;
                        $etapesReconduites[$etape->getCode()]['N1']['epWithCc'] = $epWithCc;
                    }
                }
                //Clean etapes sans aucun centre de coût
                foreach($codesEtapesWithoutCC as $code)
                {
                    unset($etapesReconduites[$code]);
                }
            }
        }

        $request = $this->getRequest();
        if ($request->isPost()) {
            $fromPost = true;

            $datas    = $request->getPost();
            //Reconduire les centres de coût des EP de l'étape.
            try {
                $etapesReconduites = $this->getServiceEtape()->getEtapeReconduit($structure);
                $etapesReconduitesCc = [];
                if (isset($datas['etapes'])) {
                    foreach ($datas['etapes'] as $code) {
@@ -269,27 +238,28 @@ class OffreFormationController extends AbstractController
                    }
                }
                $result = $this->getProcessusReconduction()->reconduireCCFormation($etapesReconduitesCc);
                if ($result > 0) {
                    $this->flashMessenger()->addSuccessMessage("Les centres de coût des éléments pédagogiques des étapes sélectionnées ont bien été reconduit pour la prochaine année universitaire ($result 
                élément(s) pédagogique(s) concerné(s))");
                } else {
                    $this->flashMessenger()->addWarningMessage("Aucun centre de cout n'a été reconduit car aucun élément
                pédagogique n'existe pour cette formation pour la prochaine année universitaire.");
                }

                $this->flashMessenger()->addSuccessMessage("Les centres de coûts des éléments pédagogiques des étapes sélectionnées ont bien été reconduit (<b>uniquement dans le cas où ils n'avaient pas encore de centre de coût paramétré pour l'année prochaine</b>). $result 
                élément(s) pédagogique(s) ont été mis à jour");


            } catch (\Exception $e) {
                $this->flashMessenger()->addErrorMessage($e->getMessage());
            }
            $fromPost = true;


        }

        if(empty($etapesReconduites) && !empty($structure))
        {
            $etapesReconduites = $this->getServiceEtape()->getEtapeReconduit($structure);
        }


        return [
            'anneeN'            => $anneeN,
            'anneeN1'           => $anneeN1,
            'structures'        => $structures,
            'structure'         => $structure,
            'etapesReconduites' => $etapesReconduites,
            'fromPost'          => $fromPost,
            'etapesReconduites' => $etapesReconduites
        ];
    }

+63 −65
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@

namespace Application\Processus;

use Application\Connecteur\Bdd\BddConnecteurAwareTrait;
use Application\Entity\Db\ElementPedagogique;
use Application\Entity\Db\Etape;
use Application\Service\Traits\AnneeServiceAwareTrait;
@@ -13,6 +14,8 @@ use Application\Service\Traits\ElementPedagogiqueServiceAwareTrait;
use Application\Service\Traits\EtapeServiceAwareTrait;
use Application\Service\Traits\SourceServiceAwareTrait;
use Application\Service\Traits\VolumeHoraireEnsServiceAwareTrait;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\ParameterType;

/**
 * Description of ReconductionProcessus
@@ -23,6 +26,7 @@ class ReconductionProcessus extends AbstractProcessus
{

    use EtapeServiceAwareTrait;
    use BddConnecteurAwareTrait;
    use ElementPedagogiqueServiceAwareTrait;
    use CheminPedagogiqueServiceAwareTrait;
    use VolumeHoraireEnsServiceAwareTrait;
@@ -47,7 +51,6 @@ class ReconductionProcessus extends AbstractProcessus
    protected $centreCoutEpService;



    public function __construct()
    {
        $this->etapeService              = $this->getServiceEtape();
@@ -187,79 +190,63 @@ class ReconductionProcessus extends AbstractProcessus
        return true;
    }

    /**
     * Reconduit les centres de coutq des élements pédagogiques d'une sélection d'étapes
     *
     * @param array $etapes
     *
     * @return integer
     */


    public function reconduireCCFormation($etapes)
    {
        $anneeN       = $this->getServiceContext()->getAnnee();
        $anneeN1      = $this->getServiceContext()->getAnneeSuivante();
        $serviceEtape = $this->getServiceEtape();
        $em           = $this->getEntityManager();
        $nbEPN1       = 0;

        foreach ($etapes as $code => $etape) {
            $etapeN                     = $etape['N']['etape'];
            $elementsPedagogiqueN       = $etapeN->getElementPedagogique();
            $elementsPedagogiqueNByCode = [];
            $codesEpWithoutCc = [];
            foreach ($elementsPedagogiqueN as $ep) {
                //Check si ep a un élément pédagoggique
                $ccep = $ep->getCentreCoutEp();
                if(count($ccep) > 0)
        //Récupération des étapes dont il faut reconduire les cc
        $etapes_codes = array_keys($etapes);
        $sql = '
        SELECT 
            *            
        FROM 
            V_RECONDUCTION_CENTRE_COUT 
        WHERE
            annee_id = ?
        AND 
            etape_code IN (?)';
        $connection = $this->getEntityManager()->getConnection();
        $stmt = $connection->executeQuery($sql, [ $this->getServiceContext()->getAnnee()->getId(), $etapes_codes], [ParameterType::INTEGER, Connection::PARAM_STR_ARRAY]);
        $ccepN = $stmt->fetchAll();
        $listEp = [];
        $nbInsertedEp = 0;
        foreach ($ccepN as $key => $value) {
            if(empty($value['NEW_CENTRE_COUT_EP_ID']))
            {
                    //Si il a des centres de couts alors je le stocke
                    $elementsPedagogiqueNByCode[$ep->getCode()] = $ep;
                }
                else{
                    $codesEpWithoutCc[] = $ep->getCode();
                }
            }
            $etapeN1                     = $etape['N1']['etape'];
            $elementsPedagogiqueN1       = $etapeN1->getElementPedagogique();
            $elementsPedagogiqueN1ByCode = [];
            foreach ($elementsPedagogiqueN1 as $epN1) {
                //Si l'epN possède des CC alors je continuer
                if(!in_array($epN1->getCode(), $codesEpWithoutCc))
                //Récupération de la dernière incrémentation ID CCEP
                $nextSequence = $this->getNextSequence();
                try{
                    $stmt = $connection->insert('centre_cout_ep',
                        ['id' => $nextSequence,
                         'centre_cout_id' => $value['CENTRE_COUT_ID'],
                         'element_pedagogique_id' => $value['NEW_ELEMENT_PEDAGOGIQUE_ID'],
                         'type_heures_id' => $value['TYPE_HEURES_ID'],
                         'source_id'    => $this->getServiceSource()->getOse()->getId(),
                         'source_code'  => uniqid($value['CENTRE_COUT_ID'] . '_' . $value['TYPE_HEURES_ID'] . '_' . $value['NEW_ELEMENT_PEDAGOGIQUE_ID']),
                         'histo_createur_id' => $this->getServiceContext()->getUtilisateur()->getId(),
                         'histo_modificateur_id' => $this->getServiceContext()->getUtilisateur()->getId()
                        ]);

                    if(!in_array($value['NEW_ELEMENT_PEDAGOGIQUE_ID'], $listEp))
                    {
                    $elementsPedagogiqueN1ByCode[$epN1->getCode()] = $epN1;
                        $listEp[] = $value['NEW_ELEMENT_PEDAGOGIQUE_ID'];
                        $nbInsertedEp++;
                    }
            }

            foreach ($elementsPedagogiqueN as $ep) {
                //Cas d'un élément pédagogique historisé a ne pas reconduire
                if ($ep->estHistorise()) {
                    continue;
                }
                //Retrouver l'EP reconduite sur N1
                $epN1 = (array_key_exists($ep->getCode(), $elementsPedagogiqueN1ByCode)) ? $elementsPedagogiqueN1ByCode[$ep->getCode()] : false;
                if ($epN1) {
                    $nbEPN1++;
                    //Suppression CCEP de l'EPN1 avant la reconduction N -> N1
                    $centreCoutEpN1 = $epN1->getCentreCoutEp();
                    foreach ($centreCoutEpN1 as $ccepN1) {
                        $em->remove($ccepN1);
                    }
                    $em->flush();
                    $centreCoutEpN = $ep->getCentreCoutEp();
                    foreach ($centreCoutEpN as $ccep) {
                        //cas d'un centre de coût historisé.
                        if ($ccep->estHistorise()) {
                }catch(\Exception $e)
                {
                    continue;
                }
                        $ccepN1 = $this->centreCoutEpService->newEntity();
                        $ccepN1->setTypeHeures($ccep->getTypeHeures());
                        $ccepN1->setCentreCout($ccep->getCentreCout());
                        $ccepN1->setElementPedagogique($epN1);
                        $this->centreCoutEpService->save($ccepN1);
                    }
                    $em->persist($epN1);
            }
            }
        }
        //Execution en BDD
        $em->flush();

        return $nbEPN1;
        }
        return $nbInsertedEp;
    }


@@ -319,4 +306,15 @@ class ReconductionProcessus extends AbstractProcessus

        return $nbEPN1;
    }

    public function getNextSequence()
    {
        $connection = $this->getEntityManager()->getConnection();
        $stmt = $connection->executeQuery('SELECT CENTRE_COUT_EP_ID_SEQ.NEXTVAL val FROM DUAL');
        $result = $stmt->fetch();

        return $result['VAL'];
    }


}
 No newline at end of file
+29 −28
Original line number Diff line number Diff line
@@ -69,34 +69,35 @@ class EtapeService extends AbstractEntityService

    public function getEtapeReconduit($structure)
    {
        $anneeN  = $this->getServiceContext()->getAnnee();
        $anneeN1 = $this->getServiceContext()->getAnneeSuivante();


        $qb1 = $this->getEntityManager()->createQueryBuilder();
        $qb2 = $this->getEntityManager()->createQueryBuilder();

        $etapeN1 = $qb1
            ->select('eN1.code')
            ->from(Etape::class, 'eN1')
            ->leftJoin(Structure::class, 'sN1', \Doctrine\ORM\Query\Expr\Join::WITH, 'eN1.structure = sN1.id')
            ->where('eN1.annee = :anneeN1')
            ->andWhere('sN1 = :structure');

        $qb2 = $this->finderByStructure($structure)
            ->where($qb2->expr()->in('etp.code', $etapeN1->getDQL()))
            ->andWhere($qb2->expr()->orX(
                $qb2->expr()->eq('etp.annee', ':anneeN'),
                $qb2->expr()->eq('etp.annee', ':anneeN1')
            ))
            ->setParameter('anneeN', $anneeN)
            ->setParameter('anneeN1', $anneeN1)
            ->setParameter('structure', $structure)
            ->orderBy('etp.annee', 'desc');

        $result = $qb2->getQuery()->getResult();

        return $result;
        $annee  = $this->getServiceContext()->getAnnee()->getId();


        $sql = '
                SELECT 
            etape_id,
            etape_libelle,
            etape_code,
            count(DISTINCT element_pedagogique_id) AS nb_ep,
            count(DISTINCT new_centre_cout_ep_id) AS nb_cc_ep
        FROM 
            V_RECONDUCTION_CENTRE_COUT 
        WHERE
            annee_id = :annee
        GROUP BY 
            etape_id,
            etape_libelle,
            etape_code';
        $stmt = $this->getEntityManager()->getConnection()->prepare($sql);
        $stmt->bindParam(':annee', $annee);
        $stmt->execute();
        $result = $stmt->fetchAll();
        $etapes = [];
        foreach($result as $etape)
        {
            $etapes[$etape['ETAPE_CODE']] = $etape;
        }

        return $etapes;
    }


+10 −27
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@ $this->headScript()->offsetSetFile(100, '/js/reconduction-centre-cout.js');
    Si la formation n'est pas disponible dans la liste ci-dessous, veuillez vérifier qu'elle a bien été reconduit pour la prochaine année universitaire.
</div>

<h3>Offre de formation disponible (possédants des centres de coûts définis) pour la prochaine année universitaire :</h3>
<h3>Veuillez sélectionner les formations pour reconduire les centres de coûts :</h3>
<br/>
<?php
echo $this->messenger()->addCurrentMessagesFromFlashMessenger();
@@ -55,9 +55,6 @@ echo $this->messenger()->addCurrentMessagesFromFlashMessenger();
    </tr>
    </tbody>
</table>
<?php else: ?>
    <?php if($fromPost): ?>
        <p> <a href="<?= $this->url('aof/reconduction-centre-cout', [], ['query' => ['structure' => $structure->getId()]]) ?>" >< Retour à la liste des formations éligibles à la reconduction des centres de coûts.</a></p>
<?php else: ?>
        <form action="<?= $this->url('aof/reconduction-centre-cout', [], ['query' => ['structure' => $structure->getId()]]) ?>" method="POST" id="form-reconduction">

@@ -68,37 +65,24 @@ echo $this->messenger()->addCurrentMessagesFromFlashMessenger();
                        <th><input class="checkbox-element" type="checkbox" value="" id="check-all"></th>
                        <th>Code</th>
                        <th>Libellé</th>
                        <th colspan="3" style="text-align:center;">Année <?= $anneeN->getLibelle(); ?></th>
                        <th colspan="3" style="text-align:center;">Année <?= $anneeN1->getLibelle(); ?></th>
                    </tr>
                    <tr>
                        <th colspan="3"></th>
                        <th>EP</th>
                        <th>EP avec CC</th>
                        <th>EP sans CC</th>
                        <th>EP</th>
                        <th>EP avec CC</th>
                        <th>EP sans CC</th>
                        <th>Nb Elements pédagogiques</th>

                    </tr>

                </thead>
                <tbody>
                    <?php foreach ($etapesReconduites as $er): ?>
                    <tr>
                        <td>
                            <?php if($er['N1']['epWithCc'] > 0): ?>
                            <span style="color:#ae0000;font-size:16px;" class="glyphicon glyphicon-alert" aria-hidden="true" title="Attention des centres de coût sont déjà positionnés sur les éléments pédagogiques de la prochaine année universitaire, vous risquez des les écraser avec ceux de l'année courante."></span>
                            <?php if($er['NB_CC_EP'] > 0): ?>
                            <span style="color:#ae0000;font-size:16px;" class="glyphicon glyphicon-alert" aria-hidden="true" title="Attention des centres de coût sont déjà positionnés sur les éléments pédagogiques de la prochaine année universitaire, ils ne seront pas écrasés par ceux de cette année."></span>
                            <?php endif; ?>
                            <input class="checkbox-element" type="checkbox" name="etapes[]" value="<?= $er['N']['etape']->getCode(); ?>">
                            <input class="checkbox-element" type="checkbox" name="etapes[]" value="<?= $er['ETAPE_CODE']; ?>">
                        </td>
                        <td><?= $er['N']['etape']->getCode(); ?></td>
                        <td><?= $er['N']['etape']->getLibelle(); ?></td>
                        <td><?= count($er['N']['etape']->getElementPedagogique()); ?></td>
                        <td style="text-align:center;"><?= $er['N']['epWithCc']; ?></td>
                        <td style="text-align:center;"><?= count($er['N']['etape']->getElementPedagogique())-$er['N']['epWithCc'];?></td>
                        <td style="text-align:center;"><?= count($er['N1']['etape']->getElementPedagogique()); ?></td>
                        <td style="text-align:center;"><?= $er['N1']['epWithCc']; ?></td>
                        <td style="text-align:center;"><?= count($er['N1']['etape']->getElementPedagogique())-$er['N1']['epWithCc'];?></td>            </tr>
                        <td><?= $er['ETAPE_CODE']; ?></td>
                        <td><?=  $er['ETAPE_LIBELLE']; ?></td>
                        <td><?=  $er['NB_EP']; ?></td>
                    </tr>
                    <?php endforeach; ?>
                </tbody>
            </table>
@@ -112,4 +96,3 @@ echo $this->messenger()->addCurrentMessagesFromFlashMessenger();
                <button type='button' class='btn btn-primary' id='confirm-reconduction'>Oui</button></div>"><span class="glyphicon glyphicon-share"></span> Reconduire les centres de coûts pour l'année suivante</button>
        </form>
<?php endif; ?>
<?php endif; ?>