payDataApp / app.py
the237's picture
Upload 2 files
b0287d2 verified
import streamlit as st
from utils import *
import seaborn as sns
import matplotlib.pyplot as plt
from streamlit_option_menu import option_menu
import os
from io import BytesIO
import re
from datetime import datetime
import streamlit as st
from auth import *
import bcrypt
datasets_path = "datasets/"
reconciliated_data_folder = "datasets/reconciliated"
databases_file_path = "datasets/inserted/inserted.txt"
reconciliated_file_path = "datasets/inserted/reconciliated.txt"
cleaned_data_folder = "datasets/raw/"
synthesis_data_folder = "datasets/synthesis/"
xml_data_folder = "datasets/xml_files/"
invalid_transactions_folder = "datasets/invalid/"
csv_datasets_folder = "datasets/csv_datasets/"
csv_datasets_reconciliated = "datasets/csv_datasets_reconciliated/"
db_folder = "datasets/databases/"
# use whole page width
st.set_page_config(page_title="Prymo Data App", layout="wide")
# defines all the sections
headerSection = st.container()
logInSection = st.container()
logOutSection = st.container()
mainSection = st.container()
create_users_database()
def main():
# create the necessary folders if the do not exists
create_folder_if_not_exists(csv_datasets_folder)
create_folder_if_not_exists(csv_datasets_reconciliated)
create_folder_if_not_exists(db_folder)
create_folder_if_not_exists(datasets_path)
create_folder_if_not_exists(invalid_transactions_folder)
create_folder_if_not_exists(cleaned_data_folder)
create_folder_if_not_exists(reconciliated_data_folder)
create_folder_if_not_exists(synthesis_data_folder)
create_folder_if_not_exists(xml_data_folder)
with st.sidebar:
selected = option_menu("Menu",["Home","Data Cleaning", "Update Data","Data Mapping","Find Transaction Status",'Account',"Downloads","Doc."],
icons =['house','cloud-upload', 'gear','list-task','list-task','list-task','cloud-download','book'] , menu_icon ="border-width", default_index=0)
if selected =="Home":
st.subheader("Page d'accueil")
st.write("Bienvenue sur l'application de traitement des données transactionnelles de Prymo RDC, cette application a pour vocation d'aider son utilisateur à réaliser les tâches ci-après :")
st.write("1. Nettoyage des données brutes des transactions financières issues des classeurs de la CNSSAP")
st.write("2. Mise à jour d'une transaction financière")
st.write("3. Réconciliation entre les données de la CNSSAP et celles fournies par un opérateur")
st.write("4. Recherche d'une transaction sur la base du numéro de téléphone et / ou de l'ID CNSSAP")
st.write("5. Téléchargement des fichiers générés lors des processus et tâches ci-dessus")
st.write("**Bien vouloir lire attentivement les instructions pour une utilisation optimale de l'outil logiciel.\n Nous vous souhaitons un bon travail.**")
elif selected =="Data Cleaning":
st.subheader("Nettoyage et réconciliation des données")
st.write("Dans cette page, s'effectuent:")
st.write("1. l'upload et le nettoyage du fichier des paiements mobiles pour un mois ;")
st.write("2. l'affichage des statistiques obtenues à l'issue de l'exploitation du fichier initial.")
st.markdown("NB: le fichier uploadé doit avoir la nomenclature ci-après : **PAIEMENT MOBILE MONEY MOIS ANNEE**.\nDe plus rassurez vous que chaque feuille (**Liste**) du classeur a le même nombre de colonnes et que ces colonnes portent le même nom dans toutes les feuilles exp: **N°, Num_CNSSSAP, NOM COMPLET, NOM DU BENEFICIAIRE, N° DE TELEPHONE, MONTANT (en FC)**")
payment_file = st.file_uploader("Sélectionnez un fichier des paiements mensuels (XLS ou XLSX)",type=["xls","xlsx"])
if payment_file is not None:
# submit_btn = st.button("Traiter les données")
# if submit_btn:
# create the filename
filename = " ".join(payment_file.name.split(" ")[-2:])
# get the date period for the database
period = filename.split(".")[0].lower()
# read the processed data
data = process_excel_file(payment_file,period = period)
if data is not None:
# insert info to database if the are not yet present
if(search_database(databases_file_path,filename)==False):
# insert to database if the file is not present
insert_database(databases_file_path,filename)
# then the store in db
store_df_in_database(data,table_name="transactions")
st.info("La lecture du fichier, l'insertion en base de donnée et la création des fichiers de reporting se sont déroulés avec succès")
st.markdown(f"*Nb Lignes exportées et insérées en BD : {data.shape[0]}*")
else:
st.info("La lecture du fichier et la sauvegarde des informations de reporting ce sont déroulés avec succès, cependant les informations de ce fichier étaient déjà en base de données")
st.markdown(f"**Nb Lignes exportées : {data.shape[0]}**")
# store the general and specifics files
store_excel_file(data, cleaned_data_folder, period)
store_excel_file(data, cleaned_data_folder, period, sheet_name="AFRICELL TPP(CDF)",operator="Africell")
store_excel_file(data, cleaned_data_folder, period, sheet_name="AIRTEL TPP(CDF)",operator="Airtel")
store_excel_file(data, cleaned_data_folder, period, sheet_name="ORANGE TPP(CDF)",operator="Orange")
# store the xml version
dataframe_to_xml(data,xml_data_folder,period)
dataframe_to_xml(data,xml_data_folder,period,"Vodacom")
# if exists, merge all the preceding valid transactions and store them into a csv file
merge_all_data(data.loc[data["operator"]!="Autre",],csv_datasets_folder)
st.write("10 premières lignes du fichier résultant")
st.write(data.head(10))
st.subheader("Visuels")
# two cols for payment_mode and amount graphics
col1, col2 = st.columns(2)
with col1:
# create the barplot
sns.set(style="darkgrid")
fig1 = plt.figure(figsize=(10, 6))
sns.countplot(data=data, x="operator")
# labels for bars
for p in plt.gca().patches:
height = p.get_height()
plt.gca().text(p.get_x() + p.get_width() / 2, height, f"{height:,}", ha="center", va="bottom")
# title for the graphic and axis
plt.title("Distribution des opérateurs")
plt.xlabel("Opérateur")
plt.ylabel("Nombre de transactions")
# print the plot
st.pyplot(fig1)
with col2:
# Créez l'histplot en utilisant Seaborn
sns.set(style="darkgrid")
# aggregate data by the sum of amount
agg_data = data.groupby('operator')["amount"].sum().reset_index()
fig2 = plt.figure(figsize=(10, 6))
sns.barplot(x='operator',y="amount", data=agg_data)
# labels for bars
for p in plt.gca().patches:
height = p.get_height()
plt.gca().text(p.get_x() + p.get_width() / 2, height, f"{height:,}", ha="center", va="bottom")
# Ajoutez un titre et des étiquettes aux axes
plt.title("Somme des paiement par opérateur")
plt.xlabel("Opérateur")
plt.ylabel("Montant total")
# Affichez le graphique avec Streamlit
st.pyplot(fig2)
# invalid phone numbers
invalid_phones_df = data.loc[data["operator"]=="Autre",]
st.subheader(f"Aperçu des contacts supposés invalides ({len(invalid_phones_df)}) occurences")
st.write(invalid_phones_df.head())
# store the invalid file after insertion in the invalid transaction folder
invalid_phones_file_path = os.path.join(invalid_transactions_folder,period+"_invalid"+".xlsx")
# check if the error file already exists
if not os.path.isfile(invalid_phones_file_path):
# store the file in his folder
invalid_phones_df.to_excel(invalid_phones_file_path, index=False)
st.info("Vous pouvez ensuite vous rendre à la page de téléchargements pour consulter les fichiers disponibles")
# this part is to generate an XLSX file wich contains the synthesis of all the valid transactions
st.subheader("Génération des synthèse globale ou client")
st.info("Vous pouvez modifier les valeurs ci-dessus:")
form_col1, form_col2 = st.columns(2)
# add change_rate and global_fees_amount
change_rate = form_col1.number_input("Taux (pour 1 USD)", value=2800.0)
global_fees_amount = form_col2.number_input("Montant global des frais", value=4.5)
# check if the values where submited
if change_rate!=0.0 and global_fees_amount!=0.0:
# synth_btn = st.button("Générer la synthèse")
# if synth_btn:
# check if the synthesis is for client or global
sythesis_type = st.selectbox("Sélectionner le type de synthèse à générer : ",["Globale","Client"])
if sythesis_type=="Globale":
# compute global synthesis
st.write("Génération de la synthèse globale ...")
synthesis = calculate_synthesis(data, change_rate, global_fees_amount)
else:
# compute client synthesis
st.write("Génération de la synthèse client ...")
synthesis = calculate_synthesis(data, change_rate, global_fees_amount,global_synthesis=True)
# check if the synthesis
if synthesis is not None:
st.write(synthesis)
# button for XLSX export
if st.button("Exporter vers Excel"):
synthesis_file_name = f"{period}_synthesis.xlsx"
if sythesis_type=="Client":
synthesis_file_name = f"{period}_client_synthesis.xlsx"
synthesis_file_path = os.path.join(synthesis_data_folder,synthesis_file_name)
# check if the synthesis file already exists
if not os.path.isfile(synthesis_file_path):
synthesis.to_excel(synthesis_file_path, index=True)
if sythesis_type=="Globale":
st.info("Le fichier de synthèse a été exporté avec succès")
else:
st.info("Le fichier de synthèse client a été exporté avec succès")
st.info("Vous pouvez également vous rendre à la page de téléchargements pour consulter les fichiers disponibles")
else:
st.error("Une erreur s'est produite lors de la lecture du fichier")
else:
st.info("Veuillez uploader un fichier de type XLS ou XLSX")
elif selected =="Update Data":
st.subheader("Page de mise à jour des données")
st.markdown("Cette page permet de mettre à jour les données des transaction déjà présentes en base de données, sur la base du **nom de la feuille Excel** et de **l'index** de la transaction dans cette feuille.")
if load_all_data() is not None:
st.sidebar.write("Saisir les paramètres de la recherche")
number_in_sheet = st.sidebar.number_input("Numéro de la feuille Excel", min_value=1, step=1)
# get the request requirements
sheets = ["LISTE_M-PESA", "LISTE_ORANGE MONEY", "LISTE_AIRTEL MONEY", "Liste_AFRIMONEY"]
sheet_name = st.sidebar.selectbox("Nom de la feuille Excel", options = sheets)
periods_options = load_data_period()
period_value = st.sidebar.selectbox("Période (Mois et Année)",options=periods_options)
# load data based on them
loaded_data = load_data(number_in_sheet=number_in_sheet, sheet_name=sheet_name,period_value=period_value)
if loaded_data is not None and not loaded_data.empty:
st.subheader('Veuillez saisir les nouvelles valeurs')
st.write('**NB : Les champs suivies des (*) sont obligatoires**')
col1,col2 = st.columns(2)
with col1:
num_CNSSAP = st.text_input("Numéro CNSSAP (*)",loaded_data['num_CNSSAP'].iloc[0])
complete_name = st.text_input("Nom complet (*)",loaded_data['complete_name'].iloc[0])
beneficiary_name = st.text_input("Nom complet du Bénéficiaire",loaded_data['beneficiary_name'].iloc[0])
with col2:
phone_number = st.text_input("Téléphone **avec l'indicatif 243** (*)",value=loaded_data['phone_number'].iloc[0])
ops_options = ['Vodacom','Orange','Airtel','Africell']
operator = st.selectbox("Operateur (*)",options=ops_options,index=ops_options.index(loaded_data['operator'].iloc[0]))
wallet_options = ['M PESA','ORANGE MONEY','AIRTEL MONEY','AFRIMONEY']
e_wallet = st.selectbox("Type de E Wallet (*)",options=['M PESA','ORANGE MONEY','AIRTEL MONEY','AFRIMONEY'],index=wallet_options.index(loaded_data['e_wallet'].iloc[0]))
if num_CNSSAP and complete_name and phone_number:
if st.button('Mettre à jour'):
# verify the phone number
if verify_phone_number(phone_number)!="Inconnu":
new_transaction = (num_CNSSAP,complete_name,beneficiary_name,phone_number,operator,e_wallet,datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
if update_data(new_transaction,number_in_sheet, sheet_name,period_value) is not None:
st.success("Transaction mise à jour avec succès")
else:
st.warning("Veuillez vérifier les données soumises")
else:
# perform the update request
st.warning("Veuillez vérifier le numéro de téléphone")
else:
st.warning('Veuillez remplir les champs obligatoires')
else:
st.info("Aucune transaction trouvée avec ces informations")
else:
st.info("Aucune données n'a encore été insérée afin de réaliser une mise à jour.")
elif selected =="Downloads":
st.subheader("Téléchargement des fichiers divers")
col1, col2 = st.columns(2)
# col for raw data
with col1:
# number of files in the directory
files_ = os.listdir(cleaned_data_folder)
nb_files = len(files_)
st.subheader("Fichiers XLSX disponibles")
if(nb_files==0):
st.write(f"Aucun fichier de nettoyé disponible")
else:
st.write(f"({nb_files}) élément(s) disponible(s)")
selected_file = st.selectbox("Choisir le fichier (XLSX) à télécharger", files_)
# click to enable the download
download_file_button = st.button(label="Télécharger", key="Cleaned")
# confirm that you want effectively to download the file
if download_file_button:
with open(os.path.join(cleaned_data_folder,selected_file),"rb") as file_:
st.download_button(label="Je télécharge",data = file_.read(),file_name=selected_file)
# col2 for synthesis data
with col2:
st.subheader("Synthèses disponibles (xlsx)")
files_synth = os.listdir(synthesis_data_folder)
nb_files_synth = len(files_synth)
if nb_files_synth==0:
st.write(f"Aucun fichier de synthèse disponible")
else:
st.write(f"({nb_files_synth}) élément(s) disponible(s)")
selected_file = st.selectbox("Choisir une fichier de synthèse (XLSX) à télécharger", files_synth)
download_file_button = st.button(label="Télécharger", key="Synthesis")
# confirm that you want effectively to download a synthesis file
if download_file_button:
with open(os.path.join(synthesis_data_folder,selected_file),"rb") as file_:
st.download_button(label="Je télécharge",data = file_.read(),file_name=selected_file)
col1_, col2_ = st.columns(2)
with col1_:
st.subheader("Fichiers résultants (XML)")
xml_files = os.listdir(xml_data_folder)
nb_xml_files = len(xml_files)
if(nb_xml_files==0):
st.write(f"Fichier(s) résultant XML non disponible(s)")
else:
st.write(f"({nb_xml_files}) élément(s) disponible(s)")
selected_file = st.selectbox("Choisir une fichier (XML) à télécharger", xml_files)
download_file_button = st.button(label="Télécharger", key="XML_FILES")
# confirm that you want effectively to download a XML file
if download_file_button:
with open(os.path.join(xml_data_folder,selected_file),"rb") as file_:
st.download_button(label="Je télécharge",data = file_.read(),file_name=selected_file)
with col2_:
st.subheader("Transactions invalides")
# number of files in the directory
invalid_files = os.listdir(invalid_transactions_folder)
invalid_transactions_files = os.listdir(invalid_transactions_folder)
nb_invalid_transactions_files = len(invalid_transactions_files)
if(nb_invalid_transactions_files==0):
st.write(f"Fichier(s) d'erreurs non disponible(s)")
else:
st.write(f"({nb_invalid_transactions_files}) élément(s) disponible(s)")
invalid_selected_file = st.selectbox("Choisir un fichier de transactions invalides", invalid_files)
# click to enable the download
invalid_download_file_button = st.button(label="Télécharger",key="Invalid")
# confirm that you want effectively to download the file
if invalid_download_file_button:
with open(os.path.join(invalid_transactions_folder,invalid_selected_file),"rb") as file_:
st.download_button(label="Je télécharge",data = file_.read(),file_name=invalid_selected_file)
col1__, col2__ = st.columns(2)
with col1__:
reconciliated_transactions_files = os.listdir(reconciliated_data_folder)
nb_reconciliated_transactions_files = len(reconciliated_transactions_files)
st.subheader("Transactions réconciliées")
if(nb_reconciliated_transactions_files==0):
st.write(f"Aucun fichier de réconciliation disponible")
else:
st.write(f"({nb_files}) élément(s) disponible(s)")
reconciliated_selected_file = st.selectbox("Choisir un fichier de transactions invalides", reconciliated_files)
# click to enable the download
reconciliated_download_file_button = st.button(label="Télécharger",key="Reconciliated")
# confirm that you want effectively to download the file
if reconciliated_download_file_button:
with open(os.path.join(reconciliated_data_folder,reconciliated_selected_file),"rb") as file_:
st.download_button(label="Je télécharge",data = file_.read(),file_name=reconciliated_selected_file)
elif selected =="Data Mapping":
st.subheader("Réconciliation des données")
st.write("Dans cette partie, s'effectue la réconciliation des données entre les **transactions des paiements mobiles présentes en base de données** et un **fichier mensuel récapitulatif transmis par un opérateur**.\nPour ce faire, vous devez uploader le fichier mensuel récapitilatif des toutes les transactions transmis par un ")
st.markdown("**NB :** Les transactions nettoyées de la période que vous essayer de réconcilier **doivent déjà avoir été chargées** en base de données et le fichier uploadé doit avoir la nomenclature ci-après : ")
st.markdown("**RECAP OPERATEUR MOIS ANNEE** pour le fichier mensuel des paiements (exp : RECAP ORANGE NOVEMBRE 2023)")
if load_all_data(table_name = "reconciliations") is not None:
operator_file = st.file_uploader("**Sélectionnez un fichier mensuel transmis par l'opérateur (XLS ou XLSX)**",type=["xls","xlsx"])
reconciliation_button = st.button('Réconcilier les données')
if reconciliation_button:
if operator_file is not None:
# verify the filename for operator
operator_file_name = operator_file.name.split(".")[0]
if not is_valid_filename_operator(operator_file_name.strip()):
# print this message if the file is not well named
st.warning("Le nommage du fichier des transactions n'est pas correct")
# get the type of E - Wallet
e_wallet_name = get_wallet_type(operator_file_name.split()[1])
operator = operator_file_name.split()[1].lower().strip()
# create period's first part (operator file)
period_filename = " ".join(operator_file.name.split(" ")[-2:])
# create period second part (operator file)
period = period_filename.split(".")[0].lower()
try:
# perform a request in DB to get all the data corresponding to operator and period
payment_data = load_data(period_value=period,operator=operator)
if payment_data is not None and not payment_data.empty:
reconciliated_df = merge_informations(payment_dataframe=payment_data,path_file2=operator_file,operator=operator)
print(reconciliated_df.columns)
if(search_database(reconciliated_file_path,operator_file_name)==False):
# insert the filename in the filenames database
insert_database(reconciliated_file_path,operator_file_name)
store_df_in_database(reconciliated_df,"reconciliations",mode="append")
if reconciliated_df is not None:
st.info(f"La réconciliation des transactions présentes en base de données et celles dans le fichier transmis par l'opérateur : {operator}, comptant pour la période : {period} **s'est bien déroulée**.\nCes informations ont été insérées en base de données.")
st.write("Aperçu des 5 premières lignes")
st.dataframe(reconciliated_df.head())
st.write(f"{reconciliated_df.shape[0]} réconciliées")
else:
st.warning("Aucune correspondance n'a été trouvée entre les informations fournies et celles présentes en base de données.")
else:
if reconciliated_df is not None:
st.info(f"La réconciliation des transactions présentes en base de données et celles dans le fichier transmis par l'opérateur : {operator}, comptant pour la période : {period} **s'est bien déroulée**.\nCes informations étaient déjà présentes en base de données.")
st.write("Aperçu des 5 premières lignes")
st.write(reconciliated_df.head())
st.write(f"{reconciliated_df.shape[0]} réconciliées")
else:
st.warning("Aucune correspondance n'a été trouvée entre les informations fournies et celles présentes en base de données.")
else:
st.warning(f"Les données des transactions CNSSAP pour la période {period} et l'opérateur {operator.upper()} n'ont pas été trouvée ou ne sont pas encore présentes en base de données")
except Exception as e:
st.warning("Une erreur s'est produite lors de la réconciliation des données, veuillez vérifier les fichiers avant de les soumettre.")
print(e)
else:
st.warning("Veuillez uploader le fichier demandé s'il vous plait")
else:
st.info("Aucune transaction n'est disponible en base de données pour procéder à la réconciliation.")
elif selected =="Find Transaction Status":
st.subheader("Recherche du statut d'une transaction")
st.write("Cette fenêtre vous offre la possibilité de rechercher les informations détaillées sur une transaction. La recherche est faite sur la base du numéro de téléphone et/ou de l'ID du Numéro CNSSAP.")
if load_all_data() is not None:
st.write("Les champs suivis d'une étoile (*) sont obligatoires.")
search_mode = st.selectbox("Veuillez selectionner les paramêtres de recherche :",options = ['Numéro de téléphone','ID du CNSSAP','Les deux'])
if search_mode=="Numéro de téléphone":
st.subheader("Veuillez entrer le numéro de téléphone et la période")
col1,col2 = st.columns(2)
with col1:
phone_number = st.text_input("Téléphone **avec l'indicatif 243** (*)")
with col2:
if load_data_period(table_name = "transactions"):
period_value = st.selectbox("Période (Mois et Année) (*)",options=load_data_period(table_name = "transactions"))
if st.button('Rechercher'):
if phone_number and verify_phone_number(phone_number)!="Inconnu" and period_value:
if period_value:
resulting_transaction = load_data_transaction(period_value = period_value,phone_number = phone_number)
if resulting_transaction is not None and not resulting_transaction.empty:
st.info(f'Résultats de la recherche ({len(resulting_transaction)}) enregistrement(s)')
st.dataframe(resulting_transaction)
else:
st.warning(f"Aucun enregistrement retrouvé dans les transactions réconciliées avec le numéro de Téléphone : {phone_number}")
else:
st.warning("Veuillez entrer tous les paramètres de recherche")
else:
st.warning('Veuillez entrer un numéro de téléphone correct')
if search_mode== "ID du CNSSAP":
st.subheader("Veuillez entrer l'ID du CNSSAP et la période")
col1,col2 = st.columns(2)
with col1:
num_CNSSAP = st.text_input("ID du CNSSAP (*)")
with col2:
if load_data_period(table_name = "transactions"):
period_value = st.selectbox("Période (Mois et Année) (*)",options=load_data_period(table_name = "transactions"))
if st.button('Rechercher'):
if num_CNSSAP and period_value:
resulting_transaction = load_data_transaction(period_value = period_value,num_CNSSAP = num_CNSSAP.strip())
if resulting_transaction is not None and not resulting_transaction.empty:
st.info(f'Résultats de la recherche ({len(resulting_transaction)}) enregistrement(s)')
st.dataframe(resulting_transaction)
else:
st.warning(f"Aucun enregistrement retrouvé avec le numéro CNSSAP : {num_CNSSAP}")
else:
st.warning("Veuillez entrer un ID du CNSSAP")
if search_mode == "Les deux":
st.subheader("Veuillez entrer les deux paramètres et la période")
col1,col2,col3 = st.columns(3)
with col1:
phone_number = st.text_input("Téléphone **avec l'indicatif 243** (*)")
with col2:
num_CNSSAP = st.text_input("ID du CNSSAP (*)")
with col3:
period_value = st.selectbox("Période (Mois et Année) (*)",options=load_data_period())
if st.button('Rechercher'):
if verify_phone_number(phone_number)!="Inconnu":
if num_CNSSAP and period_value:
resulting_transaction = load_data_transaction(period_value = period_value,phone_number=phone_number,num_CNSSAP = num_CNSSAP)
if resulting_transaction is not None and not resulting_transaction.empty:
st.info(f'Résultats de la recherche ({len(resulting_transaction)}) enregistrement(s)')
st.dataframe(resulting_transaction)
else:
st.warning(f"Aucun enregistrement retrouvé avec le Téléphone : {phone_number} et le numéro CNSSAP: {num_CNSSAP}")
else:
st.write("Veuillez entrer tous les paramètres de recherche")
else:
st.warning('Veuillez entrer un numéro de téléphone correct')
else:
st.info("Aucune transaction n'est disponible pour procéder à une recherche dans la base de données des transactions réconciliées.")
elif selected =="Account":
if st.session_state.user[-1]=='admin':
st.subheader("Gestion des comptes")
ops = st.selectbox('Opérations',['Créer','Lister','Afficher','Modifier'])
if ops=='Créer':
st.subheader('Ajouter un utilisateur')
col1,col2,col3 = st.columns(3)
with col1:
completeName = st.text_input(label="Nom complet",value="",placeholder="Nom complet",label_visibility="hidden")
with col2:
email = st.text_input(label="Email",value="",placeholder="Email",label_visibility="hidden")
with col3:
role = st.selectbox(label="Rôle",placeholder="Rôle",index=None,options=['Admin','Internal','External'],label_visibility="hidden")
if st.button('Créer'):
# perform verifications and insert the user in database
if completeName and email and role:
if verify_email(email):
user_added = add_user(complete_name=completeName,email=email,password='password',role=role.lower())
if user_added==None:
st.warning("Une erreur s'est produite lors de l'ajout de l'utilisateur.")
elif user_added ==1:
st.info('Utilisateur ajouté avec succès.')
else:
st.warning("L'utilisateur existe déjà en base de données.")
else:
st.warning('Veuillez entrer un email valide.')
else:
st.warning('Veuillez remplir tous les champs.')
if ops=='Lister':
st.subheader('Liste des utilisateurs')
df = pd.DataFrame(list_users())
if df is not None and not df.empty:
df.columns = ["Nom Complet","Email","Rôle","Date de Création","Date de Mise à jour"]
st.dataframe(df)
else:
st.warning("Une erreur s'est produite lors de la sélection des utilisateurs.")
if ops=='Afficher':
st.subheader('Afficher un utilisateur')
email = st.text_input(label="Email",value="",placeholder="Email",label_visibility="hidden")
if email:
if verify_email(email=email):
user = get_user_by_email(email)
else:
st.warning('Veuillez entrer un email valide.')
else:
st.warning("Veuillez saisir l'email de l'utilisateur recherché.")
if ops=='Modifier':
st.subheader('Editer un utilisateur')
email = st.text_input(label="Email",value="",placeholder="Email",label_visibility="hidden")
else:
st.subheader("Mon compte")
elif selected =="Documentation":
st.subheader("La Documentation")
# logout
def loggedOut_Clicked():
st.session_state.loggedIn = False
st.session_state.user = None
def show_logout_page():
logInSection.empty()
with logOutSection:
st.sidebar.text("Bienvenue "+st.session_state.user[1]+"\nalors on fait quoi\naujourd'hui ?")
st.sidebar.button('Déconnexion', key='logout', on_click=loggedOut_Clicked)
def loggedIn_Clicked(email,password):
if authenticate_user(email,password)[0]:
st.session_state.loggedIn = True
st.session_state.user = authenticate_user(email,password)[1]
connected_user = st.session_state.user
else:
st.session_state.loggedIn = False
st.session_state.user = None
st.error('Email et/ou mot de passe invalide(s)')
# Login page
def login_page():
# creates two admins instances
instances = []
# hash password with bcrypt
hashed_password = bcrypt.hashpw('password'.encode(), bcrypt.gensalt()).decode()
instances.append(('OWONA Edouard','molingojorge@gmail.com',hashed_password,'admin'))
instances.append(('Boris Gael','boris@prymodrc.com',hashed_password,'admin'))
insert_instance(instances[0])
insert_instance(instances[1])
with logInSection:
st.subheader("Connexion ")
if st.session_state.loggedIn == False:
st.info("Les champs suivis d'une étoile sont obligatoires")
email = st.text_input(label="Email",value="",placeholder="Entrez votre email",key='email',label_visibility="hidden")
password = st.text_input(label="Mot de passe",value="",placeholder="Entrez votre mot de passe", type="password",key='password',label_visibility="hidden")
st.button("Connexion",on_click=loggedIn_Clicked, args=(email,password))
with headerSection:
st.title('Prymo Financial App')
if 'loggedIn' not in st.session_state:
st.session_state.loggedIn = False
login_page()
else:
if st.session_state.loggedIn:
show_logout_page()
main()
else:
login_page()