Commit fce545a0 authored by Laurent Lecluse's avatar Laurent Lecluse
Browse files

annualisation wf & wip feuille de route

parent a5f1f337
Loading
Loading
Loading
Loading
Loading
+3 −34
Original line number Diff line number Diff line
@@ -6,39 +6,8 @@ echo $this->messenger()->addCurrentMessagesFromFlashMessenger();

echo $this->intervenant($intervenant);

$urlRefresh = $this->url('workflow/feuille-de-route-refresh', ['intervenant' => $intervenant->getId()]);

?>
    <hr/>
    <h2>Feuille de route
        <a href="<?= $urlRefresh ?>"
           id="feuille-de-route-refresh"
           class="pop-ajax"
           data-loading-title="Mise à jour de la feuille de route..."
           data-forced="true"
           data-submit-reload="true"
           style="font-size:12pt"
           title="Mettre à jour la feuille de route"
        >
            <i class="fas fa-arrows-rotate"></i>
        </a>
    </h2>
    <script>
        $(function () {
            $('#feuille-de-route-refresh').popAjax({
                error: (event, popAjax) => {
                    var errBtn = '<button onclick="window.location.reload();" type="button" class="btn btn-primary">J\'ai lu, recharger la page</button>';
echo '<hr />';

                    popAjax.setContent(popAjax.getContent() + errBtn);
                },
                change: function (event, popAjax) {
                    if (!popAjax.hasErrors()) {
                        window.location.reload();
$urlRefresh = $this->url('workflow/feuille-de-route-refresh', ['intervenant' => $intervenant->getId()]);

                    }
                }
            });
        });
    </script>
<?php
echo $this->feuilleDeRoute($intervenant)->render();
echo $this->vue('workflow/feuille-de-route', ['intervenant' => $intervenant->getId(), 'urlRefresh' => $urlRefresh]);
 No newline at end of file
+36 −3
Original line number Diff line number Diff line
@@ -6,8 +6,8 @@ use Application\Controller\AbstractController;
use Application\Service\Traits\ContextServiceAwareTrait;
use Intervenant\Entity\Db\Intervenant;
use UnicaenApp\Exception\LogicException;
use UnicaenApp\View\Model\MessengerViewModel;
use UnicaenTbl\Service\TableauBordServiceAwareTrait;
use UnicaenVue\View\Model\AxiosModel;
use Workflow\Service\WfEtapeDepServiceAwareTrait;
use Workflow\Service\WfEtapeServiceAwareTrait;
use Workflow\Service\WorkflowServiceAwareTrait;
@@ -23,7 +23,6 @@ class WorkflowController extends AbstractController
    use WfEtapeServiceAwareTrait;



    public function calculerToutAction()
    {
        $action = $this->params()->fromQuery('action') === '1';
@@ -43,6 +42,40 @@ class WorkflowController extends AbstractController



    public function feuilleDeRouteDataAction()
    {
        /** @var Intervenant $intervenant */
        $intervenant = $this->getEvent()->getParam('intervenant');

        $feuilleDeRoute = $this->getServiceWorkflow()->getFeuilleDeRoute($intervenant);

        $properties = [
            'code',
            'numero',
            'libelle',
            'url',
            'atteignable',
            'courante',
            'allowed',
            'realisationPourc',
            'objectif',
            'realisation',
            ['structures', [
                'libelle',
                'atteignable',
                'courante',
                'allowed',
                'realisationPourc',
                'objectif',
                'realisation',
            ]],
        ];

        return new AxiosModel(array_values($feuilleDeRoute->getEtapes()), $properties);
    }



    public function feuilleDeRouteRefreshAction()
    {
        /** @var Intervenant $intervenant */
@@ -60,7 +93,7 @@ class WorkflowController extends AbstractController
            }
        }

        return new MessengerViewModel();
        return $this->feuilleDeRouteDataAction();
    }


+205 −0
Original line number Diff line number Diff line
<?php

namespace Workflow\Model;

use Lieu\Entity\Db\Structure;
use Intervenant\Entity\Db\Intervenant;
use Workflow\Entity\Db\WorkflowEtape;
use Workflow\Service\WorkflowService;

class FeuilleDeRoute
{
    private WorkflowService $service;

    private Intervenant $intervenant;

    private ?Structure $structure = null;

    /**
     * @var array|WorkflowEtape[]
     */
    private array $workflowEtapes;

    /**
     * @var array|FeuilleDeRouteEtape[]
     */
    private array $fdr = [];

    private bool $builted = false;



    public function __construct(WorkflowService $service, Intervenant $intervenant, array $workflowEtapes)
    {
        $this->service        = $service;
        $this->intervenant    = $intervenant;
        $this->workflowEtapes = $workflowEtapes;
    }



    public function refresh(): void
    {
        $this->fdr     = [];
        $this->builted = false;
    }



    public function getStructure(): ?Structure
    {
        return $this->structure;
    }



    public function setStructure(?Structure $structure): FeuilleDeRoute
    {
        $this->structure = $structure;
        $this->refresh();

        return $this;
    }



    public function getIntervenant(): Intervenant
    {
        return $this->intervenant;
    }



    /**
     * Retourne la liste des étapes de la feuille de route
     *
     * @return array|FeuilleDeRouteEtape[]
     */
    public function getEtapes(): array
    {
        if (!$this->builted) {
            $this->build();
        }

        return $this->fdr;
    }



    public function get(string $etapeCode): ?FeuilleDeRouteEtape
    {
        if (!$this->builted) {
            $this->build();
        }

        if (array_key_exists($etapeCode, $this->fdrByName)) {
            return $this->fdr[$etapeCode];
        } else {
            return null;
        }
    }



    public function getCourante(): ?FeuilleDeRouteEtape
    {
        return null;
    }



    private function build(): void
    {
        $this->refresh();

        $sql       = "
        SELECT
          w.etape_code,
          w.structure_id,
          str.libelle_court structure_libelle,
          w.atteignable,
          w.objectif,
          w.partiel,
          w.realisation
        FROM
          tbl_workflow w
          JOIN workflow_etape we ON we.id = w.etape_id
          LEFT JOIN structure str ON str.id = w.structure_id        
        WHERE
          w.intervenant_id = :intervenant
        ORDER BY
          we.ordre
        ";
        $sqlParams = ['intervenant' => $this->intervenant->getId()];
        if ($this->structure) {
            $sql                    .= ' AND (w.structure_id = :structure OR w.structure_id IS NULL)';
            $sqlParams['structure'] = $this->structure->getId();
        }
        $stmt = $this->service->getBdd()->selectEach($sql, $sqlParams);

        while ($d = $stmt->next()) {
            mpg_lower($d);

            $etapeCode         = $d['etape_code'];
            $structureId       = (int)$d['structure_id'];
            $structureLiblelle = $d['structure_libelle'];
            $atteignable       = (bool)$d['atteignable'];
            $objectif          = (float)$d['objectif'];
            $partiel           = (float)$d['partiel'];
            $realisation       = (float)$d['realisation'];

            $etape = $this->workflowEtapes[$etapeCode];

            $this->buildEtape($etape, $structureId, $structureLiblelle, $atteignable, $objectif, $partiel, $realisation);
        }

        foreach ($this->fdr as $fdre) {
            if (count($fdre->structures) == 1) {
            //    $fdre->structures = []; // Pas de détail par structures s'il n'y en a qu'une
            }
        }

        $this->builted = true;
    }



    private function buildEtape(WorkflowEtape $etape, int $structureId, ?string $structureLibelle, bool $atteignable, float $objectif, float $partiel, float $realisation): void
    {
        $role        = $this->service->getServiceContext()->getSelectedIdentityRole();
        $intervenant = $this->service->getServiceContext()->getIntervenant();

        if (!array_key_exists($etape->getCode(), $this->fdr)) {
            $fdre                = new FeuilleDeRouteEtape($this, $this->service);
            $fdre->workflowEtape = $etape;
            $fdre->numero        = count($this->fdr) + 1;
            $fdre->libelle       = $etape->getLibelle($role);
            if ($intervenant && !$role) {
                $fdre->url = $this->service->getUrl($etape->getRouteIntervenant() ?: $etape->getRoute(), ['intervenant' => $this->getIntervenant()->getId()]);
            } else {
                $fdre->url = $this->service->getUrl($etape->getRoute(), ['intervenant' => $this->getIntervenant()->getId()]);
            }
            $fdre->atteignable = $atteignable;
            $fdre->objectif    = $objectif;
            $fdre->realisation = $realisation;

            $this->fdr[$etape->getCode()] = $fdre;
        } else {
            $fdre = $this->fdr[$etape->getCode()];
        }

        if ($structureId) {
            if (!$this->getStructure() || $this->getStructure()->getId() == $structureId) {
                $fdres                          = new FeuilleDeRouteEtape($this, $this->service);
                $fdres->workflowEtape           = $etape;
                $fdres->numero                  = count($fdre->structures) + 1;
                $fdres->libelle                 = $structureLibelle;
                $fdres->url                     = null;
                $fdres->atteignable             = $atteignable;
                $fdres->objectif                = $objectif;
                $fdres->realisation             = $realisation;
                $fdre->structures[$structureId] = $fdres;
            }
        }
    }
}
+63 −0
Original line number Diff line number Diff line
<?php

namespace Workflow\Model;


use Workflow\Entity\Db\WorkflowEtape;
use Workflow\Service\WorkflowService;

class FeuilleDeRouteEtape
{
    private WorkflowService $service;

    private FeuilleDeRoute $feuilleDeRoute;

    /**
     * @var array|FeuilleDeRouteEtape[]
     */
    public array $structures = [];

    public int           $numero;
    public WorkflowEtape $workflowEtape;
    public string        $libelle;
    public ?string       $url         = null;
    public bool          $atteignable = true;
    public float         $objectif    = 1.0;
    public float         $realisation = 0.0;



    public function __construct(FeuilleDeRoute $feuilleDeRoute, WorkflowService $service)
    {
        $this->feuilleDeRoute = $feuilleDeRoute;
        $this->service        = $service;
    }



    public function getRealisationPourc(): int
    {
        return round(($this->realisation / $this->objectif) * 100, 0);
    }



    public function getCode(): string
    {
        return $this->workflowEtape->getCode();
    }



    public function isCourante(): bool
    {
        return $this === $this->feuilleDeRoute->getCourante();
    }



    public function isAllowed(): bool
    {
        return true;
    }
}
 No newline at end of file
+74 −31
Original line number Diff line number Diff line
@@ -2,13 +2,15 @@

namespace Workflow\Service;

use Application\Entity\Db\Annee;
use Application\Provider\Tbl\TblProvider;
use Application\Service\AbstractService;
use Application\Service\Traits\ContextServiceAwareTrait;
use Traversable;
use Laminas\View\Helper\Url;
use Intervenant\Entity\Db\Intervenant;
use Lieu\Entity\Db\Structure;
use Service\Entity\Db\TypeVolumeHoraire;
use Unicaen\BddAdmin\BddAwareTrait;
use UnicaenApp\Service\EntityManagerAwareTrait;
use UnicaenAuthentification\Service\Traits\AuthorizeServiceAwareTrait;
use UnicaenTbl\Service\TableauBordServiceAwareTrait;
@@ -16,6 +18,7 @@ use Workflow\Entity\Db\TblWorkflow;
use Workflow\Entity\Db\WfEtape;
use Workflow\Entity\Db\WorkflowEtape;
use Workflow\Entity\Db\WorkflowEtapeDependance;
use Workflow\Model\FeuilleDeRoute;

/**
 * Description of WorkflowService
@@ -30,42 +33,64 @@ class WorkflowService extends AbstractService
    use EntityManagerAwareTrait;
    use AuthorizeServiceAwareTrait;
    use TableauBordServiceAwareTrait;
    use BddAwareTrait;

    private Url $urlManager;

    /**
     * @var array Feuilles de route
     * @var array|FeuilleDeRoute[]
     */
    private array $feuillesDeRoute = [];

    /** @var array|WorkflowEtape[] */
    private array $workflowEtapes = [];



    public function __construct(Url $urlManager)
    {
        $this->urlManager = $urlManager;
    }



    /**
     * @return array|WorkflowEtape[]
     */
    public function getEtapes(): array
    {
        $anneeId = $this->getServiceContext()->getAnnee()->getId();

        if (empty($this->workflowEtapes)) {
            $this->workflowEtapes = [];

            $dql = "
            SELECT 
                we, d, wep, weperimetre
                we, partial a.{id}, d, wep, weperimetre
            FROM 
                " . WorkflowEtape::class . " we
                LEFT JOIN we.dependances d
                JOIN we.annee a
                LEFT JOIN we.dependances d WITH d.histoDestruction IS NULL
                LEFT JOIN d.etapePrecedante wep
                LEFT JOIN we.perimetre weperimetre
            WHERE
                a.id = :annee
                AND we.histoDestruction IS NULL
            ORDER BY 
                we.ordre, wep.ordre";

            $query = $this->getEntityManager()->createQuery($dql);
            $query->setParameter('annee', $anneeId);
            $query->enableResultCache(true);
            $query->setResultCacheId(self::ETAPES_CACHE_ID);
            $query->setResultCacheId(self::ETAPES_CACHE_ID.'_'.$anneeId);

            /** @var WorkflowEtape[] $iterable */
            $iterable = $query->getResult();
            foreach ($iterable as $we) {
                if ($we->getAnnee()->getId() == $anneeId) {
                    $this->workflowEtapes[$we->getCode()] = $we;
                }
            }

            $dataFile = require getcwd() . '/data/workflow_etapes.php';
            foreach ($dataFile as $weCode => $weData) {
@@ -87,7 +112,11 @@ class WorkflowService extends AbstractService
        $em = $this->getEntityManager();

        $cache = $em->getConfiguration()->getResultCache();
        $cache->deleteItem(self::ETAPES_CACHE_ID);
        $items = [];
        for( $a=2010;$a<=Annee::MAX;$a++){
            $items[] = self::ETAPES_CACHE_ID.'_'.$a;
        }
        $cache->deleteItems($items);
        $this->workflowEtapes = [];

        return $this;
@@ -127,9 +156,9 @@ class WorkflowService extends AbstractService
            $etape = $etapes[$code];
            $etape->setOrdre($order);
            $em->persist($etape);
            $em->flush($etape);
            $order++;
        }
        $em->flush();
        $this->clearEtapesCache();

        return $this;
@@ -195,6 +224,39 @@ class WorkflowService extends AbstractService



    public function getFeuilleDeRoute(Intervenant $intervenant, ?Structure $structure = null): FeuilleDeRoute
    {
        // Si la feuille de route n'existe pas, on la crée
        if (!array_key_exists($intervenant->getId(), $this->feuillesDeRoute)) {
            $this->feuillesDeRoute[$intervenant->getId()] =
                new FeuilleDeRoute($this, $intervenant, $this->getEtapes());
        }

        // On lui injecte la structure au besoin
        if (!$structure) {
            // Si la structure n'est pas précisée, alors on utilise la structure du contexte
            $structure = $this->getServiceContext()->getStructure();
        }
        $this->feuillesDeRoute[$intervenant->getId()]->setStructure($structure);

        return $this->feuillesDeRoute[$intervenant->getId()];
    }



    public function refreshFeuilleDeRoute(Intervenant|int $intervenant): void
    {
        if ($intervenant instanceof Intervenant) {
            $intervenant = $intervenant->getId();
        }

        if (array_key_exists($intervenant, $this->feuillesDeRoute)) {
            $this->feuillesDeRoute[$intervenant]->refresh();
        }
    }



    /**
     * @param WfEtapeService|WorkflowEtape|TblWorkflow|string $etape
     * @param Intervenant|null                                $intervenant
@@ -291,7 +353,7 @@ class WorkflowService extends AbstractService
     *
     * @return WorkflowEtape[]
     */
    public function getFeuilleDeRoute(?Intervenant $intervenant = null, ?Structure $structure = null)
    public function getFeuilleDeRouteOld(?Intervenant $intervenant = null, ?Structure $structure = null)
    {
        return null;
        if (!$intervenant || !$structure) {
@@ -392,10 +454,6 @@ class WorkflowService extends AbstractService



    /**
     * @param array|string    $tableauxBords
     * @param Intervenant|int $intervenant
     */
    public function calculerTableauxBord(array|string|null $tableauxBords, Intervenant|int $intervenant): array
    {
        $errors = [];
@@ -439,7 +497,7 @@ class WorkflowService extends AbstractService

        foreach ($deps as $dep => $null) {
            if (isset($tbls[$dep])) {
                if ($intervenant instanceof \Intervenant\Entity\Db\Intervenant) {
                if ($intervenant instanceof Intervenant) {
                    $value = $intervenant->getId();
                } else {
                    $value = $intervenant;
@@ -507,24 +565,9 @@ class WorkflowService extends AbstractService



    /**
     * Generates a url given the name of a route.
     *
     * @param string            $name               Name of the route
     * @param array             $params             Parameters for the link
     * @param array|Traversable $options            Options for the route
     * @param bool              $reuseMatchedParams Whether to reuse matched parameters
     *
     * @return string Url                         For the link href attribute
     * @see    \Laminas\Mvc\Router\RouteInterface::assemble()
     *
     */
    protected function getUrl($name = null, $params = [], $options = [], $reuseMatchedParams = false)
    public function getUrl(?string $name = null, array $params = [], array $options = [], bool $reuseMatchedParams = false): string
    {
        $url = \AppAdmin::container()->get('ViewHelperManager')->get('url');

        /* @var $url \Laminas\View\Helper\Url */
        return $url->__invoke($name, $params, $options, $reuseMatchedParams);
        return $this->urlManager->__invoke($name, $params, $options, $reuseMatchedParams);
    }


Loading