DocScoDoc/docs/ApiGenerationBulletinsPdf.md

432 lines
16 KiB
Markdown
Raw Permalink Normal View History

# Générer des bulletins en Python
2020-09-21 16:30:27 +02:00
Il est possible de coder de nouveaux styles de bulletins de notes (web et/ou
PDF), pour répondre précisément aux besoins de votre établissement.
2020-09-21 16:30:27 +02:00
Ce n'est pas très difficile, mais il faudra coder en langage Python avec pour le
PDF la bibliothèque ReportLab (qui est bien documentée, [voir le
guide](http://www.reportlab.com/software/opensource/rl-toolkit/guide/)).
2020-09-21 16:30:27 +02:00
ScoDoc demande la création d'un bulletin pour un étudiant donné dans semestre
donné (`formsemestre_id`). Le bulletin doit être rendu sous forme d'une liste
d'objets PLATYPUS (voir le chapitre 5 du "User Guide" de ReportLab cité plus
haut).
2020-09-21 16:30:27 +02:00
<img src="/img/alert.png" style="vertical-align: bottom; margin:0 0 0 0;"
alt="/!\" /> Attention (août 2011): nouvelle version, changement d'API: les
informations ci-dessous s'appliquent à partir de la subversion 1047.
2020-09-21 16:30:27 +02:00
## Organisation
2020-09-21 16:30:27 +02:00
A minima, il vous faut créer un module python (fichier .py) qui se définira une
classe chargée de générer vos bulletins.
2020-09-21 16:30:27 +02:00
Ce fichier doit être placé dans le répertoire `/opt/scodoc/instance/Products/ScoDoc`
Il faut aussi l'importer dans `sco_bulletins_generator.py` (voir tout à la fin
de ce fichier).
2020-09-21 16:30:27 +02:00
Voici un module minimal commenté (le fichier `sco_bulletins_example.py` est
fournit avec ScoDoc):
2020-09-21 16:30:27 +02:00
```py
2020-09-21 16:30:27 +02:00
"""Génération d'un bulletin de note style "Exemple"
(commentaire libre ici)
"""
# Quelques modules [ScoDoc](ScoDoc.md) utiles:
from sco_pdf import *
import sco_preferences
from notes_log import log
import sco_bulletins_generator
import sco_bulletins_standard
class [BulletinGeneratorExample](BulletinGeneratorExample.md)(sco_bulletins_standard.BulletinGeneratorStandard):
"""Un exemple simple de bulletin de notes en version PDF seulement.
Part du bulletin standard et redéfini la partie centrale.
"""
2022-02-27 09:28:16 +01:00
description = 'exemple (ne pas utiliser)' # la description doit être courte: elle apparait dans le menu de paramétrage
2020-09-21 16:30:27 +02:00
supported_formats = [ 'pdf' ] # indique que ce générateur ne peut produire que du PDF (la version web sera donc celle standard de [ScoDoc](ScoDoc.md))
# En général, on veut définir un format de table spécial, sans changer le reste (titre, pied de page).
# Si on veut changer le reste, surcharger les méthodes:
# .bul_title_pdf(self) : partie haute du bulletin
# .bul_part_below(self, format=*) : infos sous la table
# .bul_signatures_pdf(self) : signatures
def bul_table(self, fmt=*):
2020-09-21 16:30:27 +02:00
"""Défini la partie centrale de notre bulletin PDF.
Doit renvoyer une liste d'objets PLATYPUS
"""
assert format == 'pdf' # garde fou
return [
Paragraph( SU("L'étudiant %(nomprenom)s a une moyenne générale de %(moy_gen)s" % self.infos),
self.CellStyle # un style pdf standard
)
]
# Déclarer votre classe à ScoDoc
sco_bulletins_generator.register_bulletin_class(BulletinGeneratorExample)
2020-09-21 16:30:27 +02:00
```
Si l'on voulait générer aussi du HTML (pour la version web), il suffirait de le
déclarer dans la liste `supported_formats` et que la méthode `bul_table()`
renvoie une chaîne HTML si le paramètre `fmt` vaut `'html'`.
2020-09-21 16:30:27 +02:00
Pour modifier l'en-tête du bulletin PDF (partie au dessus de la table), il faut
surcharger la méthode `bul_title_pdf` qui elle aussi renvoie une liste d'objets
PLATYPUS:
```py
2020-09-21 16:30:27 +02:00
def bul_title_pdf(self):
...
```
De même, les informations placées sous la table principale sont renvoyées par la méthode `gen_part_below`:
```py
2020-09-21 16:30:27 +02:00
def gen_part_below(self, format=*):
"""Génère les informations placées sous la table de notes
(absences, appréciations, décisions de jury...)
Renvoie:
- en HTML: une chaine
- en PDF: une liste d'objets platypus
"""
...
```
et les signatures (seulement sur le PDF) par `bul_signatures_pdf`. Toutes ces
méthodes renvoient des listes d'objets PLATYPUS quelconques.
2020-09-21 16:30:27 +02:00
Vous pouvez partir d'un format de bulletin existant et proche de ce que voulez
obtenir et définir une sous-classe modifiant (surchargeant) seulement les
méthodes qui génèrent les éléments que vous voulez modifier.
2020-09-21 16:30:27 +02:00
<img src="/img/alert.png" style="vertical-align: bottom; margin:0 0 0 0;"
alt="/!\" /> Attention: ne pas modifier après coup le nom des classes de
générateurs (ici `BulletinGeneratorExample`), car il va être stocké en base de
données par ScoDoc.
2020-09-21 16:30:27 +02:00
## Accès aux informations
2020-09-21 16:30:27 +02:00
La plupart des informations nécessaires sont accessibles via des attributs de
votre instance de générateur que ScoDoc aura positionné avant d'appeler vos
méthodes. Notamment:
2020-09-21 16:30:27 +02:00
* `self.formsemestre`: l'objet `FormSemestre`
* `self.infos`: un (grand) dictionnaire python avec la plupart des informations
préparée pour le bulletin à générer (voir plus loin);
* `self.version`: indique la version de bulletin demandée par l'utilisateur
("long" ou "short", vous pouvez en faire ce que bon vous semble);
2020-09-21 16:30:27 +02:00
## Le dictionnaire d'informations
2020-09-21 16:30:27 +02:00
L'attribut `infos` est un dictionnaire qui contient de très nombreuses
informations. il doit être utilisé en **lecture seule** (il est possible que des
informations soient partagées entre threads différents, aussi les modifier peut
avoir des effets indésirables). .
2020-09-21 16:30:27 +02:00
### Paramètres (préférences)
2020-09-21 16:30:27 +02:00
Tous les paramètres du semestre sont accessibles via leur nom. Voir la liste sur
la page [NomsPreferences](NomsPreferences.md).
2020-09-21 16:30:27 +02:00
Exemple: `infos['SCOLAR_FONT_SIZE']` est un entier, `infos['UnivName']` est le
nom de l'université.
2020-09-21 16:30:27 +02:00
### Informations sur l'étudiant
2020-09-21 16:30:27 +02:00
#### Identité
Type | Nom | Description | Exemple de valeur
----| --- | ---- | ---
| string * | etudid | id ScoDoc de l'étudiant | 'EID15219' |
string | code_ine | | *
string | code_nip | | *
string | codepostaldomicile | | '75018'
| date_naissance | | *
| annee_naissance | | '1947'
| domicile | | *
| email | | *
| lieu_naissance | | *
| nationalite | | *
| ne | "e" si étudiante, vide sinon | *
| nom | | 'FOURIER'
| prenom | | 'JOSEPH'
| sexe | | 'M.'
| nomprenom | | 'M. Joseph Fourier'
| paysdomicile | | *
| telephone | | *
| telephonemobile | | *
| telephonemobilestr | | *
| telephonestr | | *
| typeadresse | | 'domicile'
| villedomicile | | *
| villelycee | |
#### Admission
Informations importées dans ScoDoc lors de la création de l'étudiant
(import des données d'admission): établissement d'origine, notes de
lycée, etc.)
Type | Nom | Description | Exemple de valeur
----| --- | ---- | ---
| bac | Série de bac | 'S'
| specialite | Spécialité de bac | 'SVT'
| math | note math antérieure (en terminale ou au bac ou ...) | *
| physique | note physique antérieure | *
| francais | note francais (au bac en général) | *
| anglais | note anglais antérieure | *
| annee_bac | année d'obtention du bac | '2010'
| nomlycee | | *
| codelycee | | *
| codepostallycee | | *
| qualite | note de qualité du dossier attribuée par le jury d'admission | *
| rang | rang de cet établissement dans les voeux du candidat (si applicable) | *
| rap | | "Pas d'informations sur les conditions d'admission."
| rapporteur | pseudo du collègue chargé de l'examen de ce dossier | *
| score | Score calculé pour ce dossier à l'admission | *
| commentaire | Commentaire du jury d'admission| *
| decision | Décision du jury d'admission | 'ADMIS'
| description | Comment l'étudiant a été inscrit | '(creation individuelle)'
#### Inscription
Type | Nom | Description | Exemple de valeur
----| --- | ---- | ---
2023-03-08 22:57:22 +01:00
int | annee | | 2011
2020-09-21 16:30:27 +02:00
string | etatincursem | état (I=inscrit, D=démissionnaire) | 'I'
string | inscription | | 'DUT GEII, semestre 1 FI (Mars 2011 - Jul 2011)'
string | situation | | 'inscrit en DUT GEII, semestre 1 FI (Mars 2011 - Jul 2011) le 11/09/2011'
string | statut | ? | *
2023-03-08 22:57:22 +01:00
| descr_inscription | | 'Inscrit le 27/06/2011.'
2020-09-21 16:30:27 +02:00
En outre, les attributs `sems`, `cursem` et `ins` apportent des informations
sur les semestres auxquels l'étudiant est ou a été inscrit.
`etud['sems']`est une liste de dictionnaire représentants les
semestres auxquels est ou a été inscrit l'étudiant.
2023-03-08 22:57:22 +01:00
#### Parcours et référentiel BUT
Type | Nom | Description | Exemple de valeur
--------| ---------------------- | ---- | ---
string | parcours_titre | titre du parcours | "Cybersécurité"
string | parcours_code | code du parcours | "Cyber"
string | refcomp_specialite | code spécialité | "RT"
string | refcomp_specialite_long| spécialité | "Réseaux et Télécommunications"
2020-09-21 16:30:27 +02:00
### Résultats (notes) de l'étudiant dans le semestre
Quelques infos sur les résultats. Le détail des notes est dans la
liste `infos['ues']` et ses sous-listes imbriquées (modules, evaluation).
Type | Nom | Description | Exemple de valeur
----| --- | ---- | ---
string | moy_gen | moyenne générale de l'étudiant dans le semestre | '12.00'
string | bonus_sport_culture | bonus appliqué | 0
string | moy_max | moyenne max promo | '12.00'
string | moy_min | moyenne min promo | '10.00'
string | moy_moy | moyenne des moyennes promo | '11.00'
int | nb_inscrits | nombre étudiants du semestre (incluant démissionnaires et défaillants) | 78
int | nb_demissions | nombre de démissions dans le semestre | 3
int | nb_defaillants | nombre de défaillants dans le semestre | 2
int | nbabs | nombre de 1/2 journées d'absences | 0L
int | nbabsjust | idem, justifiées | 0L
string | rang | classement | '(attente)'
string | rang_txt | classement (avec titre) | 'Rang (attente) / 2'
list | ues | résultats dans les UE, voir ci-dessous | [ liste de dict ]
Chaque élément de la liste `ues` représente les résultats de
l'étudiant dans une UE.
Type | Nom | Description | Exemple de valeur
----| --- | ---- | ---
string | acronyme | | 'UE 1'
string | coef_ue_txt | Coefficient (chaîne) | '2'
string| cur_moy_ue_txt | Moyenne prise en compte pour cette UE | '12.00'
float | max | moyenne max promo | 12.0
float | min | moyenne min promo | 10.0
list | modules | détails notes dans les modules de l'UE | [ liste de dict]
list | modules_capitalized | | []
float | moy | | 11.0
string | moy_ue_txt | moyenne étudiant dans UE | '12.00'
int | nb_moy | nombre de moyenens calculées dans cette UE (inscrits, sans démissionnaires ni défaillants) | 76
int | numero | rang tri UE | 1
string | titre | | 'Formation Générale'
int | type | code type UE | 0
string | ue_code | code dans programme formation | 'UCOD5'
string | ue_descr_html | rang ou autre info à afficher | '(attente)/2'
string | ue_descr_txt | rang ou autre info à afficher | '(attente)/2'
string | ue_id | id interne ScoDoc | 'UE14572'
dict | ue_status | statut de l'UE (voir ci-dessous)| { dict }
**Statut d'une UE (champ `ue_status`):**
Type | Nom | Description | Exemple de valeur
----| --- | ---- | ---
float | coef_ue | | 2.0
| coefs_bonus_gen | | []
| cur_coef_ue | | 2.0
| cur_moy_ue | | 12.0
string | expr_diag | infos erreur calcul formule utilisateur | {}
bool | is_capitalized | est-elle capitalisée? | False
| moy | | 12.0
| nb_missing | | 1
| nb_notes | | 1
| notes_bonus_gen | | []
| sum_coefs | | 2.0
| was_capitalized | | False
**Résultats dans un module:**
Type | Nom | Description | Exemple de valeur
----| --- | ---- | ---
| code | | *
| code_html | | *
| code_txt | | *
| computation_expr | | *
| ens | | []
| evaluations | | []
| formsemestre_id | | 'SEM15176'
| mat | | {'titre': 'Mathématiques' }
| mod_coef_txt | | '2'
| mod_descr_txt | | "Module Fondamentaux d'algèbre et de trigonométrie, coef. 2 (Béatrice DUPONT)"
| mod_eff | | 2
| mod_moy_txt | | '12.00'
| mod_rang | | '(attente)'
| mod_rang_txt | | '(attente)/2'
| module | | {voir plus loin}
| module_id | | 'MOD14576'
| moduleimpl_id | | 'MIP15178'
| name | | 'Algèbre'
| responsable_id | id du responsable | 'dupont'
| stats | statistiques sur les notes du module | `{'moy': 9.576, 'nb_missing': 2, 'max': 16.5, 'min': 0.0, 'nb_notes': 39, 'nb_valid_evals': 1}`
Le module (tel que décrit dans le programme de la formation) est représenté par:
Type | Nom | Description | Exemple de valeur
----| --- | ---- | ---
string | titre | | "Fondamentaux d'algèbre et de trigonométrie"
string | abbrev | | 'Algèbre'
string | code | | 'M1'
float | coefficient | | 2.0
| ects | | None
| formation_id | | 'FORM14570'
| heures_cours | | 0.0
| heures_td | | 30.0
| heures_tp | | 0.0
| matiere_id | | 'MAT14574'
| module_id | | 'MOD14576'
| numero | | 10
| semestre_id | | 1
| ue_id | | 'UE14572'
**Résultat dans une évaluation:**
Type | Nom | Description | Exemple de valeur
----| --- | ---- | ---
| coef_txt | | '1'
| coefficient | | 1.0
| descrheure | | ' ? 08h00'
| description | | *
| duree | | '2h'
| etat | | { voir plus loin }
| evaluation_id | | 'EVAL15226'
| evaluation_type | | 0
| heure_debut | | '08h00'
| heure_fin | | '08h00'
| jour | | '01/07/2011'
| moduleimpl_id | | 'MIP15178'
| name | | 'le 01/07/2011'
| nb_abs | | 0
| nb_att | | 0
| nb_inscrits | | 2
| nb_neutre | | 0
| nb_notes | | 2
| note_html | | '12.00'
| note_max | | 20.0
| note_txt | | '12.00'
| notes | | { voir plus loin }
| publish_incomplete | | '0'
| visibulletin | | '1'
**Etat d'une évaluation:**
Le champ `etat` d'une évaluation est un dict donnant des informations sur les résultats de la promo (et des groupes) dans cette évaluation:
2020-09-21 16:30:27 +02:00
Type | Nom | Description | Exemple de valeur
2020-09-21 16:30:27 +02:00
----| --- | ---- | ---
bool | evalattente | | False
bool | evalcomplete | | True
| evaluation_id | id interne | 15226
2020-09-21 16:30:27 +02:00
list | gr_incomplets | | []
list | gr_moyennes | | []
list | groups | liste des groupes | {}
datetime | last_modif | | datetime
2020-09-21 16:30:27 +02:00
string | median | note médianne promo | '11.00'
string | moy | note moyenne promo | '11.00'
| nb_abs | nb étudiants absents | 0
| nb_att | nb notes en attente | 0
| nb_inscrits | nb inscrits à ce module | 2
| nb_neutre | nb notes neutralisées | 0
| nb_notes | nb notes saisies | 2
`gr_moyennes` est un dict:
Type | Nom | Description | Exemple de valeur
----| --- | ---- | ---
| gr_median | | '11.00'
| gr_moy | | '11.00'
| gr_nb_att | | 0
| gr_nb_notes | | 2
| group_id | | 'G24919'
| group_name | | None
**Notes dans une évaluation:**
Le champ `notes` dans une évaluation est un dictionnaire dont les clés sont les `etudids`, et les valeurs des dictionnaires donnant les informations sur la note de l'étudiant dans cette évaluation:
Type | Nom | Description | Exemple de valeur
----| --- | ---- | ---
string | comment | commentaire saisie note | *
datetime | date | date de saisie | <mx.DateTime.DateTime object>
string | etudid | | 'EID15214'
string | evaluation_id | | 'EVAL15226'
string | uid | utilisateur ayant saisi la note | 'admin'
float | value | valeur de la note (sur 20) | 10.0
### Décisions de jury et autres informations
Type | Nom | Description | Exemple de valeur
----| --- | ---- | ---
| decision_sem | | None ou dict
string | decision_jury | décision du jury en clair (présent seulement si décision saisie) | 'Validé'
list | appreciations | | []
list | appreciations_list | | []
list | appreciations_txt | | []
string | mention | texte de la mention calculée | 'Très bien'
| filigranne | texte en surimpression | 'Provisoire'
## Note: la fonction log
2022-10-31 14:45:52 +01:00
Pour la mise au point, il peut être utile de recourir à la bonne vieille
fonction log, qui envoie du texte dans le fichier de log courant, normalement
`/opt/scodoc-data/log/scodoc.log`. La date et le saut de ligne final sont
automatiquement ajoutés.
2020-09-21 16:30:27 +02:00
```
log("toto")
```