Spaces:
Sleeping
Sleeping
File size: 12,824 Bytes
d8535a4 |
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 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 |
import os
import pandas as pd
import streamlit as st
from google.cloud import bigquery
from utils import load_gcp_credentials, authenticate_bigquery_updated
from html_templates import logo, payment_title, progress_bar_style, process_file_title, process_date_title, button_styles, download_button_styles, tooltip_message_payment, update_sett_placeholder,update_sett_title, conso_date_title
import io
import zipfile
from datetime import datetime
import time
from payment_queries import queries
from streamlit_option_menu import option_menu
from merge_queries import queries_merged_01, queries_merged_02, queries_merged_03, conso_query, disburse_query
from io import BytesIO
# ---- πΉ Inject Custom CSS for Styling ----
st.markdown(progress_bar_style,unsafe_allow_html=True)
# ---- πΉ Streamlit UI ----
st.markdown(logo, unsafe_allow_html=True)
st.logo("alerter_4.jpeg")
st.markdown(payment_title, unsafe_allow_html=True)
st.write("")
st.markdown(tooltip_message_payment, unsafe_allow_html = True)
st.write("")
selected = option_menu(
menu_title=None,
options=["Payment File", "Disbursement File"],
icons=["database", "bar-chart"],
menu_icon="cast",
default_index=0,
orientation="horizontal",
styles={
"container": {
"padding": "0px",
"background-color": "#800000 !important" # Maroon with force override
},
"icon": {
"color": "#ffffff !important", # White icons with forced override
"font-size": "20px"
},
"nav-link": {
"font-size": "18px",
"text-align": "center",
"margin": "0px",
"padding": "10px",
"color": "#ffffff !important", # White text for unselected tabs
"background-color": "#800000 !important", # Force maroon
},
"nav-link-selected": {
"background-color": "#a52a2a !important", # Reddish maroon for selected tab
"color": "#ffffff !important", # White text for selected tab
"font-weight": "bold",
},
},
)
# ---- πΉ User Input Date ----
if selected == 'Payment File':
st.markdown(process_date_title, unsafe_allow_html = True)
st.write("")
selected_date = st.date_input("", value=datetime.today()) # Default: Today
formatted_date = selected_date.strftime("%Y-%m-%d") # Convert to string format YYYY-MM-DD
# ---- πΉ Run Queries Button ----
st.markdown(button_styles, unsafe_allow_html = True)
if st.button("Generate Payment File"):
st.markdown(process_file_title, unsafe_allow_html = True)
st.write("")
st.write("")
# Define sheet names
sheet_names = [
"09", "11", "12", "MD", "Not_match_09", "Not_match_11", "Not_match_12"
]
# Retrieve the service account credentials
gcp_credentials = load_gcp_credentials()
if gcp_credentials:
bigquery_creds = authenticate_bigquery_updated()
client = bigquery.Client(credentials=bigquery_creds)
# Store DataFrames
dataframes = {}
# ---- π **Dynamic Log Section** ----
log_area = st.empty()
log_text_list = [] # Store logs as a list
# ---- π **Progress Bar Setup** ----
progress_bar = st.progress(0) # Initialize progress bar
progress_text = st.empty() # Placeholder for text
total_steps = len(queries) # Total number of queries to process
for i, (query_name, query) in enumerate(queries.items()):
sheet_name = sheet_names[i] if i < len(sheet_names) else f"Sheet_{i+1}"
# πΉ **Modify Query to Include Selected Date**
dynamic_query = query.replace("{selected_date}", formatted_date)
# π **Blinking Cursor Effect**
cursor_state = ["|", "/", "-", "\\"]
for cursor in cursor_state:
log_text_list.append(
f"<p class='gradient-text'>π΅ {sheet_name} is being processed... <span class='blinking-cursor'>{cursor}</span></p>"
)
log_area.markdown("".join(log_text_list), unsafe_allow_html=True) # β
FORCE NEWLINES
log_text_list.pop() # Remove last blinking message to replace it
time.sleep(0.3)
try:
# Execute Query
query_job = client.query(dynamic_query)
df = query_job.to_dataframe()
# πΉ **Fix: Remove Timezone from Datetime Columns**
for col in df.select_dtypes(include=["datetime64[ns, UTC]"]).columns:
df[col] = df[col].dt.tz_localize(None)
# Store the DataFrame
dataframes[sheet_name] = df
# π **Static Log with Record Count**
record_count = len(df)
log_text_list.append(
f"<p class='gradient-text'>β
{sheet_name} sheet created successfully... Total <b>{record_count}</b> records.</p>"
)
log_area.markdown("".join(log_text_list), unsafe_allow_html=True) # β
FORCE NEWLINES
except Exception as e:
log_text_list.append(f"<p class='gradient-text'>β Error in {sheet_name}: {e}</p>")
log_area.markdown("".join(log_text_list), unsafe_allow_html=True)
# ---- π **Update Progress Bar (Stay at 99%)** ----
progress_percentage = int(((i + 1) / total_steps) * 98) # Keep it at max 98%
progress_bar.progress(progress_percentage)
progress_text.markdown(
f'<p class="gradient-text">βοΈ Creating Payment File... {progress_percentage}%</p>',
unsafe_allow_html=True
)
time.sleep(0.5) # Small delay to simulate processing
# ---- π₯ Generate & Show Download Buttons (Only Now Progress Reaches 100%) ----
if dataframes:
progress_bar.progress(99) # Keep at 99% while preparing file
progress_text.markdown('<p class="gradient-text">βοΈ Finalizing file... Please wait...</p>', unsafe_allow_html=True)
# π₯ **Excel Generation**
excel_buffer = io.BytesIO()
with pd.ExcelWriter(excel_buffer, engine="openpyxl") as writer:
for sheet, df in dataframes.items():
df.to_excel(writer, sheet_name=sheet, index=False)
excel_buffer.seek(0)
# π₯ **CSV ZIP Generation**
csv_buffer = io.BytesIO()
with zipfile.ZipFile(csv_buffer, "w", zipfile.ZIP_DEFLATED) as zipf:
for sheet, df in dataframes.items():
csv_data = df.to_csv(index=False).encode("utf-8")
zipf.writestr(f"{sheet}_{formatted_date}.csv", csv_data)
csv_buffer.seek(0)
# ---- β
**Now Move Progress to 100% and Show Download Options** ----
progress_bar.progress(100)
progress_text.markdown('<p class="gradient-text">β
Payment file created. Ready for download.</p>', unsafe_allow_html=True)
# ---- π₯ Download Buttons ----
st.markdown(download_button_styles, unsafe_allow_html = True)
st.download_button(
label=f"π₯ Download Payment File",
data=excel_buffer,
file_name=f"queries_results_{formatted_date}.xlsx",
mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
)
elif selected == 'Disbursement File':
gcp_credentials = load_gcp_credentials()
# Radio Button for Selection
st.markdown(update_sett_placeholder,unsafe_allow_html=True)
# Styled Radio Button
st.markdown(update_sett_title, unsafe_allow_html = True)
update_option = st.radio(
"",
["Update 09", "Update 11", "Update 12"]
)
# Map selection to queries
if update_option == "Update 09":
selected_queries = queries_merged_01
elif update_option == "Update 11":
selected_queries = queries_merged_02
elif update_option == "Update 12":
selected_queries = queries_merged_03
else:
selected_queries = []
# Button to execute queries
st.markdown(button_styles, unsafe_allow_html = True)
if st.button("Execute Updates") and selected_queries:
st.markdown("<h3 style='text-align: center; color: maroon;'>Executing Queries & Updating IDs</h3>", unsafe_allow_html=True)
gcp_credentials = load_gcp_credentials()
if gcp_credentials:
bigquery_creds = authenticate_bigquery_updated()
client = bigquery.Client(credentials=bigquery_creds)
total_queries = len(selected_queries)
progress_bar = st.progress(0)
updated_counts = {}
for i, query in enumerate(selected_queries):
st.markdown(f"### Running Query {i+1} of {total_queries}...")
start_time = time.time()
# Execute query
query_job = client.query(query)
query_job.result()
updated_count = query_job.num_dml_affected_rows or 0
updated_counts[f"Query {i+1}"] = updated_count
# Update progress bar
progress = int(((i + 1) / total_queries) * 100)
progress_bar.progress(progress / 100)
# Display execution details
execution_time = time.time() - start_time
st.success(f"β
Query {i+1} executed in {execution_time:.2f} sec. **{updated_count} IDs updated.**")
time.sleep(1)
# Summary
progress_bar.progress(1.0)
# Streamlit Date Input
st.markdown(conso_date_title, unsafe_allow_html = True)
selected_date = st.date_input("")
# If a date is selected, show the download button
st.markdown(button_styles, unsafe_allow_html = True)
if st.button('Generate disbursement') and selected_date:
selected_date_str = selected_date.strftime("%Y-%m-%d")
if selected_date_str:
# β
Authenticate with BigQuery
gcp_credentials = load_gcp_credentials()
if gcp_credentials:
bigquery_creds = authenticate_bigquery_updated()
client = bigquery.Client(credentials=bigquery_creds)
# β
Set query parameters
job_config = bigquery.QueryJobConfig(
query_parameters=[
bigquery.ScalarQueryParameter("selected_date", "DATE", selected_date_str)
]
)
# β
Execute queries
conso_df = client.query(conso_query, job_config=job_config).to_dataframe()
disburse_df = client.query(disburse_query, job_config=job_config).to_dataframe()
# β
Remove timezone and convert datetime columns
def clean_datetime_columns(df):
for col in df.select_dtypes(include=["datetime64[ns, UTC]"]).columns:
df[col] = df[col].dt.tz_localize(None) # Remove timezone
for col in df.select_dtypes(include=["datetime64"]).columns:
df[col] = df[col].astype(str) # Convert datetime to string
clean_datetime_columns(conso_df)
clean_datetime_columns(disburse_df)
# β
Save to an in-memory Excel file
output = BytesIO()
with pd.ExcelWriter(output, engine="xlsxwriter") as writer:
conso_df.to_excel(writer, sheet_name="Sheet1", index=False)
disburse_df.to_excel(writer, sheet_name="disbursement_summary", index=False)
output.seek(0) # β
Reset buffer position
# β
Place buttons side by side
col1, col2 = st.columns(2)
with col1:
st.download_button(
label="Download Disbursement Data",
data=output,
file_name=f"disbursement_data_{selected_date_str}.xlsx",
mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
)
with col2:
if st.button("Generate Disbursement"):
st.success("Disbursement Generated Successfully β
")
|