Commit db216a59 authored by Bertrand Gauthier's avatar Bertrand Gauthier
Browse files

Merge branch 'release-2.1.2' of git.unicaen.fr:open-source/sygal into release-2.1.2

parents 3c4a9d9f c54f670a
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -3,6 +3,10 @@ Journal des modifications

2.1.2
-----
- Gestion des co-encadrants (ajout et retrait)
- Listing (et export) des co-encadrants sur les EDs et URs
- Ajout à l'export de l'annuaire des co-encadrants
- Onglets dans les pages d'information des structures
- Page de connexion scindée par type d'authentification activée.
- Import du témoin "corrections effectuées" de chaque thèse.
- Pages de dépôt de la version corrigée : visibles dès lors que le témoin "corrections effectuées" est à Oui.
+4 −0
Original line number Diff line number Diff line
@@ -16,6 +16,10 @@ git fetch --tags && git checkout --force 2.1.2 && bash ./install.sh
## 2. Dans la base de données

```sql
INSERT INTO CATEGORIE_PRIVILEGE (ID, CODE, LIBELLE, ORDRE) VALUES (102, 'co-encadrant', 'Gestion des co-encadrants', '21');
INSERT INTO PRIVILEGE (ID, CATEGORIE_ID, CODE, LIBELLE, ORDRE) VALUES (PRIVILEGE_ID_SEQ.nextval, 102, 'co-encadrant_afficher', 'Affichage des historiques de co-encadrants', 10);
INSERT INTO PRIVILEGE (ID, CATEGORIE_ID, CODE, LIBELLE, ORDRE) VALUES (PRIVILEGE_ID_SEQ.nextval, 102, 'co-encadrant_gerer', 'Gérer les co-encadrants', 20);

alter table TMP_THESE add CORRECTION_EFFECTUEE VARCHAR2(30 char) default 'N' not null ;

create or replace view SRC_THESE as
+167 −0
Original line number Diff line number Diff line
<?php

namespace Application;

use Application\Controller\CoEncadrantController;
use Application\Controller\Factory\CoEncadrantControllerFactory;
use Application\Form\Factory\RechercherCoEncadrantFormFactory;
use Application\Form\RechercherCoEncadrantForm;
use Application\Provider\Privilege\CoEncadrantPrivileges;
use Application\Service\CoEncadrant\CoEncadrantService;
use Application\Service\CoEncadrant\CoEncadrantServiceFactory;
use UnicaenAuth\Guard\PrivilegeController;
use Zend\Router\Http\Literal;
use Zend\Router\Http\Segment;

return [
    'bjyauthorize'    => [
        'guards' => [
            PrivilegeController::class => [
                [
                    'controller' => CoEncadrantController::class,
                    'action'     => [
                        'index',
                        'historique',
                        'rechercher-co-encadrant',
                        'generer-justificatif-coencadrements',
                        'generer-export-csv',
                    ],
                    'privileges' => [
                        CoEncadrantPrivileges::COENCADRANT_AFFICHER,
                    ],
                ],
                [
                    'controller' => CoEncadrantController::class,
                    'action'     => [
                        'ajouter-co-encadrant',
                        'retirer-co-encadrant',
                    ],
                    'privileges' => [
                        CoEncadrantPrivileges::COENCADRANT_GERER,
                    ],
                ],
            ],
        ],
    ],

    'router'          => [
        'routes' => [
            'co-encadrant' => [
                'type'          => Literal::class,
                'options'       => [
                    'route'    => '/co-encadrant',
                    'defaults' => [
                        'controller'    => CoEncadrantController::class,
                        'action'        => 'index',
                    ],
                ],
                'may_terminate' => true,
                'child_routes'  => [
                    'historique' => [
                        'type'          => Segment::class,
                        'options'       => [
                            'route'    => '/historique/:co-encadrant',
                            'defaults' => [
                                'controller'    => CoEncadrantController::class,
                                'action'        => 'historique',
                            ],
                        ],
                    ],
                    'generer-justificatif-coencadrements' => [
                        'type'          => Segment::class,
                        'options'       => [
                            'route'    => '/generer-justificatif-coencadrements/:co-encadrant',
                            'defaults' => [
                                'controller'    => CoEncadrantController::class,
                                'action'        => 'generer-justificatif-coencadrements',
                            ],
                        ],
                    ],
                    'generer-export-csv' => [
                        'type'          => Segment::class,
                        'options'       => [
                            'route'    => '/generer-export-csv/:structure-type/:structure-id',
                            'defaults' => [
                                'controller'    => CoEncadrantController::class,
                                'action'        => 'generer-export-csv',
                            ],
                        ],
                    ],
                    'rechercher-co-encadrant' => [
                        'type'          => Literal::class,
                        'options'       => [
                            'route'    => '/rechercher-co-encadrant',
                            'defaults' => [
                                'controller'    => CoEncadrantController::class,
                                'action'        => 'rechercher-co-encadrant',
                            ],
                        ],
                    ],
                    'ajouter-co-encadrant' => [
                        'type'          => Segment::class,
                        'options'       => [
                            'route'    => '/ajouter-co-encadrant/:these',
                            'defaults' => [
                                'controller'    => CoEncadrantController::class,
                                'action'        => 'ajouter-co-encadrant',
                            ],
                        ],
                    ],
                    'retirer-co-encadrant' => [
                        'type'          => Segment::class,
                        'options'       => [
                            'route'    => '/retirer-co-encadrant/:these/:co-encadrant',
                            'defaults' => [
                                'controller'    => CoEncadrantController::class,
                                'action'        => 'retirer-co-encadrant',
                            ],
                        ],
                    ],
                ],
            ],
        ],
    ],

    'navigation'      => [
        'default' => [
            'home' => [
                'pages' => [
                    'admin' => [
                        'pages' => [
                            'co-encadrant' => [
                                'label'    => 'Co-encadrant',
                                'route'    => 'co-encadrant',
                                'resource' => PrivilegeController::getResourceId(CoEncadrantController::class, 'index'),

                                'order'    => 1000,
                                'pages' => [
                                    'historique' => [
                                        'label'    => 'Historique',
                                        'route'    => 'co-encadrant/historique',
                                        'resource' => PrivilegeController::getResourceId(CoEncadrantController::class, 'historique'),
                                    ],
                                ],
                            ],
                        ],
                    ],
                ],
            ],
        ],
    ],

    'controllers' => [
        'factories' => [
            CoEncadrantController::class => CoEncadrantControllerFactory::class,
        ],
    ],
    'form_elements' => [
        'factories' => [
            RechercherCoEncadrantForm::class => RechercherCoEncadrantFormFactory::class,
        ],
    ],
    'service_manager' => [
        'factories' => [
            CoEncadrantService::class => CoEncadrantServiceFactory::class,
        ],
    ],
];
+3 −4
Original line number Diff line number Diff line
@@ -21,10 +21,10 @@ use Application\Form\Factory\PointsDeVigilanceHydratorFactory;
use Application\Form\Factory\RdvBuHydratorFactory;
use Application\Form\Factory\RdvBuTheseDoctorantFormFactory;
use Application\Form\Factory\RdvBuTheseFormFactory;
use Application\Provider\Privilege\DoctorantPrivileges;
use Application\Provider\Privilege\RapportAnnuelPrivileges;
use Application\Provider\Privilege\ThesePrivileges;
use Application\Service\Acteur\ActeurService;
use Application\Service\Acteur\ActeurServiceFactory;
use Application\Service\Financement\FinancementService;
use Application\Service\Financement\FinancementServiceFactory;
use Application\Service\Message\DiffusionMessages;
@@ -38,6 +38,7 @@ use Application\Service\TheseAnneeUniv\TheseAnneeUnivServiceFactory;
use Application\View\Helper\Url\UrlTheseHelperFactory;
use UnicaenAuth\Guard\PrivilegeController;
use UnicaenAuth\Provider\Rule\PrivilegeRuleProvider;
use Zend\Router\Http\Segment;

return [
    'bjyauthorize'    => [
@@ -1097,10 +1098,8 @@ return [
        )
    ),
    'service_manager' => [
        'invokables' => array(
            ActeurService::class => ActeurService::class,
        ),
        'factories' => [
            ActeurService::class           => ActeurServiceFactory::class,
            'TheseService'                 => TheseServiceFactory::class,
            'TheseRechercheService'        => TheseRechercheServiceFactory::class,
            'TheseObserverService'         => TheseObserverServiceFactory::class,
+207 −0
Original line number Diff line number Diff line
<?php

namespace Application\Controller;

use Application\Entity\Db\Acteur;
use Application\Entity\Db\EcoleDoctorale;
use Application\Entity\Db\Individu;
use Application\Entity\Db\These;
use Application\Entity\Db\UniteRecherche;
use Application\Form\RechercherCoEncadrantFormAwareTrait;
use Application\Service\Acteur\ActeurServiceAwareTrait;
use Application\Service\CoEncadrant\CoEncadrantServiceAwareTrait;
use Application\Service\CoEncadrant\Exporter\JustificatifCoencadrements\JustificatifCoencadrementPdfExporter;
use Application\Service\EcoleDoctorale\EcoleDoctoraleServiceAwareTrait;
use Application\Service\File\FileServiceAwareTrait;
use Application\Service\Individu\IndividuServiceAwareTrait;
use Application\Service\These\TheseServiceAwareTrait;
use Application\Service\UniteRecherche\UniteRechercheServiceAwareTrait;
use DateTime;
use UnicaenApp\View\Model\CsvModel;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\JsonModel;
use Zend\View\Model\ViewModel;
use Zend\View\Renderer\PhpRenderer;

class CoEncadrantController extends AbstractActionController {
    use ActeurServiceAwareTrait;
    use CoEncadrantServiceAwareTrait;
    use IndividuServiceAwareTrait;
    use FileServiceAwareTrait;
    use TheseServiceAwareTrait;
    use RechercherCoEncadrantFormAwareTrait;
    use EcoleDoctoraleServiceAwareTrait;
    use UniteRechercheServiceAwareTrait;


    /** @var PhpRenderer */
    private $renderer;

    /**
     * @param PhpRenderer $renderer
     */
    public function setRenderer($renderer)
    {
        $this->renderer = $renderer;
    }

    public function indexAction()
    {
        $form = $this->getRechercherCoEncadrantForm();
        $form->setAttribute('action', $this->url()->fromRoute('co-encadrant', [], [], true));
        //todo !doit remonter un acteur
        $form->setUrlCoEncadrant($this->url()->fromRoute('co-encadrant/rechercher-co-encadrant', [], [], true));
        $form->get('bouton')->setLabel("Afficher l'historique de co-encadrement");

        $request = $this->getRequest();
        if ($request->isPost()) {
            $data = $request->getPost();
            if ($data['co-encadrant']['id'] !== "") {
                $this->redirect()->toRoute('co-encadrant/historique',['co-encadrant' => $data['co-encadrant']['id']]);
            }
        }

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

    public function rechercherCoEncadrantAction()
    {
        if (($term = $this->params()->fromQuery('term'))) {
            $acteurs = $this->getCoEncadrantService()->findByText($term);
            $result = [];
            foreach ($acteurs as $acteur) {
                // mise en forme attendue par l'aide de vue FormSearchAndSelect
                $label = $acteur->getIndividu()->getPrenom() . ' ' . $acteur->getIndividu()->getNomUsuel();
                $extra = ($acteur->getIndividu()->getEmail())?:$acteur->getIndividu()->getSourceCode();
                $result[$acteur->getIndividu()->getId()] = array(
                    'id' => $acteur->getId(),   // identifiant unique de l'item
                    'label' => $label,          // libellé de l'item
                    'extra' => $extra,          // infos complémentaires (facultatives) sur l'item
                );
            }
            usort($result, function ($a, $b) {
                return strcmp($a['label'], $b['label']);
            });

            return new JsonModel($result);
        }
        exit;
    }

    public function ajouterCoEncadrantAction()
    {
        /** @var These $these */
        $theseId = $this->params()->fromRoute('these');
        $these = $this->getTheseService()->getRepository()->find($theseId);

        $form = $this->getRechercherCoEncadrantForm();
        $form->setAttribute('action', $this->url()->fromRoute('co-encadrant/ajouter-co-encadrant', [], [], true));
        $form->setUrlCoEncadrant($this->url()->fromRoute('utilisateur/rechercher-individu', [], ["query" => ['type' => Individu::TYPE_ACTEUR]], true));

        $request = $this->getRequest();
        if ($request->isPost()) {
            $data = $request->getPost();

            if (isset($data['co-encadrant']['id'])) {
                /** @var Individu $individu */
                $individu = $this->getIndividuService()->getRepository()->find($data['co-encadrant']['id']);
                $this->getActeurService()->ajouterCoEncradrant($these, $individu);
            }
        }

        return new ViewModel([
            'title' => "Ajout d'un co-encadrant pour la thèse de ". $these->getDoctorant()->getIndividu()->getPrenom() . " " . $these->getDoctorant()->getIndividu()->getNomUsuel(),
            'form' => $form,
        ]);
    }

    public function retirerCoEncadrantAction()
    {
        /** @var These $these */
        $theseId = $this->params()->fromRoute('these');
        $these = $this->getTheseService()->getRepository()->find($theseId);
        $acteurId = $this->params()->fromRoute('co-encadrant');

        /** @var Acteur $acteur */
        $acteur = $this->getActeurService()->getRepository()->find($acteurId);
        if ($acteur !== null AND $acteur->getThese() === $these) $this->getActeurService()->delete($acteur);

        $this->redirect()->toRoute('these/identite', ['these' => $these->getId()], [], true);
    }

    public function historiqueAction()
    {
        $coencadrant = $this->getCoEncadrantService()->getRequestedCoEncadrant($this);
        $theses = $this->getTheseService()->getRepository()->fetchThesesByCoEncadrant($coencadrant->getIndividu());

        $encours = []; $closes = [];
        foreach ($theses as $these) {
            if ($these->getEtatThese() === These::ETAT_EN_COURS) {
                $encours[] = $these;
            } else {
                $closes[] = $these;
            }
        }

        return new ViewModel([
            'coencadrant' => $coencadrant,
            'encours' => $encours,
            'closes' => $closes,
        ]);
    }

    public function genererJustificatifCoencadrementsAction()
    {
        $coencadrant = $this->getCoEncadrantService()->getRequestedCoEncadrant($this);
        $theses = $this->getTheseService()->getRepository()->fetchThesesByCoEncadrant($coencadrant->getIndividu());

        $logos = [];
        $logos['etablissement'] = $this->fileService->computeLogoFilePathForStructure($coencadrant->getEtablissement());

        //exporter
        $export = new JustificatifCoencadrementPdfExporter($this->renderer, 'A4');
        $export->setVars([
            'coencadrant' => $coencadrant,
            'theses' => $theses,
            'logos' => $logos,
        ]);
        $export->export('justificatif_coencadrement_' . $coencadrant->getIndividu()->getId() . ".pdf");
    }

    public function genererExportCsvAction()
    {
        $structureType = $this->params()->fromRoute('structure-type');
        $structureId = $this->params()->fromRoute('structure-id');

        /** @var EcoleDoctorale|UniteRecherche $structure */
        $structure = null;
        if ($structureType === 'ecole-doctorale') $structure = $this->getEcoleDoctoraleService()->getRepository()->find($structureId);
        if ($structureType === 'unite-recherche') $structure = $this->getUniteRechercheService()->getRepository()->find($structureId);

        $listing = $this->getCoEncadrantService()->getCoEncadrantsByStructureConcrete($structure);

        //export
        $headers = ['Co-endrants', 'Nombre d\'encadrements actuels', 'Listing'];
        $records = [];
        foreach ($listing as $item) {
            $entry = [];
            $entry['Co-endrant'] = $item['co-encadrant']->getIndividu()->getPrenom1() . " " . $item['co-encadrant']->getIndividu()->getNomUsuel();
            $entry['Nombre d\'encadrements actuels'] = count($item['theses']);
            $entry['Listing'] = implode(';',
                array_map(function(These $t) {return $t->getDoctorant()->getIndividu()->getPrenom1() . " " . $t->getDoctorant()->getIndividu()->getNomUsuel();}, $item['theses'])
            );
            $records[] = $entry;
        }
        $filename = (new DateTime())->format('Ymd-His') . '_coencadrants-' . str_replace(' ','_',$structure->getSigle()) . '.csv';
        $CSV = new CsvModel();
        $CSV->setDelimiter(';');
        $CSV->setEnclosure('"');
        $CSV->setHeader($headers);
        $CSV->setData($records);
        $CSV->setFilename($filename);

        return $CSV;
    }
}
 No newline at end of file
Loading