Spaces:
Running
Running
Update src/modules/forecasting.py
Browse files- src/modules/forecasting.py +67 -0
src/modules/forecasting.py
CHANGED
|
@@ -9,6 +9,7 @@ import numpy as np
|
|
| 9 |
# Import du module d'analyse
|
| 10 |
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
| 11 |
from Analytics.VortexOutFlux import VortexOutFlux
|
|
|
|
| 12 |
|
| 13 |
# === CSS SPÉCIFIQUE MODULE FORECASTING ===
|
| 14 |
def apply_forecasting_styles():
|
|
@@ -225,6 +226,22 @@ def apply_forecasting_styles():
|
|
| 225 |
font-weight: 700;
|
| 226 |
}
|
| 227 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 228 |
/* Divider */
|
| 229 |
#forecasting-module hr {
|
| 230 |
background: rgba(88, 166, 255, 0.3);
|
|
@@ -335,6 +352,56 @@ def show_forecasting_module(client, sheet_name):
|
|
| 335 |
st.header("JASMINE - PRÉDICTION DES FLUX DE SORTIE")
|
| 336 |
st.caption("Analyse prédictive en temps réel basée sur la régression linéaire")
|
| 337 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 338 |
try:
|
| 339 |
# Connexion à Google Sheets
|
| 340 |
sh = client.open(sheet_name)
|
|
|
|
| 9 |
# Import du module d'analyse
|
| 10 |
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
| 11 |
from Analytics.VortexOutFlux import VortexOutFlux
|
| 12 |
+
from Analytics.DataSyncForecasting import actualiser_forecasting_depuis_prets
|
| 13 |
|
| 14 |
# === CSS SPÉCIFIQUE MODULE FORECASTING ===
|
| 15 |
def apply_forecasting_styles():
|
|
|
|
| 226 |
font-weight: 700;
|
| 227 |
}
|
| 228 |
|
| 229 |
+
/* Bouton de synchronisation */
|
| 230 |
+
[data-testid="column"] .stButton[data-baseweb="button"] > button[kind="primary"] {
|
| 231 |
+
background: linear-gradient(135deg, rgba(88, 166, 255, 0.3), rgba(84, 189, 75, 0.3)) !important;
|
| 232 |
+
border: 2px solid #58a6ff !important;
|
| 233 |
+
color: #58a6ff !important;
|
| 234 |
+
font-weight: 700 !important;
|
| 235 |
+
text-transform: uppercase;
|
| 236 |
+
letter-spacing: 1px;
|
| 237 |
+
}
|
| 238 |
+
|
| 239 |
+
[data-testid="column"] .stButton[data-baseweb="button"] > button[kind="primary"]:hover {
|
| 240 |
+
background: linear-gradient(135deg, rgba(88, 166, 255, 0.5), rgba(84, 189, 75, 0.5)) !important;
|
| 241 |
+
border-color: #54bd4b !important;
|
| 242 |
+
box-shadow: 0 0 20px rgba(88, 166, 255, 0.4) !important;
|
| 243 |
+
}
|
| 244 |
+
|
| 245 |
/* Divider */
|
| 246 |
#forecasting-module hr {
|
| 247 |
background: rgba(88, 166, 255, 0.3);
|
|
|
|
| 352 |
st.header("JASMINE - PRÉDICTION DES FLUX DE SORTIE")
|
| 353 |
st.caption("Analyse prédictive en temps réel basée sur la régression linéaire")
|
| 354 |
|
| 355 |
+
# === SECTION SYNCHRONISATION ===
|
| 356 |
+
st.divider()
|
| 357 |
+
|
| 358 |
+
col_sync1, col_sync2 = st.columns([3, 1])
|
| 359 |
+
|
| 360 |
+
with col_sync1:
|
| 361 |
+
st.markdown("""
|
| 362 |
+
<div style="background: rgba(88, 166, 255, 0.05); border-left: 4px solid #58a6ff; padding: 12px; border-radius: 4px;">
|
| 363 |
+
<p style="color: #8b949e; margin: 0; font-size: 0.9rem;">
|
| 364 |
+
<strong style="color: #58a6ff;">💡 Synchronisation automatique :</strong>
|
| 365 |
+
Les données de flux de sortie sont calculées automatiquement depuis les déblocages de prêts (Prets_Master).
|
| 366 |
+
Cliquez sur le bouton pour actualiser.
|
| 367 |
+
</p>
|
| 368 |
+
</div>
|
| 369 |
+
""", unsafe_allow_html=True)
|
| 370 |
+
|
| 371 |
+
with col_sync2:
|
| 372 |
+
if st.button("🔄 Synchroniser", use_container_width=True, type="primary"):
|
| 373 |
+
with st.spinner("Synchronisation en cours..."):
|
| 374 |
+
result = actualiser_forecasting_depuis_prets(client, sheet_name)
|
| 375 |
+
|
| 376 |
+
if result['success']:
|
| 377 |
+
stats = result['stats']
|
| 378 |
+
st.success(f"✅ {result['message']}")
|
| 379 |
+
|
| 380 |
+
# Afficher les détails
|
| 381 |
+
with st.expander("📊 Détails de la synchronisation", expanded=True):
|
| 382 |
+
col1, col2, col3 = st.columns(3)
|
| 383 |
+
|
| 384 |
+
with col1:
|
| 385 |
+
st.metric("Mois Conservés", stats['nb_conserves'],
|
| 386 |
+
help="Mois gardés de l'historique manuel")
|
| 387 |
+
with col2:
|
| 388 |
+
st.metric("Mois Mis à Jour", stats['nb_mis_a_jour'],
|
| 389 |
+
help="Mois recalculés depuis Prets_Master")
|
| 390 |
+
with col3:
|
| 391 |
+
st.metric("Mois Ajoutés", stats['nb_ajoutes'],
|
| 392 |
+
help="Nouveaux mois détectés")
|
| 393 |
+
|
| 394 |
+
if stats['nb_mis_a_jour'] > 0:
|
| 395 |
+
st.info(f"**Mois mis à jour :** {', '.join(stats['mois_mis_a_jour'])}")
|
| 396 |
+
|
| 397 |
+
if stats['nb_ajoutes'] > 0:
|
| 398 |
+
st.success(f"**Nouveaux mois ajoutés :** {', '.join(stats['mois_ajoutes'])}")
|
| 399 |
+
|
| 400 |
+
# Forcer le rechargement
|
| 401 |
+
st.rerun()
|
| 402 |
+
else:
|
| 403 |
+
st.error(f"❌ {result['message']}")
|
| 404 |
+
|
| 405 |
try:
|
| 406 |
# Connexion à Google Sheets
|
| 407 |
sh = client.open(sheet_name)
|