22from tkinter import ttk
33from tkinter import messagebox
44import customtkinter as ctk
5+
56from datetime import datetime
7+ from pathlib import Path
68
7- from gui_widgets import *
8- from item import ItemsDB
9+ from gui_widgets import ItemsTable , SummaryByCategoryPivotTable
10+ from item import ItemsDB , Category , Item
11+ from expense_income_stats import ExcelReport , PdfReport
912
1013
1114class App (ctk .CTk ):
@@ -44,38 +47,24 @@ def __init__(self, db_path, *args, **kwargs):
4447 )
4548 button .pack (pady = 5 )
4649
47- # # Button for Clearing the Items in the Table (Not Deleting from Json)
48- # self.btn_clear_all_items = ctk.CTkButton(self.tab_view_settings.tab('Edit'),
49- # text='Clear Items',
50- # command=lambda: self.items_table.clear_items(),
51- # )
52- # self.btn_clear_all_items.pack(pady=5)
53- #
54- # def lesson_option(choice):
55- # lesson_number = int(choice) - 1
56- # return lesson_number
57- #
58- # optionbox_var = ctk.StringVar(value="1")
59- # optionbox = ctk.CTkOptionMenu(self.tab_view_settings.tab('Edit'),
60- # values=['1', '2'],
61- # variable=optionbox_var,
62- # command=lesson_option)
63- # optionbox.pack()
50+ button = ctk .CTkButton (self .tab_view_settings .tab ('Edit' ),
51+ text = 'Update Summaries' ,
52+ command = self .update_pivot_tables ,
53+ )
54+ button .pack (pady = 5 )
6455
6556 # Report Tab
6657 self .tab_view_settings .add ('Report' )
6758
68- # TODO: Create Event-handler for Generating Excel Report
6959 self .btn_generate_excel_report = ctk .CTkButton (self .tab_view_settings .tab ('Report' ),
7060 text = 'Generate Excel Report' ,
71- command = lambda : print ( 'Generating Excel Report ...' ) ,
61+ command = self . generate_excel_report ,
7262 )
7363 self .btn_generate_excel_report .pack (pady = 5 )
7464
75- # TODO: Create Event-handler for Generating PDF Report
7665 self .btn_generate_pdf_report = ctk .CTkButton (self .tab_view_settings .tab ('Report' ),
7766 text = 'Generate PDF Report' ,
78- command = lambda : print ( 'Generating PDF Report ...' ) ,
67+ command = self . generate_pdf_report ,
7968 )
8069 self .btn_generate_pdf_report .pack (pady = 5 )
8170
@@ -169,21 +158,32 @@ def __init__(self, db_path, *args, **kwargs):
169158 # CTkTabview for Visualizations
170159 self .tab_view_visuals = ctk .CTkTabview (self )
171160 self .tab_view_visuals .grid (row = 2 , column = 0 , padx = 5 , pady = 5 , columnspan = 3 , sticky = 'nswe' )
172- self .tab_view_visuals .add ("Expense Summary" ) # Expense Summary Tab
173- self .tab_view_visuals .add ("Income Summary" ) # add tab at the end
174- self .tab_view_visuals .set ("Expense Summary" ) # set currently visible tab
175161
176- # TODO: Expense Summary Tab Contents
177- label = ctk . CTkLabel ( master = self . tab_view_visuals . tab ( 'Expense Summary' ), text = "Under Construction" ,
178- fg_color = "red" )
179- label . pack ()
162+ expense_tab = self . tab_view_visuals . add (
163+ "Summary By Category" ) # Summary By Category Tab
164+
165+ self . tab_view_visuals . set ( "Summary By Category" ) # set currently visible tab
180166
181- # TODO: Income Summary Tab Contents
167+ # Summary By Category Tab Contents
168+ self .pivot_table = SummaryByCategoryPivotTable (self .tab_view_visuals .tab ('Summary By Category' ))
182169
183170 # ==============================================================================================================
184171 # Other Widget-Event-Callbacks Bindings
185172 self .protocol ("WM_DELETE_WINDOW" , self .on_window_close )
186173
174+ def update_pivot_tables (self ):
175+ self .pivot_table .update_pivot_table ()
176+
177+ def generate_excel_report (self ):
178+ excel_path = str (Path (__file__ ).resolve ().parent / 'report.xlsx' )
179+ report = ExcelReport (excel_path , self ._items_db )
180+ report .generate_report ()
181+
182+ def generate_pdf_report (self ):
183+ pdf_path = str (Path (__file__ ).resolve ().parent / 'report.pdf' )
184+ report = PdfReport (pdf_path , self ._items_db )
185+ report .generate_report ()
186+
187187 def on_window_close (self ):
188188 # Reference: https://stackoverflow.com/questions/111155/how-do-i-handle-the-window-close-event-in-tkinter
189189 print ('Window Closing ...' )
@@ -200,10 +200,6 @@ def _get_form_values(self):
200200 'subcategory' : self .entry_subcategory .get (),
201201 }
202202
203- def _validate_form_values (self ):
204- # TODO: Add Form Entry Validations
205- pass
206-
207203 def clear_form (self ):
208204 self .entry_name .delete (0 , last_index = len (self .entry_name .get ()))
209205 self .entry_amount .delete (0 , last_index = len (self .entry_amount .get ()))
@@ -221,13 +217,6 @@ def fill_form(self, name, amount, description, date, category='None', subcategor
221217 self .entry_category .insert (0 , category )
222218 self .entry_subcategory .insert (0 , subcategory )
223219
224- # self.entry_name.configure(placeholder_text=name)
225- # self.entry_amount.configure(placeholder_text=amount)
226- # self.entry_date.configure(textvariable=date)
227- # self.entry_description.configure(placeholder_text=description)
228- # self.entry_category.configure(placeholder_text=category)
229- # self.entry_subcategory.configure(placeholder_text=subcategory)
230-
231220 def on_btn_add_clicked (self ):
232221 new_item = self ._create_item_from_form ()
233222
@@ -259,10 +248,9 @@ def on_btn_update_clicked(self):
259248 item_obj .amount = float (self .entry_amount .get ().strip ())
260249 item_obj .description = self .entry_description .get ().strip ()
261250 item_obj .date = datetime .strptime (self .entry_date .get ().strip (), '%Y-%m-%d %H:%M:%S' )
262- item_obj .category = \
263- None if self .entry_category .get () == 'None' else \
264- Category (self .entry_category .get ().strip ()) if self .entry_subcategory .get ().strip () == 'None' else \
265- Category (self .entry_category .get ().strip (), self .entry_subcategory .get ().strip ())
251+ item_obj .category = None if self .entry_category .get () == 'None' else Category (
252+ self .entry_category .get ().strip ()) if self .entry_subcategory .get ().strip () == 'None' else Category (
253+ self .entry_category .get ().strip (), self .entry_subcategory .get ().strip ())
266254
267255 except ValueError as value_error :
268256 messagebox .showerror ('Error' , str (value_error ))
@@ -341,7 +329,7 @@ def _create_item_from_form(self) -> Item | None:
341329
342330 temp_item = Item .create (
343331 self .entry_name .get (),
344- self .entry_amount .get (),
332+ float ( self .entry_amount .get () ),
345333 self .entry_description .get (),
346334 self .entry_date .get (),
347335 category
@@ -354,14 +342,16 @@ def _create_item_from_form(self) -> Item | None:
354342 def on_row_selected (self , e ):
355343 # Reference: https://stackoverflow.com/questions/30614279/tkinter-treeview-get-selected-item-values
356344
345+ # Reference: For Multiple Selected Rows
346+ # https://stackoverflow.com/questions/48867800/tk-treeview-focus-how-do-i-get-multiple-selected-lines
347+
357348 # Set the Selected Item for the TreeView
358349 selected_item = self .items_table .focus ()
359350 item_dct = self .items_table .item (selected_item )
360351
361352 values = item_dct ['values' ]
362353 item_id = item_dct ['text' ]
363354 row = [item_id ] + list (values )
364- print (row )
365355
366356 self .fill_form (
367357 values [0 ],
@@ -371,9 +361,3 @@ def on_row_selected(self, e):
371361 category = values [4 ],
372362 subcategory = values [5 ]
373363 )
374-
375- # def on_rows_selected(self, e):
376- # # Reference: https://stackoverflow.com/questions/48867800/tk-treeview-focus-how-do-i-get-multiple-selected-lines
377- # selected_items = self.items_table.selection() # Gets the Selected Items from TreeView Table
378- # # self.items_table.selection_set(selected_items)
379- # selected_items = [self.items_table.item(selected_item) for selected_item in selected_items]
0 commit comments