Spaces:
Sleeping
Sleeping
Update src/module/Dashboard.py
Browse files- src/module/Dashboard.py +37 -16
src/module/Dashboard.py
CHANGED
|
@@ -45,28 +45,49 @@ class HospitalDashboard:
|
|
| 45 |
return False
|
| 46 |
|
| 47 |
def _get_kpis(self):
|
| 48 |
-
"""
|
| 49 |
-
|
| 50 |
-
df_today = self.df_res[pd.to_datetime(self.df_res['date']) == last_date]
|
| 51 |
-
df_adm_today = self.df_adm[pd.to_datetime(self.df_adm['date']) == last_date]
|
| 52 |
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
|
| 57 |
-
|
| 58 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 59 |
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 63 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
return {
|
| 65 |
-
'
|
|
|
|
| 66 |
'taux_global': taux_global,
|
| 67 |
-
'
|
| 68 |
-
'nb_tension': nb_tension,
|
| 69 |
-
'nb_ruptures': nb_ruptures
|
| 70 |
}
|
| 71 |
|
| 72 |
def plot_main_chart(self):
|
|
|
|
| 45 |
return False
|
| 46 |
|
| 47 |
def _get_kpis(self):
|
| 48 |
+
"""Calcul des KPIs globaux avec typage forcé"""
|
| 49 |
+
df = self.df_ressources
|
|
|
|
|
|
|
| 50 |
|
| 51 |
+
# --- FIX CRITIQUE : Conversion forcée avant calcul ---
|
| 52 |
+
# Même si l'ETL a tourné, on s'assure ici que ce sont des nombres
|
| 53 |
+
# pour éviter l'erreur TypeError: '>' not supported between instances of 'str' and 'int'
|
| 54 |
|
| 55 |
+
if 'lits_occupes' in df.columns:
|
| 56 |
+
df['lits_occupes'] = pd.to_numeric(df['lits_occupes'], errors='coerce').fillna(0)
|
| 57 |
+
|
| 58 |
+
if 'lits_total' in df.columns:
|
| 59 |
+
df['lits_total'] = pd.to_numeric(df['lits_total'], errors='coerce').fillna(0)
|
| 60 |
+
|
| 61 |
+
if 'personnel_disponible' in df.columns:
|
| 62 |
+
df['personnel_disponible'] = pd.to_numeric(df['personnel_disponible'], errors='coerce').fillna(0)
|
| 63 |
+
|
| 64 |
+
if 'personnel_requis' in df.columns:
|
| 65 |
+
df['personnel_requis'] = pd.to_numeric(df['personnel_requis'], errors='coerce').fillna(0)
|
| 66 |
+
# -----------------------------------------------------
|
| 67 |
+
|
| 68 |
+
# Calculs sécurisés
|
| 69 |
+
total_lits = df['lits_total'].sum()
|
| 70 |
+
total_occupes = df['lits_occupes'].sum()
|
| 71 |
|
| 72 |
+
# Calcul du taux global (avec protection division par zéro)
|
| 73 |
+
if total_lits > 0:
|
| 74 |
+
taux_global = (total_occupes / total_lits) * 100
|
| 75 |
+
else:
|
| 76 |
+
taux_global = 0
|
| 77 |
+
|
| 78 |
+
# Tension RH
|
| 79 |
+
total_staff_dispo = df['personnel_disponible'].sum()
|
| 80 |
+
total_staff_req = df['personnel_requis'].sum()
|
| 81 |
|
| 82 |
+
tension_rh = 0
|
| 83 |
+
if total_staff_req > 0:
|
| 84 |
+
tension_rh = (1 - (total_staff_dispo / total_staff_req)) * 100
|
| 85 |
+
|
| 86 |
return {
|
| 87 |
+
'lits_total': int(total_lits),
|
| 88 |
+
'lits_occupes': int(total_occupes),
|
| 89 |
'taux_global': taux_global,
|
| 90 |
+
'tension_rh': tension_rh
|
|
|
|
|
|
|
| 91 |
}
|
| 92 |
|
| 93 |
def plot_main_chart(self):
|