# Implémentation jurys BUT

*Quelques notes informelles sur la gestion des jurys BUT.*

Fichiers sources:

```txt
app/but/jury_but.py
app/but/cursus_but.py
```

## Validations enregistrées

- UEs : comme pour les formations classiques
  
- RCUE: `ApcValidationRCUE(etudid, formsemestre, ue1, ue2)`
  - Le formsemestre est optionnel: c'est celui d'où a été émise la validation.
  - Pour retrouver le niveau, passer par l'UE: `ue1.niveau_competence`
  
- Années BUT: `ApcValidationAnnee`
  - liée au référentiel de compétence.

## La page saisie jury BUT (annuelle)

Partir de la liste des niveaux à valider pour cet étudiant dans sa scolarité,
selon le parcours de l'étudiant. Le parcours est donné par son inscription dans
le semestre courant (celui duquel on lance la saisie).
Chaque compétence forme une ligne, comme sur la fiche étudiant.
Le semestre courant donne l'année scolaire (2022, ...) et l'année BUT courante (1, 2, 3)
On affiche les colonnes suivantes (exemple d'un jury de BUT2 S4):

| BUT1          | BUT2 S2 | BUT2 S3 | BUT2 RCUE | autorisation | BUT3        |
|---------------|---------|---------|-----------|--------------|-------------|
| Compétence 1  | rcue    | UE1.3   | UE1.4     | code         | feu vert S5 |
| Compétence 2  | ...     | ...     | ...       | ...          | ...         |

sur chaque code un popup explicatif (date de validation)

Actuellement (9.4), l'état du BUT1 (et BUT2 quand on sera en BUT3) n'est pas
rappelé sur cet affichage.

### Rappel sur les validations de jury

En BUT, on va utiliser 3 types de décisions de jury: sur les UEs, les RCUEs et
les années de BUT. Une décision sur une UE concerne l'UE d'un semestre, d'une
année scolaire donnée: on peut enregistre une décision AJ sur l'UE12 en 2022,
puis ADM sur l'UE12 d'an nouveau formsemestre en 2023. Ce n'est pas le cas pour
les décisions concernant le cursus BUT: on valide (ou non) l'année BUT1, puis
BUT2 puis BUT3. Un redoublant pour avoir son BUT1 en AJ, puis il passera en ADM
l'année suivante. Pareil pour les RCUEs. Autrement dit, le code d'une année BUT
ou d'un RCUE, pour un étudiant donné, est unique.

### Validations d'UE antérieures

Les validations d'UEs externes existaient avant ScoDoc 9.
Elles sont utilisées quand un étudiant arrive en transfert avec une UE validée
mais pas un semestre complet (ne pas confondre avec les "semestres extérieurs"
qui sont gérés comme des formsemestres ordinaires).

Les UE antérieures sont présentes dans les bulletins BUT.

### Tenue du jury

Le jury part d'un formsemestre (dit origine).
Dans ce formsemestre, `etud` est inscrit à un parcours (ou au tronc commun): on
sait quels niveaux il doit valider durant année.

Le jury (pour un niveau) peut éditer:

- l'UE du formsemestre origine (qui peut être déjà validée en cas de
  modification)
- l'UE du formsemestre précédent si l'origine est impaire et que ce formsemestre
  impair n'est pas verrouillé (sinon, affichée mais en lecture seule)
- le RCUE

#### Édition décision d'UE

Le menu jury (activé par défaut) pour une UE affichera:

- Si en cours: la moyenne courante, la décision recommandée basée sur cette note
- Si validée ailleurs que dans le semestre en cours: le code et la moyenne
  enregistrés.
- Si pas en cours, menu désactivé, pas d'édition de la décision d'UE.

#### Édition décision de RCUE

Le menu RCUE est désactivé par défaut: calcul automatique en fonction des
décisions d'UE.

Le code enregistré (rappel: chaque RCUE n'a qu'un code enregistré, contrairement
aux UEs) est affiché (code couleur s'ile st différent d ecelui calculé).

La modification du code RCUE peut entrainer la modification des codes des UEs
qui le constituent: code RCUE `ADJ` => UEs non validante passées en `ADJR`
(géré par `DecisionRCUE.record` et en js dans `jury_but.js`). )

La modification de codes d'UE devrait ou pourrait modifier le code RCUE proposé,
mais ce n'est pas implémenté en 9.4.92.

### Classes

Ordre de construction:
- `DecisionsProposeesAnnee`
  - `RegroupementCoherentUE`
  - `DecisionsProposeesRCUE(rcue)`
  - `DecisionsProposeesUE`

#### `RegroupementCoherentUE(etud, ApcNiveau, ues_pair, ues_impair)`

Modélise un couple d'UEs associées au même niveau de compétence du référentiel.

L'ancienne classe `RegroupementCoherentUE` (définie dans
`models/but_validation.py`) ne répondait pas au besoin car elle était construite sur
la base de deux formsemestres. 

- On part de toutes les UEs de nos formations associées à ce niveau. On peut
  avoir un nombre quelconque d'UEs paires et impaires associées à ce niveau.

- Les UEs associées à ce niveau peuvent être:
  - validées (externes, ou dans un formsemestre connu), avec une moyenne enregistrée
  - ou en cours: dans un formsemestre suivi par l'étudiant, avec une moyenne
    d'UE calculable.

Notons qu'il peut arriver qu'aucune des UEs n'appartiennent au semestre origine
(capitalisations, validations antérieures). Dans ce cas, leurs décisions ne sont
pas toujours éditables, mais le RCUE l'est.

Pour chaque côté (impair, pair), on va chercher:

- l'UE en cours pendant l'année scolaire du formsemestre origine s'il y en a
  une (ie cherche dans les formations des formsemestres de même année scolaire
  que l'origine)
- la validation de jury enregistrée pour cette UE en cours
- la validation d'UE validante enregistrée (capitalisation ou antérieure, peu
  importe)

NB: s'il y a plusieurs UEs en cours (double inscription, erreur): prend celle du
formsemestre commencé le plus récemment.

État d'un `RegroupementCoherentUE`:

- **complete** : False si on n'a pas les deux UEs

#### Opérations sur `RegroupementCoherentUE`

- init:
  - Chercher l'UE en cours pour pair, impair: `ue_cur_pair`, `ue_cur_impair`, et
    leurs validations `validation_ue_cur_pair`, `validation_ue_cur_impair`.
  - Chercher pour pair, impair la meilleure validation d'UE enregistrée dans un
    autre formsemestre. `validation_ue_best_pair`
  - complete = les deux UEs validées ou en cours cette année
  - moy_rcue: moyenne des moyennes d'UE

#### DecisionsProposeesAnnee

- `decisions_ues` : considérer les UEs associées aux niveaux et non celles des
  semestres. Notez que même si l'étudiant n'est pas inscrit ("dispensé") à une UE
  dans le formsemestre origine, elle doit apparaitre sur la page jury.
- `rcues_annee`: liste des `RegroupementCoherentUE`
- `decisions_rcue_by_niveau`

#### DecisionsProposeesRCUE

- `record`: modifie les codes d'UE en fonction du RCUE: *si le RCUE est `ADJ`,
  les UEs non validées sont passées à `ADJR`.
  - Les validations d'UEs antérieures ou capitalisées ne sont pas concernées car
    déjà valides.
  - Si le formsemestre contenant l'UE à modifier est verrouillé, on
    modifie quand même et on émet un warning.
  - Les RCUE/UE du niveau inférieur peuvent aussi être modifiées (c'est déjà le
    cas, `ADSUP`).

#### DecisionsProposeesUE

L'objet peut représenter une validation capitalisée ou antérieure: il est alors
en lecture seule.

Pour chaque RCUE, on a les deux UEs à considérer dans `ue_1`, `ue_2`.

- Modifier affichage UE "en lecture seule"
- Ne pas restreindre la recherche aux UEs du formsemestre.
- Le calcul de la moyenne en utilisant `ResultatsSemestreBUT` n'est évidemment
  utilisé que pour l'UE en cours.
