Beispiel #1
0
 def GetNetInfo(self, net_asset_code):
     from datetime import datetime
     AssetsFound = AssetList()
     net_asset_macro_name = "Retrieve_" + net_asset_code[0] + "_balances"
     print "Running " + net_asset_macro_name
     iret = self.iim.iimPlay(net_asset_macro_name)
     if (iret != 1):
         print "Bad status", iret, "returned from", net_asset_macro_name, "Error text:", self.iim.iimGetErrorText()
     else:
         if net_asset_code[1] != -1:
             InpDate = self.iim.iimGetExtract(1).split(" ")
             month = self.Month_int(InpDate[0])
             if len(InpDate) < 4:
                 InpDate = self.iim.iimGetExtract(1).split("/")
                 month = int(InpDate[0])
             day = int(InpDate[1][:2])
             year = int(InpDate[2])
             try:
                 InpTime = InpDate[3].split(":")
                 ampm = InpDate[4]
                 hour = int(InpTime[0])
                 min = int(InpTime[1])
                 sec = int(InpTime[2])
                 if (ampm == "pm"):
                     hour += 12
                 elif (ampm == "am") and (hour == 12):
                     hour -= 12
                 NewDate = datetime(year, month, day, hour, min, sec)
             except:
                 NewDate = datetime.now()
             extract_index = 2
         else:
             NewDate = datetime.now()
             extract_index = 1
         account_index = 0
         account_negative_flag = net_asset_code[2]
         while "NODATA" not in self.iim.iimGetExtract(extract_index):
             assetName = self.iim.iimGetExtract(extract_index)
             extract_index += 1
             asset = AssetsFound.append(assetName)
             asset.set_type(self.get_asset_type(assetName))
             # if account_negative_flag is set for current index, store the negative of the returned balance. In other words, if balance is negative and flag is set, store positive.  If balance is positive and flag is set, store negative.
             # if account_negatve flag is not set, store balance retrieved
             account_total = round(float(self.iim.iimGetExtract(extract_index).replace("$", "").replace(",", "").replace("(","").replace(")","").replace("- ","-")),2)
             if account_negative_flag[account_index] == True:
                 if account_total < 0:
                     asset.set_total(str(-account_total))
                 elif account_total > 0:
                     asset.set_total("-" + str(account_total))
                 else:
                     asset.set_total("0.0")
             else:
                 asset.set_total(str(account_total))
             account_index += 1
             extract_index += 1
             asset.set_last_pull_date(NewDate)
     return AssetsFound
Beispiel #2
0
    def __init__(self, parent, title="PyAsset", cfgFile="", assetFile=""):
        self.parent = parent
        self.frame = self
        self.assets = AssetList(self)
        self.bills = BillList()
        self.cur_asset = Asset(name=assetFile)
        self.edited = False
        self.payType = ""
        self.ref_date = None
        self.netpay = ""
        self.payDepositAcct = ""
        self.cfgFile = copy.deepcopy(cfgFile)

        super(AssetFrame, self).__init__(parent, title=title)

        if self.readConfigFile(cfgFile):
            valid_date_seps = ['/', '-']
            for j in range(len(valid_date_seps)):
                date_sep = valid_date_seps[j]
                date_fields = self.dateFormat.split(valid_date_seps[j])
                if len(date_fields) == 3:
                    break
            if len(date_fields) == 3:
                Date.set_global_date_format(self, self.dateFormat)
                Date.set_global_date_sep(self, date_sep)

                self.curr_date = Date.set_curr_date(self)
                self.proj_date = Date.set_proj_date(self, "")
                Date.set_global_curr_date(self, self.curr_date)
                Date.set_global_proj_date(self, self.proj_date)
                Date.set_curr_paydate(self)
                Date.set_next_paydate(self)

                self.make_widgets()
                self.filename = assetFile
                if self.filename == "":
                    d = wx.FileDialog(self, "Open", "", "", "*.qif",
                                      wx.FD_OPEN)
                    if d.ShowModal() == wx.ID_OK:
                        fname = d.GetFilename()
                        dir = d.GetDirectory()
                        self.filename = os.path.join(dir, fname)
                if self.filename:
                    latest_assets = qif.load_file(self, self.filename)
                    self.process_asset_list(latest_assets)
            else:
                error = 'Badly formatted date format sting: %s - Aborting!\n'
                self.DisplayMsg(error)
        else:
            error = cfgFile + ' does not exist / cannot be opened!! - Aborting\n'
            self.DisplayMsg(error)
Beispiel #3
0
    def __init__(self, parent, assetFile="", readmode="normal"):
        self.parent = parent
        self.assets = AssetList(self)
        self.filename = assetFile
        self.edited = False

        if assetFile:
            self.read_qif(assetFile, readmode)
        else:
            error = assetFile + ' does not exist / cannot be opened!! - Aborting\n'
            self.DisplayMsg(error)
Beispiel #4
0
 def close(self, *args):
     if self.edited:
         d = wx.MessageDialog(self, 'Save file before closing?', 'Question',
                              wx.YES_NO)
         if d.ShowModal() == wx.ID_YES:
             self.save_file()
     self.assets = AssetList()
     self.cur_asset = None
     nrows = self.assetGrid.GetNumberRows()
     if nrows > 0:
         self.assetGrid.DeleteRows(0, nrows)
         self.redraw_all(-1)
     self.edited = 0
     self.SetTitle("PyAsset: Asset")
     return
Beispiel #5
0
    def __init__(self, style, parent, my_id, title="PyAsset:Asset", myfile=None, **kwds):
        self.assets = AssetList()
        self.bills = BillList()
        self.cur_asset = None
        self.edited = 0
        self.rowSize = 27
        self.colSize = 20

        if style == None:
            style = wx.DEFAULT_FRAME_STYLE
        kwds["style"] = style
        wx.Frame.__init__(self, parent, my_id, title, **kwds)

        self.make_widgets()

        if myfile:
            self.cur_asset.read_qif(myfile)
            self.redraw_all(-1)
            if self.cur_asset.get_name() != None:
                self.SetTitle("PyAsset: Asset %s" % self.cur_asset.get_name())
        return
Beispiel #6
0
    def read_qif(self, filename, readmode="normal"):
        if readmode == 'normal':  # things not to do on 'import':
            name = filename.replace('.qif', '')
            self.filename = os.path.split(name)[1]
        Found_assets = AssetList(self)
        mffile = open(filename, 'r')
        lines = mffile.readlines()
        mffile.close()
        section = UNKNOWN
        for line in lines:
            input_type, rest = line[0], line[1:].strip().replace(",", "")
            if input_type == "!":
                if rest == "Account":
                    section = ACCOUNT
                elif rest.__contains__("Type"):
                    section = DETAIL
                    cur_transaction = Transaction(self)
                else:
                    if section == ACCOUNT:
                        section = "account"
                    elif section == DETAIL:
                        section = "detail"
                    else:
                        section = "unknown"
                    print("in", section, "section got unknown ! line: ",
                          line[:-1])

            elif input_type == "^":
                if section == DETAIL:
                    cur_asset.transactions.append(cur_transaction)
                    cur_transaction = Transaction(self)
            elif input_type == "C":
                if section == DETAIL:
                    if rest == "*" or rest == "C":
                        cur_transaction.set_state("cleared")
                    elif rest == "X" or rest == "R":
                        cur_transaction.set_state("reconciled")
                    else:
                        cur_transaction.set_state("unknown")
            elif input_type == "D":
                if section == DETAIL:
                    formatted_date = Date.parse_date(self, rest, "%m/%d/%y")
                    formatted_date['month'] = formatted_date['month'] - 1
                    cur_transaction.set_due_date(formatted_date)
            elif input_type == "L":
                if section == ACCOUNT:
                    cur_asset.set_limit(rest)
            elif input_type == "N":
                if section == ACCOUNT:
                    cur_asset = Found_assets.get_asset_by_name(rest)
                elif section == DETAIL:
                    cur_transaction.set_check_num(rest)
            elif input_type == "P" or input_type == "M":  # JJG 1/22/2022  Seems some use M lines incorrectly!
                if section == DETAIL:
                    cur_transaction.set_payee(rest)
            elif input_type == "T":
                kind = line[1:].strip()
                if section == ACCOUNT:
                    if kind == "Bank":
                        if cur_asset.get_name().upper().find("SAVINGS") != -1:
                            cur_asset.set_type("Savings")
                        elif cur_asset.get_name().upper().find(
                                "CHECKING") != -1:
                            cur_asset.set_type("Checking")
                    elif kind == "CCard":
                        cur_asset.set_type("Credit card")
                elif section == DETAIL:
                    cur_transaction.set_amount(rest)
            elif input_type == "U":
                if section == DETAIL:
                    cur_transaction.set_amount(rest)
            else:
                if section == ACCOUNT:
                    section = "account"
                elif section == DETAIL:
                    section = "detail"
                else:
                    section = "unknown"
                print("in", section, "section got unparsable line: ",
                      line[:-1])
            pass
        return Found_assets
Beispiel #7
0
 def write_qif(self, filename):
     Found_assets = AssetList(self)
     # Write and process Assets and Transactions here!   JJG 1/17/2022
     print("In writing ", filename, " as .qif file. Found_assets = ",
           Found_assets)
     return True
Beispiel #8
0
    def ProcessAssetsSheet(self):
        AccountWithTransactions = self.wb.get_sheet_names()
        AccountWithTransactions.remove("Bills")
        AssetsFound = AssetList()
        AssetPlaces = dict()
        ColumnHeaders = dict()

        ws = self.wb.get_sheet_by_name("Assets")

        # First, determine all assets being tracked by parsing first column

        for col in ws.columns:
            row_num = 1
            asset_num = 0
            for cell in col:
                cv = cell.value
                if cv != None:
                    new_asset = None
                    if cv in AccountWithTransactions:
                        new_asset = AssetsFound.append(cv)
                        AssetPlaces[asset_num] = (cv, row_num)
                        asset_num += 1
                    elif not ("Bills" in cv or "Accounts" in cv or "Cash" in cv or "Assets" in cv or "Total" in cv):
                        new_asset = AssetsFound.append(cv)
                        AssetPlaces[asset_num] = (cv, row_num)
                        asset_num += 1
                    if new_asset != None:
                        asset_name = new_asset.name
                        if "Checking" in asset_name:
                            new_asset.set_type("Checking")
                        elif "Savings" in asset_name:
                            new_asset.set_type("Savings")
                        elif "Money Market" in asset_name:
                            new_asset.set_type("Money Market")
                        elif "Overdraft" in asset_name:
                            new_asset.set_type("Overdraft")
                        elif "TSP" in asset_name or "Annuity" in asset_name or "Life" in asset_name:
                            new_asset.set_type("Retirement")
                        elif "Visa" in asset_name or "MC" in asset_name:
                            new_asset.set_type("Credit Card")
                        elif "Sears" in asset_name or "Macy's" in asset_name:
                            new_asset.set_type("Store Card")
                        else:
                            new_asset.set_type("Other")
                row_num += 1
            break

        # Next, get column header locations by locating longest row with labels

        max_len = 0
        max_row = 0
        row_num = 1
        row_len = 0
        for row in ws.rows:
            col_num = 1
            for cell in row:
                cv = cell.value
                if cv != None:
                    row_len += 1
                col_num += 1
            if row_len > max_len:
                max_len = row_len
                max_row = row_num
            row_num += 1
            row_len = 0
        row_num = 1
        for row in ws.rows:
            if row_num == max_row:
                col_num = 1
                for cell in row:
                    cv = cell.value
                    if cv != None and col_num != 1:
                        ColumnHeaders[col_num] = cv
                    col_num += 1
                break
            row_num += 1

        # Finally, get data on assets

        for asset_num in range(0, len(AssetsFound)):
            asset_row_num = AssetPlaces.get(asset_num, "None")[1]
            row_num = 1
            for row in ws.rows:
                if row_num == asset_row_num:
                    col_num = 1
                    asset = AssetsFound[asset_num]
                    for cell in row:
                        heading = ColumnHeaders.get(col_num, "None")
                        if heading != "None":
                            cv = cell.value
                            if "Value (Curr)" in heading:
                                asset.set_total(cv)
                            elif "Value (Proj)" in heading:
                                asset.set_value_proj(cv)
                            elif heading == "last pulled":
                                asset.set_last_pull_date(cv)
                            elif heading == "Limit":
                                asset.set_limit(cv)
                            elif heading == "Avail (Online)":
                                asset.set_avail(cv)
                            elif heading == "Avail (Proj)":
                                asset.set_avail_proj(cv)
                            elif heading == "Rate":
                                asset.set_rate(cv)
                            elif heading == "Payment":
                                asset.set_payment(cv)
                            elif heading == "Due Date":
                                asset.set_due_date(cv)
                            elif heading == "Sched":
                                asset.set_sched(cv)
                            elif heading == "Min Pmt":
                                asset.set_min_pay(cv)
                            elif "Cash Limit" in heading:
                                asset.set_cash_limit(cv)
                            elif "Cash used" in heading:
                                asset.set_cash_used(cv)
                            elif "Cash avail" in heading:
                                asset.set_cash_avail(cv)
                            else:
                                pass
                        col_num += 1
                    break
                row_num += 1

        #print AssetsFound
        return AssetsFound
Beispiel #9
0
 def GetNetInfo(self, net_asset_code):
     from datetime import datetime
     AssetsFound = AssetList(self)
     net_asset_macro_name = "Retrieve_" + net_asset_code[0] + "_balances"
     print("Running " + net_asset_macro_name)
     iret = self.iim.iimPlay(net_asset_macro_name)
     if (iret != 1):
         print("Bad status", iret, "returned from", net_asset_macro_name,
               "Error text:", self.iim.iimGetErrorText())
     else:
         if net_asset_code[1] != -1:
             InpDate = self.iim.iimGetExtract(1).split(" ")
             month = self.Month_int(InpDate[0])
             if len(InpDate) < 4:
                 InpDate = self.iim.iimGetExtract(1).split("/")
                 month = int(InpDate[0])
             day = int(InpDate[1][:2])
             year = int(InpDate[2])
             try:
                 InpTime = InpDate[3].split(":")
                 ampm = InpDate[4]
                 hour = int(InpTime[0])
                 min = int(InpTime[1])
                 sec = int(InpTime[2])
                 if (ampm == "pm"):
                     hour += 12
                 elif (ampm == "am") and (hour == 12):
                     hour -= 12
                 NewDate = datetime(year, month, day, hour, min, sec)
             except:
                 NewDate = datetime.now()
             extract_index = 2
         else:
             NewDate = datetime.now()
             extract_index = 1
         account_index = 0
         account_negative_flag = net_asset_code[2]
         while "NODATA" not in self.iim.iimGetExtract(extract_index):
             assetName = self.iim.iimGetExtract(extract_index)
             extract_index += 1
             asset = AssetsFound.append(assetName)
             asset.set_type(self.get_asset_type(assetName))
             # if account_negative_flag is set for current index, store the negative of the returned balance. In other words, if balance is negative and flag is set, store positive.  If balance is positive and flag is set, store negative.
             # if account_negatve flag is not set, store balance retrieved
             account_value = round(
                 float(
                     self.iim.iimGetExtract(extract_index).replace(
                         "$", "").replace(",", "").replace("(", "").replace(
                             ")", "").replace("- ", "-")), 2)
             if account_negative_flag[account_index] == True:
                 if account_value < 0:
                     asset.set_value(str(-account_value))
                 elif account_value > 0:
                     asset.set_value("-" + str(account_value))
                 else:
                     asset.set_value("0.0")
             else:
                 asset.set_value(str(account_value))
             account_index += 1
             extract_index += 1
             asset.set_last_pull_date(NewDate)
     return AssetsFound
Beispiel #10
0
    def ProcessAssetsSheet(self, parent) -> object:
        self.parent = parent
        AssetsFound = AssetList(parent)

        ws = self.wb.get_sheet_by_name("Assets")

        for row in ws.rows:
            cv = row[0].value
            if cv == None or "Bills" in cv or "Total" in cv or "Cash Flow" in cv:
                continue
            elif "Accounts" in cv or "Other" in cv:
                #                print(row)
                ColumnHeaders = dict()
                col_num = 1
                for cell in row:
                    cv = cell.value
                    if cv != None:
                        if col_num == 1:
                            headerValue = "Name"
                        else:
                            headerValue = cv
                        ColumnHeaders[col_num] = headerValue
                        col_num += 1
                    else:
                        break
                    if len(ColumnHeaders) == 1:
                        continue
            #                print(ColumnHeaders)
            else:
                col_num = 1
                for cell in row:
                    cv = cell.value
                    if col_num == 1:

                        # First column means this is a new asset... save name and pointer to the new asset location for later
                        # Also set type of asset using clues from the account name
                        new_asset = AssetsFound.get_asset_by_name(cv)
                        asset_name = new_asset.get_name()
                        if "Checking" in asset_name:
                            new_asset.set_type("Checking")
                        elif "Savings" in asset_name:
                            new_asset.set_type("Savings")
                        elif "Money Market" in asset_name:
                            new_asset.set_type("Money Market")
                        elif "Overdraft" in asset_name:
                            new_asset.set_type("Overdraft")
                        elif "TSP" in asset_name or "Annuity" in asset_name or "Life" in asset_name:
                            new_asset.set_type("Retirement")
                        elif "Visa" in asset_name or "MC" in asset_name or "Master Card" in asset_name or "Blue" in asset_name or "Credit Card" in asset_name:
                            new_asset.set_type("Credit Card")
                        elif "Sears" in asset_name or "Macy's" in asset_name:
                            new_asset.set_type("Store Card")
                        elif "Loan" in asset_name:
                            new_asset.set_type("Loan")
                        else:
                            new_asset.set_type("Other")

                    else:  # 2nd and remaining columns are more data for the current asset...
                        # determine what field and update the object appropriately

                        heading = ColumnHeaders.get(col_num, "None")
                        if heading != "None":
                            if "Value (Curr)" in heading:
                                new_asset.set_value(cv)
                            elif "Value (Proj)" in heading:
                                new_asset.set_value_proj(cv)
                            elif heading == "last pulled":
                                new_asset.set_last_pull_date(cv)
                            elif heading == "Limit":
                                new_asset.set_limit(cv)
                            elif heading == "Avail (Online)":
                                new_asset.set_avail(cv)
                            elif heading == "Avail (Proj)":
                                new_asset.set_avail_proj(cv)
                            elif heading == "Estimate Method":
                                new_asset.set_est_method(cv)
                            elif heading == "Rate":
                                new_asset.set_rate(cv)
                            elif heading == "Payment":
                                new_asset.set_payment(cv)
                            elif heading == "Due Date":
                                new_asset.set_due_date(cv)
                            elif heading == "Sched":
                                new_asset.set_sched_date(cv)
                            elif heading == "Min Pmt":
                                new_asset.set_min_pay(cv)
                            elif "Stmt Bal" in heading:
                                new_asset.set_stmt_bal(cv)
                            elif "Amt Over" in heading:
                                new_asset.set_amt_over(cv)
                            elif "Cash Limit" in heading:
                                new_asset.set_cash_limit(cv)
                            elif "Cash used" in heading:
                                new_asset.set_cash_used(cv)
                            elif "Cash avail" in heading:
                                new_asset.set_cash_avail(cv)
                            else:
                                print("Unknown field " + heading + " ignored!")
                                pass

                    col_num += 1
                    if col_num > len(ColumnHeaders):
                        break

        return AssetsFound
Beispiel #11
0
class AssetFrame(wx.Frame):
    def __init__(self, style, parent, my_id, title="PyAsset:Asset", myfile=None, **kwds):
        self.assets = AssetList()
        self.bills = BillList()
        self.cur_asset = None
        self.edited = 0
        self.rowSize = 27
        self.colSize = 20

        if style == None:
            style = wx.DEFAULT_FRAME_STYLE
        kwds["style"] = style
        wx.Frame.__init__(self, parent, my_id, title, **kwds)

        self.make_widgets()

        if myfile:
            self.cur_asset.read_qif(myfile)
            self.redraw_all(-1)
            if self.cur_asset.get_name() != None:
                self.SetTitle("PyAsset: Asset %s" % self.cur_asset.get_name())
        return

    def DisplayMsg(self, str):
        d = wx.MessageDialog(self, str, "Error", wx.OK | wx.ICON_INFORMATION)
        d.ShowModal()
        d.Destroy()
        return wx.CANCEL

    def make_widgets(self):
        self.menubar = wx.MenuBar()
        self.SetMenuBar(self.menubar)
        self.statusbar = self.CreateStatusBar(1, 0)
        self.make_filemenu()
        self.make_editmenu()
        self.make_helpmenu()
        self.make_grid()
        self.set_properties()
        self.do_layout()

    def make_filemenu(self):
        self.filemenu = wx.Menu()
#        ID_EXPORT_TEXT = wx.NewId()
#        ID_ARCHIVE = wx.NewId()
#        ID_IMPORT_CSV = wx.NewId()
        ID_IMPORT_XLSM = wx.NewId()
        ID_UPDATE_FROM_NET = wx.NewId()
        ID_PROPERTIES = wx.NewId()
        self.filemenu.Append(wx.ID_OPEN, "Open\tCtrl-o",
                             "Open a new transction file", wx.ITEM_NORMAL)
        self.filemenu.Append(wx.ID_SAVE, "Save\tCtrl-s",
                             "Save the current transactions in the same file", wx.ITEM_NORMAL)
        self.filemenu.Append(wx.ID_SAVEAS, "Save As",
                             "Save the current transactions under a different name", wx.ITEM_NORMAL)
        self.filemenu.Append(wx.ID_CLOSE, "Close\tCtrl-w",
                             "Close the current file", wx.ITEM_NORMAL)
#        self.filemenu.Append(ID_EXPORT_TEXT, "Export Text",
#                             "Export the current transaction register as a text file",
#                             wx.ITEM_NORMAL)
#        self.filemenu.Append(ID_ARCHIVE, "Archive",
#                             "Archive transactions older than a specified date",
#                             wx.ITEM_NORMAL)
        self.filemenu.AppendSeparator()
#        self.filemenu.Append(ID_IMPORT_CSV, "Import CSV\tCtrl-c",
#                             "Import transactions from a CSV file",
#                             wx.ITEM_NORMAL)
        self.filemenu.Append(ID_IMPORT_XLSM, "Import XLSM file\tCtrl-i",
                             "Import transactions from an EXCEL file with Macros",
                             wx.ITEM_NORMAL)
        self.filemenu.Append(ID_UPDATE_FROM_NET, "Update Accounts from Net\tCtrl-u",
                             "Update accounts using pre-defined iMacros",
                            wx.ITEM_NORMAL)
        self.filemenu.AppendSeparator()
        self.filemenu.Append(ID_PROPERTIES, "Properties\tCtrl-p",
                             "Display and/or edit Number and Data/Time display properties, pay frequencies",
                            wx.ITEM_NORMAL)
        self.filemenu.AppendSeparator()
        self.filemenu.Append(wx.ID_EXIT, "Quit\tCtrl-q",
                             "Exit PyAsset", wx.ITEM_NORMAL)
        self.menubar.Append(self.filemenu, "&File")
        wx.EVT_MENU(self, wx.ID_OPEN, self.load_file)
        wx.EVT_MENU(self, wx.ID_SAVE, self.save_file)
        wx.EVT_MENU(self, wx.ID_SAVEAS, self.save_as_file)
        wx.EVT_MENU(self, wx.ID_CLOSE, self.close)
#        wx.EVT_MENU(self, ID_EXPORT_TEXT, self.export_text)
#        wx.EVT_MENU(self, ID_ARCHIVE, self.archive)
#        wx.EVT_MENU(self, ID_IMPORT_CSV, self.import_CSV_file)
        wx.EVT_MENU(self, ID_IMPORT_XLSM, self.import_XLSM_file)
        wx.EVT_MENU(self, ID_UPDATE_FROM_NET, self.update_from_net)
        wx.EVT_MENU(self, ID_PROPERTIES, self.properties)
        wx.EVT_MENU(self, wx.ID_EXIT, self.quit)
        return

    def make_editmenu(self):
        ID_SORT = wx.NewId()
        ID_DELETE_ENTRY = wx.NewId()
        self.editmenu = wx.Menu()
        self.editmenu.Append(wx.ID_NEW, "New Entry\tCtrl-n",
                             "Create a new asset in the list",
                             wx.ITEM_NORMAL)
        self.editmenu.Append(ID_DELETE_ENTRY, "Delete Entry",
                             "Delete the current asset", wx.ITEM_NORMAL)
        self.editmenu.Append(ID_SORT, "Sort Entries",
                             "Sort entries", wx.ITEM_NORMAL)
        self.menubar.Append(self.editmenu, "&Edit")
        wx.EVT_MENU(self, wx.ID_NEW, self.newentry)
        wx.EVT_MENU(self, ID_DELETE_ENTRY, self.deleteentry)
        wx.EVT_MENU(self, ID_SORT, self.sort)
        return

    def make_helpmenu(self):
        ID_HELP = wx.NewId()
        self.helpmenu = wx.Menu()
        self.helpmenu.Append(wx.ID_ABOUT, "About",
                             "About PyAsset", wx.ITEM_NORMAL)
        self.helpmenu.Append(ID_HELP, "Help\tCtrl-h",
                             "PyAsset Help", wx.ITEM_NORMAL)

        self.menubar.Append(self.helpmenu, "&Help")
        wx.EVT_MENU(self, wx.ID_ABOUT, self.about)
        wx.EVT_MENU(self, ID_HELP, self.gethelp)
        return

    def make_grid(self):
        self.assetGrid = AssetGrid(self)

    def set_properties(self):
        self.total_width = self.assetGrid.set_properties(self)

    def do_layout(self):
        self.sizer_1 = wx.BoxSizer(wx.VERTICAL)
        self.sizer_1.Add(self.assetGrid, 1, wx.EXPAND, 0)
        self.SetSizer(self.sizer_1)
        self.SetAutoLayout(True)
        self.sizer_1.Fit(self)
        self.sizer_1.SetSizeHints(self)
        self.Layout()
        self.Show()

    def redraw_all(self, index=None):
        nassets = len(self.assets)
        if index == -1:
            nrows = self.assetGrid.GetNumberRows()
            if nrows > 0 and (index == None or index == -1):
                self.assetGrid.DeleteRows(0, nrows)
                nrows = 0
            start_range = 0
            end_range = nassets
            if nrows < nassets:
                rows_needed = nassets - nrows
                self.assetGrid.AppendRows(rows_needed)
        else:
            nrows = 1
            start_range = index
            end_range =  start_range + 1
        for row in range(start_range, end_range):
            for col in range(self.assetGrid.getNumLayoutCols()):
                ret_val = wx.OK
                if row < 0 or row >= len(self.assets):
                    str = "Warning: skipping redraw on bad cell %d %d!" % (row, col)
                    ret_val = self.DisplayMsg(str)
                if ret_val != wx.OK:
                    continue

                # Logic to always display Value (Curr), Value (Proj), Avail(Proj), Amt Over, Cash Limit, Cash Used and Cash Avail for credit cards and store cards
                asset_type = self.assets[row].get_type()
                col_name = self.assetGrid.getColName(col)
                self.assetGrid.setColZeroSuppress(row, col, True)
                if (asset_type == "store card" or asset_type == "credit card") and ("Curr" in col_name or "Proj" in col_name or "Amt" in col_name or "Cash" in col_name):
                    self.assetGrid.setColZeroSuppress(row, col, False)

#                cellValue = self.assetGrid.GridCellDefaultRenderer(row, col)
                cellType = self.assetGrid.getColType(col)
                if cellType == self.assetGrid.DOLLAR_TYPE:
                    self.assetGrid.GridCellDollarRenderer(row, col)
                elif cellType == self.assetGrid.RATE_TYPE:
                    self.assetGrid.GridCellPercentRenderer(row, col)
                elif cellType == self.assetGrid.DATE_TYPE:
                    self.assetGrid.GridCellDateRenderer(row, col)
                elif cellType == self.assetGrid.DATE_TIME_TYPE:
                    self.assetGrid.GridCellDateTimeRenderer(row, col)
                elif cellType == self.assetGrid.STRING_TYPE:
                    self.assetGrid.GridCellStringRenderer(row, col)
                else:
                    self.assetGrid.GridCellErrorRenderer(row, col)
        if index == -1:
            self.assetGrid.SetGridCursor(nassets-1, 0)
            self.assetGrid.MakeCellVisible(nassets-1, True)
        elif index > 0:
            self.assetGrid.SetGridCursor(index, 0)
            self.assetGrid.MakeCellVisible(index, True)
        nassets = len(self.assets)
        self.SetSize(size=(self.total_width, nassets*self.rowSize))
        self.Show()

    def assetchange(self, evt):
        row = evt.GetRow()
        col = evt.GetCol()
        val = evt.String
        colName = self.assetGrid.getColName(col)
        if colName == "Acct name":
            self.assets[row].set_name(val)
        elif colName == "Curr val":
            self.assets[row].set_total(val)
        elif colName == "Last pulled":
            self.assets[row].set_last_pull_date(val)
        elif colName == "Limit":
            self.assets[row].set_limit(val)
        elif colName == "Avail online":
            self.assets[row].set_avail(val)
        elif colName == "Rate":
            self.assets[row].set_rate(val)
        elif colName == "Payment amt":
            self.assets[row].set_payment(val)
        elif colName == "Due date":
            self.assets[row].set_due_date(val)
        elif colName == "Sched date":
            self.assets[row].set_sched(val)
        elif colName == "Min Pmt":
            self.assets[row].set_min_pay(val)
        elif colName == "Stmt Bal":
            self.assets[row].set_stme_bal(val)
        elif colName == "Amt Over":
            self.assets[row].set_amt_over(val)
        elif colName == "Cash Limit":
            self.assets[row].set_cash_limit(val)
        elif colName == "Cash Used":
            self.assets[row].set_cash_used(val)
        elif colName == "Cash Avail":
            self.assets[row].set_cash_avail(val)
        else:
            print "assetchange: Warning: modifying incorrect cell! row, ", row, " col ", col
        return

    def load_file(self, *args):
        self.close()
        self.cur_asset = Asset()
        self.edited = 0
        d = wx.FileDialog(self, "Open", "", "", "*.qif", wx.OPEN)
        if d.ShowModal() == wx.ID_OK:
            fname = d.GetFilename()
            dir = d.GetDirectory()
            self.cur_asset.read_qif(os.path.join(dir, fname))
            self.redraw_all(-1)
        if self.cur_asset.name: self.SetTitle("PyAsset: %s" % self.cur_asset.name)
        return

    def save_file(self, *args):
        for cur_asset in self.assets:
            if not cur_asset.filename:
                self.save_as_file()
            else:
                self.edited = 0
            self.cur_asset.write_qif()
        return

    def save_as_file(self, *args):
        d = wx.FileDialog(self, "Save", "", "", "*.qif", wx.SAVE)
        if d.ShowModal() == wx.ID_OK:
            fname = d.GetFilename()
            dir = d.GetDirectory()
            self.cur_asset.write_qif(os.path.join(dir, fname))
        if self.cur_asset.name: self.SetTitle("PyAsset: %s" % self.cur_asset.name)
        return

    def close(self, *args):
        if self.edited:
            d = wx.MessageDialog(self, 'Save file before closing?', 'Question',
                                 wx.YES_NO)
            if d.ShowModal() == wx.ID_YES:
                self.save_file()
        self.assets = AssetList()
        self.cur_asset = None
        nrows = self.assetGrid.GetNumberRows()
        if nrows > 0:
            self.assetGrid.DeleteRows(0, nrows)
            self.redraw_all(-1)
        self.edited = 0
        self.SetTitle("PyAsset: Asset")
        return

    def quit(self, *args):
        self.close()
        self.Close()

    #
    #     @brief Receives data to be written to and its location
    #
    #     @params[in] date_
    #     Data of transaction
    #     @params[in] amount_
    #     Amount of money for transaction
    #     @params[in] memo_
    #     Description of transaction
    #     @params[in] payee_
    #     Who transaction was paid to
    #     @params[in] filelocation_
    #     Location of the Output file
    #
    #
    # https://en.wikipedia.org/wiki/Quicken_Interchange_Format
    #

    def write_file(self, date_, amount_, memo_, payee_, filelocation_):
        outFile = open(filelocation_, "a")  # Open file to be appended
        outFile.write("!Type:Cash\n")  # Header of transaction, Currently all set to cash
        outFile.write("D")  # Date line starts with the capital D
        outFile.write(date_)
        outFile.write("\n")

        outFile.write("T")  # Transaction amount starts here
        outFile.write(amount_)
        outFile.write("\n")

        outFile.write("M")  # Memo Line
        outFile.write(memo_)
        outFile.write("\n")

        if (payee_ != -1):
            outFile.write("P")  # Payee line
            outFile.write(payee_)
            outFile.write("\n")

        outFile.write("^\n")  # The last line of each transaction starts with a Caret to mark the end
        outFile.close()

    #
    #     @brief  Takes given CSV and parses it to be exported to a QIF
    #
    #     @params[in] inf_
    #     File to be read and converted to QIF
    #     @params[in] outf_
    #     File that the converted data will go
    #     @params[in] deff_
    #     File with the settings for converting CSV
    #
    #

    def read_csv(self, inf_, outf_, deff_):  # will need to receive input csv and def file

        csvdeff = csv.reader(deff_, delimiter=',')
        next(csvdeff, None)

        for settings in csvdeff:
            date_ = (settings[0])  # convert to 
            amount_ = (settings[2])  # How much was the transaction
            memo_ = (settings[3])  # discription of the transaction
            payee_ = (settings[4])  # Where the money is going
            deli_ = settings[5]  # How the csv is separated
            header_ = (settings[6])  # Set if there is a header to skip

        csvIn = csv.reader(inf_, delimiter=deli_)  # create csv object using the given separator

        if header_ >= 1:  # If there is a header skip the fist line
            next(csvIn, None)  # skip header

        for row in csvIn:
            self.write_file(row[date_], row[amount_], row[memo_], row[payee_], outf_)  # export each row as a qif entry

        inf_.close()
        deff_.close()

    def import_CSV_file(self, *args):
        # Appends the records from a .csv file to the current Asset
        d = wx.FileDialog(self, "Import", "", "", "*.csv", wx.OPEN)
        if d.ShowModal() == wx.ID_OK:
            self.edited = 1
            fname = d.GetFilename()
            dir = d.GetDirectory()
            total_name_in = os.path.join(dir, fname)
            total_name_extension_place = total_name_in.find(".csv")
            total_name_def = ""
            total_name_qif = ""
            if total_name_extension_place != -1:
                total_name_def = total_name_in[:total_name_extension_place] + ".def"
                total_name_qif = total_name_in[:total_name_extension_place] + ".qif"
            # pr total_name_in, total_name_def, total_name_qif
            error = ""
            try:
                fromfile = open(total_name_in, 'r')
            except:
                error = total_name_in + ' does not exist / cannot be opened !!\n'

            if total_name_qif != "":
                try:
                    tofile = open(total_name_qif, 'a')
                except:
                    error = total_name_qif + ' cannot be created !!\n'

            if total_name_def != "":
                if os.path.isfile(total_name_def):
                    deffile = open(total_name_def, 'r')
                else:
                    error = total_name_def + ' does not exist / cannot be opened !!\n'

            if error == "":
                tofile = total_name_qif
                self.read_csv(fromfile, tofile, deffile)
                self.cur_asset.read_qif(total_name_qif)
                fromfile.close()
                deffile.close()
                self.redraw_all(-1)
            else:
                d = wx.MessageDialog(self, error, wx.OK | wx.ICON_INFORMATION)
                d.ShowModal()
                d.Destroy()
                return
        if self.cur_asset.name: self.SetTitle("PyAsset: %s" % self.cur_asset.name)
        return

    def import_XLSM_file(self, *args):
        # Appends or Merges as appropriate the records from a .xlsm file to the current Asset
        d = wx.FileDialog(self, "Import", "", "", "*.xlsm", wx.OPEN)
        if d.ShowModal() == wx.ID_OK:
            self.edited = 1
            fname = d.GetFilename()
            dir = d.GetDirectory()
            total_name_in = os.path.join(dir, fname)
            error = ""
            try:
                fromfile = open(total_name_in, 'r')
            except:
                error = total_name_in + ' does not exist / cannot be opened !!\n'
            fromfile.close()

            if error == "":
                self.cur_assets = None
                xlsm = ExcelToAsset()
                xlsm.OpenXLSMFile(total_name_in)
                latest_assets = xlsm.ProcessAssetsSheet()
#                print latest_assets
                for i in range(len(latest_assets)):
                    xlsm_asset = latest_assets.__getitem__(i)
                    self.cur_asset = copy.deepcopy(xlsm_asset)
                    cur_name = self.cur_asset.get_name()
                    found = False
                    for j in range(len(self.assets)):
                        if self.assets[j].get_name() == cur_name:
                            self.assets[j] = copy.deepcopy(xlsm_asset)
                            found = True
                            break
                    if not found:
                        self.assets.append(self.cur_asset.get_name())
                        self.assets[-1] = copy.deepcopy(xlsm_asset)
#                latest_bills = xlsm.ProcessBillsSheet(self.bills)
#                print latest_bills
                #TODO: Process latest_bills
                if self.cur_asset.name:
                    self.SetTitle("PyAsset: Asset %s" % total_name_in)
                self.redraw_all(-1)
            else:
                d = wx.MessageDialog(self, error, wx.OK | wx.ICON_INFORMATION)
                d.ShowModal()
                d.Destroy()

    def update_from_net(self, *args):
        w = iMacrosToAsset()
        w.Init()
        net_asset_codes = [("HFCU",1,[False,False,False,True]),
                           ("BOA",-1,[False,True]),
                           ("CITI",-1,[True]),
                           ("MACYS",-1,[True]),
                           ("SEARS",-1,[True]),
                           ("TSP",-1,[False,False,False,True]),
                           ("MET",1,[False])]
        for net_asset_code in net_asset_codes:
            latest_assets = w.GetNetInfo(net_asset_code)
    #        print latest_assets
            for i in range(len(latest_assets)):
                net_asset = latest_assets.__getitem__(i)
                if net_asset != None:
                    latest_name = net_asset.get_name()
                    found = False
                    for j in range(len(self.assets)):
                        cur_name = self.assets[j].get_name()
                        if "(" in cur_name:
                            cur_name = cur_name.split("(")[1].split(")")[0]
                        if cur_name in latest_name:
                            net_index = j
                            found = True
                            break
                    if not found:
                        self.assets.append(latest_name)
                        net_index = -1
                    # Always update Value (Curr) column... others check if non-zero value before update is done!
                    self.assets[net_index].set_total(net_asset.get_total())
                    if net_asset.get_value_proj() != 0.0:
                        self.assets[net_index].set_value_proj(net_asset.get_value_proj())
                    if net_asset.get_last_pull_date() != 0.0:
                        self.assets[net_index].set_last_pull_date(net_asset.get_last_pull_date())
                    if net_asset.get_limit() != 0.0:
                        self.assets[net_index].set_limit(net_asset.get_limit())
                    if net_asset.get_avail() != 0.0:
                        self.assets[net_index].set_avail(net_asset.get_avail())
                    if net_asset.get_avail_proj() != 0.0:
                        self.assets[net_index].set_avail_proj(net_asset.get_avail_proj())
                    if net_asset.get_rate() != 0.0:
                        self.assets[net_index].set_rate(net_asset.get_rate())
                    if net_asset.get_payment() != 0.0:
                        self.assets[net_index].set_payment(net_asset.get_payment())
                    if net_asset.get_due_date() != 0.0:
                        self.assets[net_index].set_due_date(net_asset.get_due_date())
                    if net_asset.get_sched() != 0.0:
                        self.assets[net_index].set_sched(net_asset.get_sched())
                    if net_asset.get_min_pay() != 0.0:
                        self.assets[net_index].set_min_pay(net_asset.get_min_pay())
                    if net_asset.get_stmt_bal() != 0.0:
                        self.assets[net_index].set_stmt_bal(net_asset.get_stmt_bal())
                    if net_asset.get_amt_over() != 0.0:
                        self.assets[net_index].set_amt_over(net_asset.get_amt_over())
                    if net_asset.get_cash_limit() != 0.0:
                        self.assets[net_index].set_cash_limit(net_asset.get_cash_limit())
                    if net_asset.get_cash_used() != 0.0:
                        self.assets[net_index].set_cash_used(net_asset.get_cash_used())
                    if net_asset.get_cash_avail() != 0.0:
                        self.assets[net_index].set_cash_avail(net_asset.get_cash_avail())

        w.Finish()
        self.redraw_all(-1)

    def properties(self, *args):
# TODO  properties
        self.DisplayMsg("properties called")

    def export_text(self, *args):
        d = wx.FileDialog(self, "Save", "", "", "*.txt", wx.SAVE)
        if d.ShowModal() == wx.ID_OK:
            fname = d.GetFilename()
            dir = d.GetDirectory()
            self.cur_asset.write_txt(os.path.join(dir, fname))
        return

    def archive(self, *args):
        d = wx.TextEntryDialog(self,
                               "Archive transactions before what date (mm/dd/yy)?",
                               "Archive Date")
        if d.ShowModal() == wx.ID_OK:
            date = Date(d.GetValue())
        else:
            date = None
        d.Destroy()
        if not date: return
        archive = Asset()
        newcb_starttransaction = Transaction()
        newcb_starttransaction.amount = 0
        newcb_starttransaction.payee = "Starting Balance"
        newcb_starttransaction.memo = "Archived by PyAsset"
        newcb_starttransaction.cleared = 1
        newcb_starttransaction.date = date

        newcb = Asset()
        newcb.filename = self.cur_asset.filename
        newcb.name = self.cur_asset.name
        newcb.append(newcb_starttransaction)
        archtot = 0

        for transaction in self.cur_asset:
            if transaction.date < date and transaction.cleared:
                archive.append(transaction)
                archtot += transaction.amount
            else:
                newcb.append(transaction)
        newcb_starttransaction.amount = archtot
        self.cur_asset = newcb
        while 1:
            d = wx.FileDialog(self, "Save Archive As", "", "", "*.qif", wx.SAVE)
            if d.ShowModal() == wx.ID_OK:
                fname = d.GetFilename()
                dir = d.GetDirectory()
            d.Destroy()
            if fname: break
        archive.write_qif(os.path.join(dir, fname))
        self.redraw_all(-1)
        self.edited = 1
        return

    def newentry(self, *args):
        self.edited = 1
        self.cur_asset.append(Asset())
        self.assetGrid.AppendRows()
        nassets = self.assetGrid.GetNumberRows()
        self.assetGrid.SetGridCursor(nassets - 1, 0)
        self.assetGrid.MakeCellVisible(nassets - 1, 1)

    def sort(self, *args):
        self.edited = 1
        self.cur_asset.sort()
        self.redraw_all(-1)

    def deleteentry(self, *args):
        index = self.assetGrid.GetGridCursorRow()
        if index < 0: return
        d = wx.MessageDialog(self,
                             "Really delete this asset?",
                             "Really delete?", wx.YES_NO)
        if d.ShowModal() == wx.ID_YES:
            del self.cur_asset[index]
        self.redraw_all(index - 1)  # only redraw cells [index-1:]
        return

    def about(self, *args):
        d = wx.MessageDialog(self,
                             "Python Asset Manager\n"
                             "Copyright (c) 2016,2017 Joseph J. Gorak\n"
                             "Based on idea from Python Checkbook (pyCheckbook)\n"
                             "written by Richard P. Muller\n"
                             "Released under the Gnu GPL\n",
                             "About PyAsset",
                             wx.OK | wx.ICON_INFORMATION)
        d.ShowModal()
        d.Destroy()
        return

    def gethelp(self, *args):
        d = HelpDialog(self, -1, "Help", __doc__)
        val = d.ShowModal()
        d.Destroy()
        return
Beispiel #12
0
class AssetFrame(wx.Frame):
    def __init__(self, parent, title="PyAsset", cfgFile="", assetFile=""):
        self.parent = parent
        self.frame = self
        self.assets = AssetList(self)
        self.bills = BillList()
        self.cur_asset = Asset(name=assetFile)
        self.edited = False
        self.payType = ""
        self.ref_date = None
        self.netpay = ""
        self.payDepositAcct = ""
        self.cfgFile = copy.deepcopy(cfgFile)

        super(AssetFrame, self).__init__(parent, title=title)

        if self.readConfigFile(cfgFile):
            valid_date_seps = ['/', '-']
            for j in range(len(valid_date_seps)):
                date_sep = valid_date_seps[j]
                date_fields = self.dateFormat.split(valid_date_seps[j])
                if len(date_fields) == 3:
                    break
            if len(date_fields) == 3:
                Date.set_global_date_format(self, self.dateFormat)
                Date.set_global_date_sep(self, date_sep)

                self.curr_date = Date.set_curr_date(self)
                self.proj_date = Date.set_proj_date(self, "")
                Date.set_global_curr_date(self, self.curr_date)
                Date.set_global_proj_date(self, self.proj_date)
                Date.set_curr_paydate(self)
                Date.set_next_paydate(self)

                self.make_widgets()
                self.filename = assetFile
                if self.filename == "":
                    d = wx.FileDialog(self, "Open", "", "", "*.qif",
                                      wx.FD_OPEN)
                    if d.ShowModal() == wx.ID_OK:
                        fname = d.GetFilename()
                        dir = d.GetDirectory()
                        self.filename = os.path.join(dir, fname)
                if self.filename:
                    latest_assets = qif.load_file(self, self.filename)
                    self.process_asset_list(latest_assets)
            else:
                error = 'Badly formatted date format sting: %s - Aborting!\n'
                self.DisplayMsg(error)
        else:
            error = cfgFile + ' does not exist / cannot be opened!! - Aborting\n'
            self.DisplayMsg(error)

    def clear_all_assets(self):
        self.assets = AssetList(self)
        self.redraw_all(-1)

    def readConfigFile(self, cfgFile):
        if cfgFile == "":
            d = wx.FileDialog(self, "", "", "", "*.cfg", wx.FD_OPEN)
            if d.ShowModal() == wx.ID_OK:
                fname = d.GetFilename()
                dir = d.GetDirectory()
                total_name_in = os.path.join(dir, fname)
                self.cfgFile = total_name_in
        else:
            self.cfgFile = cfgFile
        try:
            file = open(self.cfgFile, 'r')
            lines = file.readlines()
            self.dateFormat = lines.pop(0).replace('\n', '')
            Date.set_global_date_format(self, self.dateFormat)
            self.payType = lines.pop(0).replace('\n', '')
            in_ref_date = lines.pop(0).replace('\n', '')
            ref_date = Date.parse_date(self, in_ref_date, self.dateFormat)
            self.ref_date = ref_date["dt"]
            self.netpay = lines.pop(0).replace('\n', '')
            self.payDepositAcct = lines.pop(0).replace('\n', '')
            file.close()
            return True
        except:
            return False

    def writeConfigFile(self):
        if self.cfgFile == "":
            d = wx.FileDialog(self, "", "", "", "*.cfg", wx.FD_OPEN)
            if d.ShowModal() == wx.ID_OK:
                fname = d.GetFilename()
                dir = d.GetDirectory()
                total_name_in = os.path.join(dir, fname)
                self.cfgFile = total_name_in
        file = open(self.cfgFile, 'w')
        file.write("%s\n" % self.dateFormat)
        file.write("%s\n" % self.payType)
        file.write("%s\n" % self.ref_date)
        file.write("%s\n" % self.netpay)
        file.write("%s\n" % self.payDepositAcct)
        file.close()

    def DisplayMsg(self, str):
        d = wx.MessageDialog(self, str, "Error", wx.OK | wx.ICON_INFORMATION)
        d.ShowModal()
        d.Destroy()

    def make_widgets(self):
        self.menubar = wx.MenuBar()
        self.SetMenuBar(self.menubar)
        self.make_filemenu()
        self.make_editmenu()
        self.make_helpmenu()
        self.setup_layout()

    def make_filemenu(self):
        self.filemenu = wx.Menu()
        ID_EXPORT_TEXT = wx.NewId()
        ID_ARCHIVE = wx.NewId()
        ID_IMPORT_CSV = wx.NewId()
        ID_IMPORT_XLSM = wx.NewId()
        ID_UPDATE_FROM_NET = wx.NewId()
        ID_PROPERTIES = wx.NewId()
        self.filemenu.Append(wx.ID_OPEN, "Open\tCtrl-o",
                             "Open a new transction file", wx.ITEM_NORMAL)
        self.filemenu.Append(wx.ID_SAVE, "Save\tCtrl-s",
                             "Save the current transactions in the same file",
                             wx.ITEM_NORMAL)
        self.filemenu.Append(
            wx.ID_SAVEAS, "Save As",
            "Save the current transactions under a different name",
            wx.ITEM_NORMAL)
        self.filemenu.Append(wx.ID_CLOSE, "Close\tCtrl-w",
                             "Close the current file", wx.ITEM_NORMAL)
        self.filemenu.Append(
            ID_EXPORT_TEXT, "Export Text",
            "Export the current transaction register as a text file",
            wx.ITEM_NORMAL)
        self.filemenu.Append(
            ID_ARCHIVE, "Archive",
            "Archive transactions older than a specified date", wx.ITEM_NORMAL)
        self.filemenu.AppendSeparator()
        self.filemenu.Append(ID_IMPORT_CSV, "Import CSV\tCtrl-c",
                             "Import transactions from a CSV file",
                             wx.ITEM_NORMAL)
        self.filemenu.Append(
            ID_IMPORT_XLSM, "Import XLSM file\tCtrl-i",
            "Import transactions from an EXCEL file with Macros",
            wx.ITEM_NORMAL)
        self.filemenu.Append(ID_UPDATE_FROM_NET,
                             "Update Accounts from Net\tCtrl-u",
                             "Update accounts using pre-defined iMacros",
                             wx.ITEM_NORMAL)
        self.filemenu.AppendSeparator()
        self.filemenu.Append(
            ID_PROPERTIES, "Properties\tCtrl-p",
            "Display and/or edit Number and Data/Time display properties, pay frequencies",
            wx.ITEM_NORMAL)
        self.filemenu.AppendSeparator()
        self.filemenu.Append(wx.ID_EXIT, "Quit\tCtrl-q", "Exit PyAsset",
                             wx.ITEM_NORMAL)
        self.menubar.Append(self.filemenu, "&File")
        self.Bind(wx.EVT_MENU, self.load_file, None, wx.ID_OPEN)
        self.Bind(wx.EVT_MENU, self.save_file, None, wx.ID_SAVE)
        self.Bind(wx.EVT_MENU, self.save_as_file, None, wx.ID_SAVEAS)
        self.Bind(wx.EVT_MENU, self.close, None, wx.ID_CLOSE)
        self.Bind(wx.EVT_MENU, self.export_text, None, ID_EXPORT_TEXT)
        self.Bind(wx.EVT_MENU, self.archive, None, ID_ARCHIVE)
        self.Bind(wx.EVT_MENU, self.import_CSV_file, None, ID_IMPORT_CSV)
        self.Bind(wx.EVT_MENU, self.import_XLSM_file, None, ID_IMPORT_XLSM)
        self.Bind(wx.EVT_MENU, self.update_from_net, None, ID_UPDATE_FROM_NET)
        self.Bind(wx.EVT_MENU, self.properties, None, ID_PROPERTIES)
        self.Bind(wx.EVT_MENU, self.quit, None, wx.ID_EXIT)

    def make_editmenu(self):
        ID_SORT = wx.NewId()
        ID_DELETE_ENTRY = wx.NewId()
        self.editmenu = wx.Menu()
        self.editmenu.Append(wx.ID_NEW, "New Entry\tCtrl-n",
                             "Create a new asset in the list", wx.ITEM_NORMAL)
        self.editmenu.Append(ID_DELETE_ENTRY, "Delete Entry",
                             "Delete the current asset", wx.ITEM_NORMAL)
        self.editmenu.Append(ID_SORT, "Sort Entries", "Sort entries",
                             wx.ITEM_NORMAL)
        self.menubar.Append(self.editmenu, "&Edit")
        self.Bind(wx.EVT_MENU, self.newentry, None, wx.ID_NEW)
        self.Bind(wx.EVT_MENU, self.deleteentry, None, ID_DELETE_ENTRY)
        self.Bind(wx.EVT_MENU, self.sort, None, ID_SORT)

    def make_helpmenu(self):
        ID_HELP = wx.NewId()
        self.helpmenu = wx.Menu()
        self.helpmenu.Append(wx.ID_ABOUT, "About", "About PyAsset",
                             wx.ITEM_NORMAL)
        self.helpmenu.Append(ID_HELP, "Help\tCtrl-h", "PyAsset Help",
                             wx.ITEM_NORMAL)

        self.menubar.Append(self.helpmenu, "&Help")
        self.Bind(wx.EVT_MENU, self.about, None, wx.ID_ABOUT)
        self.Bind(wx.EVT_MENU, self.gethelp, None, ID_HELP)

    def make_bill_button(self, panel):
        self.billButton = Button(panel, label="Bills")
        self.billButton.Bind(wx.EVT_LEFT_DOWN, self.onBillButtonClick)

    def onBillButtonClick(self, evt):
        self.DisplayMsg("Bill button clicked!")

    def make_date_grid(self, panel):
        self.currDateLabel = wx.StaticText(panel, label="Curr Date")
        dates = Date(self, self.dateFormat, self.payType, self.ref_date)
        self.curr_date = dates.get_curr_date()
        self.currDate = wx.StaticText(panel, label=self.curr_date["str"])
        self.projDateLabel = wx.StaticText(panel, label="Proj Date")
        displayDateFormat = self.dateFormat.replace("%m", "mm").replace(
            "%d", "dd").replace("%y", "yy").replace("%Y", "yyyy")
        self.projDateInput = wx.TextCtrl(panel,
                                         style=wx.TE_PROCESS_ENTER,
                                         value=displayDateFormat)
        self.currPayDateLabel = wx.StaticText(panel, label="Current Pay Date")
        self.currPayDate = dates.get_curr_paydate()
        self.currPayDateOutput = wx.StaticText(panel,
                                               label=str(self.currPayDate))
        self.nextPayDateLabel = wx.StaticText(panel, label="Next Pay Date")
        self.nextPayDate = dates.get_next_paydate()
        self.nextPayDateOutput = wx.StaticText(panel,
                                               label=str(self.nextPayDate))

        self.projDateInput.Bind(wx.EVT_TEXT_ENTER, self.onProjDateEntered)

    def update_date_grid_dates(self, oldDateFormat, newDateFormat):
        if oldDateFormat != newDateFormat:
            self.curr_date = Date.convertDateFormat(self, self.curr_date,
                                                    oldDateFormat,
                                                    newDateFormat)
        self.currDate.LabelText = self.curr_date["str"]
        self.currDate.Refresh()
        try:
            if oldDateFormat != newDateFormat:
                self.proj_date = Date.convertDateFormat(
                    self, self.proj_date, oldDateFormat, newDateFormat)
            if self.proj_date == None:
                self.projDateInput.LabelText = newDateFormat.replace(
                    "%m",
                    "mm").replace("%d",
                                  "dd").replace("%y",
                                                "yy").replace("%Y", "yyyy")
            else:
                self.projDateInput.LabelText = self.proj_date
        except:
            self.projDateInput.LabelText = newDateFormat.replace(
                "%m", "mm").replace("%d",
                                    "dd").replace("%y",
                                                  "yy").replace("%Y", "yyyy")
        self.projDateInput.Refresh()
        if oldDateFormat != newDateFormat:
            self.currPayDate = Date.convertDateFormat(self, self.currPayDate,
                                                      oldDateFormat,
                                                      newDateFormat)
        self.currPayDateOutput.LabelText = Date.get_curr_paydate(self)
        self.currPayDateOutput.Refresh()
        if oldDateFormat != newDateFormat:
            self.nextPayDate = Date.convertDateFormat(self, self.nextPayDate,
                                                      oldDateFormat,
                                                      newDateFormat)
        self.nextPayDateOutput.LabelText = Date.get_next_paydate(self)
        self.nextPayDateOutput.Refresh()

    def onProjDateEntered(self, evt):
        in_date = evt.String
        date_format = Date.get_global_date_format(self)
        returned_date = Date.parse_date(self, in_date, date_format)
        if returned_date != None:
            self.proj_date = wx.DateTime.FromDMY(returned_date["day"],
                                                 returned_date["month"] - 1,
                                                 returned_date["year"])
            self.proj_year = returned_date["year"]
            self.proj_month = returned_date["month"]
            self.proj_day = returned_date["day"]
            print(
                "Projected date %s, parse: Month: %02d, Day: %02d, Year: %04d"
                % (self.proj_date.Format(self.dateFormat), self.proj_month,
                   self.proj_day, self.proj_year))
            Date.set_proj_date(self, in_date)
        else:
            self.proj_date = None
            self.DisplayMsg("Bad projected date ignored: %s" % (in_date))

    def make_asset_grid(self, panel):
        self.assetGrid = AssetGrid(panel)
        self.needed_width = self.assetGrid.set_properties(self)

    def add_transaction_frame(self, row, col):
        name = self.assets[row].name
        transactions = self.assets[row].transactions
        self.trans_frame = TransactionFrame(None, self, -1, row, transactions,
                                            name)

    def get_transaction_frame(self):
        return self.trans_frame

    def setup_layout(self):
        self.panel = wx.Panel(self)

        self.make_bill_button(self.panel)
        self.make_date_grid(self.panel)
        self.make_asset_grid(self.panel)

        self.date_fgs = wx.FlexGridSizer(1, 9, 5, 5)
        self.date_fgs.AddMany([(self.billButton),
                               (self.currDateLabel, 1, wx.ALIGN_CENTER),
                               (self.currDate, 1, wx.ALIGN_CENTER),
                               (self.projDateLabel, 1, wx.ALIGN_CENTER),
                               (self.projDateInput, 1, wx.EXPAND),
                               (self.currPayDateLabel, 1, wx.ALIGN_CENTER),
                               (self.currPayDateOutput, 1, wx.ALIGN_CENTER),
                               (self.nextPayDateLabel, 1, wx.ALIGN_CENTER),
                               (self.nextPayDateOutput, 1, wx.ALIGN_CENTER)])

        self.asset_fgs = wx.FlexGridSizer(2, 1, 0, 0)
        self.asset_fgs.Add(self.assetGrid,
                           proportion=1,
                           flag=wx.RESERVE_SPACE_EVEN_IF_HIDDEN | wx.EXPAND)

        self.mainSizer = wx.BoxSizer(wx.VERTICAL)
        self.mainSizer.Add(self.date_fgs)
        self.mainSizer.Add(self.asset_fgs)

        self.panel.Fit()
        self.panel.SetSizer(self.mainSizer)
        self.date_fgs.SetSizeHints(self.panel)
        self.asset_fgs.SetSizeHints(self.panel)

        self.Fit()
        self.Layout()
        self.Show()

    def redraw_all(self, index=-1):
        self.edited = True
        nassets = len(self.assets)
        if index == -1:
            nrows = nassets + 1
            if nrows > 0 and (index == None or index == -1):
                self.assetGrid.DeleteRows(0, nrows)
                nrows = 0
            start_range = 0
            end_range = nassets
            if nrows < nassets:
                rows_needed = nassets - nrows
                self.assetGrid.AppendRows(rows_needed)
        else:
            start_range = index
            end_range = start_range + 1
        for row in range(start_range, end_range):
            for col in range(self.assetGrid.getNumLayoutCols()):
                ret_val = wx.OK
                if row < 0 or row >= len(self.assets):
                    str = "Warning: skipping redraw on bad cell %d %d!" % (row,
                                                                           col)
                    ret_val = self.DisplayMsg(str)
                if ret_val != wx.OK:
                    continue

                # Logic to always display Value (Curr), Value (Proj), Avail(Proj), Amt Over, Cash Limit, Cash Used and Cash Avail for credit cards,store cards, and overdraft
                asset_type = self.assets[row].get_type()
                col_name = self.assetGrid.getColName(col)
                self.assetGrid.setColZeroSuppress(row, col, True)
                if (asset_type == "store card" or asset_type == "credit card"
                        or asset_type == "overdraft") and (
                            "Curr" in col_name or "Proj" in col_name
                            or "Amt" in col_name or "Cash" in col_name):
                    self.assetGrid.setColZeroSuppress(row, col, False)
                cellValue = self.assetGrid.GridCellDefaultRenderer(row, col)
                cellType = self.assetGrid.getColType(col)
                if cellType == self.assetGrid.DOLLAR_TYPE:
                    self.assetGrid.GridCellDollarRenderer(row, col)
                elif cellType == self.assetGrid.RATE_TYPE:
                    self.assetGrid.GridCellPercentRenderer(row, col)
                elif cellType == self.assetGrid.DATE_TYPE:
                    self.assetGrid.GridCellDateRenderer(row, col)
                elif cellType == self.assetGrid.DATE_TIME_TYPE:
                    self.assetGrid.GridCellDateTimeRenderer(row, col)
                elif cellType == self.assetGrid.STRING_TYPE:
                    self.assetGrid.GridCellStringRenderer(row, col)
                else:
                    self.assetGrid.GridCellErrorRenderer(row, col)
        if index == -1:
            self.assetGrid.SetGridCursor(0, 0)  # was (nassets-1, 0)
            self.assetGrid.MakeCellVisible(0, True)  # was (nassets-1, 0)
        elif index > 0:
            self.assetGrid.SetGridCursor(index, 0)
            self.assetGrid.MakeCellVisible(index, True)

    def assetchange(self, evt):
        row = evt.GetRow()
        col = evt.GetCol()
        val = evt.String
        modified = True
        colName = self.assetGrid.getColName(col)
        if colName == "Acct name":
            self.assets[row].set_name(val)
        elif colName == "Curr val":
            self.assets[row].set_value(val)
        elif colName == "Last pulled":
            self.assets[row].set_last_pull_date(val)
        elif colName == "Limit":
            self.assets[row].set_limit(val)
        elif colName == "Avail online":
            self.assets[row].set_avail(val)
        elif colName == "Rate":
            self.assets[row].set_rate(val)
        elif colName == "Payment amt":
            self.assets[row].set_payment(val)
        elif colName == "Due date":
            self.assets[row].set_due_date(val)
        elif colName == "Sched date":
            self.assets[row].set_sched_date(val)
        elif colName == "Min Pmt":
            self.assets[row].set_min_pay(val)
        elif colName == "Stmt Bal":
            self.assets[row].set_stme_bal(val)
        elif colName == "Amt Over":
            self.assets[row].set_amt_over(val)
        elif colName == "Cash Limit":
            self.assets[row].set_cash_limit(val)
        elif colName == "Cash Used":
            self.assets[row].set_cash_used(val)
        elif colName == "Cash Avail":
            self.assets[row].set_cash_avail(val)
        else:
            print("assetchange: Warning: modifying incorrect cell! row, ", row,
                  " col ", col)
            modified = False

        if modified == True:
            self.edited = True

    def update_all_Date_Formats(self, oldDateFormat, newDateFormat):
        self.edited = True
        self.update_date_grid_dates(oldDateFormat, newDateFormat)
        #TODO:  Add code to update asset_grids and transaction grids   JJG 06/10/2020

    def load_file(self, assetFile):
        latest_assets = qif.load_file(self, "")
        if latest_assets != None:
            self.process_asset_list(latest_assets)

    def save_file(self, *args):
        for cur_asset in self.assets:
            if cur_asset.filename == "":
                self.save_as_file()
            else:
                self.edited = False
            self.cur_asset.write_qif()

    def save_as_file(self, *args):
        d = wx.FileDialog(self, "Save", "", "", "*.qif", wx.FD_SAVE)
        if d.ShowModal() == wx.ID_OK:
            fname = d.GetFilename()
            dir = d.GetDirectory()
            self.cur_asset.write_qif(os.path.join(dir, fname))
        if self.cur_asset.name:
            self.SetTitle("PyAsset: %s" % self.cur_asset.name)

    def close(self, *args):
        pass  # Not sure what to do here yet!  JJG 1/17/2022
        #self.cur_asset = None
        #del self.assets
        #del self.bills
        #self.assets = AssetList(self)
        #self.bills = BillList()
        #self.redraw_all()
        #self.edited = False
        #self.SetTitle("PyAsset: Asset")

    def quit(self, *args):
        self.close()
        self.Close()

    #
    #     @brief Receives data to be written to and its location
    #
    #     @params[in] date_
    #     Data of transaction
    #     @params[in] amount_
    #     Amount of money for transaction
    #     @params[in] memo_
    #     Description of transaction
    #     @params[in] payee_
    #     Who transaction was paid to
    #     @params[in] filelocation_
    #     Location of the Output file
    #
    #
    # https://en.wikipedia.org/wiki/Quicken_Interchange_Format
    #

    def write_file(self, date_, amount_, memo_, payee_, filelocation_):
        outFile = open(filelocation_, "a")  # Open file to be appended
        outFile.write(
            "!Type:Cash\n")  # Header of transaction, Currently all set to cash
        outFile.write("D")  # Date line starts with the capital D
        outFile.write(date_)
        outFile.write("\n")

        outFile.write("T")  # Transaction amount starts here
        outFile.write(amount_)
        outFile.write("\n")

        outFile.write("M")  # Memo Line
        outFile.write(memo_)
        outFile.write("\n")

        if (payee_ != -1):
            outFile.write("P")  # Payee line
            outFile.write(payee_)
            outFile.write("\n")

        outFile.write(
            "^\n"
        )  # The last line of each transaction starts with a Caret to mark the end
        outFile.close()

    #
    #     @brief  Takes given CSV and parses it to be exported to a QIF
    #
    #     @params[in] inf_
    #     File to be read and converted to QIF
    #     @params[in] outf_
    #     File that the converted data will go
    #     @params[in] deff_
    #     File with the settings for converting CSV
    #
    #

    def read_csv(self, inf_, outf_,
                 deff_):  # will need to receive input csv and def file
        csvdeff = csv.reader(deff_, delimiter=',')
        next(csvdeff, None)

        for settings in csvdeff:
            date_ = (settings[0])  # convert to
            amount_ = (settings[2])  # How much was the transaction
            memo_ = (settings[3])  # discription of the transaction
            payee_ = (settings[4])  # Where the money is going
            deli_ = settings[5]  # How the csv is separated
            header_ = (settings[6])  # Set if there is a header to skip

        csvIn = csv.reader(
            inf_,
            delimiter=deli_)  # create csv object using the given separator

        if header_ >= 1:  # If there is a header skip the fist line
            next(csvIn, None)  # skip header

        for row in csvIn:
            self.write_file(row[date_], row[amount_], row[memo_], row[payee_],
                            outf_)  # export each row as a qif entry

        inf_.close()
        deff_.close()

    def import_CSV_file(self, *args):
        # Appends the records from a .csv file to the current Asset
        d = wx.FileDialog(self, "Import", "", "", "*.csv", wx.FD_OPEN)
        if d.ShowModal() == wx.ID_OK:
            self.edited = True
            fname = d.GetFilename()
            dir = d.GetDirectory()
            total_name_in = os.path.join(dir, fname)
            total_name_extension_place = total_name_in.find(".csv")
            total_name_def = ""
            total_name_qif = ""
            if total_name_extension_place != -1:
                total_name_def = total_name_in[:total_name_extension_place] + ".def"
                total_name_qif = total_name_in[:total_name_extension_place] + ".qif"
            # pr total_name_in, total_name_def, total_name_qif
            error = ""
            try:
                fromfile = open(total_name_in, 'r')
            except:
                error = total_name_in + ' does not exist / cannot be opened !!\n'

            if total_name_qif != "":
                try:
                    tofile = open(totoal_name_qif, 'a')
                except:
                    error = total_name_qif + ' cannot be created !!\n'

            if total_name_def != "":
                if os.path.isfile(total_name_def):
                    deffile = open(total_name_def, 'r')
                else:
                    error = total_name_def + ' does not exist / cannot be opened !!\n'

            if error == "":
                tofile = total_name_qif
                self.read_csv(fromfile, tofile, deffile)
                self.cur_asset.read_qif(total_name_qif)
                fromfile.close()
                deffile.close()
                self.redraw_all(-1)
                if self.cur_asset.name:
                    self.SetTitle("PyAsset: %s" % self.cur_asset.name)
            else:
                self.Display(error)
                return

    def process_asset_list(self, assetList):
        for i in range(len(assetList.assets)):
            cur_asset = assetList.assets[i]
            cur_name = cur_asset.get_name()
            j = self.assets.index(cur_name)
            if j != -1:
                self.assets.assets[
                    j] = cur_asset  # For now, just replace, when dates are working, save later date JJG 1/22/2022
            else:
                self.assets.append_by_object(cur_asset)
        self.redraw_all()

    def import_XLSM_file(self, *args):
        # Appends or Merges as appropriate the records from a .xlsm file to the current Asset
        d = wx.FileDialog(self, "Import", "", "", "*.xlsm", wx.FD_OPEN)
        if d.ShowModal() == wx.ID_OK:
            self.edited = True
            fname = d.GetFilename()
            dir = d.GetDirectory()
            total_name_in = os.path.join(dir, fname)
            error = ""
            try:
                fromfile = open(total_name_in, 'r')
                fromfile.close()
            except:
                error = total_name_in + ' does not exist / cannot be opened !!\n'

            if error == "":
                self.cur_assets = None
                xlsm = ExcelToAsset(ignore_sheets=[
                    'Assets', 'Bills', 'Shop Your Way transactions',
                    'Slate transactions', 'Slate old transactions'
                ])
                xlsm.OpenXLSMFile(total_name_in)
                latest_assets = xlsm.ProcessAssetsSheet(self)
                self.process_asset_list(latest_assets)
                transaction_sheet_names = xlsm.GetTransactionSheetNames()
                for sheet in transaction_sheet_names:
                    sheet_index = self.assets.index(sheet)
                    if sheet_index != -1:
                        self.assets[
                            sheet_index].transactions = xlsm.ProcessTransactionSheet(
                                self.assets[sheet_index], sheet)
                        if self.assets[sheet_index].transactions:
                            proj_value = self.assets[
                                sheet_index].transactions.update_current_and_projected_values(
                                )
                            self.assets[sheet_index].set_value_proj(proj_value)
                    else:
                        print(sheet + " not found in asset list")

                #TODO: Process latest_bills here (False since not written yet!)
                if False:
                    self.latest_bills = xlsm.ProcessBillsSheet(self.bills)
                    print(self.latest_bills)
            else:
                self.DisplayMsg(error)

    def update_from_net(self, *args):
        w = iMacrosToAsset()
        w.Init()
        net_asset_codes = [
            ("HFCU", 1, [False, False, False, True]),
            #("BOA",-1,[False,True]),
            #("AMEX",-1,[True,True]),
            #("CITI",-1,[True]),
            #("MACYS",-1,[True]),
            #("SYW",-1,[True]),
            #("TSP",-1,[False,False,False,True]),
            #("MET",1,[False])
        ]
        for net_asset_code in net_asset_codes:
            latest_assets = w.GetNetInfo(net_asset_code)
            #print latest_assets
            for i in range(len(latest_assets)):
                net_asset = latest_assets.__getitem__(i)
                if net_asset != None:
                    latest_name = net_asset.get_name()
                    found = False
                    for j in range(len(self.assets)):
                        cur_name = self.assets[j].get_name()
                        if "(" in cur_name:
                            cur_name = cur_name.split("(")[1].split(")")[0]
                        if cur_name in latest_name:
                            net_index = j
                            found = True
                            break
                    if not found:
                        self.assets.append(latest_name)
                        net_index = -1
                    # Always update Value (Curr) column and type ... others check if non-zero value before update is done!
                    self.assets[net_index].set_value(net_asset.get_value())
                    self.assets[net_index].set_type(net_asset.get_type())
                    if net_asset.get_value_proj() != 0.0:
                        self.assets[net_index].set_value_proj(
                            net_asset.get_value_proj())
                    if net_asset.get_last_pull_date() != 0.0:
                        self.assets[net_index].set_last_pull_date(
                            net_asset.get_last_pull_date())
                    if net_asset.get_limit() != 0.0:
                        self.assets[net_index].set_limit(net_asset.get_limit())
                    if net_asset.get_avail() != 0.0:
                        self.assets[net_index].set_avail(net_asset.get_avail())
                    if net_asset.get_avail_proj() != 0.0:
                        self.assets[net_index].set_avail_proj(
                            net_asset.get_avail_proj())
                    if net_asset.get_rate() != 0.0:
                        self.assets[net_index].set_rate(net_asset.get_rate())
                    if net_asset.get_payment() != 0.0:
                        self.assets[net_index].set_payment(
                            net_asset.get_payment())
                    if net_asset.get_due_date() != None:
                        self.assets[net_index].set_due_date(
                            net_asset.get_due_date())
                    if net_asset.get_sched_date() != None:
                        self.assets[net_index].set_sched_date(
                            net_asset.get_sched_date())
                    if net_asset.get_min_pay() != 0.0:
                        self.assets[net_index].set_min_pay(
                            net_asset.get_min_pay())
                    if net_asset.get_stmt_bal() != 0.0:
                        self.assets[net_index].set_stmt_bal(
                            net_asset.get_stmt_bal())
                    if net_asset.get_amt_over() != 0.0:
                        self.assets[net_index].set_amt_over(
                            net_asset.get_amt_over())
                    if net_asset.get_cash_limit() != 0.0:
                        self.assets[net_index].set_cash_limit(
                            net_asset.get_cash_limit())
                    if net_asset.get_cash_used() != 0.0:
                        self.assets[net_index].set_cash_used(
                            net_asset.get_cash_used())
                    if net_asset.get_cash_avail() != 0.0:
                        self.assets[net_index].set_cash_avail(
                            net_asset.get_cash_avail())
        w.Finish()
        self.redraw_all()

    def properties(self, *args):
        dateFormat = Date.get_global_date_format(self)
        ref_date_parsed = Date.parse_date(self, self.ref_date, dateFormat)
        if ref_date_parsed != None:
            ref_date_dt = ref_date_parsed["dt"]
            ref_date = wx.DateTime.FromDMY(ref_date_dt.day, ref_date_dt.month,
                                           ref_date_dt.year).Format(dateFormat)
        else:
            ref_date = ""  # For now to test!  JJG 08/06/2021
        frame = PropertyFrameWithForm(self, self.dateFormat, self.payType,
                                      ref_date, self.netpay,
                                      self.payDepositAcct)
        frame.Show()

    def setDateFormat(self, new_DateFormat):
        self.dateFormat = new_DateFormat

    def setPayType(self, new_type):
        self.payType = new_type

    def setRefDate(self, new_ref_date):
        self.ref_date = new_ref_date

    def setNetPay(self, new_netpay):
        self.netpay = new_netpay

    def setPayDepositAcct(self, new_PayDepositAcct):
        self.payDepositAcct = new_PayDepositAcct

    def getDateFormat(self):
        return self.dateFormat

    def getPayType(self):
        return self.payType

    def getRefDate(self):
        return self.ref_date

    def getNetPay(self):
        return self.netpay

    def getPayDepositAcct(self):
        return self.payDepositAcct

    def export_text(self, *args):
        d = wx.FileDialog(self, "Save", "", "", "*.txt", wx.SAVE)
        if d.ShowModal() == wx.ID_OK:
            fname = d.GetFilename()
            dir = d.GetDirectory()
            self.cur_asset.write_txt(os.path.join(dir, fname))

    def archive(self, *args):
        d = wx.TextEntryDialog(
            self, "Archive transactions before what date (mm/dd/yy)?",
            "Archive Date")
        if d.ShowModal() == wx.ID_OK:
            date = Date(d.GetValue())
        else:
            date = None
        d.Destroy()
        if not date:
            return
        archive = Asset()
        newcb_starttransaction = Transaction()
        newcb_starttransaction.amount = 0
        newcb_starttransaction.payee = "Starting Balance"
        newcb_starttransaction.memo = "Archived by PyAsset"
        newcb_starttransaction.state = "cleared"
        newcb_starttransaction.date = date

        newcb = Asset()
        newcb.filename = self.cur_asset.filename
        newcb.name = self.cur_asset.name
        newcb.append(newcb_starttransaction)
        archtot = 0

        for transaction in self.cur_asset:
            if transaction.date < date and transaction.state == "cleared":
                archive.append(transaction)
                archtot += transaction.amount
            else:
                newcb.append(transaction)
        newcb_starttransaction.amount = archtot
        self.cur_asset = newcb
        while 1:
            d = wx.FileDialog(self, "Save Archive As", "", "", "*.qif",
                              wx.SAVE)
            if d.ShowModal() == wx.ID_OK:
                fname = d.GetFilename()
                dir = d.GetDirectory()
            d.Destroy()
            if fname: break
        archive.write_qif(os.path.join(dir, fname))
        self.redraw_all(-1)
        self.edited = True

    def newentry(self, *args):
        self.edited = True
        self.assets.append("New Asset")
        self.assetGrid.AppendRows()
        nassets = self.assetGrid.GetNumberRows()
        self.assetGrid.SetGridCursor(nassets - 1, 0)
        self.assetGrid.MakeCellVisible(nassets - 1, 1)
        self.redraw_all()

    def sort(self, *args):
        self.edited = True
        self.assets.sort()
        self.redraw_all()

    def deleteentry(self, *args):
        index = self.assetGrid.GetGridCursorRow()
        indices = self.assetGrid.SelectedCells
        if index >= 0:
            d = wx.MessageDialog(self, "Really delete this asset?",
                                 "Really delete?", wx.YES_NO)
            if d.ShowModal() == wx.ID_YES:
                del self.assets[index]
            self.redraw_all(
            )  # TODO: Can we make a self.redraw(index-1)  so that only the assets[index-1:] get updated?  JJG 07/09/2021

    def about(self, *args):
        d = wx.MessageDialog(
            self, "Python Asset Manager\n"
            "Copyright (c) 2016-2022 Joseph J. Gorak\n"
            "Released under the Gnu GPL\n", "About PyAsset",
            wx.OK | wx.ICON_INFORMATION)
        d.ShowModal()
        d.Destroy()

    def gethelp(self, *args):
        d = HelpDialog(self, -1, "Help", __doc__)
        val = d.ShowModal()
        d.Destroy()

    def MsgBox(self, message):
        d = wx.MessageDialog(self, message, "error",
                             wx.OK | wx.ICON_INFORMATION)
        d.ShowModal()
        d.Destroy()
Beispiel #13
0
 def clear_all_assets(self):
     self.assets = AssetList(self)
     self.redraw_all(-1)