Commit 86c073c1 authored by Bertrand Gauthier's avatar Bertrand Gauthier
Browse files

Rapports d'activité : initialisation du formulaire de création d'un nouveau...

Rapports d'activité : initialisation du formulaire de création d'un nouveau rapport avec les formations suivies (module Formation).
parent 53750342
Loading
Loading
Loading
Loading
+1 −2
Changes for CHANGELOG.md: 1 added line, 2 removed lines.
Original line number Diff line number Diff line
@@ -3,11 +3,10 @@ Journal des modifications

7.1.0
-----
- 
- Rapports d'activité : initialisation du formulaire de création d'un nouveau rapport avec les formations suivies (module Formation).

7.0.1
-----
- [FIX] Module Substitutions : plantage de la page consacrée aux doublons (substitutions possibles).
- [FIX] Module Substitutions : plantage de la page de détails d'une substitution d'UR.
- [FIX] Services de recherche : la jointure avec la structure substituante n'est plus à faire.
- [FIX] Utilisation de Structure::getCode() par getSourceCode() pour les établissements d'inscription (correction d'effets de bord des substitutions).
+5 −6
Changes for module/Formation/src/Formation/Service/Inscription/InscriptionService.php: 5 added lines, 6 removed lines.
Original line number Diff line number Diff line
@@ -107,23 +107,22 @@ class InscriptionService {
        $qb = $this->getRepository()->createQueryBuilder('inscription')
            ->join('inscription.doctorant', 'doctorant')->addSelect('doctorant')
            ->join('inscription.session', 'session')->addSelect('session')
            ->join('session.formation', 'formation')->addSelect('formation')
            ->join('session.seances', 'seance')->addSelect('seance')
            ->andWhere('inscription.doctorant = :doctorant')->setParameter('doctorant', $doctorant);

        if ($type !== null) {
            $qb =  $qb->join('session.formation', 'formation')->addSelect('formation')
                ->andWhere('formation.type = :type')->setParameter('type', $type);
            $qb->andWhere('formation.type = :type')->setParameter('type', $type);
        }

        if ($annee !== null) {
            $debut = DateTime::createFromFormat('d/m/Y','01/09/'.($annee-1));
            $fin = DateTime::createFromFormat('d/m/Y','31/08/'.($annee));

            $qb = $qb->join('session.seances', 'seance')
            $qb
                ->andWhere('seance.debut >= :debut')->setParameter('debut', $debut)
                ->andWhere('seance.fin <= :fin')->setParameter('fin', $fin);
        }

        $result = $qb->getQuery()->getResult();
        return $result;
        return $qb->getQuery()->getResult();
    }
}
 No newline at end of file
+20 −2
Changes for module/RapportActivite/src/RapportActivite/Controller/RapportActiviteController.php: 20 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -13,10 +13,12 @@ use Doctrine\ORM\Query\Expr\Join;
use Fichier\FileUtils;
use Fichier\Service\Fichier\FichierServiceAwareTrait;
use Fichier\Service\Fichier\FichierStorageServiceAwareTrait;
use Formation\Service\Inscription\InscriptionServiceAwareTrait as FormationInscriptionServiceAwareTrait;
use InvalidArgumentException;
use Laminas\Http\Response;
use Laminas\View\Model\ViewModel;
use RapportActivite\Entity\Db\RapportActivite;
use RapportActivite\Entity\Formation;
use RapportActivite\Form\RapportActiviteAbstractForm;
use RapportActivite\Form\RapportActiviteAnnuelForm;
use RapportActivite\Form\RapportActiviteFinContratForm;
@@ -40,6 +42,7 @@ class RapportActiviteController extends AbstractController
    use ValidationServiceAwareTrait;
    use TheseAnneeUnivServiceAwareTrait;
    use AnneeUnivServiceAwareTrait;
    use FormationInscriptionServiceAwareTrait;

    private RapportActiviteAnnuelForm $annuelForm;
    private RapportActiviteFinContratForm $finContratForm;
@@ -113,7 +116,7 @@ class RapportActiviteController extends AbstractController
    /**
     * Ajout d'un nouveau rapport.
     */
    public function ajouterAction()
    public function ajouterAction(): Response|ViewModel
    {
        $this->these = $this->requestedThese();
        $estFinContrat = (bool)$this->params('estFinContrat');
@@ -296,7 +299,7 @@ class RapportActiviteController extends AbstractController
        $this->rapports = $this->rapportActiviteService->findRapportsForThese($this->these);
    }

    private function initForm(RapportActiviteAbstractForm $form, RapportActivite $rapportActivite)
    private function initForm(RapportActiviteAbstractForm $form, RapportActivite $rapportActivite): void
    {
        if ($rapportActivite->getId() === null) {
            $anneesUnivs = $rapportActivite->getThese()->getAnneesUnivInscription();
@@ -306,6 +309,21 @@ class RapportActiviteController extends AbstractController
                ->getAnneesUnivsDisponibles();
            $form->setAnneesUnivs($anneesUnivsPossibles);

            // TODO : Modifier le process/formulaire pour avoir l'année avant et pouvoir ainsi filtrer les formations
            //
            // 2 idées :
            //   - soit générer dans le bouton autant de liens de création de RA qu'il y a de couples (type de RA ; année) possibles
            //     (ex : 'Annuel 2022', 'Annuel 2023', 'Fin de contrat 2023'). On pourra utiliser ça :
            //       $anneesUnivsPossiblesPourRapportAnnuel = $this->rapportActiviteCreationRule->getAnneesUnivsDisponiblesPourRapportAnnuel();
            //       $anneesUnivsPossiblesPourRapportFinContrat = $this->rapportActiviteCreationRule->getAnneesUnivsDisponiblesPourRapportFinContrat();
            //     L'avantage est que ça évite aussi l'exception "Interdit de créer ce type de rapport" déclénchée ci-après.
            //
            //   - soit modifier le comportement du formulaire pour faire saisir d'abord l'année seule (.e. validation group)
            //     et ensuite le formulaire entier (avec année grisée) initialisé avec les formations de l'année choisie.
            //     Cf. AnneeUnivService pour les bornes de début et de fin d'une année univ.
            $formationInscriptions = $this->inscriptionService->getInscriptionByDoctorantAndAnnee($rapportActivite->getThese()->getDoctorant());
            $rapportActivite->setFormationsFromInscriptions($formationInscriptions);

            if ($rapportActivite->estFinContrat() && !$this->rapportActiviteCreationRule->canCreateRapportFinContrat() ||
                !$rapportActivite->estFinContrat() && !$this->rapportActiviteCreationRule->canCreateRapportAnnuel()) {
                throw new InvalidArgumentException("Interdit de créer ce type de rapport");
+5 −0
Changes for module/RapportActivite/src/RapportActivite/Controller/RapportActiviteControllerFactory.php: 5 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@ use Application\Service\AnneeUniv\AnneeUnivService;
use Application\Service\Validation\ValidationService;
use Fichier\Service\Fichier\FichierService;
use Fichier\Service\Fichier\FichierStorageService;
use Formation\Service\Inscription\InscriptionService as FormationInscriptionService;
use Psr\Container\ContainerInterface;
use RapportActivite\Form\RapportActiviteAnnuelForm;
use RapportActivite\Form\RapportActiviteFinContratForm;
@@ -69,6 +70,10 @@ class RapportActiviteControllerFactory
        $anneeUnivService = $container->get(AnneeUnivService::class);
        $controller->setAnneeUnivService($anneeUnivService);

        /** @var FormationInscriptionService $formationInscriptionService */
        $formationInscriptionService = $container->get(FormationInscriptionService::class);
        $controller->setInscriptionService($formationInscriptionService);

        return $controller;
    }
}
+108 −59
Changes for module/RapportActivite/src/RapportActivite/Entity/Db/RapportActivite.php: 108 added lines, 59 removed lines.
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@

namespace RapportActivite\Entity\Db;

use Application\Constants;
use Application\Entity\AnneeUniv;
use Application\Entity\Db\TypeValidation;
use DateTime;
@@ -18,6 +19,7 @@ use These\Entity\Db\These;
use UnicaenApp\Entity\HistoriqueAwareInterface;
use UnicaenApp\Entity\HistoriqueAwareTrait;
use UnicaenAvis\Entity\Db\AvisType;
use Webmozart\Assert\Assert;

class RapportActivite implements ResourceInterface, HistoriqueAwareInterface
{
@@ -38,8 +40,22 @@ class RapportActivite implements ResourceInterface, HistoriqueAwareInterface
    private ?string $descriptionProjetRecherche = null;
    private ?string $principauxResultatsObtenus = null;
    private ?string $productionsScientifiques = null;

    /**
     * Le stockage des formations dans le rapport d'activité est très rudimentaire. Comme il n'y a pas de relation
     * 'to-many' entre le {@see \RapportActivite\Entity\Db\RapportActivite} et les formations suivies, on la
     * "simule" en stockant une chaîne de caractères représentant au format JSON la liste des formations suivies
     * (intitulé et durée).
     */
    private ?string $formationsSpecifiques = null;
    /**
     * Le stockage des formations dans le rapport d'activité est très rudimentaire. Comme il n'y a pas de relation
     * 'to-many' entre le {@see \RapportActivite\Entity\Db\RapportActivite} et les formations suivies, on la
     * "simule" en stockant une chaîne de caractères représentant au format JSON la liste des formations suivies
     * (intitulé et durée).
     */
    private ?string $formationsTransversales = null;

    private ?string $actionsDiffusionCultureScientifique = null;
    private ?string $autresActivites = null;
    private ?string $calendrierPrevionnelFinalisation = null;
@@ -175,21 +191,56 @@ class RapportActivite implements ResourceInterface, HistoriqueAwareInterface
    }

    /**
     * @return string|null
     * Initialisation des formations transversales et/ou spécifiques suivies par le doctorant à partir des
     * {@see \Formation\Entity\Db\Inscription} renseignées dans le module Formation.
     *
     * Le stockage des formations dans le rapport d'activité est très rudimentaire. Comme il n'y a pas de relation
     * 'to-many' entre le {@see \RapportActivite\Entity\Db\RapportActivite} et les formations suivies, on la
     * "simule" en stockant une chaîne de caractères représentant au format JSON la liste des formations suivies
     * (intitulé et durée).
     *
     * @param \Formation\Entity\Db\Inscription[] $formationInscriptions
     */
    public function getFormationsSpecifiques(): ?string
    public function setFormationsFromInscriptions(array $formationInscriptions): void
    {
        return $this->formationsSpecifiques;
        // parcours des inscriptions à des sessions pour cumul des durées par intitulé de formation
        $infosFormations = [];
        foreach ($formationInscriptions as $inscription) {
            $session = $inscription->getSession();
            $dateDebut = $session->getDateDebut();
            if ($dateDebut > new DateTime()) {
                continue; // on écarte les sessions situées dans le futur
            }
            if ($inscription->computeDureePresence() === 0.0) {
                continue; // on écarte les inscription dont la durée de présence est nulle
            }
            $formation = $session->getFormation();
            $type = $formation->getType();
            $intitule = sprintf('%s (%s)', $formation->getLibelle(), $dateDebut->format(Constants::DATE_FORMAT));
            $infosFormations[$type][$session->getId()] = $infosFormations[$type][$session->getId()] ?? ['intitule' => null, 'temps' => 0.0];
            $infosFormations[$type][$session->getId()]['intitule'] = $intitule;
            $infosFormations[$type][$session->getId()]['temps'] += $inscription->computeDureePresence();
        }
        foreach ($infosFormations as $type => $data) {
            $formations = array_map(fn($d) => Formation::fromArray($d), $data);
            if ($formations) {
                if ($type === \Formation\Entity\Db\Formation::TYPE_CODE_SPECIFIQUE) {
                    $this->setFormationsSpecifiques($formations);
                } elseif ($type === \Formation\Entity\Db\Formation::TYPE_CODE_TRAVERSAL) {
                    $this->setFormationsTransversales($formations);
                }
            }
        }
    }

    /**
     * @return \RapportActivite\Entity\Formation[]
     */
    public function getFormationsSpecifiquesToArray(): array
    public function getFormationsSpecifiques(): array
    {
        $toArray = [];
        if ($actions = $this->getFormationsSpecifiques()) {
            foreach (json_decode($actions, true) as $array) {
        if ($formations = $this->formationsSpecifiques) {
            foreach (json_decode($formations, true) as $array) {
                $toArray[] = Formation::fromArray($array);
            }
        }
@@ -199,34 +250,32 @@ class RapportActivite implements ResourceInterface, HistoriqueAwareInterface

    public function getFormationsSpecifiquesTempsTotal(): int
    {
        return array_reduce($this->getFormationsSpecifiquesToArray(), fn(int $sum, $e) => $sum + $e->getTemps(), 0);
        return array_reduce($this->getFormationsSpecifiques(), fn(int $sum, $e) => $sum + $e->getTemps(), 0);
    }

    /**
     * @param string|null $formationsSpecifiques
     * @return self
     * @param \RapportActivite\Entity\Formation[] $formations
     */
    public function setFormationsSpecifiques(?string $formationsSpecifiques): self
    public function setFormationsSpecifiques(array $formations = []): self
    {
        $this->formationsSpecifiques = $formationsSpecifiques;
        return $this;
    }
        Assert::allIsInstanceOf($formations, Formation::class);

    /**
     * @return string|null
     */
    public function getFormationsTransversales(): ?string
    {
        return $this->formationsTransversales;
        usort($formations, fn($a, $b) => $b->getTemps() <=> $a->getTemps());
        $formations = array_map(fn($entity) => $entity->toArray(), $formations);
        $formationsAsString = json_encode($formations);

        $this->formationsSpecifiques = $formationsAsString;

        return $this;
    }

    /**
     * @return \RapportActivite\Entity\Formation[]
     */
    public function getFormationsTransversalesToArray(): array
    public function getFormationsTransversales(): array
    {
        $toArray = [];
        if ($actions = $this->getFormationsTransversales()) {
        if ($actions = $this->formationsTransversales) {
            foreach (json_decode($actions, true) as $array) {
                $toArray[] = Formation::fromArray($array);
            }
@@ -237,34 +286,32 @@ class RapportActivite implements ResourceInterface, HistoriqueAwareInterface

    public function getFormationsTransversalesTempsTotal(): int
    {
        return array_reduce($this->getFormationsTransversalesToArray(), fn(int $sum, $e) => $sum + $e->getTemps(), 0);
        return array_reduce($this->getFormationsTransversales(), fn(int $sum, $e) => $sum + $e->getTemps(), 0);
    }

    /**
     * @param string|null $formationsTransversales
     * @return self
     * @param \RapportActivite\Entity\Formation[] $formations
     */
    public function setFormationsTransversales(?string $formationsTransversales): self
    public function setFormationsTransversales(array $formations = []): self
    {
        $this->formationsTransversales = $formationsTransversales;
        return $this;
    }
        Assert::allIsInstanceOf($formations, Formation::class);

    /**
     * @return string|null
     */
    public function getActionsDiffusionCultureScientifique(): ?string
    {
        return $this->actionsDiffusionCultureScientifique;
        usort($formations, fn($a, $b) => $b->getTemps() <=> $a->getTemps());
        $formations = array_map(fn($entity) => $entity->toArray(), $formations);
        $formationsAsString = $formations ? json_encode($formations) : null;

        $this->formationsTransversales = $formationsAsString;

        return $this;
    }

    /**
     * @return ActionDiffusionCultureScientifique[]
     * @return \RapportActivite\Entity\ActionDiffusionCultureScientifique[]
     */
    public function getActionsDiffusionCultureScientifiqueToArray(): array
    public function getActionsDiffusionCultureScientifique(): array
    {
        $toArray = [];
        if ($actions = $this->getActionsDiffusionCultureScientifique()) {
        if ($actions = $this->actionsDiffusionCultureScientifique) {
            foreach (json_decode($actions, true) as $array) {
                $toArray[] = ActionDiffusionCultureScientifique::fromArray($array);
            }
@@ -275,35 +322,33 @@ class RapportActivite implements ResourceInterface, HistoriqueAwareInterface

    public function getActionsDiffusionCultureScientifiqueTempsTotal(): int
    {
        return array_reduce($this->getActionsDiffusionCultureScientifiqueToArray(), fn(int $sum, $e) => $sum + $e->getTemps(), 0);
        return array_reduce($this->getActionsDiffusionCultureScientifique(), fn(int $sum, $e) => $sum + $e->getTemps(), 0);
    }

    /**
     * @param string|null $actionsDiffusionCultureScientifique
     * @return self
     * @param \RapportActivite\Entity\ActionDiffusionCultureScientifique[] $actions
     */
    public function setActionsDiffusionCultureScientifique(?string $actionsDiffusionCultureScientifique): self
    public function setActionsDiffusionCultureScientifique(array $actions = []): self
    {
        $this->actionsDiffusionCultureScientifique = $actionsDiffusionCultureScientifique;
        return $this;
    }
        Assert::allIsInstanceOf($actions, ActionDiffusionCultureScientifique::class);

    /**
     * @return string|null
     */
    public function getAutresActivites(): ?string
    {
        return $this->autresActivites;
        usort($actions, fn($a, $b) => $a->getDate() <=> $b->getDate());
        $actions = array_map(fn($action) => $action->toArray(), $actions);
        $actionsAsString = json_encode($actions);

        $this->actionsDiffusionCultureScientifique = $actionsAsString;

        return $this;
    }

    /**
     * @return AutreActivite[]
     * @return \RapportActivite\Entity\AutreActivite[]
     */
    public function getAutresActivitesToArray(): array
    public function getAutresActivites(): array
    {
        $toArray = [];
        if ($actions = $this->getAutresActivites()) {
            foreach (json_decode($actions, true) as $array) {
        if ($activites = $this->autresActivites) {
            foreach (json_decode($activites, true) as $array) {
                $toArray[] = AutreActivite::fromArray($array);
            }
        }
@@ -313,16 +358,20 @@ class RapportActivite implements ResourceInterface, HistoriqueAwareInterface

    public function getAutresActivitesTempsTotal(): int
    {
        return array_reduce($this->getAutresActivitesToArray(), fn(int $sum, $e) => $sum + $e->getTemps(), 0);
        return array_reduce($this->getAutresActivites(), fn(int $sum, $e) => $sum + $e->getTemps(), 0);
    }

    /**
     * @param string|null $autresActivites
     * @return self
     * @param \RapportActivite\Entity\AutreActivite[] $autresActivites
     */
    public function setAutresActivites(?string $autresActivites): self
    public function setAutresActivites(array $autresActivites = []): self
    {
        $this->autresActivites = $autresActivites;
        usort($autresActivites, fn($a, $b) => $a->getDate() <=> $b->getDate());
        $autresActivites = array_map(fn($action) => $action->toArray(), $autresActivites);
        $autresActivitesAsString = json_encode($autresActivites);

        $this->autresActivites = $autresActivitesAsString;

        return $this;
    }

Loading