forked from ScoDoc/ScoDoc
Update opolka/ScoDoc from ScoDoc/ScoDoc #2
@ -6,18 +6,18 @@
|
||||
"""ScoDoc 9 API : Assiduités
|
||||
"""
|
||||
from datetime import datetime
|
||||
from flask_json import as_json
|
||||
from flask import g, request
|
||||
from flask_login import login_required, current_user
|
||||
|
||||
from flask import g, request
|
||||
from flask_json import as_json
|
||||
from flask_login import current_user, login_required
|
||||
|
||||
from app import db, log
|
||||
import app.scodoc.sco_assiduites as scass
|
||||
import app.scodoc.sco_utils as scu
|
||||
from app import db
|
||||
from app.api import api_bp as bp
|
||||
from app.api import api_web_bp
|
||||
from app.api import get_model_api_object
|
||||
from app.api import api_web_bp, get_model_api_object
|
||||
from app.decorators import permission_required, scodoc
|
||||
from app.models import Assiduite, FormSemestre, Identite, ModuleImpl
|
||||
from app.models import Assiduite, FormSemestre, Identite, ModuleImpl, Scolog
|
||||
from app.scodoc.sco_exceptions import ScoValueError
|
||||
from app.scodoc.sco_permissions import Permission
|
||||
from app.scodoc.sco_utils import json_error
|
||||
@ -556,8 +556,15 @@ def _delete_singular(assiduite_id: int, database):
|
||||
assiduite_unique: Assiduite = Assiduite.query.filter_by(id=assiduite_id).first()
|
||||
if assiduite_unique is None:
|
||||
return (404, "Assiduite non existante")
|
||||
scass.simple_invalidate_cache(assiduite_unique.to_dict())
|
||||
ass_dict = assiduite_unique.to_dict()
|
||||
log(f"delete_assiduite: {assiduite_unique}")
|
||||
Scolog.logdb(
|
||||
method="delete_assiduite",
|
||||
etudid=assiduite_unique.etudiant.id,
|
||||
msg=f"assiduité: {assiduite_unique}",
|
||||
)
|
||||
database.session.delete(assiduite_unique)
|
||||
scass.simple_invalidate_cache(ass_dict)
|
||||
return (200, "OK")
|
||||
|
||||
|
||||
@ -630,6 +637,12 @@ def assiduite_edit(assiduite_id: int):
|
||||
err: str = ", ".join(errors)
|
||||
return json_error(404, err)
|
||||
|
||||
log(f"assiduite_edit: {assiduite_unique}")
|
||||
Scolog.logdb(
|
||||
"assiduite_edit",
|
||||
assiduite_unique.etudiant.id,
|
||||
msg=f"assiduite: modif {assiduite_unique}",
|
||||
)
|
||||
db.session.add(assiduite_unique)
|
||||
db.session.commit()
|
||||
scass.simple_invalidate_cache(assiduite_unique.to_dict())
|
||||
@ -645,14 +658,17 @@ def assiduite_edit(assiduite_id: int):
|
||||
@permission_required(Permission.ScoAbsChange)
|
||||
def assiduites_edit():
|
||||
"""
|
||||
Edition d'une assiduité à partir de son id
|
||||
Edition de plusieurs assiduités
|
||||
La requête doit avoir un content type "application/json":
|
||||
{
|
||||
"etat"?: str,
|
||||
"moduleimpl_id"?: int
|
||||
"desc"?: str
|
||||
"est_just"?: bool
|
||||
}
|
||||
[
|
||||
{
|
||||
"assiduite_id" : int,
|
||||
"etat"?: str,
|
||||
"moduleimpl_id"?: int
|
||||
"desc"?: str
|
||||
"est_just"?: bool
|
||||
}
|
||||
]
|
||||
"""
|
||||
edit_list: list[object] = request.get_json(force=True)
|
||||
|
||||
@ -664,7 +680,7 @@ def assiduites_edit():
|
||||
for i, data in enumerate(edit_list):
|
||||
assi: Identite = Assiduite.query.filter_by(id=data["assiduite_id"]).first()
|
||||
if assi is None:
|
||||
errors[i] = "Cet assiduité n'existe pas."
|
||||
errors[i] = f"assiduité {data['assiduite_id']} n'existe pas."
|
||||
continue
|
||||
|
||||
code, obj = _edit_singular(assi, data)
|
||||
@ -727,6 +743,12 @@ def _edit_singular(assiduite_unique, data):
|
||||
err: str = ", ".join(errors)
|
||||
return (404, err)
|
||||
|
||||
log(f"_edit_singular: {assiduite_unique}")
|
||||
Scolog.logdb(
|
||||
"assiduite_edit",
|
||||
assiduite_unique.etudiant.id,
|
||||
msg=f"assiduite: modif {assiduite_unique}",
|
||||
)
|
||||
db.session.add(assiduite_unique)
|
||||
scass.simple_invalidate_cache(assiduite_unique.to_dict())
|
||||
|
||||
|
@ -3,16 +3,10 @@
|
||||
"""
|
||||
from datetime import datetime
|
||||
|
||||
from app import db
|
||||
from app.models import ModuleImpl
|
||||
from app import db, log
|
||||
from app.models import ModuleImpl, Scolog
|
||||
from app.models.etudiants import Identite
|
||||
from app.auth.models import User
|
||||
from app.scodoc.sco_utils import (
|
||||
EtatAssiduite,
|
||||
EtatJustificatif,
|
||||
localize_datetime,
|
||||
is_period_overlapping,
|
||||
)
|
||||
from app.scodoc.sco_exceptions import ScoValueError
|
||||
from app.scodoc.sco_utils import (
|
||||
EtatAssiduite,
|
||||
@ -92,6 +86,20 @@ class Assiduite(db.Model):
|
||||
}
|
||||
return data
|
||||
|
||||
def __str__(self) -> str:
|
||||
"chaine pour journaux et debug (lisible par humain français)"
|
||||
try:
|
||||
etat_str = EtatAssiduite(self.etat).name.lower().capitalize()
|
||||
except ValueError:
|
||||
etat_str = "Invalide"
|
||||
return f"""{etat_str} {
|
||||
"just." if self.est_just else "non just."
|
||||
} de {
|
||||
self.date_debut.strftime("%d/%m/%Y %Hh%M")
|
||||
} à {
|
||||
self.date_fin.strftime("%d/%m/%Y %Hh%M")
|
||||
}"""
|
||||
|
||||
@classmethod
|
||||
def create_assiduite(
|
||||
cls,
|
||||
@ -140,33 +148,12 @@ class Assiduite(db.Model):
|
||||
est_just=est_just,
|
||||
)
|
||||
|
||||
return nouv_assiduite
|
||||
|
||||
@classmethod
|
||||
def fast_create_assiduite(
|
||||
cls,
|
||||
etudid: int,
|
||||
date_debut: datetime,
|
||||
date_fin: datetime,
|
||||
etat: EtatAssiduite,
|
||||
moduleimpl_id: int = None,
|
||||
description: str = None,
|
||||
entry_date: datetime = None,
|
||||
est_just: bool = False,
|
||||
) -> object or int:
|
||||
"""Créer une nouvelle assiduité pour l'étudiant"""
|
||||
# Vérification de non duplication des périodes
|
||||
nouv_assiduite = Assiduite(
|
||||
date_debut=date_debut,
|
||||
date_fin=date_fin,
|
||||
etat=etat,
|
||||
etudid=etudid,
|
||||
moduleimpl_id=moduleimpl_id,
|
||||
description=description,
|
||||
entry_date=entry_date,
|
||||
est_just=est_just,
|
||||
log(f"create_assiduite: {nouv_assiduite}")
|
||||
Scolog.logdb(
|
||||
method="create_assiduite",
|
||||
etudid=etud.id,
|
||||
msg=f"assiduité: {nouv_assiduite}",
|
||||
)
|
||||
|
||||
return nouv_assiduite
|
||||
|
||||
|
||||
@ -266,29 +253,6 @@ class Justificatif(db.Model):
|
||||
)
|
||||
return nouv_justificatif
|
||||
|
||||
@classmethod
|
||||
def fast_create_justificatif(
|
||||
cls,
|
||||
etudid: int,
|
||||
date_debut: datetime,
|
||||
date_fin: datetime,
|
||||
etat: EtatJustificatif,
|
||||
raison: str = None,
|
||||
entry_date: datetime = None,
|
||||
) -> object or int:
|
||||
"""Créer un nouveau justificatif pour l'étudiant"""
|
||||
|
||||
nouv_justificatif = Justificatif(
|
||||
date_debut=date_debut,
|
||||
date_fin=date_fin,
|
||||
etat=etat,
|
||||
etudid=etudid,
|
||||
raison=raison,
|
||||
entry_date=entry_date,
|
||||
)
|
||||
|
||||
return nouv_justificatif
|
||||
|
||||
|
||||
def is_period_conflicting(
|
||||
date_debut: datetime,
|
||||
|
@ -93,7 +93,7 @@ _formsemestreEditor = ndb.EditableTable(
|
||||
)
|
||||
|
||||
|
||||
def get_formsemestre(formsemestre_id: int):
|
||||
def get_formsemestre(formsemestre_id: int) -> dict:
|
||||
"list ONE formsemestre"
|
||||
if formsemestre_id is None:
|
||||
raise ValueError("get_formsemestre: id manquant")
|
||||
|
@ -1608,12 +1608,12 @@ function deleteJustificatif(justif_id) {
|
||||
function errorAlert() {
|
||||
const html = `
|
||||
<h3>Avez vous les droits suffisant pour cette action ?</h3>
|
||||
<p>Si c'est bien le cas : veuillez de l'aide sur le canal Assistance de ScoDoc</p>
|
||||
<p>Si c'est bien le cas : demandez de l'aide sur le canal Assistance de ScoDoc</p>
|
||||
<br>
|
||||
<p><i>pour les développeurs : l'erreur est affichée dans la console JS</i></p>
|
||||
|
||||
`;
|
||||
const div = document.createElement("div");
|
||||
div.innerHTML = html;
|
||||
openAlertModal("Une erreur s'est déclanchée", div);
|
||||
openAlertModal("Une erreur s'est produite", div);
|
||||
}
|
||||
|
@ -8,10 +8,12 @@
|
||||
"""
|
||||
|
||||
from flask import g, url_for
|
||||
from app.models import Identite, Justificatif
|
||||
from app import log
|
||||
from app.models import FormSemestre, Identite, Justificatif
|
||||
from app.tables import table_builder as tb
|
||||
import app.scodoc.sco_assiduites as scass
|
||||
from app.scodoc import sco_preferences
|
||||
from app.scodoc import sco_utils as scu
|
||||
|
||||
|
||||
class TableAssi(tb.Table):
|
||||
@ -23,12 +25,13 @@ class TableAssi(tb.Table):
|
||||
self,
|
||||
etuds: list[Identite] = None,
|
||||
dates: tuple[str, str] = None,
|
||||
formsemestre: FormSemestre = None,
|
||||
**kwargs,
|
||||
):
|
||||
self.rows: list["RowEtud"] = [] # juste pour que VSCode nous aide sur .rows
|
||||
classes = ["gt_table", "gt_left"]
|
||||
self.dates = [str(dates[0]) + "T00:00", str(dates[1]) + "T23:59"]
|
||||
|
||||
self.formsemestre = formsemestre
|
||||
super().__init__(
|
||||
row_class=RowAssi,
|
||||
classes=classes,
|
||||
@ -50,6 +53,17 @@ class RowAssi(tb.Row):
|
||||
|
||||
# pour le moment très simple, extensible (codes, liens bulletins, ...)
|
||||
def __init__(self, table: TableAssi, etud: Identite, *args, **kwargs):
|
||||
# Etat de l'inscription au formsemestre
|
||||
if "classes" not in kwargs:
|
||||
kwargs["classes"] = []
|
||||
try:
|
||||
inscription = table.formsemestre.etuds_inscriptions[etud.id]
|
||||
if inscription.etat == scu.DEMISSION:
|
||||
kwargs["classes"].append("etuddem")
|
||||
except KeyError:
|
||||
log(f"RowAssi: etudid {etud.id} non inscrit à {table.formsemestre.id}")
|
||||
kwargs["classes"].append("non_inscrit") # ne devrait pas arriver !
|
||||
|
||||
super().__init__(table, etud.id, *args, **kwargs)
|
||||
self.etud = etud
|
||||
self.dates = table.dates
|
||||
|
@ -4,6 +4,7 @@ from flask import g, request, render_template
|
||||
|
||||
from flask import abort, url_for
|
||||
|
||||
from app import db
|
||||
from app.comp import res_sem
|
||||
from app.comp.res_compat import NotesTableCompat
|
||||
from app.decorators import (
|
||||
@ -669,9 +670,11 @@ def visu_assi_group():
|
||||
map(str, group_ids)
|
||||
|
||||
groups_infos = sco_groups_view.DisplayedGroupsInfos(group_ids)
|
||||
|
||||
formsemestre = db.session.get(FormSemestre, groups_infos.formsemestre_id)
|
||||
etuds = etuds_sorted_from_ids([m["etudid"] for m in groups_infos.members])
|
||||
table: TableAssi = TableAssi(etuds=etuds, dates=list(dates.values()))
|
||||
table: TableAssi = TableAssi(
|
||||
etuds=etuds, dates=list(dates.values()), formsemestre=formsemestre
|
||||
)
|
||||
|
||||
if fmt.startswith("xls"):
|
||||
return scu.send_file(
|
||||
|
@ -121,15 +121,6 @@ class _Merger:
|
||||
"entry_date": self.entry_date,
|
||||
},
|
||||
)
|
||||
# retour = Justificatif.fast_create_justificatif(
|
||||
# etudid=self.etudid,
|
||||
# date_debut=date_deb,
|
||||
# date_fin=date_fin,
|
||||
# etat=EtatJustificatif.VALIDE,
|
||||
# raison=self.raison,
|
||||
# entry_date=self.entry_date,
|
||||
# )
|
||||
# return retour
|
||||
|
||||
def _to_assi(self):
|
||||
date_deb = _Merger._tuple_to_date(self.deb)
|
||||
@ -161,17 +152,6 @@ class _Merger:
|
||||
},
|
||||
)
|
||||
|
||||
# retour = Assiduite.fast_create_assiduite(
|
||||
# etudid=self.etudid,
|
||||
# date_debut=date_deb,
|
||||
# date_fin=date_fin,
|
||||
# etat=EtatAssiduite.ABSENT,
|
||||
# moduleimpl_id=self.moduleimpl,
|
||||
# description=self.raison,
|
||||
# entry_date=self.entry_date,
|
||||
# )
|
||||
# return retour
|
||||
|
||||
def export(self):
|
||||
"""Génère un nouvel objet Assiduité ou Justificatif"""
|
||||
obj: Assiduite or Justificatif = None
|
||||
|
Loading…
Reference in New Issue
Block a user