File size: 6,814 Bytes
eae5bee
 
59a8c9f
 
 
 
 
eae5bee
 
 
 
 
 
 
 
 
59a8c9f
eae5bee
 
 
 
59a8c9f
 
 
 
 
eae5bee
 
 
59a8c9f
eae5bee
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59a8c9f
eae5bee
 
 
 
 
 
 
 
59a8c9f
 
 
eae5bee
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59a8c9f
 
 
eae5bee
59a8c9f
 
 
eae5bee
 
 
 
 
 
 
59a8c9f
eae5bee
 
 
 
 
59a8c9f
 
eae5bee
 
59a8c9f
 
eae5bee
 
 
 
59a8c9f
eae5bee
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59a8c9f
 
eae5bee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
import streamlit as st
import pandas as pd
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from datetime import datetime, timedelta

# ==============================================================================
# CONFIGURATION SMTP (À sécuriser via st.secrets sur Hugging Face)
# ==============================================================================
# Dans st.secrets, ajoutez une section [smtp] avec :
# server = "smtp.gmail.com"
# port = 587
# email = "votre_email@gmail.com"
# password = "votre_mot_de_passe_application"
# ==============================================================================

def envoyer_email_rappel(destinataire_client, destinataire_admin, details_pret):
    """
    Envoie un email au Client (Rappel) et à l'Admin (Notification).
    """
    try:
        smtp_server = st.secrets["smtp"]["server"]
        smtp_port = st.secrets["smtp"]["port"]
        sender_email = st.secrets["smtp"]["email"]
        sender_password = st.secrets["smtp"]["password"]
    except Exception:
        st.error("⚠️ Secrets SMTP non configurés. Impossible d'envoyer l'email.")
        return False

    sujet = f"🔔 Rappel Échéance - Prêt {details_pret['ID_Pret']}"
    
    # Corps du message
    corps = f"""
    Bonjour {details_pret['Nom_Complet']},

    Ceci est un rappel automatique concernant votre prêt chez Vortex-Flux.

    Une échéance de paiement est prévue pour demain.
    
    📋 Détails de l'échéance :
    --------------------------------
    ID Prêt      : {details_pret['ID_Pret']}
    Date prévue  : {details_pret['Date_Echeance']}
    Montant      : {details_pret['Montant_Versement']} XOF
    --------------------------------

    Merci de prévoir les fonds nécessaires.

    Cordialement,
    L'équipe Vortex-Flux.
    """

    try:
        # Connexion SMTP
        server = smtplib.SMTP(smtp_server, smtp_port)
        server.starttls()
        server.login(sender_email, sender_password)

        # 1. Envoi au CLIENT
        if destinataire_client and "@" in destinataire_client:
            msg_client = MIMEMultipart()
            msg_client['From'] = sender_email
            msg_client['To'] = destinataire_client
            msg_client['Subject'] = sujet
            msg_client.attach(MIMEText(corps, 'plain'))
            server.sendmail(sender_email, destinataire_client, msg_client.as_string())

        # 2. Envoi à l'ADMIN (Copie)
        msg_admin = MIMEMultipart()
        msg_admin['From'] = sender_email
        msg_admin['To'] = destinataire_admin
        msg_admin['Subject'] = f"[ADMIN] Copie Rappel - {details_pret['Nom_Complet']}"
        msg_admin.attach(MIMEText(f"Notification envoyée au client.\n\n{corps}", 'plain'))
        server.sendmail(sender_email, destinataire_admin, msg_admin.as_string())

        server.quit()
        return True
    except Exception as e:
        st.error(f"Erreur technique SMTP : {e}")
        return False

def verifier_et_notifier_echeances(client, sheet_name):
    st.markdown("### 📧 Centre de Notifications")
    
    # Utilisation de session_state pour éviter de spammer à chaque rechargement de page
    if 'check_done' not in st.session_state:
        st.session_state.check_done = False

    col_btn, col_info = st.columns([1, 3])
    
    with col_btn:
        lancer_verif = st.button("🔄 Vérifier Échéances (1.5j)")

    if lancer_verif:
        st.session_state.check_done = True
        try:
            sh = client.open(sheet_name)
            
            # 1. Récupération des Prêts
            ws_prets = sh.worksheet("Prets_Master")
            df_prets = pd.DataFrame(ws_prets.get_all_records())

            # 2. Récupération des Clients (pour avoir les emails)
            ws_clients = sh.worksheet("Clients_KYC")
            df_clients = pd.DataFrame(ws_clients.get_all_records())
            
            # Création d'un dictionnaire ID -> Email pour recherche rapide
            map_emails = dict(zip(df_clients['ID_Client'], df_clients['Email']))

            now = datetime.now()
            delta_limit = timedelta(days=1.5) # 36 heures
            alertes_count = 0

            st.write("Analyse des échéanciers en cours...")

            for index, row in df_prets.iterrows():
                # On ne traite que les prêts ACTIFS
                if str(row.get('Statut', '')).upper() != "ACTIF":
                    continue

                # Récupération de la chaîne de dates (ex: "10/05/2025;17/05/2025")
                dates_str = str(row.get('Dates_Versements', ''))
                if not dates_str:
                    continue

                dates_list = dates_str.split(';')
                
                for d_str in dates_list:
                    try:
                        d_obj = datetime.strptime(d_str.strip(), "%d/%m/%Y")
                        
                        # LOGIQUE 1.5 JOURS
                        # L'échéance est dans le futur ET la différence est < 1.5 jours
                        diff = d_obj - now
                        
                        if timedelta(seconds=0) < diff <= delta_limit:
                            client_id = row['ID_Client']
                            email_client = map_emails.get(client_id, "")
                            # Email Admin (Vous) - À changer ou mettre dans secrets
                            email_admin = st.secrets["smtp"]["email"] if "smtp" in st.secrets else "admin@vortex.com" 

                            details = {
                                'ID_Pret': row['ID_Pret'],
                                'Nom_Complet': row['Nom_Complet'],
                                'Date_Echeance': d_str,
                                'Montant_Versement': row['Montant_Versement']
                            }

                            # Envoi
                            succes = envoyer_email_rappel(email_client, email_admin, details)
                            
                            if succes:
                                st.toast(f"📧 Rappel envoyé pour {row['Nom_Complet']} (Echéance : {d_str})", icon="✅")
                                alertes_count += 1
                            else:
                                st.toast(f"❌ Échec envoi pour {row['Nom_Complet']}", icon="⚠️")
                                
                    except ValueError:
                        continue # Format date invalide, on ignore

            if alertes_count == 0:
                st.info("Aucune échéance proche (< 1.5 jours) détectée.")
            else:
                st.success(f"✅ Terminé : {alertes_count} notifications envoyées.")

        except Exception as e:
            st.error(f"Erreur lors de la vérification : {e}")