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

Notification des listes

parent 3713e31c
No related branches found
No related tags found
No related merge requests found
Showing
with 283 additions and 1 deletion
-- Nouveaux Templates ---------------------------------------------------------
INSERT INTO unicaen_renderer_template (code, description, document_type, document_sujet, document_corps, document_css, namespace) VALUES ('FORMATION_SESSION_RAPPEL_DEMANDE_VALIDATION', '<p>Courrier de rappel de la demande de validation d''une inscription à une formation du plan de formation</p>', 'mail', 'RAPPEL Vous n''avez pas encore validé la demande de formation de VAR[AGENT#Denomination]', e'<p>Bonjour,</p>
<p>Vous n\'avez pas encore validé la demande de formation de VAR[AGENT#Denomination] pour la session VAR[SESSION#libelle] du VAR[SESSION#periode].<br>Veuillez vous rendre dans votre tableau de bord en tant que Valideur·euse sur l\'application VAR[Macro#AppName] (VAR[Url#AppLink]) afin de statuer sur cette demande.</p>
<p>Bonne journée,<br>L\'application VAR[Macro#AppName]</p>', null, 'Formation\Provider\Template');
INSERT INTO unicaen_renderer_template (code, description, document_type, document_sujet, document_corps, document_css, namespace) VALUES ('FORMATION_EMARGEMENT', '<p>Feuille d''émargement</p>', 'pdf', 'Emargement_Session_VAR[SESSION#id].pdf', e'<h2 style="text-align: center;">Feuille d\'émargement</h2>
<p><strong>Atelier</strong><br>Libellé : VAR[SESSION#libelle]<br>Période : VAR[SESSION#periode]</p>
<p><br><strong>Formateur·trices<br></strong>VAR[SESSION#FormateursAvecSignature]</p>
<p><strong>Séance</strong><br>Lieu : VAR[SEANCE#lieu]<br>Date : VAR[SEANCE#periode]</p>
<p><br><strong>Liste des inscrit·es<br></strong>VAR[SESSION#InscritsAvecSignature]</p>', 'table.bordered { border-collapse: collapse; } table.bordered td { border: 1px solid black; } table.bordered th { border: 1px solid black; }', 'Formation\Provider\Template');
-- Nouvelles Macros -----------------------------------------------------------
INSERT INTO unicaen_renderer_macro (code, description, variable_name, methode_name) VALUES ('SESSION#InscritsAvecSignature', '<p>Retourne un tableau des inscrits de la liste principale avec une case pour leur signature</p>', 'session', 'getArrayListePrincipales');
INSERT INTO unicaen_renderer_macro (code, description, variable_name, methode_name) VALUES ('SESSION#FormateursAvecSignature', '<p>Fournit un tableau listant les formateurs avec un case pour la signature</p>', 'session', 'getArrayFormateurs');
INSERT INTO unicaen_renderer_macro (code, description, variable_name, methode_name) VALUES ('SEANCE#periode', '<p>Retourne la période au format DD/MM/YYYY H:m au DD/MM/YYYY H:m</p>', 'seance', 'getPeriode');
INSERT INTO unicaen_renderer_macro (code, description, variable_name, methode_name) VALUES ('SEANCE#lieu', '<p>Retourne le lieu de la séance "Batiment Salle - Campus Ville"</p>', 'seance', 'toStringLieu');
......@@ -13,6 +13,10 @@ use Formation\Form\Annulation\AnnulationForm;
use Formation\Form\Annulation\AnnulationFormFactory;
use Formation\Form\Annulation\AnnulationHydrator;
use Formation\Form\Annulation\AnnulationHydratorFactory;
use Formation\Form\Notification\NotificationForm;
use Formation\Form\Notification\NotificationFormFactory;
use Formation\Form\Notification\NotificationHydrator;
use Formation\Form\Notification\NotificationHydratorFactory;
use Formation\Form\Session\SessionForm;
use Formation\Form\Session\SessionFormFactory;
use Formation\Form\Session\SessionHydrator;
......@@ -112,6 +116,7 @@ return [
'changer-etat',
'notifier-responsable-pour-validation',
'notifier-inscrit',
],
'privileges' => [
FormationinstancePrivileges::FORMATIONINSTANCE_GERER_INSCRIPTION,
......@@ -396,6 +401,16 @@ return [
],
],
],
'notifier-inscrit' => [
'type' => Segment::class,
'options' => [
'route' => '/notifier-inscrit/:session',
'defaults' => [
/** @see SessionController::notifierInscritAction() */
'action' => 'notifier-inscrit',
],
],
],
/** gestion des formateurs ************************************************/
'ajouter-formateur' => [
'type' => Segment::class,
......@@ -498,12 +513,14 @@ return [
'factories' => [
AnnulationForm::class => AnnulationFormFactory::class,
SessionForm::class => SessionFormFactory::class,
NotificationForm::class => NotificationFormFactory::class,
],
],
'hydrators' => [
'factories' => [
AnnulationHydrator::class => AnnulationHydratorFactory::class,
SessionHydrator::class => SessionHydratorFactory::class,
NotificationHydrator::class => NotificationHydratorFactory::class,
],
],
'view_helpers' => [
......
......@@ -5,6 +5,7 @@ namespace Formation\Controller;
use DateTime;
use Formation\Entity\Db\Inscription;
use Formation\Form\Annulation\AnnulationFormAwareTrait;
use Formation\Form\Notification\NotificationFormAwareTrait;
use Formation\Form\SelectionFormateur\SelectionFormateurFormAwareTrait;
use Formation\Form\SelectionGestionnaire\SelectionGestionnaireFormAwareTrait;
use Formation\Form\Session\SessionFormAwareTrait;
......@@ -55,6 +56,7 @@ class SessionController extends AbstractActionController
use UserServiceAwareTrait;
use AnnulationFormAwareTrait;
use NotificationFormAwareTrait;
use SelectionFormateurFormAwareTrait;
use SelectionGestionnaireFormAwareTrait;
use SessionFormAwareTrait;
......@@ -609,6 +611,66 @@ class SessionController extends AbstractActionController
return $vm;
}
public function notifierInscritAction(): ViewModel
{
$session = $this->getSessionService()->getRequestedSession($this);
$form = $this->getNotificationForm();
$form->setAttribute('action', $this->url()->fromRoute('session/notifier-inscrit', ['session' => $session->getId()], [], true));
$form->bind($session);
$request = $this->getRequest();
if ($request->isPost()) {
$data = $request->getPost();
$form->setData($data);
if ($form->isValid()) {
$inscriptions = match ($data['liste']) {
Inscription::PRINCIPALE => $session->getListePrincipale(),
Inscription::COMPLEMENTAIRE => $session->getListeComplementaire(),
'tous' => $session->getListeValide(),
default => [],
};
$sujet = trim($data['sujet']);
$corps = trim($data['corps']);
foreach ($inscriptions as $inscription) {
$adresse = $inscription->getIndividu()->getEmail();
$mails[$inscription->getIndividu()->getDenomination()] = ($adresse)?$this->getNotificationService()->getMailService()->sendMail($adresse, $sujet, $corps,'Formation'):null;
}
$success = []; $probleme = [];
foreach ($mails as $individu => $mail) {
if ($mail === null) $probleme[] = $individu; else $success[] = $individu;
}
if (!empty($success)) {
$successTexte = " Les stagiaires ont été notifié·es (".count($success)." courrier·s envoyé·s).";
}
if (!empty($probleme)) {
$problemeTexte = "L'opération n'a pas pu être faite pour les inscriptions de : <ul>";
foreach ($probleme as $individu) $problemeTexte .= "<li>" . $individu . "</li>";
$problemeTexte .= "</ul>";
}
$vm = new ViewModel([
'title' => "Notification des inscrits",
'reponse' => "Opération effectuée",
'success' => $successTexte??null,
'error' => $problemeTexte??null,
]);
$vm->setTemplate('default/reponse');
return $vm;
}
}
$vm = new ViewModel([
'title' => "Notification des inscrits",
'form' => $form,
]);
$vm->setTemplate('default/default-form');
return $vm;
}
public function resultatEnqueteAction(): ViewModel
{
$session = $this->getSessionService()->getRequestedSession($this);
......
......@@ -3,6 +3,7 @@
namespace Formation\Controller;
use Formation\Form\Annulation\AnnulationForm;
use Formation\Form\Notification\NotificationForm;
use Formation\Form\SelectionFormateur\SelectionFormateurForm;
use Formation\Form\SelectionGestionnaire\SelectionGestionnaireForm;
use Formation\Form\Session\SessionForm;
......@@ -68,11 +69,13 @@ class SessionControllerFactory
/**
* @var AnnulationForm $annulationForm
* @var NotificationForm $notificationForm
* @var SelectionFormateurForm $selectionFormateurForm
* @var SelectionGestionnaireForm $selectionGestionnaireForm
* @var SessionForm $sessionForm
*/
$annulationForm = $container->get('FormElementManager')->get(AnnulationForm::class);
$notificationForm = $container->get('FormElementManager')->get(NotificationForm::class);
$sessionForm = $container->get('FormElementManager')->get(SessionForm::class);
$selectionFormateurForm = $container->get('FormElementManager')->get(SelectionFormateurForm::class);
$selectionGestionnaireForm = $container->get('FormElementManager')->get(SelectionGestionnaireForm::class);
......@@ -94,6 +97,7 @@ class SessionControllerFactory
$controller->setSessionService($sessionService);
$controller->setUserService($userService);
$controller->setAnnulationForm($annulationForm);
$controller->setNotificationForm($notificationForm);
$controller->setSessionForm($sessionForm);
$controller->setSelectionFormateurForm($selectionFormateurForm);
$controller->setSelectionGestionnaireForm($selectionGestionnaireForm);
......
......@@ -418,6 +418,21 @@ class Session implements
return $array;
}
/**
* @return Inscription[]
*/
public function getListeValide(): array
{
$array = array_filter($this->inscriptions->toArray(), function (Inscription $a) {
return ($a->estNonHistorise()
AND !$a->isEtatActif(InscriptionEtats::ETAT_DESISTEMENT));
});
usort($array, function (Inscription $a, Inscription $b) {
return $a->getStagiaireDenomination() <=> $b->getStagiaireDenomination();
});
return $array;
}
/**
* @return Inscription[]
*/
......
<?php
namespace Formation\Form\Notification;
use Formation\Entity\Db\Inscription;
use Laminas\Form\Element\Button;
use Laminas\Form\Element\Select;
use Laminas\Form\Element\Text;
use Laminas\Form\Element\Textarea;
use Laminas\Form\Form;
use Laminas\InputFilter\Factory;
class NotificationForm extends Form {
public function init(): void
{
// liste
$this->add([
'type' => Select::class,
'name' => 'liste',
'options' => [
'label' => "Liste à notifier <span class='icon icon-obligatoire' title='Obligatoire'></span> :",
'label_options' => [
'disable_html_escape' => true,
],
'empty_option' => "Sélectionner une liste d'inscrit·e ...",
'value_options' => [
Inscription::PRINCIPALE => 'Liste principale',
Inscription::COMPLEMENTAIRE => 'Liste complémentaire',
'tous' => 'Tou·tes les inscrit·es',
],
],
'attributes' => [
'id' => 'liste',
'class' => 'bootstrap-selectpicker show-tick',
'data-live-search' => 'true',
],
]);
// libelle
$this->add([
'type' => Text::class,
'name' => 'sujet',
'options' => [
'label' => "Sujet du courrier <span class='icon icon-obligatoire' title='Champ obligatoire'></span>:",
'label_options' => [ 'disable_html_escape' => true, ],
],
'attributes' => [
'id' => 'sujet',
],
]);
// corps
$this->add([
'name' => 'corps',
'type' => Textarea::class,
'options' => [
'label' => "Corps du courrier <span class='icon icon-obligatoire' title='Champ obligatoire'></span>:",
'label_options' => [ 'disable_html_escape' => true, ],
],
'attributes' => [
'id' => 'corps',
'class' => 'tinymce',
],
]);
//bouton
$this->add([
'type' => Button::class,
'name' => 'creer',
'options' => [
'label' => '<span class="icon icon-notifier"></span> Notifier ',
'label_options' => [
'disable_html_escape' => true,
],
],
'attributes' => [
'type' => 'submit',
'class' => 'btn btn-success',
],
]);
//input filter
$this->setInputFilter((new Factory())->createInputFilter([
'liste' => ['required' => true,],
'sujet' => ['required' => true,],
'corps' => ['required' => true,],
]));
}
}
\ No newline at end of file
<?php
namespace Formation\Form\Notification;
trait NotificationFormAwareTrait
{
private NotificationForm $notificationForm;
public function getNotificationForm(): NotificationForm
{
return $this->notificationForm;
}
public function setNotificationForm(NotificationForm $notificationForm): void
{
$this->notificationForm = $notificationForm;
}
}
\ No newline at end of file
<?php
namespace Formation\Form\Notification;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
use Psr\Container\NotFoundExceptionInterface;
class NotificationFormFactory
{
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function __invoke(ContainerInterface $container): NotificationForm
{
$hydrator = $container->get('HydratorManager')->get(NotificationHydrator::class);
$form = new NotificationForm();
$form->setHydrator($hydrator);
return $form;
}
}
\ No newline at end of file
<?php
namespace Formation\Form\Notification;
use Laminas\Hydrator\HydratorInterface;
class NotificationHydrator implements HydratorInterface
{
public function extract(object $object): array
{
return [];
}
public function hydrate(array $data, object $object): object
{
return $object;
}
}
\ No newline at end of file
<?php
namespace Formation\Form\Notification;
use Psr\Container\ContainerInterface;
class NotificationHydratorFactory
{
public function __invoke(ContainerInterface $container): NotificationHydrator
{
$hydrator = new NotificationHydrator();
return $hydrator;
}
}
\ No newline at end of file
......@@ -35,6 +35,7 @@ $canSupprimerInscription = $this->isAllowed(FormationinstancePrivileges::getReso
$urlRetour = $this->url('session/afficher', ['session' => $instance->getId()], ['fragment' => 'inscriptions'], true);
$canNotifierValideur = $this->isAllowed(FormationinstancePrivileges::getResourceId(FormationinstancePrivileges::FORMATIONINSTANCE_GERER_INSCRIPTION));
$canNotifierInscrit = $this->isAllowed(FormationinstancePrivileges::getResourceId(FormationinstancePrivileges::FORMATIONINSTANCE_GERER_INSCRIPTION));
$liste = $instance->getListeDisponible();
$principaleComplete = $instance->isListePrincipaleComplete();
......@@ -46,11 +47,18 @@ $inscriptions = $instance->getInscriptions()
<?php /** @see \Formation\Controller\SessionController::notifierResponsablePourValidationAction() */ ?>
<a href="<?php echo $this->url('session/notifier-responsable-pour-validation', ['session' => $instance->getId()], []); ?>"
class="btn btn-primary ajax-modal" data-event="modification"
class="btn btn-primary ajax-modal"
>
<span class="icon icon-notifier"></span>
Rappel de la demande de validation aux valideur·euses
</a>
<?php /** @see \Formation\Controller\SessionController::notifierInscritAction() */ ?>
<a href="<?php echo $this->url('session/notifier-inscrit', ['session' => $instance->getId()], []); ?>"
class="btn btn-primary ajax-modal"
>
<span class="icon icon-notifier"></span>
Notifier les inscrit·es
</a>
<div class="row">
<div class="col-md-6">
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment