2023-02-07 18:49:51 +01:00
# Script de migration des données de la base "absences" -> "assiduites"/"justificatifs"
from app import db
2023-02-09 21:04:53 +01:00
from app . profiler import Profiler
2023-02-07 18:49:51 +01:00
from app . models import (
Assiduite ,
Justificatif ,
Absence ,
Identite ,
2023-02-09 21:04:53 +01:00
ModuleImplInscription ,
2023-02-07 18:49:51 +01:00
Departement ,
)
2023-02-09 21:04:53 +01:00
from app . scodoc . sco_utils import (
EtatAssiduite ,
EtatJustificatif ,
localize_datetime ,
ProgressBarColors ,
printProgressBar ,
)
2023-02-07 18:49:51 +01:00
from datetime import time , datetime , date
2023-02-09 21:04:53 +01:00
from json import dump
2023-02-07 18:49:51 +01:00
2023-02-09 21:04:53 +01:00
class _glob :
2023-02-07 18:49:51 +01:00
DUPLICATIONS_ASSIDUITES : dict [ tuple [ date , bool , int ] , Assiduite ] = { }
2023-02-09 21:04:53 +01:00
DUPLICATIONS_JUSTIFICATIFS : dict [ tuple [ date , bool , int ] , Justificatif ] = { }
2023-02-07 18:49:51 +01:00
DUPLICATED : list [ Justificatif ] = [ ]
2023-02-09 21:04:53 +01:00
PROBLEMS : dict [ int , list [ str ] ] = { }
CURRENT_ETU : list = [ ]
MODULES : list [ tuple [ int , int ] ] = [ ]
COMPTE : list [ int , int ] = [ ]
2023-02-08 19:48:34 +01:00
2023-02-07 18:49:51 +01:00
def migrate_abs_to_assiduites (
dept : str = " " , morning : str = None , noon : str = None , evening : str = None
) :
"""
une absence à 3 états :
| . estabs | . estjust |
| 1 | 0 | - > absence non justifiée
| 1 | 1 | - > absence justifiée
| 0 | 1 | - > justifié
dualité des temps :
. matin : bool ( 0 : 00 - > time_pref | time_pref - > 23 : 59 : 59 )
. jour : date ( jour de l ' absence/justificatif)
. moduleimpl_id : relation - > moduleimpl_id
description : str - > motif abs / raision justif
. entry_date : datetime - > timestamp d ' entrée de l ' abs
. etudid : relation - > Identite
"""
2023-02-09 21:04:53 +01:00
Profiler . clear ( )
time_elapsed : Profiler = Profiler ( " migration " )
time_elapsed . start ( )
2023-02-08 19:48:34 +01:00
if morning is None :
2023-02-07 18:49:51 +01:00
pref_time_morning = time ( 8 , 0 )
else :
morning : list [ str ] = morning . split ( " h " )
pref_time_morning = time ( int ( morning [ 0 ] ) , int ( morning [ 1 ] ) )
2023-02-08 19:48:34 +01:00
if noon is None :
2023-02-07 18:49:51 +01:00
pref_time_noon = time ( 12 , 0 )
else :
noon : list [ str ] = noon . split ( " h " )
pref_time_noon = time ( int ( noon [ 0 ] ) , int ( noon [ 1 ] ) )
2023-02-08 19:48:34 +01:00
if evening is None :
2023-02-07 18:49:51 +01:00
pref_time_evening = time ( 18 , 0 )
else :
evening : list [ str ] = evening . split ( " h " )
pref_time_evening = time ( int ( evening [ 0 ] ) , int ( evening [ 1 ] ) )
absences_query = Absence . query
2023-02-08 19:48:34 +01:00
if dept is not None :
2023-02-07 18:49:51 +01:00
2023-02-09 21:04:53 +01:00
dept : Departement = Departement . query . filter_by ( acronym = dept ) . first ( )
if dept is not None :
etuds_id : list [ int ] = [ etud . id for etud in dept . etudiants ]
absences_query = absences_query . filter ( Absence . etudid . in_ ( etuds_id ) )
absences : Absence = absences_query . order_by ( Absence . etudid )
2023-02-07 18:49:51 +01:00
2023-02-09 21:04:53 +01:00
_glob . DUPLICATED = [ ]
_glob . DUPLICATIONS_ASSIDUITES = { }
_glob . DUPLICATIONS_JUSTIFICATIFS = { }
_glob . PROBLEMS = { }
_glob . CURRENT_ETU = [ ]
_glob . MODULES = [ ]
_glob . COMPTE = [ 0 , 0 ]
absences_len : int = absences . count ( )
print (
f " { ProgressBarColors . BLUE } { absences_len } absences vont être migrées { ProgressBarColors . RESET } "
)
2023-02-08 19:48:34 +01:00
printProgressBar ( 0 , absences_len , " Progression " , " effectué " , autosize = True )
for i , abs in enumerate ( absences ) :
2023-02-09 21:04:53 +01:00
try :
if abs . estabs :
generated = _from_abs_to_assiduite (
abs , pref_time_morning , pref_time_noon , pref_time_evening
)
2023-02-07 18:49:51 +01:00
if not isinstance ( generated , str ) :
db . session . add ( generated )
2023-02-09 21:04:53 +01:00
_glob . COMPTE [ 0 ] + = 1
except Exception as e :
if abs . id not in _glob . PROBLEMS :
_glob . PROBLEMS [ abs . id ] = [ ]
_glob . PROBLEMS [ abs . id ] . append ( e . args [ 0 ] )
try :
if abs . estjust :
generated = _from_abs_to_justificatif (
abs , pref_time_morning , pref_time_noon , pref_time_evening
)
if not isinstance ( generated , str ) :
db . session . add ( generated )
_glob . COMPTE [ 1 ] + = 1
except Exception as e :
if abs . id not in _glob . PROBLEMS :
_glob . PROBLEMS [ abs . id ] = [ ]
_glob . PROBLEMS [ abs . id ] . append ( e . args [ 0 ] )
if i % 10 == 0 :
printProgressBar (
i ,
absences_len ,
" Progression " ,
" effectué " ,
autosize = True ,
2023-02-07 18:49:51 +01:00
)
2023-02-08 19:48:34 +01:00
2023-02-09 21:04:53 +01:00
if i % 1000 == 0 :
printProgressBar (
i ,
absences_len ,
" Progression " ,
" effectué " ,
autosize = True ,
)
db . session . commit ( )
2023-02-07 18:49:51 +01:00
2023-02-09 21:04:53 +01:00
dup_assi = _glob . DUPLICATED
2023-02-07 18:49:51 +01:00
assi : Assiduite
for assi in dup_assi :
assi . moduleimpl_id = None
db . session . add ( assi )
db . session . commit ( )
2023-02-08 19:48:34 +01:00
printProgressBar (
absences_len ,
absences_len ,
" Progression " ,
" effectué " ,
autosize = True ,
2023-02-09 21:04:53 +01:00
finish_msg = f " { ProgressBarColors . GREEN } Les absences ont bien été migrées. { ProgressBarColors . RESET } " ,
)
time_elapsed . stop ( )
print (
f " { ProgressBarColors . GREEN } La migration a pris { time_elapsed . elapsed ( ) : .2f } secondes { ProgressBarColors . RESET } "
)
print (
f " { ProgressBarColors . RED } Il y a eu { len ( _glob . PROBLEMS ) } absences qui n ' ont pas pu être migrée. "
2023-02-08 19:48:34 +01:00
)
2023-02-09 21:04:53 +01:00
print (
f " Vous retrouverez un fichier json { ProgressBarColors . GREEN } /tmp/scodoc_migration_abs.json { ProgressBarColors . RED } contenant les ids des absences ainsi que les erreurs liées. "
)
with open ( " /tmp/scodoc_migration_abs.json " , " w " , encoding = " utf-8 " ) as file :
dump ( _glob . PROBLEMS , file )
print (
f " { ProgressBarColors . CYAN } { _glob . COMPTE [ 0 ] } assiduités et { _glob . COMPTE [ 1 ] } justificatifs ont été générés. { ProgressBarColors . RESET } "
)
# afficher nombre justificatifs généré par rapport au nombre de justificatifs
2023-02-08 19:48:34 +01:00
2023-02-07 18:49:51 +01:00
def _from_abs_to_assiduite (
_abs : Absence , morning : time , noon : time , evening : time
) - > Assiduite :
etat = EtatAssiduite . ABSENT
date_deb : datetime = None
date_fin : datetime = None
2023-02-09 21:04:53 +01:00
2023-02-07 18:49:51 +01:00
if _abs . matin :
date_deb = datetime . combine ( _abs . jour , morning )
date_fin = datetime . combine ( _abs . jour , noon )
else :
date_deb = datetime . combine ( _abs . jour , noon )
date_fin = datetime . combine ( _abs . jour , evening )
date_deb = localize_datetime ( date_deb )
date_fin = localize_datetime ( date_fin )
2023-02-09 21:04:53 +01:00
duplicata : Assiduite = _glob . DUPLICATIONS_ASSIDUITES . get (
2023-02-07 18:49:51 +01:00
( _abs . jour , _abs . matin , _abs . etudid )
)
if duplicata is not None :
2023-02-09 21:04:53 +01:00
_glob . DUPLICATED . append ( duplicata )
2023-02-07 18:49:51 +01:00
return " Duplicated "
desc : str = _abs . description
entry_date : datetime = _abs . entry_date
2023-02-09 21:04:53 +01:00
if _abs . etudid not in _glob . CURRENT_ETU :
etud : Identite = Identite . query . filter_by ( id = _abs . etudid ) . first ( )
if etud is None :
return " No Etud "
_glob . CURRENT_ETU . append ( _abs . etudid )
moduleimpl_id : int = _abs . moduleimpl_id
if (
moduleimpl_id is not None
and ( _abs . etudid , _abs . moduleimpl_id ) not in _glob . MODULES
) :
moduleimpl_inscription : ModuleImplInscription = (
ModuleImplInscription . query . filter_by (
moduleimpl_id = _abs . moduleimpl_id , etudid = _abs . etudid
) . first ( )
)
if moduleimpl_inscription is None :
raise Exception ( " Moduleimpl_id incorrect ou étudiant non inscrit " )
2023-02-07 18:49:51 +01:00
2023-02-09 21:04:53 +01:00
retour = Assiduite . fast_create_assiduite (
etudid = _abs . etudid ,
2023-02-07 18:49:51 +01:00
date_debut = date_deb ,
date_fin = date_fin ,
etat = etat ,
2023-02-09 21:04:53 +01:00
moduleimpl_id = moduleimpl_id ,
2023-02-07 18:49:51 +01:00
description = desc ,
entry_date = entry_date ,
)
2023-02-09 21:04:53 +01:00
_glob . DUPLICATIONS_ASSIDUITES [ ( _abs . jour , _abs . matin , _abs . etudid ) ] = retour
2023-02-07 18:49:51 +01:00
return retour
def _from_abs_to_justificatif (
_abs : Absence , morning : time , noon : time , evening : time
) - > Justificatif :
2023-02-09 21:04:53 +01:00
2023-02-07 18:49:51 +01:00
etat = EtatJustificatif . VALIDE
date_deb : datetime = None
date_fin : datetime = None
if _abs . matin :
date_deb = datetime . combine ( _abs . jour , morning )
date_fin = datetime . combine ( _abs . jour , noon )
else :
date_deb = datetime . combine ( _abs . jour , noon )
date_fin = datetime . combine ( _abs . jour , evening )
date_deb = localize_datetime ( date_deb )
date_fin = localize_datetime ( date_fin )
2023-02-09 21:04:53 +01:00
duplicata : Justificatif = _glob . DUPLICATIONS_JUSTIFICATIFS . get (
( _abs . jour , _abs . matin , _abs . etudid )
)
if duplicata is not None :
return " Duplicated "
2023-02-07 18:49:51 +01:00
desc : str = _abs . description
entry_date : datetime = _abs . entry_date
2023-02-09 21:04:53 +01:00
if _abs . etudid not in _glob . CURRENT_ETU :
etud : Identite = Identite . query . filter_by ( id = _abs . etudid ) . first ( )
if etud is None :
return " No Etud "
_glob . CURRENT_ETU . append ( _abs . etudid )
2023-02-07 18:49:51 +01:00
2023-02-09 21:04:53 +01:00
retour = Justificatif . fast_create_justificatif (
etudid = _abs . etudid ,
2023-02-07 18:49:51 +01:00
date_debut = date_deb ,
date_fin = date_fin ,
etat = etat ,
raison = desc ,
entry_date = entry_date ,
)
2023-02-09 21:04:53 +01:00
_glob . DUPLICATIONS_JUSTIFICATIFS [ ( _abs . jour , _abs . matin , _abs . etudid ) ] = retour
2023-02-07 18:49:51 +01:00
return retour