Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -151,11 +151,10 @@ The reporting period is from {start_date.strftime('%d %B %Y')} to {end_date.strf
|
|
| 151 |
The currency is South African Rand (ZAR).
|
| 152 |
The report must contain sections for Revenue, Operating Expenses, and Net Income or Loss. Each of these sections must be a clear table.
|
| 153 |
The Revenue section must contain a single table showing only the 'Total Revenue'. Do NOT create a table that itemizes or lists individual income sources.
|
| 154 |
-
The report must also include a "Key Highlights" section with bullet points and a final
|
| 155 |
Use the provided JSON data for all financial figures.
|
| 156 |
For the Net Income or Loss table, if the net position is negative, display the amount in parentheses.
|
| 157 |
-
Separate the major sections with a horizontal rule.
|
| 158 |
-
Your output should just be the report, no quips.
|
| 159 |
"""
|
| 160 |
try:
|
| 161 |
st.info("Sending request to Gemini for final report formatting...")
|
|
@@ -191,7 +190,6 @@ def create_pdf_report(report_text):
|
|
| 191 |
|
| 192 |
for element in soup.find_all(True):
|
| 193 |
if element.name in ['h1', 'h2', 'h3']:
|
| 194 |
-
# --- BUG FIX 1: Correctly extract the number from the tag ---
|
| 195 |
level = int(element.name[1])
|
| 196 |
font_size = {1: 16, 2: 14, 3: 12}.get(level, 11)
|
| 197 |
pdf.set_font('helvetica', 'B', font_size)
|
|
@@ -234,8 +232,7 @@ def create_pdf_report(report_text):
|
|
| 234 |
if is_total_row:
|
| 235 |
pdf.set_font('helvetica', 'B', 10)
|
| 236 |
|
| 237 |
-
|
| 238 |
-
if len(row) == len(col_widths): # Ensure row has the correct number of cells
|
| 239 |
pdf.cell(col_widths[0], 7, row[0], border=1)
|
| 240 |
pdf.cell(col_widths[1], 7, row[1], border=1, align='R')
|
| 241 |
pdf.ln()
|
|
@@ -294,14 +291,31 @@ def main():
|
|
| 294 |
|
| 295 |
if st.session_state['transactions']:
|
| 296 |
df = pd.DataFrame(st.session_state['transactions'])
|
|
|
|
| 297 |
df['Date'] = pd.to_datetime(df['Date'], errors='coerce', dayfirst=True)
|
| 298 |
df.dropna(subset=['Date'], inplace=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 299 |
if not df.empty:
|
| 300 |
st.session_state['min_date'] = df['Date'].min().date()
|
| 301 |
st.session_state['max_date'] = df['Date'].max().date()
|
|
|
|
| 302 |
st.write("### Extracted Transactions")
|
| 303 |
st.dataframe(df.astype(str))
|
| 304 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 305 |
st.write("### Generate Financial Report")
|
| 306 |
col1, col2 = st.columns(2)
|
| 307 |
with col1:
|
|
@@ -314,10 +328,12 @@ def main():
|
|
| 314 |
if not st.session_state['transactions']:
|
| 315 |
st.error("No transactions available to generate report. Please upload files first.")
|
| 316 |
else:
|
| 317 |
-
|
| 318 |
-
|
| 319 |
-
|
| 320 |
-
|
|
|
|
|
|
|
| 321 |
|
| 322 |
if filtered_df.empty:
|
| 323 |
st.warning("No transactions found within the selected date range.")
|
|
|
|
| 151 |
The currency is South African Rand (ZAR).
|
| 152 |
The report must contain sections for Revenue, Operating Expenses, and Net Income or Loss. Each of these sections must be a clear table.
|
| 153 |
The Revenue section must contain a single table showing only the 'Total Revenue'. Do NOT create a table that itemizes or lists individual income sources.
|
| 154 |
+
The report must also include a "Key Highlights" section with bullet points and a final "Summary" paragraph.
|
| 155 |
Use the provided JSON data for all financial figures.
|
| 156 |
For the Net Income or Loss table, if the net position is negative, display the amount in parentheses.
|
| 157 |
+
Separate the major sections with a horizontal rule.
|
|
|
|
| 158 |
"""
|
| 159 |
try:
|
| 160 |
st.info("Sending request to Gemini for final report formatting...")
|
|
|
|
| 190 |
|
| 191 |
for element in soup.find_all(True):
|
| 192 |
if element.name in ['h1', 'h2', 'h3']:
|
|
|
|
| 193 |
level = int(element.name[1])
|
| 194 |
font_size = {1: 16, 2: 14, 3: 12}.get(level, 11)
|
| 195 |
pdf.set_font('helvetica', 'B', font_size)
|
|
|
|
| 232 |
if is_total_row:
|
| 233 |
pdf.set_font('helvetica', 'B', 10)
|
| 234 |
|
| 235 |
+
if len(row) == len(col_widths):
|
|
|
|
| 236 |
pdf.cell(col_widths[0], 7, row[0], border=1)
|
| 237 |
pdf.cell(col_widths[1], 7, row[1], border=1, align='R')
|
| 238 |
pdf.ln()
|
|
|
|
| 291 |
|
| 292 |
if st.session_state['transactions']:
|
| 293 |
df = pd.DataFrame(st.session_state['transactions'])
|
| 294 |
+
# Clean and validate data
|
| 295 |
df['Date'] = pd.to_datetime(df['Date'], errors='coerce', dayfirst=True)
|
| 296 |
df.dropna(subset=['Date'], inplace=True)
|
| 297 |
+
|
| 298 |
+
# Perform the same robust cleaning for Amount as in the aggregation function
|
| 299 |
+
if 'Amount' in df.columns:
|
| 300 |
+
df['Amount'] = df['Amount'].astype(str).str.replace(r'[^\d.]', '', regex=True)
|
| 301 |
+
df['Amount'] = pd.to_numeric(df['Amount'], errors='coerce').fillna(0)
|
| 302 |
+
|
| 303 |
if not df.empty:
|
| 304 |
st.session_state['min_date'] = df['Date'].min().date()
|
| 305 |
st.session_state['max_date'] = df['Date'].max().date()
|
| 306 |
+
|
| 307 |
st.write("### Extracted Transactions")
|
| 308 |
st.dataframe(df.astype(str))
|
| 309 |
|
| 310 |
+
# --- NEW FEATURE: Download Processed CSV Button ---
|
| 311 |
+
st.download_button(
|
| 312 |
+
label="Download Processed CSV",
|
| 313 |
+
data=df.to_csv(index=False).encode('utf-8'),
|
| 314 |
+
file_name='processed_transactions.csv',
|
| 315 |
+
mime='text/csv',
|
| 316 |
+
)
|
| 317 |
+
# --- END OF NEW FEATURE ---
|
| 318 |
+
|
| 319 |
st.write("### Generate Financial Report")
|
| 320 |
col1, col2 = st.columns(2)
|
| 321 |
with col1:
|
|
|
|
| 328 |
if not st.session_state['transactions']:
|
| 329 |
st.error("No transactions available to generate report. Please upload files first.")
|
| 330 |
else:
|
| 331 |
+
# Re-create dataframe from session state to ensure it's fresh for filtering
|
| 332 |
+
df_report = pd.DataFrame(st.session_state['transactions'])
|
| 333 |
+
df_report['Date'] = pd.to_datetime(df_report['Date'], errors='coerce', dayfirst=True)
|
| 334 |
+
|
| 335 |
+
mask = (df_report['Date'] >= pd.to_datetime(start_date)) & (df_report['Date'] <= pd.to_datetime(end_date))
|
| 336 |
+
filtered_df = df_report.loc[mask]
|
| 337 |
|
| 338 |
if filtered_df.empty:
|
| 339 |
st.warning("No transactions found within the selected date range.")
|