Commit 8b4107eb authored by Jean-Philippe Metivier's avatar Jean-Philippe Metivier
Browse files

Importation/Complétion d'un plan de formation depuis un CSV

parent ff9f3a2a
Loading
Loading
Loading
Loading
+1 −1
Changes for documentation/release/3.2.5.md: 1 added line, 1 removed line.
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@ Modification en BD

```postgresql
-- nouveau template 
INSERT INTO public.unicaen_renderer_template (code, description, document_type, document_sujet, document_corps, document_css, namespace) 
INSERT INTO unicaen_renderer_template (code, description, document_type, document_sujet, document_corps, document_css, namespace) 
VALUES (
'ENTRETIEN_VALIDATION_4-AGENT', null, 'mail', 
'VAR[AGENT#Denomination] vient de valider son entretien professionnel', 
+70 −0
Changes for documentation/release/4.1.2.md: 70 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -4,6 +4,8 @@ Version 4.X.X (XX/11/2023)
Évolution
---
- Mes Formations : Axe comme élément de chapeau des groupes
- Mes Formations : Domaine de formation
- Importation/Complétion d'un plan de formation depuis un CSV

Modification en BD
---
@@ -38,6 +40,74 @@ alter table formation_groupe
    add constraint formation_groupe_formation_axe_id_fk
        foreign key (axe_id) references formation_axe on delete set null;

-- Nouvelle table pour les domaines de formation
create table formation_domaine
(
    id                    serial
        constraint formation_domaine_pk
            primary key,
    libelle               varchar(1024)           not null,
    description           text,
    ordre                 integer   default 9999  not null,
    histo_creation        timestamp default now() not null,
    histo_createur_id     integer   default 0     not null
        constraint formation_domaine_unicaen_utilisateur_user_id_fk
            references unicaen_utilisateur_user,
    histo_modification    timestamp,
    histo_modificateur_id integer
        constraint formation_domaine_unicaen_utilisateur_user_id_fk2
            references unicaen_utilisateur_user,
    histo_destruction     timestamp,
    histo_destructeur_id  integer
        constraint formation_domaine_unicaen_utilisateur_user_id_fk3
            references unicaen_utilisateur_user
);

-- linker formation <-> domaine
create table formation_formation_domaine
(
    formation_id integer not null
        constraint formaton_formation_domaine_formation_id_fk
            references formation on delete cascade,
    domaine_id   integer not null
        constraint formaton_formation_domaine_formation_domaine_id_fk
            references formation_domaine on delete cascade,
    constraint formaton_formation_domaine_pk
        primary key (formation_id, domaine_id)
);

-- Nouveaux privileges
INSERT INTO unicaen_privilege_categorie (code, libelle, ordre, namespace)
VALUES ('axe','Gestion des axes de formation',310,'Formation\Provider\Privilege');
INSERT INTO unicaen_privilege_privilege(CATEGORIE_ID, CODE, LIBELLE, ORDRE)
WITH d(code, lib, ordre) AS (
    SELECT 'axe_index', 'Accéder à l''index', 10 UNION
    SELECT 'axe_ajouter', 'Ajouter', 20 UNION
    SELECT 'axe_modifier', 'Modifier', 30 UNION
    SELECT 'axe_historiser', 'Historiser/Restaurer', 40 UNION
    SELECT 'axe_supprimer', 'Supprimer', 50 UNION
    SELECT 'axe_afficher', 'Afficher', 15
)
SELECT cp.id, d.code, d.lib, d.ordre
FROM d
JOIN unicaen_privilege_categorie cp ON cp.CODE = 'axe';
-- TODO attribuer les privilèges en fonction de votre établissement

INSERT INTO unicaen_privilege_categorie (code, libelle, ordre, namespace)
VALUES ('formationdomaine', 'Gestion des domaines (Formation)', 309, 'Formation\Provider\Privilege');
INSERT INTO unicaen_privilege_privilege(CATEGORIE_ID, CODE, LIBELLE, ORDRE)
WITH d(code, lib, ordre) AS (
    SELECT 'formationdomaine_index', 'Accéder à l''index', 10 UNION
    SELECT 'formationdomaine_afficher', 'Afficher', 20 UNION
    SELECT 'formationdomaine_ajouter', 'Ajouter', 30 UNION
    SELECT 'formationdomaine_modifier', 'Modifier', 40 UNION
    SELECT 'formationdomaine_historiser', 'Historiser/Restaurer', 50 UNION
    SELECT 'formationdomaine_supprimer', 'Supprimer', 60
)
SELECT cp.id, d.code, d.lib, d.ordre
FROM d
JOIN unicaen_privilege_categorie cp ON cp.CODE = 'formationdomaine';
-- TODO attribuer les privilèges en fonction de votre établissement

```

+201 −0
Changes for module/Formation/config/merged/domaine.config.php: 201 added lines, 0 removed lines.
Original line number Diff line number Diff line
<?php

namespace Formation;

use Formation\Controller\DomaineController;
use Formation\Controller\DomaineControllerFactory;
use Formation\Form\Domaine\DomaineForm;
use Formation\Form\Domaine\DomaineFormFactory;
use Formation\Form\Domaine\DomaineHydrator;
use Formation\Form\Domaine\DomaineHydratorFactory;
use Formation\Provider\Privilege\FormationdomainePrivileges;
use Formation\Service\Domaine\DomaineService;
use Formation\Service\Domaine\DomaineServiceFactory;
use UnicaenPrivilege\Guard\PrivilegeController;
use Laminas\Router\Http\Literal;
use Laminas\Router\Http\Segment;

return [
    'bjyauthorize' => [
        'guards' => [
            PrivilegeController::class => [
                [
                    'controller' => DomaineController::class,
                    'action' => [
                        'index',
                    ],
                    'privileges' => [
                        FormationdomainePrivileges::FORMATIONDOMAINE_INDEX,
                    ],
                ],
                [
                    'controller' => DomaineController::class,
                    'action' => [
                        'afficher',
                    ],
                    'privileges' => [
                        FormationdomainePrivileges::FORMATIONDOMAINE_AFFICHER,
                    ],
                ],
                [
                    'controller' => DomaineController::class,
                    'action' => [
                        'ajouter',
                    ],
                    'privileges' => [
                        FormationdomainePrivileges::FORMATIONDOMAINE_AJOUTER,
                    ],
                ],
                [
                    'controller' => DomaineController::class,
                    'action' => [
                        'modifier',
                    ],
                    'privileges' => [
                        FormationdomainePrivileges::FORMATIONDOMAINE_MODIFIER,
                    ],
                ],
                [
                    'controller' => DomaineController::class,
                    'action' => [
                        'historiser',
                        'restaurer',
                    ],
                    'privileges' => [
                        FormationdomainePrivileges::FORMATIONDOMAINE_HISTORISER,
                    ],
                ],
                [
                    'controller' => DomaineController::class,
                    'action' => [
                        'supprimer',
                    ],
                    'privileges' => [
                        FormationdomainePrivileges::FORMATIONDOMAINE_SUPPRIMER,
                    ],
                ],
            ],
        ],
    ],

    'navigation'      => [
        'formation' => [
            'home' => [
                'pages' => [
                    'gestion-formation' => [
                        'pages' => [
                            'domaine' => [
                                'label'    => 'Domaine de formation',
                                'route'    => 'formation-domaine',
                                'resource' => PrivilegeController::getResourceId(DomaineController::class, 'index') ,
                                'order'    => 206,
                                'icon' => 'fas fa-angle-right',
                            ],
                        ],
                    ],
                ],
            ],
        ],
    ],

    'router' => [
        'routes' => [
            'formation-domaine' => [
                'type'  => Literal::class,
                'options' => [
                    'route'    => '/formation-domaine',
                    'defaults' => [
                        /** @see DomaineController::indexAction() */
                        'controller' => DomaineController::class,
                        'action' => 'index',
                    ],
                ],
                'may_terminate' => true,
                'child_routes' => [
                    'afficher' => [
                        'type'  => Segment::class,
                        'options' => [
                            'route'    => '/afficher/:domaine',
                            'defaults' => [
                                /** @see DomaineController::afficherAction() */
                                'action'     => 'afficher',
                            ],
                        ],
                    ],
                    'ajouter' => [
                        'type'  => Literal::class,
                        'options' => [
                            'route'    => '/ajouter',
                            'defaults' => [
                                /** @see DomaineController::ajouterAction() */
                                'action'     => 'ajouter',
                            ],
                        ],
                    ],
                    'modifier' => [
                        'type'  => Segment::class,
                        'options' => [
                            'route'    => '/modifier/:domaine',
                            'defaults' => [
                                /** @see DomaineController::modifierAction() */
                                'action'     => 'modifier',
                            ],
                        ],
                    ],
                    'historiser' => [
                        'type'  => Segment::class,
                        'options' => [
                            'route'    => '/historiser/:domaine',
                            'defaults' => [
                                /** @see DomaineController::historiserAction() */
                                'action'     => 'historiser',
                            ],
                        ],
                    ],
                    'restaurer' => [
                        'type'  => Segment::class,
                        'options' => [
                            'route'    => '/restaurer/:domaine',
                            'defaults' => [
                                /** @see DomaineController::restaurerAction() */
                                'action'     => 'restaurer',
                            ],
                        ],
                    ],
                    'supprimer' => [
                        'type'  => Segment::class,
                        'options' => [
                            'route'    => '/supprimer/:domaine',
                            'defaults' => [
                                /** @see DomaineController::supprimerAction() */
                                'action'     => 'supprimer',
                            ],
                        ],
                    ],
                ],
            ],
        ],
    ],

    'service_manager' => [
        'factories' => [
            DomaineService::class => DomaineServiceFactory::class,
        ],
    ],
    'controllers'     => [
        'factories' => [
            DomaineController::class => DomaineControllerFactory::class,
        ],
    ],
    'form_elements' => [
        'factories' => [
            DomaineForm::class => DomaineFormFactory::class,
        ],
    ],
    'hydrators' => [
        'factories' => [
            DomaineHydrator::class => DomaineHydratorFactory::class,
        ],
    ]

];
 No newline at end of file
+20 −2
Changes for module/Formation/config/merged/plan-de-formation.config.php: 20 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -8,6 +8,10 @@ use Formation\Form\PlanDeFormation\PlanDeFormationForm;
use Formation\Form\PlanDeFormation\PlanDeFormationFormFactory;
use Formation\Form\PlanDeFormation\PlanDeFormationHydrator;
use Formation\Form\PlanDeFormation\PlanDeFormationHydratorFactory;
use Formation\Form\PlanDeFormationImportation\PlanDeFormationImportationForm;
use Formation\Form\PlanDeFormationImportation\PlanDeFormationImportationFormFactory;
use Formation\Form\PlanDeFormationImportation\PlanDeFormationImportationHydrator;
use Formation\Form\PlanDeFormationImportation\PlanDeFormationImportationHydratorFactory;
use Formation\Form\SelectionPlanDeFormation\SelectionPlanDeFormationForm;
use Formation\Form\SelectionPlanDeFormation\SelectionPlanDeFormationFormFactory;
use Formation\Form\SelectionPlanDeFormation\SelectionPlanDeFormationHydrator;
@@ -73,7 +77,8 @@ return [
                    'action' => [
                        'gerer-formations',
                        'reprendre',
                        'supprimer'
                        'supprimer',
                        'importer-depuis-csv',
                    ],
                    'privileges' => [
                        PlanformationPrivileges::PLANFORMATION_SUPPRIMER
@@ -210,6 +215,17 @@ return [
                            ],
                        ],
                    ],
                    'importer' => [
                        'type'  => Literal::class,
                        'options' => [
                            /** @see PlanDeFormationController::importerDepuisCscAction() */
                            'route'    => '/importer-depuis-csv',
                            'defaults' => [
                                'controller' => PlanDeFormationController::class,
                                'action'     => 'importer-depuis-csv',
                            ],
                        ],
                    ],

                ],
            ],
@@ -229,14 +245,16 @@ return [
    'form_elements' => [
        'factories' => [
            PlanDeFormationForm::class => PlanDeFormationFormFactory::class,
            PlanDeFormationImportationForm::class => PlanDeFormationImportationFormFactory::class,
            SelectionPlanDeFormationForm::class => SelectionPlanDeFormationFormFactory::class,
        ],
    ],
    'hydrators' => [
        'factories' => [
            PlanDeFormationHydrator::class => PlanDeFormationHydratorFactory::class,
            PlanDeFormationImportationHydrator::class => PlanDeFormationImportationHydratorFactory::class,
            SelectionPlanDeFormationHydrator::class => SelectionPlanDeFormationHydratorFactory::class,
        ],
    ]
    ],

];
 No newline at end of file
+129 −0
Changes for module/Formation/src/Formation/Controller/DomaineController.php: 129 added lines, 0 removed lines.
Original line number Diff line number Diff line
<?php

namespace Formation\Controller;

use Formation\Entity\Db\Domaine;
use Formation\Form\Domaine\DomaineFormAwareTrait;
use Formation\Service\Domaine\DomaineServiceAwareTrait;
use Laminas\Http\Response;
use Laminas\Mvc\Controller\AbstractActionController;
use Laminas\View\Model\ViewModel;

class DomaineController extends AbstractActionController {
    use DomaineServiceAwareTrait;
    use DomaineFormAwareTrait;

    public function indexAction(): ViewModel
    {
        $domaines = $this->getDomaineService()->getDomaines('ordre', 'ASC', true);

        return new ViewModel([
            'domaines' => $domaines,
        ]);
    }

    public function afficherAction(): ViewModel
    {
        $domaine = $this->getDomaineService()->getRequestedDomaine($this);

        return new ViewModel([
            'title' => "Affichage de du domaine [".$domaine->getLibelle()."]",
            'domaine' => $domaine,
        ]);
    }

    public function ajouterAction(): ViewModel
    {
        $domaine = new Domaine();

        $form = $this->getDomaineForm();
        $form->setAttribute('action', $this->url()->fromRoute('formation-domaine/ajouter', [], [], true));
        $form->bind($domaine);

        $request = $this->getRequest();
        if ($request->isPost()) {
            $data = $request->getPost();
            $form->setData($data);
            if ($form->isValid()) {
                $this->getDomaineService()->create($domaine);
                exit();
            }
        }

        $vm = new ViewModel([
            'title' => "Ajout d'un domaine de formation",
            'form' => $form,
        ]);
        $vm->setTemplate('default/default-form');
        return $vm;
    }

    public function modifierAction(): ViewModel
    {
        $domaine = $this->getDomaineService()->getRequestedDomaine($this);

        $form = $this->getDomaineForm();
        $form->setAttribute('action', $this->url()->fromRoute('formation-domaine/modifier', ['domaine' => $domaine->getId()], [], true));
        $form->bind($domaine);

        $request = $this->getRequest();
        if ($request->isPost()) {
            $data = $request->getPost();
            $form->setData($data);
            if ($form->isValid()) {
                $this->getDomaineService()->update($domaine);
                exit();
            }
        }

        $vm = new ViewModel([
            'title' => "Modification du domaine [".$domaine->getLibelle()."]",
            'form' => $form,
        ]);
        $vm->setTemplate('default/default-form');
        return $vm;
    }

    public function historiserAction() : Response
    {
        $domaine = $this->getDomaineService()->getRequestedDomaine($this);
        $this->getDomaineService()->historise($domaine);

        $retour = $this->params()->fromRoute('retour');
        if ($retour) return $this->redirect()->toUrl($retour);
        return $this->redirect()->toRoute('formation-domaine', [], [], true);
    }

    public function restaurerAction() : Response
    {
        $domaine = $this->getDomaineService()->getRequestedDomaine($this);
        $this->getDomaineService()->restore($domaine);

        $retour = $this->params()->fromRoute('retour');
        if ($retour) return $this->redirect()->toUrl($retour);
        return $this->redirect()->toRoute('formation-domaine', [], [], true);
    }

    public function supprimerAction() : ViewModel
    {
        $domaine = $this->getDomaineService()->getRequestedDomaine($this);

        $request = $this->getRequest();
        if ($request->isPost()) {
            $data = $request->getPost();
            if ($data["reponse"] === "oui") $this->getDomaineService()->delete($domaine);
            exit();
        }

        $vm = new ViewModel();
        if ($domaine !== null) {
            $vm->setTemplate('default/confirmation');
            $vm->setVariables([
                'title' => "Suppression du domaine " . $domaine->getLibelle(),
                'text' => "La suppression est définitive êtes-vous sûr&middot;e de vouloir continuer ?",
                'action' => $this->url()->fromRoute('formation-domaine/supprimer', ["domaine" => $domaine->getId()], [], true),
            ]);
        }
        return $vm;
    }
}
 No newline at end of file
Loading