Skip to content
Snippets Groups Projects
Select Git revision
  • a1d37cc63242746670252247f9d711335a1d03be
  • master default protected
2 results

Global_Var.py

Blame
  • bulletin_but_xml_compat.py 13.42 KiB
    # -*- mode: python -*-
    # -*- coding: utf-8 -*-
    
    ##############################################################################
    #
    # Gestion scolarite IUT
    #
    # Copyright (c) 1999 - 2024 Emmanuel Viennet.  All rights reserved.
    #
    # This program is free software; you can redistribute it and/or modify
    # it under the terms of the GNU General Public License as published by
    # the Free Software Foundation; either version 2 of the License, or
    # (at your option) any later version.
    #
    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    # GNU General Public License for more details.
    #
    # You should have received a copy of the GNU General Public License
    # along with this program; if not, write to the Free Software
    # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    #
    #   Emmanuel Viennet      emmanuel.viennet@viennet.net
    #
    ##############################################################################
    
    """Génération du bulletin en format XML / compatibilité ScoDoc 7
    
     => exporte quelques résultats BUT dans le format des anciens bulletins XML ScoDoc 7
     afin d'avoir un affichage acceptable sur les ENT anciens.
    
    Les plate-formes modernes utilisent uniquement la version JSON (but/bulletin_but.py)
    """
    
    
    import datetime
    from xml.etree import ElementTree
    from xml.etree.ElementTree import Element
    
    from app import db, log
    from app.but import bulletin_but
    from app.models import BulAppreciations, FormSemestre, Identite, UniteEns
    import app.scodoc.sco_utils as scu
    from app.scodoc import codes_cursus
    from app.scodoc import sco_photos
    from app.scodoc import sco_preferences
    from app.scodoc import sco_xml
    from app.scodoc.sco_xml import quote_xml_attr
    
    
    def bulletin_but_xml_compat(
        formsemestre_id,
        etudid,
        doc=None,  # XML document
        force_publishing=False,
        xml_nodate=False,
        xml_with_decisions=False,  # inclue les decisions même si non publiées
        version="long",
    ) -> str:
        """Bulletin XML au format ScoDoc 7, avec informations "BUT" """
        from app.scodoc import sco_bulletins
    
        log(
            f"bulletin_but_xml_compat( formsemestre_id={formsemestre_id}, etudid={etudid} )"
        )
        etud = Identite.get_etud(etudid)
        formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
        results = bulletin_but.ResultatsSemestreBUT(formsemestre)
        nb_inscrits = results.get_inscriptions_counts()[scu.INSCRIT]
        # etat_inscription = etud.inscription_etat(formsemestre.id)
        etat_inscription = results.formsemestre.etuds_inscriptions[etudid].etat
        if (not formsemestre.bul_hide_xml) or force_publishing:
            published = 1
        else:
            published = 0
        if xml_nodate:
            docdate = ""
        else:
            docdate = datetime.datetime.now().isoformat()
        el = {
            "etudid": str(etudid),
            "formsemestre_id": str(formsemestre_id),
            "date": docdate,
            "publie": str(published),
        }
        if formsemestre.etapes:
            el["etape_apo"] = formsemestre.etapes[0].etape_apo or ""
            n = 2
            for et in formsemestre.etapes[1:]:
                el["etape_apo" + str(n)] = et.etape_apo or ""
                n += 1
        x = Element("bulletinetud", **el)
        if doc:
            is_appending = True
            doc.append(x)
        else:
            is_appending = False
            doc = x
        # Infos sur l'etudiant
        doc.append(
            Element(
                "etudiant",
                etudid=str(etudid),
                code_nip=etud.code_nip or "",
                code_ine=etud.code_ine or "",
                nom=quote_xml_attr(etud.nom),
                prenom=quote_xml_attr(etud.prenom),
                civilite=quote_xml_attr(etud.civilite_str),
                sexe=quote_xml_attr(etud.civilite_str),  # compat
                photo_url=quote_xml_attr(sco_photos.get_etud_photo_url(etud.id)),
                email=quote_xml_attr(etud.get_first_email() or ""),
                emailperso=quote_xml_attr(etud.get_first_email("emailperso") or ""),
            )
        )
        # Disponible pour publication ?
        if not published:
            return sco_xml.XML_HEADER + ElementTree.tostring(doc).decode(
                scu.SCO_ENCODING
            )  # stop !
    
        if etat_inscription == scu.INSCRIT:
            # Moyenne générale:
            doc.append(
                Element(
                    "note",
                    value=scu.fmt_note(results.etud_moy_gen[etud.id]),
                    min=scu.fmt_note(results.etud_moy_gen.min()),
                    max=scu.fmt_note(results.etud_moy_gen.max()),
                    moy=scu.fmt_note(results.etud_moy_gen.mean()),  # moyenne des moy. gen.
                )
            )
            rang = 0  # XXX TODO rang de l'étudiant selon la moy gen indicative
            # valeur du bonus sport
            if results.bonus is not None:
                bonus = results.bonus[etud.id]
            else:
                bonus = 0
            doc.append(Element("rang", value=str(rang), ninscrits=str(nb_inscrits)))
            # XXX TODO: ajouter "rang_group" : rangs dans les partitions
            doc.append(Element("note_max", value="20"))  # notes toujours sur 20
            doc.append(Element("bonus_sport_culture", value=str(bonus)))
            # Liste les UE / modules /evals
            for ue in results.ues:  # avec bonus
                rang_ue = 0  # XXX TODO rang de l'étudiant dans cette UE
                nb_inscrits_ue = (
                    nb_inscrits  # approx: compliqué de définir le "nb d'inscrit à une UE"
                )
                x_ue = Element(
                    "ue",
                    id=str(ue.id),
                    numero=quote_xml_attr(ue.numero),
                    acronyme=quote_xml_attr(ue.acronyme or ""),
                    titre=quote_xml_attr(ue.titre or ""),
                    code_apogee=quote_xml_attr(ue.code_apogee or ""),
                )
                doc.append(x_ue)
                if ue.type != codes_cursus.UE_SPORT:
                    v = results.etud_moy_ue[ue.id][etud.id]
                    vmin = results.etud_moy_ue[ue.id].min()
                    vmax = results.etud_moy_ue[ue.id].max()
                else:
                    v = results.bonus or 0.0
                    vmin = vmax = 0.0
                x_ue.append(
                    Element(
                        "note",
                        value=scu.fmt_note(v),
                        min=scu.fmt_note(vmin),
                        max=scu.fmt_note(vmax),
                    )
                )
                x_ue.append(Element("ects", value=str(ue.ects if ue.ects else 0)))
                x_ue.append(Element("rang", value=str(rang_ue)))
                x_ue.append(Element("effectif", value=str(nb_inscrits_ue)))
                # Liste les modules rattachés à cette UE
                for modimpl in results.formsemestre.modimpls:
                    # Liste ici uniquement les modules rattachés à cette UE
                    if modimpl.module.ue.id == ue.id:
                        # mod_moy = scu.fmt_note(results.etud_moy_ue[ue.id][etud.id])
                        try:
                            coef = results.modimpl_coefs_df[modimpl.id][ue.id]
                        except KeyError:
                            coef = 0.0
                        x_mod = Element(
                            "module",
                            id=str(modimpl.id),
                            code=str(modimpl.module.code or ""),
                            coefficient=str(coef),
                            numero=str(modimpl.module.numero or 0),
                            titre=quote_xml_attr(modimpl.module.titre or ""),
                            abbrev=quote_xml_attr(modimpl.module.abbrev or ""),
                            code_apogee=quote_xml_attr(modimpl.module.code_apogee or ""),
                        )
                        # XXX TODO  rangs et effectifs
                        # --- notes de chaque eval:
                        if version != "short":
                            for e in modimpl.evaluations:
                                if e.visibulletin or version == "long":
                                    x_eval = Element(
                                        "evaluation",
                                        date_debut=(
                                            e.date_debut.isoformat() if e.date_debut else ""
                                        ),
                                        date_fin=(
                                            e.date_fin.isoformat() if e.date_fin else ""
                                        ),
                                        coefficient=str(e.coefficient),
                                        # pas les poids en XML compat
                                        evaluation_type=str(e.evaluation_type),
                                        description=quote_xml_attr(e.description),
                                        # notes envoyées sur 20, ceci juste pour garder trace:
                                        note_max_origin=str(e.note_max),
                                        # --- deprecated
                                        jour=(
                                            e.date_debut.isoformat() if e.date_debut else ""
                                        ),
                                        heure_debut=e.heure_debut(),
                                        heure_fin=e.heure_fin(),
                                    )
                                    x_mod.append(x_eval)
                                    try:
                                        x_eval.append(
                                            Element(
                                                "note",
                                                value=scu.fmt_note(
                                                    results.modimpls_results[
                                                        e.moduleimpl_id
                                                    ].evals_notes[e.id][etud.id],
                                                    note_max=e.note_max,
                                                ),
                                            )
                                        )
                                    except KeyError:
                                        x_eval.append(
                                            Element("note", value="", note_max="")
                                        )
    
                                    # XXX TODO: Evaluations incomplètes ou futures: XXX
                # XXX TODO UE capitalisee (listee seulement si meilleure que l'UE courante)
    
        # --- Absences
        if sco_preferences.get_preference("bul_show_abs", formsemestre_id):
            _, nbabsjust, nbabs = formsemestre.get_abs_count(etud.id)
            doc.append(Element("absences", nbabs=str(nbabs), nbabsjust=str(nbabsjust)))
    
        # -------- LA SUITE EST COPIEE SANS MODIF DE sco_bulletins_xml.py ---------
        # TODO : refactoring
    
        # --- Decision Jury
        if (
            sco_preferences.get_preference("bul_show_decision", formsemestre_id)
            or xml_with_decisions
        ):
            infos, dpv = sco_bulletins.etud_descr_situation_semestre(
                etudid,
                formsemestre,
                fmt="xml",
                show_uevalid=sco_preferences.get_preference(
                    "bul_show_uevalid", formsemestre_id
                ),
            )
            x_situation = Element("situation")
            x_situation.text = quote_xml_attr(infos["situation"])
            doc.append(x_situation)
            if dpv:
                decision = dpv["decisions"][0]
                etat = decision["etat"]
                if decision["decision_sem"]:
                    code = decision["decision_sem"]["code"] or ""
                else:
                    code = ""
                if (
                    decision["decision_sem"]
                    and "compense_formsemestre_id" in decision["decision_sem"]
                ):
                    doc.append(
                        Element(
                            "decision",
                            code=code,
                            etat=str(etat),
                            compense_formsemestre_id=str(
                                decision["decision_sem"]["compense_formsemestre_id"] or ""
                            ),
                        )
                    )
                else:
                    doc.append(Element("decision", code=code, etat=str(etat)))
    
                if decision[
                    "decisions_ue"
                ]:  # and sco_preferences.get_preference( 'bul_show_uevalid', formsemestre_id): always publish (car utile pour export Apogee)
                    for ue_id in decision["decisions_ue"].keys():
                        ue = db.session.get(UniteEns, ue_id)
                        if ue:
                            doc.append(
                                Element(
                                    "decision_ue",
                                    ue_id=str(ue.id),
                                    numero=quote_xml_attr(ue.numero),
                                    acronyme=quote_xml_attr(ue.acronyme),
                                    titre=quote_xml_attr(ue.titre or ""),
                                    code=decision["decisions_ue"][ue_id]["code"],
                                )
                            )
    
                for aut in decision["autorisations"]:
                    doc.append(
                        Element(
                            "autorisation_inscription", semestre_id=str(aut["semestre_id"])
                        )
                    )
            else:
                doc.append(Element("decision", code="", etat="DEM"))
        # --- Appreciations
        appreciations = BulAppreciations.get_appreciations_list(formsemestre.id, etudid)
        for appreciation in appreciations:
            x_appr = Element(
                "appreciation",
                date=appreciation.date.isoformat() if appreciation.date else "",
            )
            x_appr.text = quote_xml_attr(appreciation.comment_safe())
            doc.append(x_appr)
    
        if is_appending:
            return None
        else:
            return sco_xml.XML_HEADER + ElementTree.tostring(doc).decode(scu.SCO_ENCODING)