1+ # For the web ui setup
2+ import streamlit as st
3+ import pandas as pd
4+ import matplotlib .pyplot as plt
5+ # For proper importing stuff
6+ import os
7+ import sys
8+ sys .path .insert (0 ,os .path .abspath (os .path .join (os .path .dirname (__file__ ),'..' ,'..' ,'..' )))
9+ # Initialize the session states
10+ from CLI .app .streamlit_setup import init_st , sync_data
11+
12+ init_st ()
13+
14+ st .title ('Monthly Summary' )
15+
16+ # Get current month and year
17+ current_month = st .session_state .current_month
18+ month_name = pd .to_datetime (current_month ).strftime ('%B %Y' )
19+
20+ # Filter expenses and income for the current month
21+ expenses = [expense for expense in st .session_state .expenses if expense ['date' ][:7 ] == current_month ]
22+ income = [inc for inc in st .session_state .income if inc ['date' ][:7 ] == current_month ]
23+
24+ # Calculate totals
25+ total_expenses = sum (expense ['price' ] for expense in expenses )
26+ total_income = sum (inc ['amount' ] for inc in income )
27+ net_savings = total_income - total_expenses
28+
29+ # Display metrics
30+ col1 , col2 , col3 = st .columns (3 )
31+ with col1 :
32+ st .metric ('Total Expenses' , f"${ total_expenses :.2f} " )
33+ with col2 :
34+ st .metric ('Total Income' , f"${ total_income :.2f} " )
35+ with col3 :
36+ st .metric ('Net Savings' , f"${ net_savings :.2f} " , delta_color = "inverse" if net_savings < 0 else "normal" )
37+
38+ st .divider ()
39+
40+ # Expense breakdown by category
41+ expense_by_category = {}
42+ for expense in expenses :
43+ category = expense ['tags' ]
44+ expense_by_category [category ] = expense_by_category .get (category , 0 ) + expense ['price' ]
45+
46+ if expense_by_category :
47+ st .subheader ('Expenses by Category' )
48+
49+ # Create a DataFrame for the table
50+ df = pd .DataFrame ({
51+ 'Category' : list (expense_by_category .keys ()),
52+ 'Amount' : list (expense_by_category .values ())
53+ }).sort_values ('Amount' , ascending = False )
54+
55+ # Display table
56+ st .dataframe (df , hide_index = True )
57+
58+ # Create pie chart
59+ fig , ax = plt .subplots ()
60+ ax .pie (df ['Amount' ], labels = df ['Category' ], autopct = '%1.1f%%' )
61+ ax .set_title ('Expense Distribution' )
62+ st .pyplot (fig )
63+ else :
64+ st .write ("No expenses recorded for this month." )
65+
66+ st .divider ()
67+
68+ # Income breakdown by source
69+ income_by_source = {}
70+ for inc in income :
71+ source = inc ['source' ]
72+ income_by_source [source ] = income_by_source .get (source , 0 ) + inc ['amount' ]
73+
74+ if income_by_source :
75+ st .subheader ('Income by Source' )
76+
77+ # Create a DataFrame for the table
78+ df = pd .DataFrame ({
79+ 'Source' : list (income_by_source .keys ()),
80+ 'Amount' : list (income_by_source .values ())
81+ }).sort_values ('Amount' , ascending = False )
82+
83+ # Display table
84+ st .dataframe (df , hide_index = True )
85+
86+ # Create pie chart
87+ fig , ax = plt .subplots ()
88+ ax .pie (df ['Amount' ], labels = df ['Source' ], autopct = '%1.1f%%' )
89+ ax .set_title ('Income Distribution' )
90+ st .pyplot (fig )
91+ else :
92+ st .write ("No income recorded for this month." )
93+
94+ st .divider ()
95+
96+ # Monthly comparison (if previous months exist)
97+ all_months = sorted (list (set ([expense ['date' ][:7 ] for expense in st .session_state .expenses ] + [inc ['date' ][:7 ] for inc in st .session_state .income ])), reverse = True )
98+
99+ if len (all_months ) > 1 :
100+ st .subheader ('Monthly Comparison' )
101+
102+ # Create a DataFrame for monthly data
103+ monthly_data = []
104+ for month in all_months :
105+ month_expenses = sum (expense ['price' ] for expense in st .session_state .expenses if expense ['date' ][:7 ] == month )
106+ month_income = sum (inc ['amount' ] for inc in st .session_state .income if inc ['date' ][:7 ] == month )
107+ monthly_data .append ({
108+ 'Month' : pd .to_datetime (month ).strftime ('%B %Y' ),
109+ 'Expenses' : month_expenses ,
110+ 'Income' : month_income ,
111+ 'Savings' : month_income - month_expenses
112+ })
113+
114+ df = pd .DataFrame (monthly_data )
115+
116+ # Display table
117+ st .dataframe (df , hide_index = True )
118+
119+ # Create bar chart
120+ fig , ax = plt .subplots ()
121+ df .plot (x = 'Month' , y = ['Expenses' , 'Income' ], kind = 'bar' , ax = ax )
122+ ax .set_title ('Monthly Expenses vs Income' )
123+ ax .set_ylabel ('Amount ($)' )
124+ plt .xticks (rotation = 45 )
125+ plt .tight_layout ()
126+ st .pyplot (fig )
127+
128+ # Create savings trend chart
129+ fig , ax = plt .subplots ()
130+ df .plot (x = 'Month' , y = 'Savings' , kind = 'line' , marker = 'o' , ax = ax )
131+ ax .set_title ('Monthly Savings Trend' )
132+ ax .set_ylabel ('Savings ($)' )
133+ plt .xticks (rotation = 45 )
134+ plt .tight_layout ()
135+ st .pyplot (fig )
136+
137+ # Export options
138+ st .subheader ('Export Data' )
139+ col1 , col2 = st .columns (2 )
140+ with col1 :
141+ if st .button ('Export Expenses to CSV' ):
142+ result = st .session_state .tracker .export_to_csv ('expenses' , 'expenses.csv' )
143+ if result ['success' ]:
144+ st .download_button (
145+ label = "Download Expenses CSV" ,
146+ data = result ['data' ].to_csv (index = False ).encode ('utf-8' ),
147+ file_name = "expenses.csv" ,
148+ mime = "text/csv"
149+ )
150+ with col2 :
151+ if st .button ('Export Summary to PDF' ):
152+ result = st .session_state .tracker .export_to_pdf ('expenses' , 'monthly_summary.pdf' )
153+ if result ['success' ]:
154+ with open ('monthly_summary.pdf' , 'rb' ) as f :
155+ st .download_button (
156+ label = "Download PDF Summary" ,
157+ data = f ,
158+ file_name = "monthly_summary.pdf" ,
159+ mime = "application/pdf"
160+ )
0 commit comments