[BANKING] Fleshing out more banking information. Logic to populate fast-access bank account list added UNTESTED
Some checks failed
build / build (21) (push) Has been cancelled

This commit is contained in:
Jkibbels 2024-11-06 20:01:41 -05:00
parent d8a6b7ecd9
commit 87afc5c8ab
3 changed files with 149 additions and 24 deletions

View File

@ -27,7 +27,7 @@ import java.util.Random;
public class AccountNumberGenerator {
// Callers of this function are required to verify the given number is unique.
public static String NewAccountNumber(String symbol, Integer routingNumber, Integer accountType, String username) {
public static String GenerateNewAccountNumber(String symbol, Integer routingNumber, Integer accountType, String username) {
String generatedAccountNumber = symbol + "-" + routingNumber + "-" + accountType + "-";
// Block to translate part of username into number format
@ -48,4 +48,22 @@ public class AccountNumberGenerator {
return generatedAccountNumber;
}
// the below functions must be given a key generated from the above function or they will combust into
// not less than one million pieces! :)
public static String GetFinancialSymbolFromId(String accountId) {
return accountId.substring(0, 4);
}
public static Integer GetRoutingNumberFromId(String accountId) {
return Integer.parseInt(accountId.substring(5, 9));
}
public static Integer GetAccountNumberFromId(String accountId) {
return Integer.parseInt(accountId.substring(10, accountId.length()));
}
public static Integer GetAccountTypeFromId(String accountId) {
return (int) accountId.charAt(10);
}
}

View File

@ -6,9 +6,9 @@ import java.util.List;
// TODO: Add ability to store NBT data of items in the future so we can store not just money but items too
// like a safety deposit box
public class IndividualAccount {
private String accountNumber;
private Integer accountNumber;
private String accountNumberAlias;
private String routingNumber; // Will always be the bank it's in
private Integer routingNumber; // Will always be the bank it's in
private List<String> accountHolders;
private Integer accountBalance;
private Boolean allowNegativeBalance;
@ -18,7 +18,7 @@ public class IndividualAccount {
public IndividualAccount() {}
public IndividualAccount(String accountNumber, String routingNumber, List<String> holders,
public IndividualAccount(Integer accountNumber, Integer routingNumber, List<String> holders,
Boolean allowNegativeBalance, Integer initialBalance, String alias) {
this.accountNumber = accountNumber;
this.routingNumber = routingNumber;
@ -28,6 +28,12 @@ public class IndividualAccount {
this.accountNumberAlias = alias;
}
public void AddAccountHolder(String newHolder) {
if (!accountHolders.contains(newHolder)) {
accountHolders.add(newHolder);
}
}
public void AliasAccount(String newAlias) {
this.accountNumberAlias = newAlias;
}
@ -36,6 +42,10 @@ public class IndividualAccount {
return accountLocked;
}
public void LockAccount() {
accountLocked = true;
}
public Boolean Deposit(Integer amount) {
Boolean success = false;
if (!accountLocked)
@ -96,11 +106,11 @@ public class IndividualAccount {
return accountBalance;
}
public String GetAccountNumber() {
public Integer GetAccountNumber() {
return accountNumber;
}
public String GetRoutingNumber() {
public Integer GetRoutingNumber() {
return routingNumber;
}

View File

@ -1,10 +1,11 @@
package jesse.keeblarcraft.BankMgr;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import static java.util.Map.entry;
import jesse.keeblarcraft.ConfigMgr.ConfigManager;
// Contains the information of an individual bank
@ -12,9 +13,17 @@ import jesse.keeblarcraft.ConfigMgr.ConfigManager;
// The bank will keep track of all accounts within its facilities. In addition to accounts, the bank
// maintains its own identifier which is unique and other misc things.
public class IndividualBank {
private Map<String, Integer> ACCOUNT_TYPES = Map.ofEntries(
entry("checking", 0),
entry("savings", 1)
);
ConfigManager config = new ConfigManager();
private String routingNumber; // this is the banks unique identifier
private String numberOfAccounts; // Total number of accounts the bank has. This includes only active accounts
private Integer routingNumber; // this is the banks unique identifier
private Integer numberOfAccounts; // Total number of accounts the bank has. This includes only active accounts inside accountsList.
private String bankFourLetterIdentifier;
private Integer maxBankAccounts = 100_000_000; // Making this simple for myself any one type of account has 8 random numbers genereated so 10^8 possible accounts
// Think FDIC but from the servers account (keeblarcraft insurance corporation)
// KBIC will ensure an amount of money based on its trustworthiness to a bank and the number of holders it has.
@ -38,30 +47,118 @@ public class IndividualBank {
// READ IN BANK CONFIG
// A modified config reader is needed here for when each IndividualAccount is read in - the name is taken from that and is attached to the
// 'accountsListFromName' structure. This makes it no worse than O(n) to fill these two structures in
// 'accountsListFromName' structure. This makes it no worse than O(n) to fill these two structures in.
// NOTE: This is an *EXPENSIVE* operation! Future us might need to update this. Also note a method is needed for everytime a player opens a new account
// or gets put on one to update the map every time
for (Entry<Integer, IndividualAccount> account : accountsList.entrySet()) {
// We must loop over the string of holders for each account as well to make the flattened accountsListFromName map
List<String> accountHolders = account.getValue().GetAccountHolders();
// Match each user to the secondary map & add to list-value if not existing
for (Integer holderIndex = 0; holderIndex < accountHolders.size(); holderIndex++) {
if (accountsListFromName.containsKey(accountHolders.get(holderIndex))) {
// Case 1: User exists, update map entry
accountsListFromName.get(accountHolders.get(holderIndex)).add(account.getKey()); // Add a new account id to this person in the new flat map
} else {
// Case 2: User does not already exist; add a new map entry
accountsListFromName.put(accountHolders.get(holderIndex), List.of(account.getKey())); // Store name as key, and new List with the value of ACCOUNT #
}
}
}
public Boolean CreateAccount(String holderName, String accountType) {
if (accountType.toLowerCase() != "checking" || accountType.toLowerCase() != "savings") {
return false;
} // TODO: Replace String with enum type in future and remove this early return
numberOfAccounts = accountsList.size();
}
// Updates the regular bank account list & the fast-access bank account list
// NO values are allowed to be null. Manually update lists separately if that's the behaviour you want!
public void UpdateBankAccounts(String newHolderName, Integer accountIdentifier, IndividualAccount newAccountOnly) {
// Update the fast-access map first
if (accountsListFromName.containsKey(newHolderName)) {
// Check if user is already in map
accountsListFromName.get(newHolderName).add(accountIdentifier);
} else {
// Add new entry to map
accountsListFromName.put(newHolderName, List.of(accountIdentifier));
}
// Update regular account list
if (accountsList.containsKey(accountIdentifier)) {
// This path assumes we are adding a holder as opposed to adding an account (else, how else would this work?)
accountsList.get(accountIdentifier).AddAccountHolder(newHolderName);
} else {
// Non-existent account means a new one!
accountsList.put(accountIdentifier, newAccountOnly);
numberOfAccounts++;
}
}
public Boolean CreateAccount(String holderName, String accountTypeStr) {
Boolean success = false;
if (accountsList.size() <= maxBankAccounts && ACCOUNT_TYPES.containsKey(accountTypeStr.toLowerCase())) {
// Verify this isn't a blacklisted user
if (!lockedUsers.contains(holderName)) {
Integer maxAttempts = 1000; // Reasonably a unique bank account should pop up within 1000 generations. If not, the user may try again.
String accountId = AccountNumberGenerator.GenerateNewAccountNumber(bankFourLetterIdentifier, routingNumber, ACCOUNT_TYPES.get(accountTypeStr), holderName);
// TODO: Fix in future with a method that will guarentee a one-time necessary number generator. Statistically speaking; this will be okay for the
// entire life time of the server. BUT, you never know!
while (maxAttempts != 0 && !accountsList.containsKey(AccountNumberGenerator.GetAccountNumberFromId(accountId))) {
accountId = AccountNumberGenerator.GenerateNewAccountNumber(bankFourLetterIdentifier, routingNumber, ACCOUNT_TYPES.get(accountTypeStr), holderName);
maxAttempts--;
}
// Final check to add the account
Integer actualAccountNumber = AccountNumberGenerator.GetAccountNumberFromId(accountId);
if (!accountsList.containsKey(actualAccountNumber)) {
IndividualAccount newAccount = new IndividualAccount(actualAccountNumber, this.routingNumber, List.of(holderName), false, 0, "");
UpdateBankAccounts(holderName, actualAccountNumber, newAccount);
success = true;
}
}
}
return success;
}
public Boolean HasAccount(String accountIdentifier) {
public void AliasAccount(String accountId, String newAlias) {
Integer accountNumber = AccountNumberGenerator.GetAccountNumberFromId(accountId);
if (accountsList.containsKey(accountNumber)) {
accountsList.get(accountNumber).AliasAccount(newAlias);
}
}
public Boolean LockAccountHolder(String holderName) {
Boolean success = false;
Integer accountIter = 0;
for (Entry<String, List<Integer>> holderAccounts : accountsListFromName.entrySet()) {
accountsList.get(holderAccounts.getValue().get(accountIter++)).LockAccount();
}
return success;
}
public Boolean CloseAccount(String accountId) {
Boolean success = false;
Integer accountNumber = AccountNumberGenerator.GetAccountNumberFromId(accountId);
if (accountsList.get(accountNumber).GetAccountBalance() == 0) {
accountsList.remove(accountNumber);
success = true;
}
return success;
}
public Boolean HasAccount(Integer accountIdentifier) {
Boolean containsAccount = false;
if (accountsList.containsKey(accountIdentifier)) {
containsAccount = true;
}
return true;
return containsAccount;
}
}