class MainFrame(wx.Frame): WILDCARD = "YAML (*.yml)|*.yml|" \ "All files (*.*)|*.*" def __init__(self): super().__init__(parent=None, title='Cash Flow Calculator') self.settingsFile = os.getcwd() + '/data/' + '.cash_flow_settings.yml' self.settings = AppSettings() self.ts = TransactionStore() self.defaultDir = os.getcwd() + '/data' self.notebook = wx.Notebook(self) self.notebook.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.handleNotebookChange) self.transactionManagement = TransactionManagement( self.notebook, self.ts, self.settings) self.notebook.AddPage(self.transactionManagement, "Transaction Management") self.cashFlowDisplay = CashFlowDisplay(self.notebook, self.ts, self.settings) self.notebook.AddPage(self.cashFlowDisplay, "Cash Flow") self.SetInitialSize(wx.Size(650, 650)) self.create_menu() self.loadSettings() self.loadTransactions(self.settings.dataFile) self.Show() def handleNotebookChange(self, event): self.updateChildren() event.Skip() def updateChildren(self): self.transactionManagement.loadSettings() self.transactionManagement.redraw() self.cashFlowDisplay.loadSettings() self.cashFlowDisplay.updateList() def create_menu(self): menu_bar = wx.MenuBar() file_menu = wx.Menu() new_file_menu_item = file_menu.Append(wx.ID_ANY, "New File", "Create a new file") open_file_menu_item = file_menu.Append(wx.ID_ANY, "Open...", "Open a file") save_menu_item = file_menu.Append(wx.ID_ANY, "Save", "Save to current file") save_as_menu_item = file_menu.Append(wx.ID_ANY, "Save As", "Save file with new name") menu_bar.Append(file_menu, "&File") self.Bind( event=wx.EVT_MENU, handler=self.on_new_file, source=new_file_menu_item, ) self.Bind( event=wx.EVT_MENU, handler=self.on_open_file, source=open_file_menu_item, ) self.Bind( event=wx.EVT_MENU, handler=self.on_save, source=save_menu_item, ) self.Bind( event=wx.EVT_MENU, handler=self.on_save_as, source=save_as_menu_item, ) self.SetMenuBar(menu_bar) def on_new_file(self, event): self.loadSettings() self.settings.dataFile = None self.saveSettings() self.loadTransactions() def on_open_file(self, event): dlg = wx.FileDialog(self, message="Choose a file", defaultDir=self.defaultDir, defaultFile="", wildcard=MainFrame.WILDCARD, style=wx.FD_OPEN | wx.FD_CHANGE_DIR | wx.FD_FILE_MUST_EXIST | wx.FD_PREVIEW) if dlg.ShowModal() == wx.ID_OK: self.loadSettings() self.settings.dataFile = dlg.GetPath() self.loadTransactions(self.settings.dataFile) self.saveSettings() dlg.Destroy() def on_save(self, event): if self.settings.dataFile is not None: self.saveTransactions() self.saveSettings() else: self.on_save_as(event) def on_save_as(self, event): if self.settings.dataFile is not None: defaultDir = os.path.dirname(self.settings.dataFile) defaultFile = os.path.basename(self.settings.dataFile) else: defaultDir = self.defaultDir defaultFile = "" dlg = wx.FileDialog(self, message="Save file as ...", defaultDir=defaultDir, defaultFile=defaultFile, wildcard=MainFrame.WILDCARD, style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) if dlg.ShowModal() == wx.ID_OK: self.settings.dataFile = dlg.GetPath() self.saveTransactions(self.settings.dataFile) self.saveSettings() dlg.Destroy() def loadTransactions(self, file=None): self.ts = TransactionStore() if file is not None: self.ts.loadTransactions(file) self.transactionManagement.ts = self.ts self.cashFlowDisplay.ts = self.ts self.updateChildren() def saveTransactions(self, file=None): if file is None: file = self.settings.dataFile self.settings.dataFile = file self.ts.saveTransactions(file) def saveSettings(self): try: with open(self.settingsFile, "w") as f: yaml.dump(self.settings, f) except: print("Can't save settings for some reason.") def loadSettings(self): try: with open(self.settingsFile, "r") as f: self.settings = yaml.load(f, Loader=yaml.Loader) self.transactionManagement.settings = self.settings self.cashFlowDisplay.settings = self.settings self.updateChildren() except: print("Can't load settings file. Using defaults.")
class TestFileOperations(unittest.TestCase): def setUp(self): self.file = f'./test-{time.time()}' t1 = Transaction( start=date.today(), description="Once, today", amount=1.00, frequency=Transaction.ONCE) t2 = Transaction( start=date.today(), original_start=date.today()-timedelta(days=1), end=date.today()+timedelta(days=56), description="Weekly", amount=1.02, frequency=Transaction.WEEKLY, skip=set([date.today()+timedelta(days=7)]), scheduled=True, cleared=True) self.ts = TransactionStore() self.ts.store.append(t1) self.ts.store.append(t2) def tearDown(self): os.remove(self.file) def assertTransactionsEqual(self, t1, t2): self.assertEqual(t1.start, t2.start) self.assertEqual(t1.original_start, t2.original_start) self.assertEqual(t1.end, t2.end) self.assertEqual(t1.description, t2.description) self.assertEqual(t1.amount, t2.amount) self.assertEqual(t1.frequency, t2.frequency) self.assertEqual(t1.skip.symmetric_difference(t2.skip), set()) self.assertEqual(t1.scheduled, t2.scheduled) self.assertEqual(t1.cleared, t2.cleared) def test_file_operations(self): self.assertEqual(len(self.ts.store), 2) t1 = next((t for t in self.ts.store if t.amount == 1.00), None) self.assertIsNotNone(t1) t2 = next((t for t in self.ts.store if t.amount == 1.02), None) self.assertIsNotNone(t2) self.ts.saveTransactions(self.file) ts = TransactionStore() ts.loadTransactions(self.file) self.assertEqual(len(ts.store), 2) t1_l = next((t for t in ts.store if t.amount == 1.00), None) self.assertIsNotNone(t1_l) self.assertTransactionsEqual(t1_l, t1) t2_l = next((t for t in ts.store if t.amount == 1.02), None) self.assertIsNotNone(t2_l) self.assertTransactionsEqual(t2_l, t2)