implemented loading banking system from file
This commit is contained in:
parent
4b3f2bb59f
commit
fae01ef464
|
@ -0,0 +1,6 @@
|
||||||
|
Bank;BLZ;Kontonummer;PIN;Kontostand;Kontoart;Zins %;Ueberziehungsbetrag;Kundennummer;Name;Vorname;Kunde Straße;Kunde PLZ;Kunde Ort
|
||||||
|
VR Bank Rhein-Neckar;MA2424;4711;1234;50,14 €;Sparkonto;3%;;123456;Mustermann;Max;Bahnhofstraße 1;68159;Mannheim
|
||||||
|
VR Bank Rhein-Neckar;MA2424;8321;1234;500,14;Girokonto;;1.000,27 €;123456;Mustermann;Max;Bahnhofstraße 1;68159;Mannheim
|
||||||
|
Berliner Bank;19087;1717;1234;500,14;Sparkonto;1,003;;717171;Mustermann;Max;Bahnhofstraße 1;68159;Mannheim
|
||||||
|
Berliner Bank;19087;1919;1234;540,2;Sparkonto;1,1;;717171;Mustermann;Max;Bahnhofstraße 1;68159;Mannheim
|
||||||
|
Zocker Bank;Zock7777;4444;7777;-8000,5;Girokonto;;50000,5;31124;Hogo;Gruber;Berlinestraß 33 / 1;7899;Berlin
|
|
|
@ -1,5 +1,7 @@
|
||||||
package me.teridax.jcash.banking;
|
package me.teridax.jcash.banking;
|
||||||
|
|
||||||
|
import me.teridax.jcash.decode.Decoder;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
|
@ -9,10 +11,33 @@ public abstract class Account {
|
||||||
private final int pin;
|
private final int pin;
|
||||||
private final double balance;
|
private final double balance;
|
||||||
|
|
||||||
public Account(int iban, int pin) {
|
public Account(int iban, int pin, double balance) {
|
||||||
this.iban = iban;
|
this.iban = iban;
|
||||||
this.pin = pin;
|
this.pin = pin;
|
||||||
this.balance = 0.0d;
|
this.balance = balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Account fromColumns(String[] columns) {
|
||||||
|
Objects.requireNonNull(columns);
|
||||||
|
|
||||||
|
var iban = Decoder.decodeUniqueIdentificationNumber(columns[0]);
|
||||||
|
var pin = Decoder.decodeUniqueIdentificationNumber(columns[1]);
|
||||||
|
var balance = Decoder.decodeCurrency(columns[2]);
|
||||||
|
var type = Decoder.decodeName(columns[3]);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (type.equals("Sparkonto")) {
|
||||||
|
var interest = Decoder.decodePercent(columns[4]);
|
||||||
|
return new SavingsAccount(iban, pin, balance, interest);
|
||||||
|
} else if (type.equals("Girokonto")) {
|
||||||
|
var overdraft = Decoder.decodeCurrency(columns[5]);
|
||||||
|
return new Girokonto(iban, pin, balance, overdraft);
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Invalid account type: " + type);
|
||||||
|
}
|
||||||
|
} catch (IllegalArgumentException | NullPointerException e) {
|
||||||
|
throw new IllegalArgumentException("Account format: ", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getIban() {
|
public int getIban() {
|
||||||
|
|
|
@ -8,7 +8,7 @@ public final class Bank {
|
||||||
private final String blz;
|
private final String blz;
|
||||||
private final Map<Owner, Set<Account>> accounts;
|
private final Map<Owner, Set<Account>> accounts;
|
||||||
|
|
||||||
private Bank(String blz, String name) {
|
Bank(String blz, String name) {
|
||||||
this.blz = blz;
|
this.blz = blz;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.accounts = new HashMap<>();
|
this.accounts = new HashMap<>();
|
||||||
|
@ -22,6 +22,12 @@ public final class Bank {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addAccount(Owner owner, Account account) {
|
||||||
|
var set = this.accounts.getOrDefault(owner, new HashSet<>());
|
||||||
|
set.add(account);
|
||||||
|
this.accounts.put(owner, set);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (obj instanceof Bank) {
|
if (obj instanceof Bank) {
|
||||||
|
@ -39,7 +45,7 @@ public final class Bank {
|
||||||
return accounts.get(owner).toArray(Account[]::new);
|
return accounts.get(owner).toArray(Account[]::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String validateBlz(String maybeBlz) {
|
public static String validateBlz(String maybeBlz) {
|
||||||
var builder = new StringBuilder();
|
var builder = new StringBuilder();
|
||||||
maybeBlz.trim().chars().filter(ch -> Character.isDigit(ch) || Character.isLetter(ch)).forEach(builder::append);
|
maybeBlz.trim().chars().filter(ch -> Character.isDigit(ch) || Character.isLetter(ch)).forEach(builder::append);
|
||||||
var blz = builder.toString();
|
var blz = builder.toString();
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
package me.teridax.jcash.banking;
|
package me.teridax.jcash.banking;
|
||||||
|
|
||||||
import java.io.File;
|
import me.teridax.jcash.decode.Decoder;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.util.ArrayList;
|
import java.nio.file.Path;
|
||||||
import java.util.HashSet;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public final class BankingManagementSystem {
|
public final class BankingManagementSystem {
|
||||||
|
|
||||||
|
@ -16,22 +15,43 @@ public final class BankingManagementSystem {
|
||||||
this.banks = new HashSet<>();
|
this.banks = new HashSet<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BankingManagementSystem loadFromCsv(File file) {
|
private static String[] tail(String[] array, int index) {
|
||||||
|
return Arrays.stream(array).skip(index).toArray(String[]::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BankingManagementSystem loadFromCsv(Path file) {
|
||||||
try {
|
try {
|
||||||
var content = Files.readString(file.toPath());
|
var bms = new BankingManagementSystem();
|
||||||
|
var content = Files.readString(file);
|
||||||
|
|
||||||
var banks = new ArrayList<Bank>();
|
content.lines().skip(1).forEach(line -> {
|
||||||
|
var columns = line.split(";");
|
||||||
|
|
||||||
content.lines().forEach(line -> {
|
if (columns.length != 14)
|
||||||
// load bank and account from line.
|
throw new IllegalArgumentException("invalid column count: " + columns.length);
|
||||||
// transfer accounts to existing bank if already created
|
|
||||||
|
var owner = Owner.fromColumns(tail(columns, 8));
|
||||||
|
var account = Account.fromColumns(tail(columns, 2));
|
||||||
|
|
||||||
|
var blz = Bank.validateBlz(columns[1]);
|
||||||
|
var name = Decoder.decodeName(columns[0]);
|
||||||
|
var bankOfLine = new Bank(blz, name);
|
||||||
|
|
||||||
|
var bankOfSet = bms.banks.stream().filter(b -> b.equals(bankOfLine)).findFirst();
|
||||||
|
if (bankOfSet.isPresent()) {
|
||||||
|
bankOfSet.get().addAccount(owner, account);
|
||||||
|
} else {
|
||||||
|
bankOfLine.addAccount(owner, account);
|
||||||
|
bms.banks.add(bankOfLine);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
} catch (IOException e) {
|
return bms;
|
||||||
throw new IllegalArgumentException("Could not read file " + file);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
} catch (IOException e) {
|
||||||
|
throw new IllegalArgumentException("Could not read file " + file, e);
|
||||||
|
} catch (IllegalArgumentException | NullPointerException e) {
|
||||||
|
throw new IllegalArgumentException("Could not parse file " + file, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,8 @@ public class Girokonto extends Account {
|
||||||
|
|
||||||
private final double overdraft;
|
private final double overdraft;
|
||||||
|
|
||||||
public Girokonto(int iban, int pin, double overdraft) {
|
public Girokonto(int iban, int pin, double balance, double overdraft) {
|
||||||
super(iban, pin);
|
super(iban, pin, balance);
|
||||||
this.overdraft = overdraft;
|
this.overdraft = overdraft;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package me.teridax.jcash.banking;
|
package me.teridax.jcash.banking;
|
||||||
|
|
||||||
|
import me.teridax.jcash.decode.Decoder;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
|
@ -11,9 +13,7 @@ public final class Owner {
|
||||||
private int zip;
|
private int zip;
|
||||||
private String city;
|
private String city;
|
||||||
|
|
||||||
private Owner() { }
|
private Owner(int uid, String familyName, String name, int zip, String city, String street) {
|
||||||
|
|
||||||
public Owner(int uid, String familyName, String name, int zip, String city, String street) {
|
|
||||||
this.uid = uid;
|
this.uid = uid;
|
||||||
this.familyName = familyName;
|
this.familyName = familyName;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
@ -22,6 +22,22 @@ public final class Owner {
|
||||||
this.street = street;
|
this.street = street;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Owner fromColumns(String... columns) throws IllegalArgumentException, NullPointerException {
|
||||||
|
Objects.requireNonNull(columns);
|
||||||
|
|
||||||
|
if (columns.length != 6)
|
||||||
|
throw new IllegalArgumentException("Invalid number of columns: " + columns.length);
|
||||||
|
|
||||||
|
var uid = Decoder.decodeUniqueIdentificationNumber(columns[0]);
|
||||||
|
var familyName = Decoder.decodeName(columns[1]);
|
||||||
|
var name = Decoder.decodeName(columns[2]);
|
||||||
|
var street = Decoder.decodeStreet(columns[3]);
|
||||||
|
var zip = Decoder.decodeUniqueIdentificationNumber(columns[4]);
|
||||||
|
var city = Decoder.decodeName(columns[5]);
|
||||||
|
|
||||||
|
return new Owner(uid, familyName, name, zip, city, street);
|
||||||
|
}
|
||||||
|
|
||||||
public long getUid() {
|
public long getUid() {
|
||||||
return uid;
|
return uid;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,8 @@ public class SavingsAccount extends Account {
|
||||||
|
|
||||||
private final double interest;
|
private final double interest;
|
||||||
|
|
||||||
public SavingsAccount(int iban, int pin, double interest) {
|
public SavingsAccount(int iban, int pin, double balance, double interest) {
|
||||||
super(iban, pin);
|
super(iban, pin, balance);
|
||||||
this.interest = interest;
|
this.interest = interest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
package me.teridax.jcash.banking;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
public class Testing {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
BankingManagementSystem.loadFromCsv(Paths.get("res/BankCSV_etwurf.csv"));
|
||||||
|
}
|
||||||
|
}
|
|
@ -38,7 +38,7 @@ public class Decoder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int decodeSerialNumber(String number) throws IllegalArgumentException, NullPointerException {
|
public static int decodeUniqueIdentificationNumber(String number) throws IllegalArgumentException, NullPointerException {
|
||||||
Objects.requireNonNull(number);
|
Objects.requireNonNull(number);
|
||||||
|
|
||||||
// check if the string is a valid unsigned number
|
// check if the string is a valid unsigned number
|
||||||
|
@ -57,11 +57,13 @@ public class Decoder {
|
||||||
|
|
||||||
var trimmed = name.trim();
|
var trimmed = name.trim();
|
||||||
|
|
||||||
// check if the string is a valid unsigned number
|
var pattern = Pattern.compile("[\\w-\\s]+", Pattern.CASE_INSENSITIVE);
|
||||||
if (!trimmed.trim().chars().allMatch(Character::isLetter))
|
var matcher = pattern.matcher(trimmed);
|
||||||
throw new IllegalArgumentException("Not a valid name: " + name);
|
if (matcher.find()) {
|
||||||
|
return matcher.group();
|
||||||
return trimmed;
|
} else {
|
||||||
|
throw new IllegalArgumentException("not a void name");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String decodeStreet(String street) throws IllegalArgumentException, NullPointerException {
|
public static String decodeStreet(String street) throws IllegalArgumentException, NullPointerException {
|
||||||
|
@ -78,9 +80,9 @@ public class Decoder {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDecodeSuccessfulFunctions() {
|
public void testDecodeSuccessfulFunctions() {
|
||||||
decodeSerialNumber("95786978625347895");
|
decodeUniqueIdentificationNumber("95786978625347895");
|
||||||
decodeSerialNumber(" 927856347 ");
|
decodeUniqueIdentificationNumber(" 927856347 ");
|
||||||
decodeSerialNumber("0");
|
decodeUniqueIdentificationNumber("0");
|
||||||
|
|
||||||
decodeName("Adolf");
|
decodeName("Adolf");
|
||||||
decodeName("Günther");
|
decodeName("Günther");
|
||||||
|
@ -101,10 +103,10 @@ public class Decoder {
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test(expected = IllegalArgumentException.class)
|
||||||
public void testDecodeInvalidFunctions() {
|
public void testDecodeInvalidFunctions() {
|
||||||
decodeSerialNumber("q0948tvb6q047t 740 t74z0tz 784");
|
decodeUniqueIdentificationNumber("q0948tvb6q047t 740 t74z0tz 784");
|
||||||
decodeSerialNumber("-39867.8475");
|
decodeUniqueIdentificationNumber("-39867.8475");
|
||||||
decodeSerialNumber("-398678475");
|
decodeUniqueIdentificationNumber("-398678475");
|
||||||
decodeSerialNumber(" ß9qu908t76q34798t6q734vb9843");
|
decodeUniqueIdentificationNumber(" ß9qu908t76q34798t6q734vb9843");
|
||||||
|
|
||||||
decodeName("John Doe");
|
decodeName("John Doe");
|
||||||
decodeName("3490qt67v 0b34");
|
decodeName("3490qt67v 0b34");
|
||||||
|
|
Loading…
Reference in New Issue