class BANK create run feature {NONE} -- Implementation store: BANK_STORE over: BOOLEAN last_error: STRING data_file: RAW_FILE data_filename: STRING = "bank.data" fd: FORMAT_DOUBLE feature {NONE} -- Initialization run do create fd.make(2, 2) create store.make(100) store.ranges.account.interest_deposit := [0.01, 0.04] store.ranges.account.interest_debit := [0.02, 0.1] store.ranges.account.creditline := [-1000.0, 0.0] store.ranges.studentaccount.interest_deposit := [0.02, 0.03] store.ranges.studentaccount.interest_debit := [0.03, 0.06] store.ranges.studentaccount.creditline := [-300.0, 0.0] store.ranges.retireeaccount.interest_deposit := [0.02, 0.03] store.ranges.retireeaccount.interest_debit := [0.03, 0.06] store.ranges.retireeaccount.creditline := [-300.0, 0.0] create last_error.make_empty create data_file.make (data_filename) if data_file.exists then data_file.open_read store ?= store.retrieved (data_file) data_file.close end session if data_file.is_creatable then data_file.open_write store.independent_store (data_file) data_file.close end end feature -- Basic operations session do from until over loop main_screen end end print_last_error do if not last_error.is_empty then print ("Error: " + last_error + "%N%N") last_error := "" end end print_header do clear_screen print ("**************************************%N") print ("********* BANK of FOOP *********%N") print ("**************************************%N") end clear_screen do io.put_character ((0x1B).to_character_8) io.put_string ("[2J") io.put_character ((0x1B).to_character_8) io.put_string ("[H") end main_screen do print_header print ("Operations:%N") print (" r ...list/edit global ranges%N") print (" p ...list/create/edit/delete persons%N") print (" a ...list/create/edit/delete accounts%N") print (" q ...quit%N") print ("%N") print_last_error print ("Enter a command, followed by : ") io.read_character io.next_line inspect io.last_character.lower when 'r' then ranges_screen when 'p' then persons_screen when 'a' then accounts_screen when 'q' then over := True else last_error := "Error: Unknown command '" + io.last_character.out + "'" end print ("%N%N") end ranges_screen local back: BOOLEAN do from until back loop print_header print ("Global Ranges:%N") print (" Account:%N") print_ranges(store.ranges.account) print (" Student account:%N") print_ranges(store.ranges.studentaccount) print (" Retiree account:%N") print_ranges(store.ranges.retireeaccount) print ("%N") print ("Operations:%N") print (" a ...edit account ranges%N") print (" s ...edit student account ranges%N") print (" r ...edit retiree account ranges%N") print (" b ...back%N") print ("%N") print_last_error print ("Enter a command, followed by : ") io.read_character io.next_line inspect io.last_character.lower when 'a' then edit_ranges("account", store.ranges.account) when 's' then edit_ranges("student account", store.ranges.studentaccount) when 'r' then edit_ranges("retiree account", store.ranges.retireeaccount) when 'b' then back := True else last_error := "Error: Unknown command '" + io.last_character.out + "'" end print ("%N%N") end end print_ranges(range: like {BANK_STORE}.account_range) do print (" - Interest deposit: " + print_range(range.interest_deposit) + "%N") print (" - Interest debit: " + print_range(range.interest_debit) + "%N") print (" - Creditline: " + print_range(range.creditline) + "%N") end print_range(range: like {BANK_STORE}.range): STRING_8 do Result := "[" + fd.formatted(range.min) + ", " + fd.formatted(range.max) + "]" end edit_ranges(type: STRING_8; range: like {BANK_STORE}.account_range) do print ("%N") print ("Edit " + type + " range:%N") edit_range("interest depost", range.interest_deposit) edit_range("interest debit", range.interest_debit) edit_range("creditline", range.creditline) end edit_range(type: STRING_8; range: like {BANK_STORE}.range) do print ("Enter " + type + " minimum [" + fd.formatted(range.min) + "]: ") io.readline if io.last_string.is_double then range.min := io.last_string.to_double end print ("Enter " + type + " maximum [" + fd.formatted(range.max) + "]: ") io.readline if io.last_string.is_double then range.max := io.last_string.to_double end end persons_screen local back: BOOLEAN do from until back loop print_header print ("Operations:%N") print (" l ...list persons%N") print (" c ...create person%N") print (" e ...edit person%N") print (" d ...delete person%N") print (" b ...back%N") print ("%N") print_last_error print ("Enter a command, followed by : ") io.read_character io.next_line inspect io.last_character.lower when 'l' then list_persons print ("Press to go back") io.read_line when 'c' then create_persons when 'e' then edit_person when 'd' then delete_person when 'b' then back := True else last_error := "Error: Unknown command '" + io.last_character.out + "'" end print ("%N%N") end end list_persons do print ("%N") print ("Persons: " + store.persons.count.out + "%N") from store.persons.start until store.persons.off loop print ("#" + store.persons.index.out + " " + store.persons.item.surname + ", " + store.persons.item.firstname) if attached {RETIREE} store.persons.item then print (" (RETIREE)") elseif attached {STUDENT} store.persons.item then print (" (STUDENT)") end print ("%N") store.persons.forth end print ("%N") end create_persons local back: BOOLEAN firstname: STRING surname: STRING do from until back loop print_header print ("Operations:%N") print (" p ...create person%N") print (" s ...create student%N") print (" r ...create retiree%N") print (" b ...back%N") print ("%N") print_last_error print ("Enter a command, followed by : ") io.read_character io.next_line inspect io.last_character.lower when 'p', 's', 'r' then print ("Enter surname: ") io.readline surname := io.last_string.twin print ("Enter firstname: ") io.readline firstname := io.last_string.twin inspect io.last_character.lower when 'p' then store.persons.put(create {PERSON}.make(surname, firstname)) when 's' then store.persons.put(create {STUDENT}.make(surname, firstname)) when 'r' then store.persons.put(create {RETIREE}.make(surname, firstname)) else end last_error := "Person (#" + store.persons.count.out + ") created successfully" back := True when 'b' then back := True else last_error := "Error: Unknown command '" + io.last_character.out + "'" end print ("%N%N") end rescue if not (create {EXCEPTIONS}).is_signal then last_error := "Exception: " + (create {EXCEPTIONS}).tag_name retry end end edit_person local back: BOOLEAN num: INTEGER do list_persons from until back loop print_last_error print ("Enter person id (b ...back): ") io.readline io.last_string.to_lower if io.last_string.is_integer then num := io.last_string.to_integer if store.persons.valid_index (num) then store.persons.go_i_th (num) print ("Enter surname [" + store.persons.item.surname + "]: ") io.readline if not io.last_string.is_empty then store.persons.item.surname := io.last_string.twin end print ("Enter firstname [" + store.persons.item.firstname + "]: ") io.readline if not io.last_string.is_empty then store.persons.item.firstname := io.last_string.twin end last_error := "Person (#" + num.out + ") edited successfully" back := True else last_error := "Invalid person id" end elseif io.last_string.is_equal ("b") then back := True else last_error := "Not a number" end end end delete_person local back: BOOLEAN do list_persons from until back loop print_last_error print ("Enter person id (b ...back): ") io.readline io.last_string.to_lower if io.last_string.is_integer then if store.persons.valid_index (io.last_string.to_integer) then store.persons.go_i_th (io.last_string.to_integer) store.persons.remove last_error := "Person (#" + io.last_string + ") removed successfully" back := True else last_error := "Invalid person id" end elseif io.last_string.is_equal ("b") then back := True else last_error := "Not a number" end end end accounts_screen local back: BOOLEAN done: BOOLEAN do from until back loop print_header print ("Operations:%N") print (" l ...list accounts%N") print (" c ...create account%N") print (" e ...edit account%N") print (" d ...delete account%N") print (" b ...back%N") print ("%N") print_last_error print ("Enter a command, followed by : ") io.read_character io.next_line inspect io.last_character.lower when 'l' then list_accounts from done := False until back or done loop print ("Enter account id for details (b ...back): ") io.readline io.last_string.to_lower if io.last_string.is_integer then if store.accounts.valid_index (io.last_string.to_integer) then store.accounts.go_i_th (io.last_string.to_integer) print ("%N") print ("Account #" + store.accounts.index.out + ":%N") list_account_details(store.accounts.item) print ("Press to go back") io.read_line done := True else print ("Invalid account id%N%N") end elseif io.last_string.is_equal("b") then done := True else print ("Not a number%N%N") end end when 'c' then create_accounts when 'e' then edit_accounts when 'd' then delete_account when 'b' then back := True else last_error := "Error: Unknown command '" + io.last_character.out + "'" end print ("%N%N") end end list_accounts local account: ACCOUNT person: PERSON do print ("%N") print ("Accounts: " + store.accounts.count.out + "%N") from store.accounts.start until store.accounts.off loop account := store.accounts.item account.get_authorized_signers.linear_representation.start person := account.get_authorized_signers.linear_representation.item print ("#" + store.accounts.index.out + " " + person.surname + ", " + person.firstname) if attached {RETIREEACCOUNT} account then print (" (RETIREE ACCOUNT)") elseif attached {STUDENTACCOUNT} account then print (" (STUDENT ACCOUNT)") end print ("%N") store.accounts.forth end print ("%N") end list_account_details(account: ACCOUNT) local person: PERSON range: like {BANK_STORE}.account_range do range := store.ranges.account if attached {RETIREEACCOUNT} account then range := store.ranges.retireeaccount elseif attached {STUDENTACCOUNT} account then range := store.ranges.studentaccount end print (" - Balance: " + fd.formatted(account.balance) + "%N") print (" - Interest deposit: " + fd.formatted(account.interest_deposit) + " " + print_range(range.interest_deposit) + "%N") print (" - Interest debit: " + fd.formatted(account.interest_debit) + " " + print_range(range.interest_debit) +"%N") print (" - Creditline: " + fd.formatted(account.creditline) + " " + print_range(range.creditline) +"%N") print (" - Authorized signers:%N") from account.get_authorized_signers.linear_representation.start until account.get_authorized_signers.linear_representation.off loop person := account.get_authorized_signers.linear_representation.item print (" - #" + account.get_authorized_signers.linear_representation.index.out + " " + person.surname + ", " + person.firstname) if attached {RETIREE} person then print (" (RETIREE)") elseif attached {STUDENT} person then print (" (STUDENT)") end print ("%N") account.get_authorized_signers.linear_representation.forth end print (" - Type: ") if attached {RETIREEACCOUNT} account then print ("Retiree account") elseif attached {STUDENTACCOUNT} account then print ("Student account") else print ("Account") end print ("%N%N") end create_accounts local back: BOOLEAN do from until back loop print_header print ("Operations:%N") print (" a ...create account%N") print (" s ...create student account%N") print (" r ...create retiree account%N") print (" b ...back%N") print ("%N") print_last_error print ("Enter a command, followed by : ") io.read_character io.next_line inspect io.last_character.lower when 'a' then back := create_account('a', store.ranges.account) when 's' then back := create_account('s', store.ranges.studentaccount) when 'r' then back := create_account('r', store.ranges.retireeaccount) when 'b' then back := True else last_error := "Error: Unknown command '" + io.last_character.out + "'" end print ("%N%N") end rescue if not (create {EXCEPTIONS}).is_signal then last_error := "Exception: " + (create {EXCEPTIONS}).tag_name retry end end create_account(type: CHARACTER; range: like {BANK_STORE}.account_range): BOOLEAN local back: BOOLEAN next: BOOLEAN interest_deposit: like {ACCOUNT}.interest_deposit interest_debit: like {ACCOUNT}.interest_debit creditline: like {ACCOUNT}.creditline do Result := false interest_deposit := (range.interest_deposit.min + range.interest_deposit.max) / 2 interest_debit := (range.interest_debit.min + range.interest_debit.max) / 2 creditline := (range.creditline.min + range.creditline.max) / 2 print_last_error from next := False list_persons until back or next loop print ("Enter person (authorized signer) id (b ...back): ") io.readline io.last_string.to_lower if io.last_string.is_integer then if store.persons.valid_index (io.last_string.to_integer) then store.persons.go_i_th (io.last_string.to_integer) next := True else print ("Invalid person id%N%N") end elseif io.last_string.is_equal ("b") then back := True else print ("Not a number%N%N") end end from next := False until back or next loop print ("Enter interest deposit " + print_range(range.interest_deposit) + " [" + fd.formatted(interest_deposit) + "] (b ...back): ") io.readline io.last_string.to_lower if io.last_string.is_empty then next := True elseif io.last_string.is_double then interest_deposit := io.last_string.to_double next := True elseif io.last_string.is_equal ("b") then back := True else print ("Invalid interest deposit number%N%N") end end from next := False until back or next loop print ("Enter interest debit " + print_range(range.interest_debit) + " [" + fd.formatted(interest_debit) + "] (b ...back):") io.readline io.last_string.to_lower if io.last_string.is_empty then next := True elseif io.last_string.is_double then interest_debit := io.last_string.to_double next := True elseif io.last_string.is_equal ("b") then back := True else print ("Invalid interest debit number%N%N") end end from next := False until back or next loop print ("Enter creditline " + print_range(range.creditline) + " [" + fd.formatted(creditline) + "] (b ...back): ") io.readline io.last_string.to_lower if io.last_string.is_empty then next := True elseif io.last_string.is_double then creditline := io.last_string.to_double next := True elseif io.last_string.is_equal ("b") then back := True else print ("Invalid creditline number%N%N") end end if not back then inspect type when 'a' then store.accounts.put(create {ACCOUNT}.make(store.persons.item, interest_deposit, interest_debit, creditline, range.interest_deposit, range.interest_debit, range.creditline)) when 's' then store.accounts.put(create {STUDENTACCOUNT}.make(store.persons.item, interest_deposit, interest_debit, creditline, range.interest_deposit, range.interest_debit, range.creditline)) when 'r' then store.accounts.put(create {RETIREEACCOUNT}.make(store.persons.item, interest_deposit, interest_debit, creditline, range.interest_deposit, range.interest_debit, range.creditline)) else end last_error := "Account (#" + store.accounts.count.out + ") created successfully" Result := true back := True end end edit_accounts local back: BOOLEAN do list_accounts from until back loop print_last_error print ("Enter account id (b ...back): ") io.readline io.last_string.to_lower if io.last_string.is_integer then if store.accounts.valid_index (io.last_string.to_integer) then store.accounts.go_i_th (io.last_string.to_integer) edit_account(store.accounts.index, store.accounts.item) back := True else last_error := "Invalid account id" end elseif io.last_string.is_equal ("b") then back := True else last_error := "Not a number" end end end edit_account(index: INTEGER; account: ACCOUNT) local back: BOOLEAN do from until back loop print_header print ("Edit account #" + index.out + ":%N") list_account_details (account) print ("Operations:%N") print (" 1 ...edit interest deposit%N") print (" 2 ...edit interest debit%N") print (" 3 ...edit creditline%N") print (" 4 ...add authorized signer%N") print (" 5 ...remove authorized signer%N") print (" 6 ...deposit%N") print (" 7 ...withdraw%N") print (" 8 ...transfer%N") print (" 9 ...advance%N") print (" b ...back%N") print ("%N") print_last_error print ("Enter a command, followed by : ") io.read_character io.next_line inspect io.last_character.lower when '1' then when '2' then when '3' then when '4' then when '5' then when '6' then when '7' then when '8' then when '9' then when 'b' then back := True else last_error := "Error: Unknown command '" + io.last_character.out + "'" end print ("%N%N") end end delete_account local back: BOOLEAN do list_accounts from until back loop print_last_error print ("Enter account id (b ...back): ") io.readline io.last_string.to_lower if io.last_string.is_integer then if store.accounts.valid_index (io.last_string.to_integer) then store.accounts.go_i_th (io.last_string.to_integer) store.accounts.remove last_error := "Account (#" + io.last_string + ") removed successfully" back := True else last_error := "Invalid account id" end elseif io.last_string.is_equal ("b") then back := True else last_error := "Not a number" end end end end