Commit 6d481f49 authored by Anthony Gautreau's avatar Anthony Gautreau
Browse files

Pegase : libellés longs de la composante et du regroupement du catalogue...

Pegase : libellés longs de la composante et du regroupement du catalogue (catalogueOunit, catalogueGroup), libellés courts en catalogueOunitAbbreviation et catalogueGroupAbbreviation
parent d64d1c6c
Loading
Loading
Loading
Loading
Loading
+1 −1
Changes for README.md: 1 added line, 1 removed line.
Original line number Diff line number Diff line
@@ -313,7 +313,7 @@ Les relations sont données en IRI (`"ounit": "/ounits/901"`). Une propriété s
| ounit | `ounitId`, `ounitCode` (code de structure Pegase), `title`, `abbreviation`, `lastModified` |
| programme | `code`, `title`, `ects`, `eqfLevelProvided` (6, 7 ou 8), `languageOfInstruction`, `description` et `learningOutcomes` (syllabus de l'année), `length` (`2/2`), `elmLearningOpportunityType`, `iscedCode`, `levelInDiploma` (niveau SISE), `diplomaCode` et `diplomaTitle` (formation), `ounit`, `lastModified` |
| course | `code`, `title`, `ects`, `languageOfInstruction`, `academicTerm` (`1/2`, `2/2`), `description`, `learningOutcomes`, `prerequisites`, `bibliography`, `assessmentMethod` et `teachingMethod` (syllabus), `elmModeOfLearning`, `elmLearningActivityType` et `elmLearningOpportunityType`, `iscedCode`, `deprecated` (absent de la période la plus récente), `diplomaCode` et `diplomaTitle` (formation porteuse), `courseType` (UE, EC...), `parentCourseCodes` (cours exposés qui le contiennent), `ounit`, `relatedProgramme`, `lastModified` |
| instance | `id` (`LAE112-2026-1`), `course`, `academicTermId` (`2026/2027-1/2`), `startDate`, `endDate`, `ects`, `languageOfInstruction`, `elmModeOfLearning`, `elmLearningActivityType` et `elmLearningOpportunityType` (pour cette période), `engagementHours`, `catalogueOunit` et `catalogueGroup` (composante et regroupement du catalogue), `lastModified` |
| instance | `id` (`LAE112-2026-1`), `course`, `academicTermId` (`2026/2027-1/2`), `startDate`, `endDate`, `ects`, `languageOfInstruction`, `elmModeOfLearning`, `elmLearningActivityType` et `elmLearningOpportunityType` (pour cette période), `engagementHours`, `catalogueOunit` et `catalogueGroup` (libellés longs de la composante et du regroupement du catalogue), `catalogueOunitAbbreviation` et `catalogueGroupAbbreviation` (leurs libellés courts, propres au semestre : « Staps S1 »), `lastModified` |

`lastModified` est la date de l'import.

+28 −0
Changes for api/migrations/Version20261008213359.php: 28 added lines, 0 removed lines.
Original line number Diff line number Diff line
<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

final class Version20261008213359 extends AbstractMigration
{
    public function getDescription(): string
    {
        return 'Pegase : libellés courts de la composante et du regroupement du catalogue';
    }

    public function up(Schema $schema): void
    {
        $this->addSql('ALTER TABLE course_instance ADD catalogue_ounit_abbreviation VARCHAR(255) DEFAULT NULL');
        $this->addSql('ALTER TABLE course_instance ADD catalogue_group_abbreviation VARCHAR(255) DEFAULT NULL');
    }

    public function down(Schema $schema): void
    {
        $this->addSql('ALTER TABLE course_instance DROP catalogue_ounit_abbreviation');
        $this->addSql('ALTER TABLE course_instance DROP catalogue_group_abbreviation');
    }
}
+6 −0
Changes for api/src/Entity/CourseInstance.php: 6 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -64,10 +64,16 @@ class CourseInstance
    #[ORM\Column(type: 'json', nullable: true)]
    public ?array $catalogueOunit = null;

    #[ORM\Column(nullable: true)]
    public ?string $catalogueOunitAbbreviation = null;

    /** @var list<array{string: string, lang: string}>|null */
    #[ORM\Column(type: 'json', nullable: true)]
    public ?array $catalogueGroup = null;

    #[ORM\Column(nullable: true)]
    public ?string $catalogueGroupAbbreviation = null;

    #[ORM\Column]
    public \DateTimeImmutable $lastModified;
}
+56 −7
Changes for api/src/Pegase/PegaseImporter.php: 56 added lines, 7 removed lines.
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ use App\Entity\CourseInstance;
use App\Entity\Ounit;
use App\Entity\Programme;
use App\Pegase\Selection\CoursCatalogue;
use App\Pegase\Selection\NoeudCatalogue;
use App\Pegase\Selection\SelectionCoursInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Monolog\Attribute\WithMonologChannel;
@@ -175,8 +176,14 @@ final class PegaseImporter
            $contextes[$id] = $this->contextes($detail, $selection->racinesCatalogue);
        }
        $lies = $this->objetsLies($details, $contextes);
        $this->logger->info(\sprintf('%s : lecture de %d formations et années liées', $libelle, \count($lies)));
        $objets = $this->lireObjets($lies);
        $noeuds = $this->noeudsCatalogue($selection->cours);
        $this->logger->info(\sprintf(
            '%s : lecture de %d formations et années liées, %d nœuds du catalogue',
            $libelle,
            \count($lies),
            \count($noeuds),
        ));
        $objets = $this->lireObjets(array_values(array_unique([...$lies, ...$noeuds])));

        $occurrences = [];
        $retenus = [];
@@ -187,7 +194,7 @@ final class PegaseImporter
        foreach ($occurrences as $liste) {
            $course = $this->course($liste, $details[$liste[0]->id], $contextes[$liste[0]->id], $objets, $retenus);
            foreach ($liste as $cours) {
                $this->instance($course, $cours, $details[$cours->id], $periode);
                $this->instance($course, $cours, $details[$cours->id], $periode, $objets);
            }
        }

@@ -244,6 +251,25 @@ final class PegaseImporter
        return array_keys($lies);
    }

    /**
     * @param list<CoursCatalogue> $cours cours retenus dans la période
     *
     * @return list<string> identifiants des composantes et regroupements du catalogue, pour leur libellé long
     */
    private function noeudsCatalogue(array $cours): array
    {
        $ids = [];
        foreach ($cours as $occurrence) {
            foreach ([$occurrence->composante, $occurrence->regroupement] as $noeud) {
                if (null !== $noeud) {
                    $ids[$noeud->id] = true;
                }
            }
        }

        return array_keys($ids);
    }

    /**
     * @param list<string> $ids identifiants d'objets maquette
     *
@@ -418,9 +444,16 @@ final class PegaseImporter
    /**
     * Une instance par cours, période et semestre. Un cours placé deux fois sous le même semestre garde son
     * premier regroupement.
     *
     * @param array<string, ObjetMaquette> $objets détails lus dans la période, nœuds du catalogue compris
     */
    private function instance(Course $course, CoursCatalogue $cours, ObjetMaquette $detail, Periode $periode): void
    {
    private function instance(
        Course $course,
        CoursCatalogue $cours,
        ObjetMaquette $detail,
        Periode $periode,
        array $objets,
    ): void {
        $id = $course->code.'-'.$periode->annee;
        $academicTermId = $periode->annee.'/'.($periode->annee + 1);
        if (null !== $cours->semestre) {
@@ -443,12 +476,28 @@ final class PegaseImporter
        $instance->elmLearningActivityType = Elm::typesActivite($detail, $this->configuration->typesHeure);
        $instance->elmLearningOpportunityType = Elm::typesOpportuniteCours($detail);
        $instance->engagementHours = $volumes ? round(array_sum($volumes) / 60, 2) : null;
        $instance->catalogueOunit = null === $cours->composante ? null : $this->titre($cours->composante);
        $instance->catalogueGroup = null === $cours->regroupement ? null : $this->titre($cours->regroupement);
        $instance->catalogueOunit = $this->titreCatalogue($cours->composante, $objets);
        $instance->catalogueOunitAbbreviation = $cours->composante?->libelle;
        $instance->catalogueGroup = $this->titreCatalogue($cours->regroupement, $objets);
        $instance->catalogueGroupAbbreviation = $cours->regroupement?->libelle;
        $instance->lastModified = $this->date;
        $this->instances[$id] = $instance;
    }

    /**
     * @param array<string, ObjetMaquette> $objets détails lus dans la période
     *
     * @return list<array{string: string, lang: string}>|null libellé long du nœud, à défaut son libellé court
     */
    private function titreCatalogue(?NoeudCatalogue $noeud, array $objets): ?array
    {
        if (null === $noeud) {
            return null;
        }

        return $this->titre($objets[$noeud->id]->libelleLong ?? $noeud->libelle);
    }

    /**
     * ISCED d'un programme : celui du diplôme SISE de sa formation. ISCED d'un cours : celui du diplôme de sa
     * formation porteuse, à défaut l'union de ceux de ses programmes.
+4 −4
Changes for api/src/Pegase/Selection/CoursCatalogue.php: 4 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -15,8 +15,8 @@ final readonly class CoursCatalogue
     * @param string|null         $type         type d'objet de formation (EC, ECA...)
     * @param float|null          $ects         ECTS de la maquette, absents sur certains objets
     * @param int|null            $semestre     1 ou 2, null si aucun semestre n'a pu être déduit
     * @param string|null $composante   libellé de la composante du catalogue
     * @param string|null $regroupement libellé du regroupement du catalogue
     * @param NoeudCatalogue|null $composante   composante du catalogue
     * @param NoeudCatalogue|null $regroupement regroupement du catalogue
     */
    public function __construct(
        public string $id,
@@ -25,8 +25,8 @@ final readonly class CoursCatalogue
        public ?string $type,
        public ?float $ects,
        public ?int $semestre,
        public ?string $composante,
        public ?string $regroupement,
        public ?NoeudCatalogue $composante,
        public ?NoeudCatalogue $regroupement,
    ) {
    }

Loading