forked from ScoDoc/ScoDoc
Accepte codage boursiers O/N (USPN), fonction de resynchro globale, table de tous les étudiants courants avec état boursier.
This commit is contained in:
parent
60109bb513
commit
568c8681ba
@ -271,23 +271,11 @@ def dept_formsemestres_courants(acronym: str):
|
|||||||
"""
|
"""
|
||||||
dept = Departement.query.filter_by(acronym=acronym).first_or_404()
|
dept = Departement.query.filter_by(acronym=acronym).first_or_404()
|
||||||
date_courante = request.args.get("date_courante")
|
date_courante = request.args.get("date_courante")
|
||||||
if date_courante:
|
date_courante = datetime.fromisoformat(date_courante) if date_courante else None
|
||||||
test_date = datetime.fromisoformat(date_courante)
|
|
||||||
else:
|
|
||||||
test_date = app.db.func.now()
|
|
||||||
# Les semestres en cours de ce département
|
|
||||||
formsemestres = FormSemestre.query.filter(
|
|
||||||
FormSemestre.dept_id == dept.id,
|
|
||||||
FormSemestre.date_debut <= test_date,
|
|
||||||
FormSemestre.date_fin >= test_date,
|
|
||||||
)
|
|
||||||
return [
|
return [
|
||||||
d.to_dict_api()
|
formsemestre.to_dict_api()
|
||||||
for d in formsemestres.order_by(
|
for formsemestre in FormSemestre.get_dept_formsemestres_courants(
|
||||||
FormSemestre.date_debut.desc(),
|
dept, date_courante
|
||||||
FormSemestre.modalite,
|
|
||||||
FormSemestre.semestre_id,
|
|
||||||
FormSemestre.titre,
|
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ from app.models.but_refcomp import (
|
|||||||
parcours_formsemestre,
|
parcours_formsemestre,
|
||||||
)
|
)
|
||||||
from app.models.config import ScoDocSiteConfig
|
from app.models.config import ScoDocSiteConfig
|
||||||
|
from app.models.departements import Departement
|
||||||
from app.models.etudiants import Identite
|
from app.models.etudiants import Identite
|
||||||
from app.models.evaluations import Evaluation
|
from app.models.evaluations import Evaluation
|
||||||
from app.models.formations import Formation
|
from app.models.formations import Formation
|
||||||
@ -521,7 +522,7 @@ class FormSemestre(db.Model):
|
|||||||
mois_pivot_periode=scu.MONTH_DEBUT_PERIODE2,
|
mois_pivot_periode=scu.MONTH_DEBUT_PERIODE2,
|
||||||
jour_pivot_annee=1,
|
jour_pivot_annee=1,
|
||||||
jour_pivot_periode=1,
|
jour_pivot_periode=1,
|
||||||
):
|
) -> tuple[int, int]:
|
||||||
"""Calcule la session associée à un formsemestre commençant en date_debut
|
"""Calcule la session associée à un formsemestre commençant en date_debut
|
||||||
sous la forme (année, période)
|
sous la forme (année, période)
|
||||||
année: première année de l'année scolaire
|
année: première année de l'année scolaire
|
||||||
@ -571,6 +572,26 @@ class FormSemestre(db.Model):
|
|||||||
mois_pivot_periode=ScoDocSiteConfig.get_month_debut_periode2(),
|
mois_pivot_periode=ScoDocSiteConfig.get_month_debut_periode2(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_dept_formsemestres_courants(
|
||||||
|
cls, dept: Departement, date_courante: datetime.datetime | None = None
|
||||||
|
) -> db.Query:
|
||||||
|
"""Liste (query) ordonnée des formsemestres courants, c'est
|
||||||
|
à dire contenant la date courant (si None, la date actuelle)"""
|
||||||
|
date_courante = date_courante or db.func.now()
|
||||||
|
# Les semestres en cours de ce département
|
||||||
|
formsemestres = FormSemestre.query.filter(
|
||||||
|
FormSemestre.dept_id == dept.id,
|
||||||
|
FormSemestre.date_debut <= date_courante,
|
||||||
|
FormSemestre.date_fin >= date_courante,
|
||||||
|
)
|
||||||
|
return formsemestres.order_by(
|
||||||
|
FormSemestre.date_debut.desc(),
|
||||||
|
FormSemestre.modalite,
|
||||||
|
FormSemestre.semestre_id,
|
||||||
|
FormSemestre.titre,
|
||||||
|
)
|
||||||
|
|
||||||
def etapes_apo_vdi(self) -> list[ApoEtapeVDI]:
|
def etapes_apo_vdi(self) -> list[ApoEtapeVDI]:
|
||||||
"Liste des vdis"
|
"Liste des vdis"
|
||||||
# was read_formsemestre_etapes
|
# was read_formsemestre_etapes
|
||||||
|
@ -149,21 +149,49 @@ def index_html(showcodes=0, showsemtable=0):
|
|||||||
</p>"""
|
</p>"""
|
||||||
)
|
)
|
||||||
#
|
#
|
||||||
if current_user.has_permission(Permission.EtudInscrit):
|
|
||||||
H.append(
|
H.append(
|
||||||
"""<hr>
|
"""<hr>
|
||||||
<h3>Gestion des étudiants</h3>
|
<h3>Gestion des étudiants</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a class="stdlink" href="etudident_create_form">créer <em>un</em> nouvel étudiant</a>
|
"""
|
||||||
|
)
|
||||||
|
if current_user.has_permission(Permission.EtudInscrit):
|
||||||
|
H.append(
|
||||||
|
f"""
|
||||||
|
<li><a class="stdlink" href="{
|
||||||
|
url_for("scolar.etudident_create_form", scodoc_dept=g.scodoc_dept)
|
||||||
|
}">créer <em>un</em> nouvel étudiant</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a class="stdlink" href="form_students_import_excel">importer de nouveaux étudiants</a>
|
<li><a class="stdlink" href="{
|
||||||
(ne pas utiliser sauf cas particulier, utilisez plutôt le lien dans
|
url_for("scolar.form_students_import_excel", scodoc_dept=g.scodoc_dept)
|
||||||
|
}">importer de nouveaux étudiants</a>
|
||||||
|
(<em>ne pas utiliser</em> sauf cas particulier : utilisez plutôt le lien dans
|
||||||
le tableau de bord semestre si vous souhaitez inscrire les
|
le tableau de bord semestre si vous souhaitez inscrire les
|
||||||
étudiants importés à un semestre)
|
étudiants importés à un semestre)
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
H.append(
|
||||||
|
f"""
|
||||||
|
<li><a class="stdlink" href="{
|
||||||
|
url_for("scolar.export_etudiants_courants", scodoc_dept=g.scodoc_dept)
|
||||||
|
}">exporter tableau des étudiants des semestres en cours</a>
|
||||||
|
</li>
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
if current_user.has_permission(
|
||||||
|
Permission.EtudInscrit
|
||||||
|
) and sco_preferences.get_preference("portal_url"):
|
||||||
|
H.append(
|
||||||
|
f"""
|
||||||
|
<li><a class="stdlink" href="{
|
||||||
|
url_for("scolar.formsemestre_import_etud_admission",
|
||||||
|
scodoc_dept=g.scodoc_dept, tous_courants=1)
|
||||||
|
}">resynchroniser les données étudiants des semestres en cours depuis le portail</a>
|
||||||
|
</li>
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
H.append("</ul>")
|
||||||
#
|
#
|
||||||
if current_user.has_permission(Permission.EditApogee):
|
if current_user.has_permission(Permission.EditApogee):
|
||||||
H.append(
|
H.append(
|
||||||
|
@ -793,21 +793,25 @@ def update_etape_formsemestre_inscription(ins, etud):
|
|||||||
|
|
||||||
|
|
||||||
def formsemestre_import_etud_admission(
|
def formsemestre_import_etud_admission(
|
||||||
formsemestre_id, import_identite=True, import_email=False
|
formsemestre_id: int, import_identite=True, import_email=False
|
||||||
):
|
) -> tuple[list[Identite], list[Identite], list[tuple[Identite, str]]]:
|
||||||
"""Tente d'importer les données admission depuis le portail
|
"""Tente d'importer les données admission depuis le portail
|
||||||
pour tous les étudiants du semestre.
|
pour tous les étudiants du semestre.
|
||||||
Si import_identite==True, recopie l'identité (nom/prenom/sexe/date_naissance)
|
Si import_identite==True, recopie l'identité (nom/prenom/sexe/date_naissance)
|
||||||
de chaque étudiant depuis le portail.
|
de chaque étudiant depuis le portail.
|
||||||
N'affecte pas les etudiants inconnus sur le portail.
|
N'affecte pas les etudiants inconnus sur le portail.
|
||||||
|
Renvoie:
|
||||||
|
- etuds_no_nip: liste d'étudiants sans code NIP
|
||||||
|
- etuds_unknown: etudiants avec NIP mais inconnus du portail
|
||||||
|
- changed_mails: (etudiant, old_mail) pour ceux dont le mail a changé
|
||||||
"""
|
"""
|
||||||
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
|
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
|
||||||
ins = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(
|
ins = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(
|
||||||
{"formsemestre_id": formsemestre_id}
|
{"formsemestre_id": formsemestre_id}
|
||||||
)
|
)
|
||||||
log(f"formsemestre_import_etud_admission: {formsemestre_id} ({len(ins)} etuds)")
|
log(f"formsemestre_import_etud_admission: {formsemestre_id} ({len(ins)} etuds)")
|
||||||
no_nip = [] # liste d'etudids sans code NIP
|
etuds_no_nip: list[Identite] = []
|
||||||
unknowns = [] # etudiants avec NIP mais inconnus du portail
|
etuds_unknown: list[Identite] = []
|
||||||
changed_mails: list[tuple[Identite, str]] = [] # modification d'adresse mails
|
changed_mails: list[tuple[Identite, str]] = [] # modification d'adresse mails
|
||||||
|
|
||||||
# Essaie de recuperer les etudiants des étapes, car
|
# Essaie de recuperer les etudiants des étapes, car
|
||||||
@ -828,7 +832,7 @@ def formsemestre_import_etud_admission(
|
|||||||
etud: Identite = Identite.query.get_or_404(etudid)
|
etud: Identite = Identite.query.get_or_404(etudid)
|
||||||
code_nip = etud.code_nip
|
code_nip = etud.code_nip
|
||||||
if not code_nip:
|
if not code_nip:
|
||||||
no_nip.append(etudid)
|
etuds_no_nip.append(etud)
|
||||||
else:
|
else:
|
||||||
data_apo = apo_etuds.get(code_nip)
|
data_apo = apo_etuds.get(code_nip)
|
||||||
if not data_apo:
|
if not data_apo:
|
||||||
@ -865,7 +869,7 @@ def formsemestre_import_etud_admission(
|
|||||||
if adresse.email != data_apo["mail"]:
|
if adresse.email != data_apo["mail"]:
|
||||||
changed_mails.append((etud, old_mail))
|
changed_mails.append((etud, old_mail))
|
||||||
else:
|
else:
|
||||||
unknowns.append(code_nip)
|
etuds_unknown.append(etud)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
sco_cache.invalidate_formsemestre(formsemestre_id=sem["formsemestre_id"])
|
sco_cache.invalidate_formsemestre(formsemestre_id=sem["formsemestre_id"])
|
||||||
return no_nip, unknowns, changed_mails
|
return etuds_no_nip, etuds_unknown, changed_mails
|
||||||
|
@ -138,111 +138,111 @@ table.dataTable.display tbody tr:hover.selected {
|
|||||||
background-color: #a9b7d1;
|
background-color: #a9b7d1;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.dataTable.order-column tbody tr>.sorting_1,
|
table.dataTable.order-column tbody tr > .sorting_1,
|
||||||
table.dataTable.order-column tbody tr>.sorting_2,
|
table.dataTable.order-column tbody tr > .sorting_2,
|
||||||
table.dataTable.order-column tbody tr>.sorting_3,
|
table.dataTable.order-column tbody tr > .sorting_3,
|
||||||
table.dataTable.display tbody tr>.sorting_1,
|
table.dataTable.display tbody tr > .sorting_1,
|
||||||
table.dataTable.display tbody tr>.sorting_2,
|
table.dataTable.display tbody tr > .sorting_2,
|
||||||
table.dataTable.display tbody tr>.sorting_3 {
|
table.dataTable.display tbody tr > .sorting_3 {
|
||||||
background-color: #f9f9f9;
|
background-color: #f9f9f9;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.dataTable.order-column tbody tr.selected>.sorting_1,
|
table.dataTable.order-column tbody tr.selected > .sorting_1,
|
||||||
table.dataTable.order-column tbody tr.selected>.sorting_2,
|
table.dataTable.order-column tbody tr.selected > .sorting_2,
|
||||||
table.dataTable.order-column tbody tr.selected>.sorting_3,
|
table.dataTable.order-column tbody tr.selected > .sorting_3,
|
||||||
table.dataTable.display tbody tr.selected>.sorting_1,
|
table.dataTable.display tbody tr.selected > .sorting_1,
|
||||||
table.dataTable.display tbody tr.selected>.sorting_2,
|
table.dataTable.display tbody tr.selected > .sorting_2,
|
||||||
table.dataTable.display tbody tr.selected>.sorting_3 {
|
table.dataTable.display tbody tr.selected > .sorting_3 {
|
||||||
background-color: #acbad4;
|
background-color: #acbad4;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.dataTable.display tbody tr.odd>.sorting_1,
|
table.dataTable.display tbody tr.odd > .sorting_1,
|
||||||
table.dataTable.order-column.stripe tbody tr.odd>.sorting_1 {
|
table.dataTable.order-column.stripe tbody tr.odd > .sorting_1 {
|
||||||
background-color: #f1f1f1;
|
background-color: #f1f1f1;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.dataTable.display tbody tr.odd>.sorting_2,
|
table.dataTable.display tbody tr.odd > .sorting_2,
|
||||||
table.dataTable.order-column.stripe tbody tr.odd>.sorting_2 {
|
table.dataTable.order-column.stripe tbody tr.odd > .sorting_2 {
|
||||||
background-color: #f3f3f3;
|
background-color: #f3f3f3;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.dataTable.display tbody tr.odd>.sorting_3,
|
table.dataTable.display tbody tr.odd > .sorting_3,
|
||||||
table.dataTable.order-column.stripe tbody tr.odd>.sorting_3 {
|
table.dataTable.order-column.stripe tbody tr.odd > .sorting_3 {
|
||||||
background-color: whitesmoke;
|
background-color: whitesmoke;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.dataTable.display tbody tr.odd.selected>.sorting_1,
|
table.dataTable.display tbody tr.odd.selected > .sorting_1,
|
||||||
table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_1 {
|
table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_1 {
|
||||||
background-color: #a6b3cd;
|
background-color: #a6b3cd;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.dataTable.display tbody tr.odd.selected>.sorting_2,
|
table.dataTable.display tbody tr.odd.selected > .sorting_2,
|
||||||
table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_2 {
|
table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_2 {
|
||||||
background-color: #a7b5ce;
|
background-color: #a7b5ce;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.dataTable.display tbody tr.odd.selected>.sorting_3,
|
table.dataTable.display tbody tr.odd.selected > .sorting_3,
|
||||||
table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_3 {
|
table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_3 {
|
||||||
background-color: #a9b6d0;
|
background-color: #a9b6d0;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.dataTable.display tbody tr.even>.sorting_1,
|
table.dataTable.display tbody tr.even > .sorting_1,
|
||||||
table.dataTable.order-column.stripe tbody tr.even>.sorting_1 {
|
table.dataTable.order-column.stripe tbody tr.even > .sorting_1 {
|
||||||
background-color: #f9f9f9;
|
background-color: #f9f9f9;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.dataTable.display tbody tr.even>.sorting_2,
|
table.dataTable.display tbody tr.even > .sorting_2,
|
||||||
table.dataTable.order-column.stripe tbody tr.even>.sorting_2 {
|
table.dataTable.order-column.stripe tbody tr.even > .sorting_2 {
|
||||||
background-color: #fbfbfb;
|
background-color: #fbfbfb;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.dataTable.display tbody tr.even>.sorting_3,
|
table.dataTable.display tbody tr.even > .sorting_3,
|
||||||
table.dataTable.order-column.stripe tbody tr.even>.sorting_3 {
|
table.dataTable.order-column.stripe tbody tr.even > .sorting_3 {
|
||||||
background-color: #fdfdfd;
|
background-color: #fdfdfd;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.dataTable.display tbody tr.even.selected>.sorting_1,
|
table.dataTable.display tbody tr.even.selected > .sorting_1,
|
||||||
table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_1 {
|
table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_1 {
|
||||||
background-color: #acbad4;
|
background-color: #acbad4;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.dataTable.display tbody tr.even.selected>.sorting_2,
|
table.dataTable.display tbody tr.even.selected > .sorting_2,
|
||||||
table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_2 {
|
table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_2 {
|
||||||
background-color: #adbbd6;
|
background-color: #adbbd6;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.dataTable.display tbody tr.even.selected>.sorting_3,
|
table.dataTable.display tbody tr.even.selected > .sorting_3,
|
||||||
table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_3 {
|
table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_3 {
|
||||||
background-color: #afbdd8;
|
background-color: #afbdd8;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.dataTable.display tbody tr:hover>.sorting_1,
|
table.dataTable.display tbody tr:hover > .sorting_1,
|
||||||
table.dataTable.order-column.hover tbody tr:hover>.sorting_1 {
|
table.dataTable.order-column.hover tbody tr:hover > .sorting_1 {
|
||||||
background-color: #eaeaea;
|
background-color: #eaeaea;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.dataTable.display tbody tr:hover>.sorting_2,
|
table.dataTable.display tbody tr:hover > .sorting_2,
|
||||||
table.dataTable.order-column.hover tbody tr:hover>.sorting_2 {
|
table.dataTable.order-column.hover tbody tr:hover > .sorting_2 {
|
||||||
background-color: #ebebeb;
|
background-color: #ebebeb;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.dataTable.display tbody tr:hover>.sorting_3,
|
table.dataTable.display tbody tr:hover > .sorting_3,
|
||||||
table.dataTable.order-column.hover tbody tr:hover>.sorting_3 {
|
table.dataTable.order-column.hover tbody tr:hover > .sorting_3 {
|
||||||
background-color: #eeeeee;
|
background-color: #eeeeee;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.dataTable.display tbody tr:hover.selected>.sorting_1,
|
table.dataTable.display tbody tr:hover.selected > .sorting_1,
|
||||||
table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_1 {
|
table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_1 {
|
||||||
background-color: #a1aec7;
|
background-color: #a1aec7;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.dataTable.display tbody tr:hover.selected>.sorting_2,
|
table.dataTable.display tbody tr:hover.selected > .sorting_2,
|
||||||
table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_2 {
|
table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_2 {
|
||||||
background-color: #a2afc8;
|
background-color: #a2afc8;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.dataTable.display tbody tr:hover.selected>.sorting_3,
|
table.dataTable.display tbody tr:hover.selected > .sorting_3,
|
||||||
table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_3 {
|
table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_3 {
|
||||||
background-color: #a4b2cb;
|
background-color: #a4b2cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -419,7 +419,13 @@ table.dataTable td {
|
|||||||
color: #333333 !important;
|
color: #333333 !important;
|
||||||
border: 1px solid #979797;
|
border: 1px solid #979797;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, white), color-stop(100%, gainsboro));
|
background: -webkit-gradient(
|
||||||
|
linear,
|
||||||
|
left top,
|
||||||
|
left bottom,
|
||||||
|
color-stop(0%, white),
|
||||||
|
color-stop(100%, gainsboro)
|
||||||
|
);
|
||||||
/* Chrome,Safari4+ */
|
/* Chrome,Safari4+ */
|
||||||
background: -webkit-linear-gradient(top, white 0%, gainsboro 100%);
|
background: -webkit-linear-gradient(top, white 0%, gainsboro 100%);
|
||||||
/* Chrome10+,Safari5.1+ */
|
/* Chrome10+,Safari5.1+ */
|
||||||
@ -447,7 +453,13 @@ table.dataTable td {
|
|||||||
color: white !important;
|
color: white !important;
|
||||||
border: 1px solid #111111;
|
border: 1px solid #111111;
|
||||||
background-color: #585858;
|
background-color: #585858;
|
||||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111111));
|
background: -webkit-gradient(
|
||||||
|
linear,
|
||||||
|
left top,
|
||||||
|
left bottom,
|
||||||
|
color-stop(0%, #585858),
|
||||||
|
color-stop(100%, #111111)
|
||||||
|
);
|
||||||
/* Chrome,Safari4+ */
|
/* Chrome,Safari4+ */
|
||||||
background: -webkit-linear-gradient(top, #585858 0%, #111111 100%);
|
background: -webkit-linear-gradient(top, #585858 0%, #111111 100%);
|
||||||
/* Chrome10+,Safari5.1+ */
|
/* Chrome10+,Safari5.1+ */
|
||||||
@ -464,7 +476,13 @@ table.dataTable td {
|
|||||||
.dataTables_wrapper .dataTables_paginate .paginate_button:active {
|
.dataTables_wrapper .dataTables_paginate .paginate_button:active {
|
||||||
outline: none;
|
outline: none;
|
||||||
background-color: #2b2b2b;
|
background-color: #2b2b2b;
|
||||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c));
|
background: -webkit-gradient(
|
||||||
|
linear,
|
||||||
|
left top,
|
||||||
|
left bottom,
|
||||||
|
color-stop(0%, #2b2b2b),
|
||||||
|
color-stop(100%, #0c0c0c)
|
||||||
|
);
|
||||||
/* Chrome,Safari4+ */
|
/* Chrome,Safari4+ */
|
||||||
background: -webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);
|
background: -webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);
|
||||||
/* Chrome10+,Safari5.1+ */
|
/* Chrome10+,Safari5.1+ */
|
||||||
@ -495,12 +513,50 @@ table.dataTable td {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(25%, rgba(255, 255, 255, 0.9)), color-stop(75%, rgba(255, 255, 255, 0.9)), color-stop(100%, rgba(255, 255, 255, 0)));
|
background: -webkit-gradient(
|
||||||
background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
|
linear,
|
||||||
background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
|
left top,
|
||||||
background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
|
right top,
|
||||||
background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
|
color-stop(0%, rgba(255, 255, 255, 0)),
|
||||||
background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
|
color-stop(25%, rgba(255, 255, 255, 0.9)),
|
||||||
|
color-stop(75%, rgba(255, 255, 255, 0.9)),
|
||||||
|
color-stop(100%, rgba(255, 255, 255, 0))
|
||||||
|
);
|
||||||
|
background: -webkit-linear-gradient(
|
||||||
|
left,
|
||||||
|
rgba(255, 255, 255, 0) 0%,
|
||||||
|
rgba(255, 255, 255, 0.9) 25%,
|
||||||
|
rgba(255, 255, 255, 0.9) 75%,
|
||||||
|
rgba(255, 255, 255, 0) 100%
|
||||||
|
);
|
||||||
|
background: -moz-linear-gradient(
|
||||||
|
left,
|
||||||
|
rgba(255, 255, 255, 0) 0%,
|
||||||
|
rgba(255, 255, 255, 0.9) 25%,
|
||||||
|
rgba(255, 255, 255, 0.9) 75%,
|
||||||
|
rgba(255, 255, 255, 0) 100%
|
||||||
|
);
|
||||||
|
background: -ms-linear-gradient(
|
||||||
|
left,
|
||||||
|
rgba(255, 255, 255, 0) 0%,
|
||||||
|
rgba(255, 255, 255, 0.9) 25%,
|
||||||
|
rgba(255, 255, 255, 0.9) 75%,
|
||||||
|
rgba(255, 255, 255, 0) 100%
|
||||||
|
);
|
||||||
|
background: -o-linear-gradient(
|
||||||
|
left,
|
||||||
|
rgba(255, 255, 255, 0) 0%,
|
||||||
|
rgba(255, 255, 255, 0.9) 25%,
|
||||||
|
rgba(255, 255, 255, 0.9) 75%,
|
||||||
|
rgba(255, 255, 255, 0) 100%
|
||||||
|
);
|
||||||
|
background: linear-gradient(
|
||||||
|
to right,
|
||||||
|
rgba(255, 255, 255, 0) 0%,
|
||||||
|
rgba(255, 255, 255, 0.9) 25%,
|
||||||
|
rgba(255, 255, 255, 0.9) 75%,
|
||||||
|
rgba(255, 255, 255, 0) 100%
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dataTables_wrapper .dataTables_length,
|
.dataTables_wrapper .dataTables_length,
|
||||||
@ -520,17 +576,69 @@ table.dataTable td {
|
|||||||
-webkit-overflow-scrolling: touch;
|
-webkit-overflow-scrolling: touch;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>th,
|
.dataTables_wrapper
|
||||||
.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>td,
|
.dataTables_scroll
|
||||||
.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>th,
|
div.dataTables_scrollBody
|
||||||
.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>td {
|
> table
|
||||||
|
> thead
|
||||||
|
> tr
|
||||||
|
> th,
|
||||||
|
.dataTables_wrapper
|
||||||
|
.dataTables_scroll
|
||||||
|
div.dataTables_scrollBody
|
||||||
|
> table
|
||||||
|
> thead
|
||||||
|
> tr
|
||||||
|
> td,
|
||||||
|
.dataTables_wrapper
|
||||||
|
.dataTables_scroll
|
||||||
|
div.dataTables_scrollBody
|
||||||
|
> table
|
||||||
|
> tbody
|
||||||
|
> tr
|
||||||
|
> th,
|
||||||
|
.dataTables_wrapper
|
||||||
|
.dataTables_scroll
|
||||||
|
div.dataTables_scrollBody
|
||||||
|
> table
|
||||||
|
> tbody
|
||||||
|
> tr
|
||||||
|
> td {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>th>div.dataTables_sizing,
|
.dataTables_wrapper
|
||||||
.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>td>div.dataTables_sizing,
|
.dataTables_scroll
|
||||||
.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>th>div.dataTables_sizing,
|
div.dataTables_scrollBody
|
||||||
.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>td>div.dataTables_sizing {
|
> table
|
||||||
|
> thead
|
||||||
|
> tr
|
||||||
|
> th
|
||||||
|
> div.dataTables_sizing,
|
||||||
|
.dataTables_wrapper
|
||||||
|
.dataTables_scroll
|
||||||
|
div.dataTables_scrollBody
|
||||||
|
> table
|
||||||
|
> thead
|
||||||
|
> tr
|
||||||
|
> td
|
||||||
|
> div.dataTables_sizing,
|
||||||
|
.dataTables_wrapper
|
||||||
|
.dataTables_scroll
|
||||||
|
div.dataTables_scrollBody
|
||||||
|
> table
|
||||||
|
> tbody
|
||||||
|
> tr
|
||||||
|
> th
|
||||||
|
> div.dataTables_sizing,
|
||||||
|
.dataTables_wrapper
|
||||||
|
.dataTables_scroll
|
||||||
|
div.dataTables_scrollBody
|
||||||
|
> table
|
||||||
|
> tbody
|
||||||
|
> tr
|
||||||
|
> td
|
||||||
|
> div.dataTables_sizing {
|
||||||
height: 0;
|
height: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
margin: 0 !important;
|
margin: 0 !important;
|
||||||
@ -541,8 +649,8 @@ table.dataTable td {
|
|||||||
border-bottom: 1px solid #111111;
|
border-bottom: 1px solid #111111;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dataTables_wrapper.no-footer div.dataTables_scrollHead>table,
|
.dataTables_wrapper.no-footer div.dataTables_scrollHead > table,
|
||||||
.dataTables_wrapper.no-footer div.dataTables_scrollBody>table {
|
.dataTables_wrapper.no-footer div.dataTables_scrollBody > table {
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -555,7 +663,6 @@ table.dataTable td {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 767px) {
|
@media screen and (max-width: 767px) {
|
||||||
|
|
||||||
.dataTables_wrapper .dataTables_info,
|
.dataTables_wrapper .dataTables_info,
|
||||||
.dataTables_wrapper .dataTables_paginate {
|
.dataTables_wrapper .dataTables_paginate {
|
||||||
float: none;
|
float: none;
|
||||||
@ -568,7 +675,6 @@ table.dataTable td {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 640px) {
|
@media screen and (max-width: 640px) {
|
||||||
|
|
||||||
.dataTables_wrapper .dataTables_length,
|
.dataTables_wrapper .dataTables_length,
|
||||||
.dataTables_wrapper .dataTables_filter {
|
.dataTables_wrapper .dataTables_filter {
|
||||||
float: none;
|
float: none;
|
||||||
@ -580,7 +686,6 @@ table.dataTable td {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ------ Ajouts spécifiques pour ScoDoc:
|
/* ------ Ajouts spécifiques pour ScoDoc:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -624,7 +729,6 @@ table.dataTable.stripe.hover tbody tr.odd:hover td,
|
|||||||
table.dataTable.stripe.hover tbody tr.odd:hover td.sorting_1,
|
table.dataTable.stripe.hover tbody tr.odd:hover td.sorting_1,
|
||||||
table.dataTable.order-column.stripe.hover tbody tr.odd:hover td.sorting_1 {
|
table.dataTable.order-column.stripe.hover tbody tr.odd:hover td.sorting_1 {
|
||||||
background-color: rgb(80%, 85%, 80%);
|
background-color: rgb(80%, 85%, 80%);
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lignes paires */
|
/* Lignes paires */
|
||||||
@ -638,7 +742,6 @@ table.dataTable.stripe.hover tbody tr.even:hover td,
|
|||||||
table.dataTable.stripe.hover tbody tr.even:hover td.sorting_1,
|
table.dataTable.stripe.hover tbody tr.even:hover td.sorting_1,
|
||||||
table.dataTable.order-column.stripe.hover tbody tr.even:hover td.sorting_1 {
|
table.dataTable.order-column.stripe.hover tbody tr.even:hover td.sorting_1 {
|
||||||
background-color: rgb(85%, 85%, 85%);
|
background-color: rgb(85%, 85%, 85%);
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reglage largeur de la table */
|
/* Reglage largeur de la table */
|
||||||
@ -653,3 +756,8 @@ table.dataTable.gt_table {
|
|||||||
table.dataTable.gt_table.gt_left {
|
table.dataTable.gt_table.gt_left {
|
||||||
margin-left: 16px;
|
margin-left: 16px;
|
||||||
}
|
}
|
||||||
|
table.dataTable.gt_table.gt_left td,
|
||||||
|
table.dataTable.gt_table.gt_left th {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
scodoc;css
|
||||||
|
@ -1133,7 +1133,8 @@ a.redlink:hover {
|
|||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
a.discretelink {
|
a.discretelink,
|
||||||
|
a:discretelink:visited {
|
||||||
color: black;
|
color: black;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
@ -1567,6 +1568,7 @@ h2.formsemestre,
|
|||||||
#gtrcontent h2 {
|
#gtrcontent h2 {
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
font-size: 130%;
|
font-size: 130%;
|
||||||
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.formsemestre_page_title table.semtitle,
|
.formsemestre_page_title table.semtitle,
|
||||||
|
@ -7,8 +7,7 @@
|
|||||||
"""Liste simple d'étudiants
|
"""Liste simple d'étudiants
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from flask import g, url_for
|
from app.models import FormSemestre, FormSemestreInscription, Identite
|
||||||
from app.models import Identite
|
|
||||||
from app.tables import table_builder as tb
|
from app.tables import table_builder as tb
|
||||||
|
|
||||||
|
|
||||||
@ -26,6 +25,7 @@ class TableEtud(tb.Table):
|
|||||||
with_foot_titles=False,
|
with_foot_titles=False,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
|
etuds = etuds or []
|
||||||
self.rows: list["RowEtud"] = [] # juste pour que VSCode nous aide sur .rows
|
self.rows: list["RowEtud"] = [] # juste pour que VSCode nous aide sur .rows
|
||||||
classes = classes or ["gt_table", "gt_left"]
|
classes = classes or ["gt_table", "gt_left"]
|
||||||
super().__init__(
|
super().__init__(
|
||||||
@ -46,10 +46,12 @@ class TableEtud(tb.Table):
|
|||||||
|
|
||||||
class RowEtud(tb.Row):
|
class RowEtud(tb.Row):
|
||||||
"Ligne de la table d'étudiants"
|
"Ligne de la table d'étudiants"
|
||||||
|
|
||||||
# pour le moment très simple, extensible (codes, liens bulletins, ...)
|
# pour le moment très simple, extensible (codes, liens bulletins, ...)
|
||||||
def __init__(self, table: TableEtud, etud: Identite, *args, **kwargs):
|
def __init__(self, table: TableEtud, etud: Identite, *args, **kwargs):
|
||||||
super().__init__(table, etud.id, *args, **kwargs)
|
super().__init__(table, etud.id, *args, **kwargs)
|
||||||
self.etud = etud
|
self.etud = etud
|
||||||
|
self.target_url = etud.url_fiche()
|
||||||
|
|
||||||
def add_etud_cols(self):
|
def add_etud_cols(self):
|
||||||
"""Ajoute colonnes étudiant: codes, noms"""
|
"""Ajoute colonnes étudiant: codes, noms"""
|
||||||
@ -85,7 +87,7 @@ class RowEtud(tb.Row):
|
|||||||
etud.nom_disp(),
|
etud.nom_disp(),
|
||||||
"identite_detail",
|
"identite_detail",
|
||||||
data={"order": etud.sort_key},
|
data={"order": etud.sort_key},
|
||||||
target=url_bulletin,
|
target=self.target_url,
|
||||||
target_attrs={"class": "etudinfo discretelink", "id": str(etud.id)},
|
target_attrs={"class": "etudinfo discretelink", "id": str(etud.id)},
|
||||||
)
|
)
|
||||||
self.add_cell("prenom", "Prénom", etud.prenom, "identite_detail")
|
self.add_cell("prenom", "Prénom", etud.prenom, "identite_detail")
|
||||||
@ -115,3 +117,70 @@ def html_table_etuds(etudids) -> str:
|
|||||||
etuds = etuds_sorted_from_ids(etudids)
|
etuds = etuds_sorted_from_ids(etudids)
|
||||||
table = TableEtud(etuds)
|
table = TableEtud(etuds)
|
||||||
return table.html()
|
return table.html()
|
||||||
|
|
||||||
|
|
||||||
|
class RowEtudWithInfos(RowEtud):
|
||||||
|
"""Ligne de la table d'étudiants avec plus d'informations:
|
||||||
|
département, formsemestre, codes, boursier
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
table: TableEtud,
|
||||||
|
etud: Identite,
|
||||||
|
formsemestre: FormSemestre,
|
||||||
|
inscription: FormSemestreInscription,
|
||||||
|
*args,
|
||||||
|
**kwargs,
|
||||||
|
):
|
||||||
|
super().__init__(table, etud, *args, **kwargs)
|
||||||
|
self.formsemestre = formsemestre
|
||||||
|
self.inscription = inscription
|
||||||
|
|
||||||
|
def add_etud_cols(self):
|
||||||
|
"""Ajoute colonnes étudiant: codes, noms"""
|
||||||
|
self.add_cell("dept", "Dépt.", self.etud.departement.acronym, "identite_detail")
|
||||||
|
self.add_cell(
|
||||||
|
"formsemestre",
|
||||||
|
"Semestre",
|
||||||
|
f"""{self.formsemestre.titre_formation()} {
|
||||||
|
('S'+str(self.formsemestre.semestre_id))
|
||||||
|
if self.formsemestre.semestre_id > 0 else ''}
|
||||||
|
""",
|
||||||
|
"identite_detail",
|
||||||
|
)
|
||||||
|
super().add_etud_cols()
|
||||||
|
self.add_cell(
|
||||||
|
"etat",
|
||||||
|
"État",
|
||||||
|
self.inscription.etat,
|
||||||
|
"inscription",
|
||||||
|
)
|
||||||
|
self.add_cell(
|
||||||
|
"boursier",
|
||||||
|
"Boursier",
|
||||||
|
"O" if self.etud.boursier else "N",
|
||||||
|
"identite_infos",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class TableEtudWithInfos(TableEtud):
|
||||||
|
"""Table d'étudiants avec formsemestre et inscription"""
|
||||||
|
|
||||||
|
def add_formsemestre(self, formsemestre: FormSemestre):
|
||||||
|
"Ajoute les étudiants de ce semestre à la table"
|
||||||
|
etuds = formsemestre.get_inscrits(order=True, include_demdef=True)
|
||||||
|
for etud in etuds:
|
||||||
|
row = self.row_class(
|
||||||
|
self, etud, formsemestre, formsemestre.etuds_inscriptions.get(etud.id)
|
||||||
|
)
|
||||||
|
row.add_etud_cols()
|
||||||
|
self.add_row(row)
|
||||||
|
|
||||||
|
|
||||||
|
def table_etudiants_courants(formsemestres: list[FormSemestre]) -> TableEtud:
|
||||||
|
"""Table des étudiants des formsemestres indiqués"""
|
||||||
|
table = TableEtudWithInfos(row_class=RowEtudWithInfos)
|
||||||
|
for formsemestre in formsemestres:
|
||||||
|
table.add_formsemestre(formsemestre)
|
||||||
|
return table
|
||||||
|
@ -105,6 +105,7 @@ from app.scodoc import sco_synchro_etuds
|
|||||||
from app.scodoc import sco_trombino
|
from app.scodoc import sco_trombino
|
||||||
from app.scodoc import sco_trombino_tours
|
from app.scodoc import sco_trombino_tours
|
||||||
from app.scodoc import sco_up_to_date
|
from app.scodoc import sco_up_to_date
|
||||||
|
from app.tables import list_etuds
|
||||||
|
|
||||||
|
|
||||||
def sco_publish(route, function, permission, methods=["GET"]):
|
def sco_publish(route, function, permission, methods=["GET"]):
|
||||||
@ -2071,6 +2072,21 @@ def check_group_apogee(group_id, etat=None, fix=False, fixmail=False):
|
|||||||
return "\n".join(H) + html_sco_header.sco_footer()
|
return "\n".join(H) + html_sco_header.sco_footer()
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/export_etudiants_courants")
|
||||||
|
@scodoc
|
||||||
|
@permission_required(Permission.ScoView)
|
||||||
|
def export_etudiants_courants():
|
||||||
|
"""Table export de tous les étudiants des formsemestres en cours."""
|
||||||
|
departement = Departement.query.get(g.scodoc_dept_id)
|
||||||
|
if not departement:
|
||||||
|
raise ScoValueError("département invalide")
|
||||||
|
formsemestres = FormSemestre.get_dept_formsemestres_courants(departement)
|
||||||
|
table = list_etuds.table_etudiants_courants(formsemestres)
|
||||||
|
return render_template(
|
||||||
|
"scolar/export_etudiants_courants.j2", sco=ScoData(), table=table
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/form_students_import_excel", methods=["GET", "POST"])
|
@bp.route("/form_students_import_excel", methods=["GET", "POST"])
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.EtudInscrit)
|
@permission_required(Permission.EtudInscrit)
|
||||||
@ -2361,35 +2377,57 @@ def form_students_import_infos_admissions(formsemestre_id=None):
|
|||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.EtudChangeAdr)
|
@permission_required(Permission.EtudChangeAdr)
|
||||||
@scodoc7func
|
@scodoc7func
|
||||||
def formsemestre_import_etud_admission(formsemestre_id, import_email=True):
|
def formsemestre_import_etud_admission(
|
||||||
"""Ré-importe donnees admissions par synchro Portail Apogée"""
|
formsemestre_id=None, import_email=True, tous_courants=False
|
||||||
|
):
|
||||||
|
"""Ré-importe donnees admissions par synchro Portail Apogée.
|
||||||
|
Si tous_courants, le fait pour tous les formsemestres courants du département
|
||||||
|
"""
|
||||||
|
if tous_courants:
|
||||||
|
departement = Departement.query.get(g.scodoc_dept_id)
|
||||||
|
formsemestres = FormSemestre.get_dept_formsemestres_courants(departement)
|
||||||
|
else:
|
||||||
|
formsemestres = [FormSemestre.get_formsemestre(formsemestre_id)]
|
||||||
|
|
||||||
|
diag_by_sem = {}
|
||||||
|
for formsemestre in formsemestres:
|
||||||
(
|
(
|
||||||
no_nip,
|
etuds_no_nip,
|
||||||
unknowns,
|
etuds_unknown,
|
||||||
changed_mails,
|
changed_mails,
|
||||||
) = sco_synchro_etuds.formsemestre_import_etud_admission(
|
) = sco_synchro_etuds.formsemestre_import_etud_admission(
|
||||||
formsemestre_id, import_identite=True, import_email=import_email
|
formsemestre.id, import_identite=True, import_email=import_email
|
||||||
)
|
|
||||||
H = [
|
|
||||||
html_sco_header.html_sem_header("Ré-import données admission"),
|
|
||||||
"<h3>Opération effectuée</h3>",
|
|
||||||
]
|
|
||||||
if no_nip:
|
|
||||||
H.append("<p>Attention: étudiants sans NIP: " + str(no_nip) + "</p>")
|
|
||||||
if unknowns:
|
|
||||||
H.append(
|
|
||||||
"<p>Attention: étudiants inconnus du portail: codes NIP="
|
|
||||||
+ str(unknowns)
|
|
||||||
+ "</p>"
|
|
||||||
)
|
)
|
||||||
|
diag = ""
|
||||||
|
if etuds_no_nip:
|
||||||
|
diag += f"""<p>Attention: étudiants sans NIP:
|
||||||
|
{', '.join([e.html_link_fiche() for e in etuds_no_nip])}
|
||||||
|
</p>"""
|
||||||
|
|
||||||
|
if etuds_unknown:
|
||||||
|
diag += f"""<p>Attention: étudiants inconnus du portail:
|
||||||
|
{', '.join([(e.html_link_fiche() + ' (nip= ' + e.code_nip + ')')
|
||||||
|
for e in etuds_unknown])}
|
||||||
|
</p>"""
|
||||||
|
|
||||||
if changed_mails:
|
if changed_mails:
|
||||||
H.append("<h3>Adresses mails modifiées:</h3><ul>")
|
diag += """<p>Adresses mails modifiées:</p><ul>"""
|
||||||
for etud, old_mail in changed_mails:
|
for etud, old_mail in changed_mails:
|
||||||
H.append(
|
diag += f"""<li>{etud.nom}: <tt>{old_mail}</tt> devient <tt>{etud.email}</tt></li>"""
|
||||||
f"""<li>{etud.nom}: <tt>{old_mail}</tt> devient <tt>{etud.email}</tt></li>"""
|
diag += "</ul>"
|
||||||
)
|
diag_by_sem[formsemestre.id] = diag
|
||||||
H.append("</ul>")
|
|
||||||
return "\n".join(H) + html_sco_header.sco_footer()
|
return f"""
|
||||||
|
{ html_sco_header.html_sem_header("Ré-import données admission") }
|
||||||
|
<h3>Opération effectuée</h3>
|
||||||
|
<p>Sur le(s) semestres(s):</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
{ '</li><li>'.join( [(s.html_link_status() + diag_by_sem[s.id]) for s in formsemestres ]) }
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
{ html_sco_header.sco_footer() }
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
sco_publish(
|
sco_publish(
|
||||||
|
Loading…
Reference in New Issue
Block a user