#---------------- # --- main.py --- #---------------- import tkinter as tk from tkinter import ttk, messagebox import re import locale from businesslogic import BusinessLogic from dataaccesslayer import DataAccessLayer def main(): # create main window window = tk.Tk() window.title('Create new account...') window.geometry('600x225') window.minsize(600, 225) # create an instance of the BusinessLogic & DataAccessLayer classes bl = BusinessLogic(window) dal = DataAccessLayer(window) def createAccount(): #routingNumber, accountNumber, openingDeposit): routingNumber = txtRoutingNumber.get() accountNumber = txtAccountNumber.get() openingDeposit = formatAsCurrency(float(txtOpeningDeposit.get())) # dal.insertNewAccount() print(f"\nCreating new account...\n" f"\tRouting #: {routingNumber}\n" f"\tAccount #: {accountNumber}\n" f"\t Deposit: {formatAsCurrency(openingDeposit)}\n\n") return True def formatAsCurrency(amount): return '{:.2f}'.format(float(amount)) # create label/prompt for the routing number lblRoutingNumber = ttk.Label(window, text="ABA routing number: ", justify="right", borderwidth=0, font="Tahoma 12", relief="solid") lblRoutingNumber.place(x=85, y=42) # create entry box for routing number txtRoutingNumber = ttk.Entry( window, validate="key", width=10, justify="left", name="routingNumber", font="Tahoma 12", validatecommand=(window.register(bl.validateRoutingNumber), '%S', # character(s) just entered or deleted '%s', # text already in the textbox, before any changes '%P', # text in the textbox if the insertion/deletion is allowed '%d', # action code, see above "txtRoutingNumber", 9 # maximum number of digits allowed ) ) txtRoutingNumber.place(x=307, y=40) # create label/prompt for the account number lblAcctNumber = ttk.Label(window, text="Account number: ", justify="right", borderwidth=0, font="Tahoma 12", relief="solid") lblAcctNumber.place(x=124, y=82) # create entry object for the account number txtAccountNumber = ttk.Entry(window, validate="key", width=19, justify="left", name="accountNumber", font="Tahoma 12", validatecommand=(window.register(bl.validateInputIsDigit), '%S', False) #, '%W', 9, 18) ) txtAccountNumber.place(x=307, y=80) # create label/prompt for the opening deposit lblOpeningDeposit = ttk.Label(window, text="Opening deposit: $", justify="right", borderwidth=0, font="Tahoma 12", relief="solid") lblOpeningDeposit.place(x=111, y=122) # create entry object for the opening deposit txtOpeningDeposit = ttk.Entry(window, validate="key", width=10, justify="left", name="openingDeposit", font="Tahoma 12", validatecommand=(window.register(bl.validateIsCurrency), '%S', '%s', '%P', True) ) txtOpeningDeposit.place(x=307, y=120) # create "Submit" button btnOK = ttk.Button(window, name="btnOK", text="Submit", width=10, command=createAccount(), #createAccount()) ).place(x=80, y=180) # create "Cancel" button btnCancel = ttk.Button(window, name="btnCancel", text="Cancel", width=10, command=window.destroy ).place(x=400, y=180) # set initial focus to the ABA routing number Entry() widget txtRoutingNumber.focus() # run ininite loop window.mainloop() # EOFunc main() if __name__ == "__main__": main() #------------------------- # --- businesslogic.py --- #------------------------- import tkinter as tk from tkinter import ttk, messagebox import re import locale class BusinessLogic: def __init__(self, parentGUI): self.parent = parentGUI def validateRoutingNumber(self, inputText, # text that was entered or deleted currentText, # text that currently in the textbox, *before* any change proposedText, # text that will be in the textbox, *if* the change is allowed actionCode, # see block comment abovew widgetName, # name of the widget object maxLength): # maximum number of digits # if number of digits currently in the textbox is less than the maximum length... if (len(proposedText) < int(maxLength)): # make sure text entered is a digit, not a character if (inputText.isdigit()): return True else: return False # length of text currently in the textbox is -eq or -gt the maximum length else: if (len(proposedText) > int(maxLength)): return False if (self.isValidRoutingNumber(proposedText)): return True # accept the input else: return False # reject it return def isValidRoutingNumber(self, routingNumber): n = 0 for i in range(0, len(str(routingNumber)), 3): n += int(str(routingNumber)[i]) * 3 + \ int(str(routingNumber)[i+1]) * 7 + \ int(str(routingNumber)[i+2]) if (n != 0 and n % 10 == 0): #print(f"{routingNumber} is a valid ABA routing number.") # messagebox.showinfo("Information", f"\"{routingNumber}\" is a valid ABA routing number.") # print(f"Routing number {routingNumber} is valid") return True else: print(f"{routingNumber} is *not* a valid ABA routing number!") # messagebox.showerror("Error", f"\"{routingNumber}\" is not a valid ABA routing number!") return False return def validateInputIsDigit(self, insertText, acceptDecimalPoint): if (acceptDecimalPoint and insertText == "."): return True else: if insertText.isdigit(): return True else: return False def isValidAccountNumber(accountNumber): if accountNumber is None: return False else: regEx = r'^[0-9]{9,18}$' # account number must be contain between 9 and 18 digits if re.match(regEx, accountNumber): return True else: return False return def validateIsCurrency( self, userInput, # amount that was entered or deleted currentAmount, # amount that's currently in the textbox, *before* any change proposedAmount, # amount that will be in the textbox, *if* the change is allowed acceptDecimal = True, # accept a decimal point? acceptMinus = False): # accept a minus sign? charsToReject = [",", "$", "."] if not acceptMinus: charsToReject.append("-") if acceptDecimal: charsToReject.remove(".") # TODO: add currency symbol for the user's locale if (userInput in charsToReject): return False # if the *proposed* amount already contains a decimal point... if ("." in proposedAmount): # and it would have more than 2 decimal places should the insertion/deletion be accepted if (len(str(proposedAmount).split(".")[1]) > 2): return False if (acceptDecimal and userInput == "."): # if the proposed amount would contain more than 1 decimal point if (proposedAmount.count(".") > 1): return False return True else: if (self.isValidCurrency(proposedAmount)): return True else: return False def isValidCurrency(self, amount): rePattern = r'^[1-9]\d*(\.\d{1,2})?$' try: if re.match(rePattern, "{:.2f}".format(float(amount))): return True else: return False except: return False return #--------------------------- # --- dataaccesslayer.py --- #--------------------------- #import re #import locale # TODO: Implement Sqlite class DataAccessLayer: def __init__(self, parentGUI): self.parent = parentGUI pass # stub function until Sqlite is implemented def insertNewAccount(self): routingNumber = self.parent.txtRoutingNumber.get(), accountNumber = self.parent.txtAccountNumber.get() openingDeposit = self.parent.txtOpeningDeposit.get() print(f"\nCreating new account...\n" f"\tRouting #: {routingNumber}\n" f"\tAccount #: {accountNumber}\n" f"\t Deposit: ${openingDeposit}\n\n")