Spaces:
Running
Running
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() |