def __init__(self,name = "", type = "OTHER", last_pull_date = 0, value = 0.0, value_proj = 0.0, est_method = "", limit = 0.0, avail = 0.0, avail_proj = 0.0, rate = 0.0, payment = 0.0, due_date = None, sched_date = None, min_pay = 0.0, stmt_bal = 0.0, amt_over = 0.0, cash_limit = 0.0, cash_used = 0.0, cash_avail = 0.0): self.dateFormat = Date.get_global_date_format(self) self.dateSep = Date.get_global_date_sep(self) self.name = name if name != "": self.filename = self.name + ".qif" self.set_type(type) self.last_pull_date = last_pull_date self.limit = limit self.avail = avail self.avail_proj = avail_proj self.rate = rate self.payment = payment self.due_date = due_date self.sched_date = sched_date self.min_pay = min_pay self.value = value self.value_proj = value_proj self.est_method = est_method self.amt_over = amt_over self.stmt_bal = stmt_bal self.cash_limit = cash_limit self.cash_used = cash_used self.cash_avail = cash_avail self.transactions = TransactionList(self, limit) return
def GridCellDateRenderer(self, row, col): cellValue = str(self.getColMethod(row, col)) if cellValue == None or cellValue == "None": tableValue = "" elif self.getColZeroSuppress( row, col) == self.ZERO_SUPPRESS and (cellValue == "0" or cellValue == ""): tableValue = "" else: returned_date = Date.parse_date(self, cellValue, Date.get_global_date_format(self)) if returned_date != None: tableDate = wx.DateTime.FromDMY(returned_date["day"], returned_date["month"] - 1, returned_date["year"]) dateFormat = Date.get_global_date_format(self) date_sep = Date.get_global_date_sep(self) dateParts = dateFormat.split(date_sep) tableValue = "" for i in range(len(dateParts)): if dateParts[i] == "%m": tableValue = tableValue + "%02d" % (int( returned_date["month"])) elif dateParts[i] == "%d": tableValue = tableValue + "%02d" % (int( returned_date["day"])) elif dateParts[i] == "%Y": tableValue = tableValue + "%04d" % (int( returned_date["year"])) elif dateParts[i] == "%y": # assume all 2 digit years are in the range 2000 <= year < 2099. Don't expect this software to be used in the year 2100!! JJG 07/08/2021 tableValue = tableValue + "%04d" % ( 2000 + int(returned_date["year"])) if i < len(dateParts) - 1: tableValue = tableValue + "%s" % ( Date.get_global_date_sep(self)) else: tableValue = "" self.DisplayMsg("Bad cell date for row %d col %d ignored: %s" % (row, col, cellValue)) self.SetCellAlignment(row, col, wx.ALIGN_CENTER, wx.ALIGN_CENTER) self.getFrame().assetGrid.SetCellValue(row, col, tableValue)
def __init__(self, parent): self.parent = parent self.dateFormat = Date.get_global_date_format(self) self.dateSep = Date.get_global_date_sep(self) self.pmt_method = None self.check_num = None self.payee = None self.amount = None self.action = None self.current_value = None self.sched_date = None self.due_date = None self.state = OUTSTANDING self.prev_state = UNKNOWN self.comment = None self.memo = None
def __init__(self, style, parent, my_id, asset_index, transactions, title="PyAsset:Transaction", myfile=None, **kwds): self.asset_index = asset_index self.transactions = transactions self.parent = parent self.dateFormat = Date.get_global_date_format(self) self.dateSep = Date.get_global_date_sep(self) if len(self.transactions) > 0: self.cur_transaction = self.transactions[0] else: self.cur_transaction = None self.edited = False self.rowSize = 30 self.colSize = 20 if style == None: style = wx.DEFAULT_FRAME_STYLE kwds["style"] = wx.DEFAULT_FRAME_STYLE wx.Frame.__init__(self, parent, my_id, title, **kwds) self.make_widgets() if myfile: self.cur_transaction.read_qif(myfile) self.SetTitle("PyAsset:Transactions for %s" % title) self.redraw_all()
def __init__(self, frame, **keywrds): self.dateFormat = Date.get_global_date_format(self) self.dateSep = Date.get_global_date_sep(self) self.columnNames = [ "Account", "Value (Curr)", "Value (Proj)", "last pulled", "Limit", "Avail (Online)", "Avail (Proj)", "Rate", "Payment", "Due Date", "Sched", "Min Pmt", "Stmt Bal", "Amt Over", "Cash Limit", "Cash used", "Cash avail" ] self.grid = grd.Grid.__init__(self, frame, **keywrds) self.minNumRows = frame.BestSize.Height self.CreateGrid(self.minNumRows, len(self.columnNames)) self.frame = frame # Define all needed evenent bindings self.Bind(grd.EVT_GRID_CELL_CHANGING, self.cellchanging) self.Bind(grd.EVT_GRID_CELL_LEFT_CLICK, self.OnCellLeftClick) self.Bind(grd.EVT_GRID_CELL_RIGHT_CLICK, self.OnCellRightClick) self.Bind(grd.EVT_GRID_CELL_LEFT_DCLICK, self.OnCellLeftDClick) self.Bind(grd.EVT_GRID_CELL_RIGHT_DCLICK, self.OnCellRightDClick) self.Bind(grd.EVT_GRID_LABEL_LEFT_CLICK, self.OnLabelLeftClick) self.Bind(grd.EVT_GRID_LABEL_RIGHT_CLICK, self.OnLabelRightClick) self.Bind(grd.EVT_GRID_LABEL_LEFT_DCLICK, self.OnLabelLeftDClick) self.Bind(grd.EVT_GRID_LABEL_RIGHT_DCLICK, self.OnLabelRightDClick) self.Bind(grd.EVT_GRID_ROW_SIZE, self.OnRowSize) self.Bind(grd.EVT_GRID_COL_SIZE, self.OnColSize) self.Bind(grd.EVT_GRID_RANGE_SELECT, self.OnRangeSelect) #self.Bind(grd.EVT_GRID_CELL_CHANGE, self.OnCellChange) self.Bind(grd.EVT_GRID_SELECT_CELL, self.OnSelectCell) self.Bind(grd.EVT_GRID_EDITOR_SHOWN, self.OnEditorShown) self.Bind(grd.EVT_GRID_EDITOR_HIDDEN, self.OnEditorHidden) self.Bind(grd.EVT_GRID_EDITOR_CREATED, self.OnEditorCreated) # Define the layout of the grid in the frame self.ACCT_NAME_COL = 0 self.ACCT_CURR_VAL_COL = 1 self.ACCT_PROJ_VAL_COL = 2 self.ACCT_LAST_PULL_COL = 3 self.ACCT_LIMIT_COL = 4 self.ACCT_AVAIL_ONLINE_COL = 5 self.ACCT_AVAIL_PROJ_COL = 6 self.ACCT_RATE_COL = 7 self.ACCT_PAYMENT_COL = 8 self.ACCT_DUE_DATE_COL = 9 self.ACCT_SCHED_DATE_COL = 10 self.ACCT_MIN_PMT_COL = 11 self.ACCT_STMT_BAL_COL = 12 self.ACCT_AMT_OVER_COL = 13 self.ACCT_CASH_LIMIT_COL = 14 self.ACCT_CASH_USED_COL = 15 self.ACCT_CASH_AVAIL_COL = 16 # Define the widths of the columns in the grid ACCT_NAME_COL_WIDTH = 150 ACCT_CURR_VAL_COL_WIDTH = 75 ACCT_PROJ_VAL_COL_WIDTH = 75 ACCT_LAST_PULL_COL_WIDTH = 120 ACCT_LIMIT_COL_WIDTH = 80 ACCT_AVAIL_ONLINE_COL_WIDTH = 80 ACCT_AVAIL_PROJ_COL_WIDTH = 80 ACCT_RATE_COL_WIDTH = 5 ACCT_PAYMENT_COL_WIDTH = 9 ACCT_DUE_DATE_COL_WIDTH = 75 ACCT_SCHED_DATE_COL_WIDTH = 75 ACCT_MIN_PMT_COL_WIDTH = 8 ACCT_STMT_BAL_COL_WIDTH = 8 ACCT_AMT_OVER_COL_WIDTH = 8 ACCT_CASH_LIMIT_COL_WIDTH = 8 ACCT_CASH_USED_COL_WIDTH = 8 ACCT_CASH_AVAIL_COL_WIDTH = 8 # Define what the valid input data types are self.DOLLAR_TYPE = 0 self.RATE_TYPE = 1 self.DATE_TYPE = 2 self.DATE_TIME_TYPE = 3 self.STRING_TYPE = 4 # Define if field is editable or not self.NOT_EDITABLE = True self.EDITABLE = False # Define if field should be suppressed if zero self.NO_ZERO_SUPPRESS = False self.ZERO_SUPPRESS = True # Define indices of columns in grid layout array self.NAME_COL = 0 self.WIDTH_COL = 1 self.TYPE_COL = 2 self.EDIT_COL = 3 self.ZERO_SUPPRESS_COL = 4 # Grid layout array self.col_info = [ [ self.ACCT_NAME_COL, ACCT_NAME_COL_WIDTH, self.STRING_TYPE, self.EDITABLE, self.ZERO_SUPPRESS ], [ self.ACCT_CURR_VAL_COL, ACCT_CURR_VAL_COL_WIDTH, self.DOLLAR_TYPE, self.NOT_EDITABLE, self.NO_ZERO_SUPPRESS ], [ self.ACCT_PROJ_VAL_COL, ACCT_PROJ_VAL_COL_WIDTH, self.DOLLAR_TYPE, self.NOT_EDITABLE, self.NO_ZERO_SUPPRESS ], [ self.ACCT_LAST_PULL_COL, ACCT_LAST_PULL_COL_WIDTH, self.DATE_TIME_TYPE, self.NOT_EDITABLE, self.ZERO_SUPPRESS ], [ self.ACCT_LIMIT_COL, ACCT_LIMIT_COL_WIDTH, self.DOLLAR_TYPE, self.EDITABLE, self.ZERO_SUPPRESS ], [ self.ACCT_AVAIL_ONLINE_COL, ACCT_AVAIL_ONLINE_COL_WIDTH, self.DOLLAR_TYPE, self.NOT_EDITABLE, self.ZERO_SUPPRESS ], [ self.ACCT_AVAIL_PROJ_COL, ACCT_AVAIL_PROJ_COL_WIDTH, self.DOLLAR_TYPE, self.NOT_EDITABLE, self.ZERO_SUPPRESS ], [ self.ACCT_RATE_COL, ACCT_RATE_COL_WIDTH, self.RATE_TYPE, self.EDITABLE, self.ZERO_SUPPRESS ], [ self.ACCT_PAYMENT_COL, ACCT_PAYMENT_COL_WIDTH, self.DOLLAR_TYPE, self.EDITABLE, self.ZERO_SUPPRESS ], [ self.ACCT_DUE_DATE_COL, ACCT_DUE_DATE_COL_WIDTH, self.DATE_TYPE, self.EDITABLE, self.ZERO_SUPPRESS ], [ self.ACCT_SCHED_DATE_COL, ACCT_SCHED_DATE_COL_WIDTH, self.DATE_TYPE, self.EDITABLE, self.ZERO_SUPPRESS ], [ self.ACCT_MIN_PMT_COL, ACCT_MIN_PMT_COL_WIDTH, self.DOLLAR_TYPE, self.EDITABLE, self.ZERO_SUPPRESS ], [ self.ACCT_STMT_BAL_COL, ACCT_STMT_BAL_COL_WIDTH, self.DOLLAR_TYPE, self.EDITABLE, self.ZERO_SUPPRESS ], [ self.ACCT_AMT_OVER_COL, ACCT_AMT_OVER_COL_WIDTH, self.DOLLAR_TYPE, self.NOT_EDITABLE, self.ZERO_SUPPRESS ], [ self.ACCT_CASH_LIMIT_COL, ACCT_CASH_LIMIT_COL_WIDTH, self.DOLLAR_TYPE, self.EDITABLE, self.ZERO_SUPPRESS ], [ self.ACCT_CASH_USED_COL, ACCT_CASH_USED_COL_WIDTH, self.DOLLAR_TYPE, self.NOT_EDITABLE, self.ZERO_SUPPRESS ], [ self.ACCT_CASH_AVAIL_COL, ACCT_CASH_AVAIL_COL_WIDTH, self.DOLLAR_TYPE, self.NOT_EDITABLE, self.ZERO_SUPPRESS ], ]
def cellchanging(self, evt): row = evt.GetRow() col = evt.GetCol() ret_val = wx.OK new_value = evt.String if row < 0 or row >= len(self.frame.transactions): str = "Warning: cellchanging on bad cell %d %d!" % (row, col) ret_val = self.DisplayMsg(str) elif self.col_info[col][self.EDIT_COL] == self.NOT_EDITABLE: str = "Warning: Changes not allowed for column %s!" % ( self.getColName(col)) ret_val = self.DisplayMsg(str) if ret_val == wx.OK and self.col_info[col][ self.TYPE_COL] == self.DOLLAR_TYPE: #TODO move regular expression for dollar format to new object m = re.match("^-?\$?\d{1,3}(\,?\d{3})*(\.\d{2})*$", new_value) if m: self.edited = True dollar_amount = new_value.replace("$", "").replace(",", "") if "." not in dollar_amount: dollar_amount += ".00" evt.Veto() self.frame.transaction_grid.SetCellValue( row, col, dollar_amount) evt.String = dollar_amount else: str = "%s is not a valid dollar string" % (new_value) ret_val = self.DisplayMsg(str) elif ret_val == wx.OK and self.col_info[col][ self.TYPE_COL] == self.RATE_TYPE: #TODO move regular expression for rate format to new object m = re.match("^\d{1,3}(\.\d{1,3})?\%?$", new_value) if m: self.edited = True evt.Veto() rate_amount = Round( float(new_value.replace("%", "")) / 100.0, 2) evt.String = "%8.5f" % (rate_amount) else: str = "%s is not a valid rate string" % (new_value) ret_val = self.DisplayMsg(str) elif ret_val == wx.OK and self.col_info[col][ self.TYPE_COL] == self.DATE_TYPE: if new_value == "" and self.getColZeroSuppress( row, col) == self.ZERO_SUPPRESS: evt.Veto() else: dateFormat = Date.get_global_date_format(self) date_sep = Date.get_global_date_sep(self) input_date = new_value.split(date_sep) dateParts = dateFormat.split(date_sep) tableValue = "" if len(input_date) == 3: for i in range(len(dateParts)): if dateParts[i] == "%m": tableValue = tableValue + "%02d" % (int( input_date[i])) elif dateParts[i] == "%d": tableValue = tableValue + "%02d" % (int( input_date[i])) elif dateParts[i] == "%Y": tableValue = tableValue + "%04d" % (int( input_date[i])) elif dateParts[i] == "%y": # assume all 2 digit years are in the range 2000 <= year < 2099. Don't expect this software to be used in the year 2100!! JJG 07/08/2021 tableValue = tableValue + "%04d" % ( 2000 + int(input_date[i])) if i < len(dateParts) - 1: tableValue = tableValue + "%s" % (date_sep) evt.Veto() try: returned_date = Date.parse_date( self, tableValue, Date.get_global_date_format(self)) except: str = "%s is not a valid date string" % (new_value) ret_val = self.DisplayMsg(str) else: self.edited = True evt.String = tableValue elif ret_val == wx.OK and self.col_info[col][ self.TYPE_COL] == self.DATE_TIME_TYPE: if new_value == "" and self.getColZeroSuppress( row, col) == self.ZERO_SUPPRESS: evt.Veto() else: #TODO move regular expression for datetime format to new object m = re.match( "^\d{1,2}([/-])\d{1,2}([/-])\d{4} \d{2}:\d{2}:\d{2}?$", new_value) if m: sep = m.groups() evt.Veto() pos1 = new_value.index(sep[0]) pos2 = new_value.rindex(sep[1]) pos3 = new_value.index(" ") pos4 = new_value.index(":") pos5 = new_value.rindex(":") mon = int(new_value[0:pos1]) day = int(new_value[pos1 + 1:pos2]) year = int(new_value[pos2 + 1:pos3]) hour = int(new_value[pos3 + 1:pos4]) min = int(new_value[pos4 + 1:pos5]) sec = int(new_value[pos5 + 1:]) try: in_datetime = datetime(year, mon, day, hour, min, sec) except: str = "%s is not a valid datetime string" % (new_value) ret_val = self.DisplayMsg(str) else: self.edited = True in_datetime_string = "%04s-%02d-%02d %02d:%02d:%02d" % ( year, mon, day, hour, min, sec) evt.String = in_datetime_string else: str = "%s is not a valid datetime string" % (new_value) ret_val = self.DisplayMsg(str) elif ret_val == wx.OK and self.col_info[col][ self.TYPE_COL] == self.STRING_TYPE: if col == self.TRANS_ACTION_COL: if new_value != "+" and new_value != "-": str = "%s is not a valid action string" % (new_value) ret_val = self.DisplayMsg(str) else: pass else: if ret_val != wx.OK: str = "Warning: cellchanging not allowed for cell %d %d!" % ( row, col) ret_val = self.DisplayMsg(str) if ret_val == wx.OK: print("TransactionGrid: Change detected for row", row, ", col", col) self.frame.assetchange(row, col, new_value) self.frame.redraw_all() else: evt.Veto()
def __init__(self, frame, **keywords): self.dateFormat = Date.get_global_date_format(self) self.dateSep = Date.get_global_date_sep(self) self.grid = grd.Grid.__init__(self, frame, **keywords) self.frame = frame self.Bind(grd.EVT_GRID_CELL_CHANGING, self.cellchanging) # test all the events self.Bind(grd.EVT_GRID_CELL_LEFT_CLICK, self.OnCellLeftClick) self.Bind(grd.EVT_GRID_CELL_RIGHT_CLICK, self.OnCellRightClick) self.Bind(grd.EVT_GRID_CELL_LEFT_DCLICK, self.OnCellLeftDClick) self.Bind(grd.EVT_GRID_CELL_RIGHT_DCLICK, self.OnCellRightDClick) self.Bind(grd.EVT_GRID_LABEL_LEFT_CLICK, self.OnLabelLeftClick) self.Bind(grd.EVT_GRID_LABEL_RIGHT_CLICK, self.OnLabelRightClick) self.Bind(grd.EVT_GRID_LABEL_LEFT_DCLICK, self.OnLabelLeftDClick) self.Bind(grd.EVT_GRID_LABEL_RIGHT_DCLICK, self.OnLabelRightDClick) self.Bind(grd.EVT_GRID_ROW_SIZE, self.OnRowSize) self.Bind(grd.EVT_GRID_COL_SIZE, self.OnColSize) self.Bind(grd.EVT_GRID_RANGE_SELECT, self.OnRangeSelect) #self.Bind(grd.EVT_GRID_CELL_CHANGE, self.OnCellChange) #self.Bind(grd.EVT_GRID_SELECT_CELL, self.OnSelectCell) self.Bind(grd.EVT_GRID_EDITOR_SHOWN, self.OnEditorShown) self.Bind(grd.EVT_GRID_EDITOR_HIDDEN, self.OnEditorHidden) self.Bind(grd.EVT_GRID_EDITOR_CREATED, self.OnEditorCreated) # Define the layout of the grid in the frame self.TRANS_PMT_METHOD_COL = 0 self.TRANS_CHECK_NUM_COL = 1 self.TRANS_PAYEE_COL = 2 self.TRANS_AMOUNT_COL = 3 self.TRANS_ACTION_COL = 4 self.TRANS_VALUE_COL = 5 self.TRANS_SCHED_DATE_COL = 6 self.TRANS_DUE_DATE_COL = 7 self.TRANS_STATE_COL = 8 self.TRANS_COMMENT_COL = 9 self.TRANS_MEMO_COL = 10 # Define the widths of the columns in the grid TRANS_PMT_METHOD_COL_WIDTH = 80 TRANS_CHECK_NUM_COL_WIDTH = 60 TRANS_PAYEE_COL_WIDTH = 400 TRANS_AMOUNT_COL_WIDTH = 60 TRANS_ACTION_COL_WIDTH = 50 TRANS_VALUE_COL_WIDTH = 65 TRANS_SCHED_DATE_COL_WIDTH = 70 TRANS_DUE_DATE_COL_WIDTH = 70 TRANS_STATE_COL_WIDTH = 70 TRANS_COMMENT_COL_WIDTH = 400 TRANS_MEMO_COL_WIDTH = 400 # Define what the valid input data types are self.DOLLAR_TYPE = 0 self.RATE_TYPE = 1 self.DATE_TYPE = 2 self.DATE_TIME_TYPE = 3 self.STRING_TYPE = 4 # Define if field is editable or not self.NOT_EDITABLE = True self.EDITABLE = False # Define if field should be suppressed if zero self.NO_ZERO_SUPPRESS = False self.ZERO_SUPPRESS = True # Define indices of columns in grid layout array self.NAME_COL = 0 self.WIDTH_COL = 1 self.TYPE_COL = 2 self.EDIT_COL = 3 self.ZERO_SUPPRESS_COL = 4 # Grid layout array self.col_info = [ [ self.TRANS_PMT_METHOD_COL, TRANS_PMT_METHOD_COL_WIDTH, self.STRING_TYPE, self.EDITABLE, self.ZERO_SUPPRESS ], [ self.TRANS_CHECK_NUM_COL, TRANS_CHECK_NUM_COL_WIDTH, self.STRING_TYPE, self.EDITABLE, self.NO_ZERO_SUPPRESS ], [ self.TRANS_PAYEE_COL, TRANS_PAYEE_COL_WIDTH, self.STRING_TYPE, self.EDITABLE, self.NO_ZERO_SUPPRESS ], [ self.TRANS_AMOUNT_COL, TRANS_AMOUNT_COL_WIDTH, self.DOLLAR_TYPE, self.EDITABLE, self.ZERO_SUPPRESS ], [ self.TRANS_ACTION_COL, TRANS_ACTION_COL_WIDTH, self.STRING_TYPE, self.EDITABLE, self.ZERO_SUPPRESS ], [ self.TRANS_VALUE_COL, TRANS_VALUE_COL_WIDTH, self.DOLLAR_TYPE, self.NOT_EDITABLE, self.ZERO_SUPPRESS ], [ self.TRANS_SCHED_DATE_COL, TRANS_SCHED_DATE_COL_WIDTH, self.DATE_TYPE, self.EDITABLE, self.ZERO_SUPPRESS ], [ self.TRANS_DUE_DATE_COL, TRANS_DUE_DATE_COL_WIDTH, self.DATE_TYPE, self.EDITABLE, self.ZERO_SUPPRESS ], [ self.TRANS_STATE_COL, TRANS_STATE_COL_WIDTH, self.STRING_TYPE, self.EDITABLE, self.ZERO_SUPPRESS ], [ self.TRANS_COMMENT_COL, TRANS_COMMENT_COL_WIDTH, self.STRING_TYPE, self.NOT_EDITABLE, self.NO_ZERO_SUPPRESS ], [ self.TRANS_MEMO_COL, TRANS_MEMO_COL_WIDTH, self.STRING_TYPE, self.EDITABLE, self.NO_ZERO_SUPPRESS ], ] return