Skip to content
Snippets Groups Projects
Commit 9ece59eb authored by Jean-Philippe Metivier's avatar Jean-Philippe Metivier
Browse files

Creation de l'index pour les gestionnaires de domaines

parent 13ea4341
No related branches found
No related tags found
No related merge requests found
# Version 1.3.0 (XX/XX/2025)
# Version 1.3.0 (XX/06/2025)
## Changements
......@@ -15,6 +15,7 @@
* Possibilité de notifier les abonné·es depuis l'action de formation.
* Possibilité d'ajouter des référents sur une action de formation.
* Ajout d'un avertissement si un agent (nécessitant un valideur) n'a pas de valideur sur la liste des inscrits.
* Ajout de la notion de Gestionnaires de domaine qui on un périmètres d'action limiter aux domaines dont ils sont responsables.
## Modification de la configuration
......
......@@ -15,6 +15,7 @@ use Application\Service\Url\UrlServiceAwareTrait;
use DemandeExterne\Provider\Etat\DemandeExterneEtats;
use Formation\Provider\Etat\SessionEtats;
use Formation\Provider\Role\FormationRoles;
use Formation\Service\Domaine\DomaineServiceAwareTrait;
use Formation\Service\Session\SessionServiceAwareTrait;
use Formation\Service\StagiaireExterne\StagiaireExterneServiceAwareTrait;
use Laminas\Http\Response;
......@@ -32,6 +33,7 @@ class IndexController extends AbstractActionController
{
use AgentServiceAwareTrait;
use DemandeExterneServiceAwareTrait;
use DomaineServiceAwareTrait;
use EtatTypeServiceAwareTrait;
use MacroServiceAwareTrait;
use ParametreServiceAwareTrait;
......@@ -51,9 +53,11 @@ class IndexController extends AbstractActionController
if ($connectedRole) {
switch ($connectedRole->getRoleId()) {
case FormationRoles::GESTIONNAIRE_FORMATION :
case FormationRoles::GESTIONNAIRE_SPECIFIQUE :
/** @see IndexController::indexGestionnaireAction() */
return $this->redirect()->toRoute('index-gestionnaire', [], [], true);
case FormationRoles::GESTIONNAIRE_SPECIFIQUE :
/** @see IndexController::indexGestionnaireSpecifiqueAction() */
return $this->redirect()->toRoute('index-gestionnaire-specifique', [], [], true);
case FormationRoles::RESPONSABLE_FORMATION :
/** @see IndexController::indexResponsableAction() */
return $this->redirect()->toRoute('index-responsable', [], [], true);
......@@ -129,6 +133,33 @@ class IndexController extends AbstractActionController
]);
}
public function indexGestionnaireSpecifiqueAction(): ViewModel
{
$user = $this->getUserService()->getConnectedUser();
$role = $this->getUserService()->getConnectedRole();
$annee = (new DateTime())->format('Y');
$domaines = $this->getDomaineService()->getDomainesByGestionnaire($user);
$sessions = $this->getSessionService()->getSessionsByDomaines($domaines, $annee);
$etatsTypesSession = $this->getEtatTypeService()->getEtatsTypesByCategorieCode(SessionEtats::TYPE);
$dictionnaireSession = [];
foreach ($etatsTypesSession as $type) $dictionnaireSession[$type->getCode()] = [];
foreach ($sessions as $session) $dictionnaireSession[$session->getEtatActif()->getType()->getCode()][] = $session;
return new ViewModel([
'user' => $user,
'role' => $role,
'domaines' => $domaines,
'etatsTypesSession' => $etatsTypesSession,
'dictionnaireSession' => $dictionnaireSession,
]);
}
public function indexResponsableAction(): ViewModel
{
$user = $this->getUserService()->getConnectedUser();
......
......@@ -8,6 +8,7 @@ use Application\Service\Macro\MacroService;
use Application\Service\Url\UrlService;
use Formation\Service\Session\SessionService;
use Formation\Service\StagiaireExterne\StagiaireExterneService;
use Formation\Service\Domaine\DomaineService;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
use Psr\Container\NotFoundExceptionInterface;
......@@ -30,6 +31,7 @@ class IndexControllerFactory
/**
* @var AgentService $agentService
* @var DemandeExterneService $demandeExterneService
* @var DomaineService $domaineService
* @var EtatTypeService $etatTypeService
* @var MacroService $macroService
* @var ParametreService $parametreService
......@@ -41,6 +43,7 @@ class IndexControllerFactory
*/
$agentService = $container->get(AgentService::class);
$demandeExterneService = $container->get(DemandeExterneService::class);
$domaineService = $container->get(DomaineService::class);
$etatTypeService = $container->get(EtatTypeService::class);
$macroService = $container->get(MacroService::class);
$parametreService = $container->get(ParametreService::class);
......@@ -53,6 +56,7 @@ class IndexControllerFactory
$controller = new IndexController();
$controller->setAgentService($agentService);
$controller->setDemandeExterneService($demandeExterneService);
$controller->setDomaineService($domaineService);
$controller->setEtatTypeService($etatTypeService);
$controller->setMacroService($macroService);
$controller->setParametreService($parametreService);
......
<?php
/**
* @see \Application\Controller\IndexController::indexGestionnaireSpecifiqueAction()
* @var User $user
* @var Role $role
* @var Domaine[] $domaines
* @var EtatType[] $etatsTypesSession
* @var Session[][] $dictionnaireSession
*/
use Formation\Entity\Db\Domaine;
use Formation\Entity\Db\Session;
use Formation\Provider\Privilege\FormationdomainePrivileges;
use UnicaenEtat\Entity\Db\EtatType;
use UnicaenUtilisateur\Entity\Db\Role;
use UnicaenUtilisateur\Entity\Db\User;
$this->headTitle("Index de gestion de vos sessions de formation ");
$sessionsEnGestion = 0;
foreach ($dictionnaireSession as $etatCode => $sessions) {
$sessionsEnGestion += count($sessions);
}
?>
<h1 class="page-header">
Index de gestion de vos sessions de formation
</h1>
<h2> Domaines dont vous êtes gestionnaires</h2>
<?php if (empty($domaines)) : ?>
<em>Vous n'avez pas de domaine en gestion.</em>
<?php else : ?>
<table class="datatable table table-condensed" id="domaines">
<thead>
<tr>
<th>Domaines</th>
<th>#Action</th>
<th class="action">Action</th>
</tr>
</thead>
<tbody>
<?php foreach ($domaines as $domaine): ?>
<tr>
<td>
<?php echo $domaine->getLibelle(); ?>
</td>
<td>
<?php echo count($domaine->getFormations()); ?>
</td>
<td class="action">
<?php if ($this->isAllowed($domaine, FormationdomainePrivileges::FORMATIONDOMAINE_AFFICHER)) : ?>
<?php /** @see \Formation\Controller\DomaineController::afficherAction() */ ?>
<a href="<?php echo $this->url('formation-domaine/afficher', ['domaine' => $domaine->getId()], [], true); ?>"
class="action secondary">
<span class="icon icon-voir"></span>
Afficher
</a>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
<div id="interne" class="tab-pane">
<h2> Sessions dont vous êtes gestionnaire
<span class="badge"><?php echo $sessionsEnGestion; ?></span>
</h2>
<div class="card">
<div class="card-header">
Formations au plan de formation dont vous êtes gestionnaire
</div>
<div class="card-body">
<div class="repartition">
<?php foreach ($dictionnaireSession as $etatCode => $sessions) : ?>
<a href="#<?php echo $etatCode; ?>" class="raccourci">
<span class="raccourci">
<?php echo $this->etattype($etatsTypesSession[$etatCode], ['display-categorie' => false]); ?>
<?php //echo $etatsTypesSession[$etatCode]->getLibelle(); ?>
<?php echo count($sessions); ?> session·s
</span>
</a>
<?php endforeach; ?>
</div>
</div>
</div>
<?php foreach ($dictionnaireSession as $etatCode => $sessions) : ?>
<?php if (!empty($sessions)) : ?>
<div class="card" id="<?php echo $etatCode; ?>">
<div class="card-header bg-default togglable">
<?php echo $this->etattype($etatsTypesSession[$etatCode], ['display-categorie' => false]); ?>
<?php echo count($sessions); ?> session·s à l'état
[<?php echo $etatsTypesSession[$etatCode]->getLibelle(); ?>]
</div>
<?php if (count($sessions) > 0) : ?>
<div class="card-body">
<?php echo $this->formationInstanceArray($sessions, ['id' => $etatCode, 'affichage' => ['gestionnaires' => false]]); ?>
</div>
<?php endif; ?>
</div>
<?php endif; ?>
<?php endforeach; ?>
</div>
<style>
div.repartition {
display: flex;
justify-content: space-between; /* Écarte uniformément les spans */
width: 100%;
}
a.raccourci {
text-decoration: none;
color: black
}
a.raccourci > span {
border: 1px solid black;
padding: 0.25rem 0.5rem;
display: inline-block;
border-radius: 0.25rem;
}
span.raccourci:hover {
cursor: pointer;
background: var(--unistrap-color-light);
}
</style>
<script>
$('.card-header.togglable').on("click", function () {
$(this).next().toggle();
});
$(function () {
let hash = $(location).attr('hash');
let name = hash.substring(1);
if (name === undefined || name === "") name = "interne";
$('button').removeClass('active');
$('button#' + name + '-tab').addClass('active');
$('div.tab-pane').hide().removeClass('active');
$('div#' + name).show().addClass('active');
//$('#' + name + '-tab').tab("show");
$('button.nav-link').on('click', function (e) {
let anchor = $(this).attr('aria-controls');
$('div.tab-pane').hide().removeClass('active');
$('div#' + anchor).show().addClass('active');
$('button').removeClass('active');
$('button#' + anchor + '-tab').addClass('active');
// console.log(anchor);
e.preventDefault(); // >> bloque le scrolling, mais aussi la ré-écriture de l'url "#info" ...
history.replaceState(null, null, "#" + anchor);
});
$('table#domaines').dataTable({
paging: false,
autoWidth: false,
order: [[1, 'asc']],
"language": {
"url": "/js/datatables_fr.json",
},
});
});
</script>
\ No newline at end of file
......@@ -151,6 +151,14 @@ return [
],
'roles' => [
FormationRoles::GESTIONNAIRE_FORMATION,
],
],
[
'controller' => IndexController::class,
'action' => [
'index-gestionnaire-specifique',
],
'roles' => [
FormationRoles::GESTIONNAIRE_SPECIFIQUE,
],
],
......@@ -230,6 +238,18 @@ return [
],
'may_terminate' => true,
],
'index-gestionnaire-specifique' => [
'type' => Literal::class,
'options' => [
'route' => '/index-gestionnaire-specifique',
'defaults' => [
/** @see IndexController::indexGestionnaireSpecifiqueAction() **/
'controller' => IndexController::class,
'action' => 'index-gestionnaire-specifique',
],
],
'may_terminate' => true,
],
'index-responsable' => [
'type' => Literal::class,
'options' => [
......
......@@ -9,6 +9,7 @@ use Formation\Entity\Db\Domaine;
use Laminas\Mvc\Controller\AbstractActionController;
use RuntimeException;
use UnicaenUtilisateur\Entity\Db\AbstractUser;
use UnicaenUtilisateur\Entity\Db\UserInterface;
class DomaineService
{
......@@ -183,6 +184,20 @@ class DomaineService
return $result;
}
/**
* @return Domaine[]
*/
public function getDomainesByGestionnaire(UserInterface $user): array
{
$qb = $this->getObjectManager()->getRepository(Domaine::class)->createQueryBuilder('domaine')
->leftJoin('domaine.gestionnaires', 'gestionnaire')->addSelect('gestionnaire')
->andWhere('gestionnaire.id = :user')->setParameter('user', $user->getId())
;
$result = $qb->getQuery()->getResult();
return $result;
}
/** Facade ********************************************************************************************************/
public function createDomaine(string $domaineLibelle): ?Domaine
......@@ -195,4 +210,5 @@ class DomaineService
}
}
\ No newline at end of file
......@@ -10,6 +10,7 @@ use DemandeExterne\Entity\Db\DemandeExterne;
use Doctrine\ORM\NonUniqueResultException;
use Doctrine\ORM\QueryBuilder;
use DoctrineModule\Persistence\ProvidesObjectManager;
use Formation\Entity\Db\Domaine;
use Formation\Entity\Db\Formateur;
use Formation\Entity\Db\Formation;
use Formation\Entity\Db\Session;
......@@ -314,6 +315,30 @@ class SessionService
return $result;
}
/** @return Session[] */
public function getSessionsByDomaines(array $domaines, ?int $annee = null): array
{
$domainesId = array_map(function (Domaine $domaine) {return $domaine->getId();}, $domaines);
$qb = $this->createQueryBuilder()
->addSelect('domaine')->join('formation.domaines', 'domaine')
->andWhere('domaine.id in (:domainesId)')->setParameter('domainesId', $domainesId);
;
$result = $qb->getQuery()->getResult();
$sessions = [];
if ($annee !== null) {
foreach ($result as $session) {
if (($session->getDebut() AND $session->getDebut(true)->format('Y') >= $annee)
OR
($session->getFin() AND $session->getFin(true)->format('Y') >= $annee)) {
$sessions[] = $session;
}
}
}
return $sessions;
}
/** FACADE *******************************************************************************************************/
public function createSession(Formation $formation): Session
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment