From ba0ed06ec025b98fc40073aaef159ad9071220a5 Mon Sep 17 00:00:00 2001 From: Andre Velkov Janusev Date: Wed, 20 Aug 2025 10:08:22 +0200 Subject: [PATCH 1/6] inital model and tests compl --- src/main/java/com/booleanuk/core/Account.java | 73 ++++++++++++++++++ .../java/com/booleanuk/core/Transaction.java | 4 + .../core/diagrams/domain-model-1.0.md | 29 +++++++ .../core/diagrams/initial-classDiagram.png | Bin 0 -> 64064 bytes .../java/com/booleanuk/core/AccountTest.java | 52 +++++++++++++ 5 files changed, 158 insertions(+) create mode 100644 src/main/java/com/booleanuk/core/Account.java create mode 100644 src/main/java/com/booleanuk/core/Transaction.java create mode 100644 src/main/java/com/booleanuk/core/diagrams/domain-model-1.0.md create mode 100644 src/main/java/com/booleanuk/core/diagrams/initial-classDiagram.png create mode 100644 src/test/java/com/booleanuk/core/AccountTest.java diff --git a/src/main/java/com/booleanuk/core/Account.java b/src/main/java/com/booleanuk/core/Account.java new file mode 100644 index 000000000..973ba52d7 --- /dev/null +++ b/src/main/java/com/booleanuk/core/Account.java @@ -0,0 +1,73 @@ +package com.booleanuk.core; + +import java.util.Date; +import java.util.HashMap; + +public class Account { + private int accountId; + private int balance = 0; + private String accountType; + private HashMap transactionHashMap = null; + + public Account(int accountId, String accountType) { + this.accountId = accountId; + this.accountType = accountType; + } + + public Account(int accountId, String accountType, int balance) { + this.accountId = accountId; + this.accountType = accountType; + this.balance = balance; + } + + public Boolean deposit(int amount) { + return null; + } + + public Boolean withdraw(int amount) { + return null; + } + + public void addTransaction(int amount) { + + } + + // GETTERS & SETTERS + + public int getAccountId() { + return accountId; + } + + public void setAccountId(int accountId) { + this.accountId = accountId; + } + + public int getBalance() { + return balance; + } + + public void setBalance(int balance) { + this.balance = balance; + } + + public String getAccountType() { + return accountType; + } + + public void setAccountType(String accountType) { + this.accountType = accountType; + } + + public HashMap getTransactionHashMap() { + return transactionHashMap; + } + + public void setTransactionHashMap(HashMap transactionHashMap) { + this.transactionHashMap = transactionHashMap; + } + + public void generateBankStatement() { + + } + +} diff --git a/src/main/java/com/booleanuk/core/Transaction.java b/src/main/java/com/booleanuk/core/Transaction.java new file mode 100644 index 000000000..a85f5696b --- /dev/null +++ b/src/main/java/com/booleanuk/core/Transaction.java @@ -0,0 +1,4 @@ +package com.booleanuk.core; + +public class Transaction { +} diff --git a/src/main/java/com/booleanuk/core/diagrams/domain-model-1.0.md b/src/main/java/com/booleanuk/core/diagrams/domain-model-1.0.md new file mode 100644 index 000000000..c9c30ab76 --- /dev/null +++ b/src/main/java/com/booleanuk/core/diagrams/domain-model-1.0.md @@ -0,0 +1,29 @@ +Class , member , method , scenario, output + +| Class | Member | Method | Scenario | Output | +| Customer | | createACurrentAccount() | Create a current acc | boolean | +| | | createASavingsAccount() | Create a savings acc | boolean | +| | | createASavingsAccount() | Create a savings acc | boolean | + + + +| **Class** | **Member** | **Method** | **Scenario** | **Output** | +| --------------- |------------------------------|-------------------------------|--------------------------------------------------------------------------|---------------| +| **Customer** | `customerId` | `createACurrentAccount()` | As a customer, I want to create a current account. | `bool` | +| | `List` | `createASavingsAccount()` | As a customer, I want to create a savings account. | `bool` | +| | `` | `depositToSavings()` | As a customer, I want to deposit to a savings account. | `bool` | +| | `` | `depositToCurrent()` | As a customer, I want to deposit to a current account. | `bool` | +| | `` | `withdrawFromCurrent()` | As a customer, I want to withdraw from current. | `int` | +| | `` | `withdrawFromSavings()` | As a customer, I want to withdraw from svaings. | `int` | +| **Account** | `accountId` | `deposit(amount)` | As a customer, I want to deposit funds. | `boolean` | +| | `balance` | `withdraw(amount)` | As a customer, I want to withdraw funds. | `boolean` | +| | `accountType` | `generateBankStatement()` | As a customer, I want to generate bank statements. | `void` | +| | `` | `createCurrentAccount()` | As a customer, I want to create a current account. | `void` | +| | `` | `createSavingsAccount()` | As a customer, I want to create a savings account. | `void` | +| | `HashMap` | `addTransaction(transaction)` | On account transaction, store the data for future statement. | `void` | +| **Transaction** | `transactionId` | `getTransactionDetails()` | As a customer, I want to view a transaction. | `Transaction` | +| | `amount` | `getTransactionAmount()` | As a customer, I want to see the transaction amount. | `decimal` | +| | `date` | `getTransactionDate()` | As a customer, I want to see the date of the transaction. | `Date` | +| | `type` | `getTransactionType()` | As a customer, I want to see the type (debit/credit) of the transaction. | `type` | + +[//]: # (TODO: remove create account from Account class) \ No newline at end of file diff --git a/src/main/java/com/booleanuk/core/diagrams/initial-classDiagram.png b/src/main/java/com/booleanuk/core/diagrams/initial-classDiagram.png new file mode 100644 index 0000000000000000000000000000000000000000..3a2f71d28e2b0359037d6ece418c8b9027db6a46 GIT binary patch literal 64064 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⪙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 U acc.setAccountType("test")); + assertThrows(IllegalArgumentException.class, () -> acc.setBalance(-530)); + } + + @Test + public void depositAndUpdateAccountBalance() { + Account acc = new Account(1, "savings", 444); + + assertTrue(acc.deposit(5000)); + assertEquals(5444, acc.getBalance()); + assertTrue(acc.deposit(54)); + assertEquals(6000, acc.getBalance()); + assertFalse(acc.deposit(-54)); + assertFalse(acc.deposit(0)); + } + + @Test + public void withdrawAndUpdateAccountBalance() { + Account acc = new Account(1, "savings", 444); + + assertTrue(acc.withdraw(400)); + assertEquals(44, acc.getBalance()); + assertTrue(acc.deposit(54)); + assertTrue(acc.withdraw(4)); + assertEquals(94, acc.getBalance()); + } + + @Test + public void withdrawLessThanBalance() { + Account acc = new Account(1, "savings", 444); + + assertFalse(acc.withdraw(1000)); + assertFalse(acc.withdraw(-1000)); + assertFalse(acc.withdraw(0)); + assertTrue(acc.withdraw(44)); + assertTrue(acc.withdraw(400)); + assertFalse(acc.withdraw(1)); + } + +} From d0122588c7bafd166c4e11e027693942e73464bc Mon Sep 17 00:00:00 2001 From: Andre Velkov Janusev Date: Wed, 20 Aug 2025 11:25:48 +0200 Subject: [PATCH 2/6] code passing tests and minor updates to test cases and classes --- src/main/java/com/booleanuk/core/Account.java | 92 +++++++++++++----- .../java/com/booleanuk/core/Customer.java | 28 ++++++ .../java/com/booleanuk/core/Transaction.java | 46 +++++++++ .../core/bank-statement-printout.png | Bin 0 -> 10791 bytes .../core/diagrams/domain-model-1.0.md | 45 +++------ .../java/com/booleanuk/core/AccountTest.java | 50 +++++++--- .../java/com/booleanuk/core/CustomerTest.java | 19 ++++ 7 files changed, 213 insertions(+), 67 deletions(-) create mode 100644 src/main/java/com/booleanuk/core/Customer.java create mode 100644 src/main/java/com/booleanuk/core/bank-statement-printout.png create mode 100644 src/test/java/com/booleanuk/core/CustomerTest.java diff --git a/src/main/java/com/booleanuk/core/Account.java b/src/main/java/com/booleanuk/core/Account.java index 973ba52d7..4ba00ea22 100644 --- a/src/main/java/com/booleanuk/core/Account.java +++ b/src/main/java/com/booleanuk/core/Account.java @@ -1,35 +1,79 @@ package com.booleanuk.core; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.util.ArrayList; import java.util.Date; -import java.util.HashMap; +import java.util.List; public class Account { private int accountId; private int balance = 0; private String accountType; - private HashMap transactionHashMap = null; + private List transactionList = new ArrayList<>(); - public Account(int accountId, String accountType) { - this.accountId = accountId; - this.accountType = accountType; + public Account(int accountId, String accountType, int balance) { + setAccountId(accountId); + setAccountType(accountType); + + if (balance < 0) + throw new IllegalArgumentException("Initial balance cant be less than 0"); + else + setBalance(balance); } - public Account(int accountId, String accountType, int balance) { - this.accountId = accountId; - this.accountType = accountType; - this.balance = balance; + public Account(int accountId, String accountType) { + setAccountId(accountId); + setAccountType(accountType); } - public Boolean deposit(int amount) { - return null; + public int deposit(int amount) { + if (amount <= 0){ + System.out.println("Deposit must be larger than 0.."); + return 0; + } + addTransaction(amount, "debit"); + return this.balance += amount; } - public Boolean withdraw(int amount) { - return null; + public int withdraw(int amount) { + if (amount < 0) { + System.out.println("Cant withdraw a negative value.."); + return 0; + } + + if (this.balance >= amount) { + balance -= amount; + addTransaction(amount, "credit"); + return amount; + } else { + System.out.println("Cant withdraw amount, balance too low.."); + return 0; + } } - public void addTransaction(int amount) { + public void addTransaction(int amount, String type) { + if (!type.toLowerCase().trim().equals("debit") && !type.toLowerCase().trim().equals("credit")) { + type = "unknown"; + } + Date today = new Date(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + String formattedDate = sdf.format(today); + Transaction transaction = new Transaction(amount, formattedDate, type); // amount, date, type + transactionList.add(transaction); + } + + public void generateBankStatement() { + System.out.printf("%-20s %-10s %-10s %-10s\n", "Date", "Credit", "Debit", "Balance"); + + for (Transaction t : transactionList) { + if (t.getType().equals("debit")) { + System.out.printf("%-20s %-10s %-10s %-10s\n", t.getDate(), " ", t.getAmount(), this.getBalance()); + } else if (t.getType().equals("credit")) { + System.out.printf("%-20s %-10s %-10s %-10s\n", t.getDate(), t.getAmount(), " ", this.getBalance()); + } + } } // GETTERS & SETTERS @@ -55,19 +99,21 @@ public String getAccountType() { } public void setAccountType(String accountType) { - this.accountType = accountType; + switch (accountType) { + case "savings", "current": + this.accountType = accountType; + break; + default: + throw new IllegalArgumentException("Unexpected value: " + accountType); + } } - public HashMap getTransactionHashMap() { - return transactionHashMap; + public List getTransactionList() { + return transactionList; } - public void setTransactionHashMap(HashMap transactionHashMap) { - this.transactionHashMap = transactionHashMap; - } - - public void generateBankStatement() { - + public void setTransactionList(List transactionList) { + this.transactionList = transactionList; } } diff --git a/src/main/java/com/booleanuk/core/Customer.java b/src/main/java/com/booleanuk/core/Customer.java new file mode 100644 index 000000000..1c2ce94af --- /dev/null +++ b/src/main/java/com/booleanuk/core/Customer.java @@ -0,0 +1,28 @@ +package com.booleanuk.core; + +import java.util.UUID; + +public class Customer { + private String id; + private Account account; + + public Customer() { + this.id = UUID.randomUUID().toString(); + } + + public void createAccount(int id, String type, int balance) { + this.account = new Account(1, type, balance); + } + + public void viewBankStatements() { + this.account.generateBankStatement(); + } + + public void depositToAccount(int amount) { + this.account.deposit(amount); + } + + public void withdrawFromAccount(int amount) { + this.account.withdraw(amount); + } +} diff --git a/src/main/java/com/booleanuk/core/Transaction.java b/src/main/java/com/booleanuk/core/Transaction.java index a85f5696b..6ee34b5ac 100644 --- a/src/main/java/com/booleanuk/core/Transaction.java +++ b/src/main/java/com/booleanuk/core/Transaction.java @@ -1,4 +1,50 @@ package com.booleanuk.core; +import java.util.Date; +import java.util.UUID; + public class Transaction { + private String id; + private int amount; + private String date; + private String type; + + public Transaction(int amount, String date, String type) { + this.id = UUID.randomUUID().toString(); + this.amount = amount; + this.date = date; + this.type = type; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getDate() { + return this.date; + } + + public void setDate(String date) { + this.date = date; + } + + public int getAmount() { + return amount; + } + + public void setAmount(int amount) { + this.amount = amount; + } } diff --git a/src/main/java/com/booleanuk/core/bank-statement-printout.png b/src/main/java/com/booleanuk/core/bank-statement-printout.png new file mode 100644 index 0000000000000000000000000000000000000000..f11a17bc3b1c4c6d03cede8d55e3fab67ecdc6ae GIT binary patch literal 10791 zcmcI~cU05swykbOI)vWAAc!>Sg0yTx02QQ(KoAJMBOnM!Nu&fqFDgYr1OZWc?;yP? zy@OPd-XWnSxj{W=+;h)<_uY5SegBAq-(ak-tTor1bA4gjnrf6}tYjB1T%f#r2cmo7 z!o>{2|MN+%5dPg0@TIzNfq&~RL`l!vbTjqz0o`2;J`G_7zI#Kd;YzXSb9%r{BP$a~ z5Q-#Wfe89NJ693qeX;N&!$l|nU_t|s42(6q18!9V;m1zjB=cB_OC)pZkH@*fy&pEE z-1e7MP*_fVd*FfZh>ax)yh;+-AA!F^4Y;fXXl*1VrBQOakYdh9RngE|gcU-wcy?|C z%MQb**s=j`Ax>p=*nn4sc;eY^X&DYW?{V$Gmrp$z3qEl*d}Ql{e&A9nnu{08S@j9R zL)XfE<210` zW_wzUa)9CSMXi|G0wXKOjYc)DXGF8_@S+a!Wye?tJI0KrcE6-jAsIt=YL|p>RW9mr zsky3ko;+a09xesx`-8OCkUY*-Ax2Fi*ZZ48TxzAx4N{tj{7F0ljT;ky2vs=z4B<|- zcaLpnxH!Bxn|-4C9`k+Z#YU$jL}OIf=2ggibSn$3+xK*0a!k*)<)rTZNjb`nc+gJN za6r=(U$F>q{Az7)Odfv)^Q<>HI#`yWawt#&Gix@w+7Uk#fU8&>r`zKrk&;nny%~M> z*%doeZt3fgHt)QAmsuIRZq~tV{LR1>SA8j>$JCD*5xJP0A1yuceZV56DCy zTUwS?M%F5(N<;8#Q-or`1wk1gh2h}=WPgJnFMC!wmx%P%btQw_mtTq?$+637U>(v~bs1OVjlR z?op+{*npcd1EEXFRNqO#nKSr6^tQKAsRX?U%@UfSP0hVsLU|9u%B_#bkLWne+5s)f zVf}dPmIkTQrbiJvvqvqhmZ!xel`&(rWL_5v5kz!eG1nd*+?HAzJ6}I_2bcX93Tz*K z>wD93!TWT)#K6H1wLc9#3y(ic;>dm1b$INn5SdTI+CoSMdN1X#q*77TDm1lw6rRO? z%PE$nwY|}{*$0{vd#0oX<-Yh(hY(UvkU8rUR{Y7JwZe5TVJW<9+ap6#CO1 zc?jNJOCUD*8s|KROo7HFQg6Nqsh&EmjM7I{FXZRgnZpo7*& zQ&pAz^DRbW{yKd6N&r z2Mm8VtjKR0I?v%45at5PKb8ss6ra6XD1@Obe#SAZ1RxQ4XMVGcX9z7i)ib&yOBc}_ zE|nAS)6&U1v<~<^Gw1rZ*lM(R@;M~3m#+G{e9F6d8OSRSHP2Dp`yyYDzI}a*2ytlv zZ@|QTi0hcbPovb_#ZK^rRQovF3Rpi3ZP$CVk#lz(E|j_1^TNA?tLKIDcprJ(=-F#5 z-;4k$O$&@4UIsvNeN7(S$X=`*@ZC&W88F^hFJ$-%F1zJlD(iD{JrSTijeNe~nF294 zv$IziK`MnB%xLqbx_Zyd?WH%rv#`0Gc6$%x$uR3W*Hfz|1GP|^ad}#VFr@UD7J{0P zfW!RYC+JhoVMFrZ)u|X;{asZ_|3@aM;ZrWWrOU*m6_L7K2^fO%_FZe(=#1GMNbJ#7}{lm6ACisO>RW1(jWV!L%jOf`&4lnmOVbkx_ywvRc5a`7qs z{ei;O09!6x6pO8$kGUDMJtMYC72vQVQuek6bG;uCIHVrRD{}c0Y1~}j3Syd*Z8BuJ zxM-tgqhHF{hxwUg2MblYLy~pIZ(aZ^S#)iz;}pMvyPY z^c9++CYaLAH0=lbQBZs7KI=am|rw zo|hASZFjn`l(3XEQ4fsdm#|5ur3bl<2}hTUAI?)S8Yjokrit`^Q0X;4KqUCrzE4Oi z``+Pg2Rm=(dgGiT=H_J_ODaS~;|1oOs~u)0-i{OW?3ClFh1(f>e*%TnjQXW93?ghL zQYXZ0KAGi)hGdG7{7_RS-tk?p^t~|Rf?c^B88am~RN^h-B*ftB?UIt0W@9h~MI|Te zqlc+pn^Dt=Z3v3R(tWA5CsDv!AH3~ErCi=wYj@1RRwd!>MEMn>Mx5A(tS3cXjf zUdRbE;#6{a7@yDKT`GeFsdK-1TYLiQxfxab&1{KJA0C;AwkC_ChriF9txcFKNh5J4 zG7boROk7~d&E;deDeAWZ`vqA%=Y0W8HkKS{KG^xO?p4k!7MO zc7uWw+hP7;qhiF97~S{@OHvT<|Ro+j>~eZqW{JJ0CiN<`|$p3zXft&4EO zh;MY1Z+_0B(W6d9}TBf=ycaG%VyHZgpte!H3GHvbFycGbdR0B=7TWH}X*{ zdv3k0UjZS)pyEBty0Yz>V3hjJrjbVfq%DDtn?x!zaj!2v&~;ML-%F(Bbo(+}suB&I z-05XIQU$bQDVA6l-LKF&#W0FV4+aQ0l7>5fT{)g3rFiNt^{Vd^NU))dB5=IhRh7Iz z$}Qu#TC)X= z0TV}$Lu%mmGhy21u9+mN(w(TQkZ2Y;hTuQ>6%&m@n_k&VTB~fduU)LNm5nV-_w&S# zEJpNPMR|Yr=?H5JozKty70xOh6 zo>02_Pl(%FwF#qV&)Pu4tKqCPADhDavZO3pK}c11p2rpsLDSKi^p17fYlj9gBEk_@ zD`-=S$uJz(s+jM+Ji|Uah$D`c3suJFVh{-?tS)~K*+b6_KPfrW3B-VsiwV>l5|ETUfJ67l7WP7ntIbTbOk zHof!oB@^*R=(>5@amd7@EU=&bGu?5*TC@OGq_lDB_Ml z3|}t3bYqG`A8xVK;cXA21Y5P;4?RN)z|2;Xm^gPgDi-2*z^`E5K*t?V$}j0mpCpgp zP^GV~@+e+8V*=f8hIg^WcX47YaM3-aBQzS0U|y*3tTf~1~oZ$+sSiOIYwsfT5^Fs^%5B> zL|QFEle0lcBW!sqp*AQQQ=i(r;-KpR%{}tIkZYx6q5l(f9FFg*!y`ipNI=s_QN6iK z%cwe~W2$!{Vv{u_1x_()9kQ`t-ARtL?mYd`uwboRp-O;*m@-DS3PTdJdkJGIq@HIc zIerTPj%QQ?REDvzQ6ZrhxKGe2@zo6i3Y z;nCn8iG^Sji;&$a*Jot2o@*BM4)i)?4Vz}2*go~RXpc@1)UJLij=XcvyU!yLdzk{P z_GnhW{GV`5l>bP8P!b^h8=Fs>2OhFhaD~x&gr@G(GuJ8mM={mvL`NLDOfrlTVD^{IrebHKg-RCs`{-5<` zDVLG(8#GP8t-OhIYqN?PUatx_0XOu&b9`hG?ne-#dZ93xFHxsrE$ub7XOD5elu#(_k2Nhf?3~Wr7iwF^#?NUA>ywr_UTZ|h1DRU<^v`8$-JGV_X)5E#K7?Fu}p`{ zyrB+|Oi)e~ZB2@C{#a6Tqba(PE3v)N;_;Decf=)h%VANUU&}_mF0i3Yp8s#D4uUql zWbx6}o{CVh75RkZBTfdU>ulqNPCY|^w>*O&0Mu;=h)C~dVwU}ZRFkjGui~lGUScxs zWUVu~ydhBUMXxw?Sa84%jpVP3*#mWCV5BuxCd`)PiYo{z zP3KM1kUDL{kUEzwLDO4SjtA7Y4(>R*Sw$c(WLrHmd1=-$i|pp(tZLtWxA2_k*!pX; z_-f(na^V-f1%xCa#4L1iTX+28tJs7)Vn`7SzM+rLSXWyi6$Cja;&PQxRPX&q0~~qd z-qil0V9KY~H(b7a_ty#KY3ki01k?7f5vpJu-z9fF#Cmxcu#9c|7wT19yfZ~#c0fG` zHg|}Oni@W3G68|L41aIyF6nmiR!Q1(r8}+bQ=jy=xSZ??T^Jtsktxb$_q$h9TqpWT zu{v)3_Y{kbywPncddHH20l3$`0`tI_IX9AjK%b`m7kTFocsfkf=vOn^E%~pCCu)H=Xc)2={8@B-gT+yj z^X$?rNpn?Ny0N8SuUX*c0QV17S#4`!rQ&=R1upr3^v4C+dr(5FO-xX7;=BjuQJHL9 zIic~%_{pErum+_7H-dk2)Du5@t)MnzVnNBV`=@7!2`+rxfMEn_~cFO z|0eXb{zw-hbe^9HoOgasA`ehUt39J{N)4YJ%|d!pHmI)-0pl z(4w3fvXp(U{xMH>U%CvYZ;m7rCi_$evpJ9uy8#6${EmLrpo*Yx-({~qNB)q2Ptq7~ zrP2rsc(d9J;5dbb*9v(FD(qp|^e+ZT87tu&JQ^g|6b9dZpiGcM)2K)Djb=g zoQN4FvXn$50!8Q(fZK0Q!xJedSg}Er3WG-M6BfYde<}G&i!@GhZJc{DO9={$Ko-RF zPG5}Rq3BI2K@isI)P+HkWWcQ>jrv0~k*` zBk|1|bTO!ZV6^gK{xoR3-*i@B`YnT>r$+kn6BZ4!hI>T|?jfoFSCaE<-JbS!n^%6W zTzwJyDen=Af`v(R?#Y6t{SJ$DCUDTL0zv9hn3y9S`~^hAe+rg!`oTCq*Hz2xCDH=- ztDH8tD7;(EBWR@hZKuF5bZol=VvuE%{sNc_k~_Z#!(R-ZK%r>L&kjmAMWPOKOKt)e z;?-RbUAVGqyT?39=mqzphbfZcEd)#A8(;3AuGR6?x_%i9@tXN89VohGdt;0_O(Mz6 zw+vMsN2Lc<*LHGL?IYGQ%XyRg(NCYyBeSdlt@^4yh>~;l`!{jc*nmzv!GE%2G?P3c-c)d~EcD6vs&*V=DF1FyhVlCcJNhQFaYCV$xQxnE2~eqqA7jdva? z(6|F0o!ewhQWnv(-;?G54-MV*qc{?QzYfO6OZ{-Ub1$cjY5Y;NVEwj=NMvdYysPs% z^uWs&88pFK=u@lSE{H}oVR;PBpygfnJpEP;gm6}T|hOuYYhu;s{W4rAYi-&dG^ zvDrx%L9uvJv_W8czXcC|PzcKnKoe+x?aQ7$aQx11 zQjPylqN+Knt|8xH3D*>YKGB~?=gpN`k|`winCb333}i@?*nrq4(nZhse9vT#OVWv+ zdcjGNBGuD97+8l}+s(qYwzsfo$js~$^#<&Z3){Po9-2>N6_Z$8GymmO;c6cP#jT7# zKko^X%WATH85eS=V*oo#WG;y zzlHr5un1q_^xt9;8+l@EXhLJ7`43NiTI4#1I_hO1HNlos1F(f9oYDKkJqXquE*FZD zvE;mYw$wfy;bRqUlVZ=o+K!$jdNC16KTw=E%765Bj2oD;5w$8xK1%}ro>crmiR9&i z`^Tru#>uJ=^jjb2aX$CWzI4pmZF??Ut0*iM=h2ept#~TR(`GEN0)X_lAdQPRVU4+Z zi}sg(U2Qz4_2Z%4TSP*UCP zB=%7O5UIa5kj4$GJWNsFhaO!6XTk{;VK4s=ne(q>RbW^!ksJ3=xXN}h4~;N2$l6$_H6H;)ehIOY!Yja%g=}S9 z)X@Jyh?!9RKMAog1m)`c+w;u7s_>)ePuoEmPw-U;`b){_`oHam|Dz7;&L-H3>mlmq z$?!D1)XgL~++49YHiWzdBs!SHU+TTNx{Q+<~PWDjL^SJ4V2}c_GNK>|N~T4V-Og*SXKKCE zq(gVb*nxr5f6vl9k70saZ2T!4a_cpnsz(L~pgNT?r5b;wR1=htLUmBd(ZLyYIHs$p z1c1oDS3-&FOh_U73T_|F%HU&&_!9uT&E}=PqSD@!74hKj9G}!;T4EX|52PAD*}`Rf zMCQ$U;Z_Wzb2Fzd%+)U$N(htUg#fC${V#J*nlzyt!*d$8{p%+eG2anmXcpQ#Unw4Q z&4^OWZd_ugbm4ofN$x!22pOOxR*b1=(YI1EwO4+J6J(Z2O#g_>+siuSAqhlDCxPj0 zY|(C#if=#jjqx2|FDZrdLgY!?tu_Errts~P!0O(TSeWdZ8p5oM|7F#sjXRT3FEcY^ z6}TZOyH^Xe;BBo4b;->JftI8{EF*RF^3-hqd72t@Rd4Ok_7&m2XtoK1eNoj?N@4%B z`7OEH0+$U3aM}K!f<7M_KQBR%Q*35S#3?ZXqZ`Rgu%_yTrc>#{oxD>{BS)%&O>JgI z?!p)hmaDD@n=@Q>y5@u8rB6wxuLR+rhZcG<|D1g`G0Pg{6ZS_Mcy%H5DXGpAO$MV{ zzFm7b8Fimwu*=z?y9JFps*1yUB?TY8`)K4wH??BIrwS1jQkreYZb9Xx37ay{gT?%w zm?l~GPDc6+X=kV`b&b}-B01;o#$)f#{x~`QVhP3{QENwS!kd}i>O2^Kd$x^oRk#f-wBc+zR*WQJAmw+1rnO*-rq?|+XS$geMHK7*R zsQjK`Nchx+I#2Vd(A2r!6M(lG>81$%V}cp88+`>h8PKA}hj%mz0= zWm&=5eIEvKM)MT4+Pkha`v}+rzsmWp3~ zuz!DbYmUG1EBJwCXRoHm-R!*QE{d!$+~1zT zT0u{EJF}AuPn>aYI?Sf)h#=Q?&7%}C5%ktgWh^OOPs1z=O-pFGwi}`3*PqG1hPJJb zb_y&wpo;+Y&T>M2TT+8wm4P;NV}W~S`*xir1{}v;WVv$>|qE~)xzjl62>nO zyDKPj7e&Io)h`68w~Zf*X84u_Q@1jrHQA{%1HY}(zY&ujPm;BJ9JL=Ue_%Ebuih}` z9X-?9HkM0(onDZ3+yi?ap6pL)7_%P-%%5}?6#jmXV=m}gp>R|Uld|nu%g%=j`D&w1 z9D~?)@0$B7&a=Nlj|FV=ZlR^4+vqcn z$1tv=M!|lM*i?;Smk#eIzIuNd#62CyETnapF!Udh0I}C6x{BI@O2`~tx3SWZ#$=B* z?f_Z~V{CwXJ_hqtbBBdy3tMiPA@KnT5GHvoE+DOFT6@bXgC8`d?Opw~Sb#)uhegxg z$a*0?jADxOY}#~IIvpFBH>ZSLDg8u9GivgxDg0Q-B z4v$OMCf~=%A5A~i`_Tu6q6T$9Czsyer znjyHaD_@M;NRY27c%!A_6o^oyy{!Fx2tX8t=lXp_Q zVGd-i^|_%{BVoX(6!`khU^LvO)i4Fp6(~K~Tm(-W≥qB8|Wyh~d z8z)_T=a&&`1El4Pe_7hH6J7q!kRpMS=QfU9jOk&jQwV%5$z}ab% zx?wYKee`!OX;xWMGs)}YOL;$tTUQbRE^zfF?{#ZGt6<6Jz~gMM#TAs8jGp^Dz_ zh)rX>tv`+?-FoYg3{nC#UVn|eA@46Y=0kQ zl$+FGj#RS5?jNsCZ2M|k3InojL2sdLYy$_*QgXg06+YN;&!@n_z2o6Ym{9^fTwGV93$fmPl`&uf(4P4a*uflm{_MP`uti=iDY6zad+z~NM!_kEV%3?eu#9NGet^e7 zrT%@9vXl3)?t^2{!js25aiksk`tu$d^KL;;O+?CA(UY!OUSwRyCj^|{so(FsKWK`; zAx9oyX3W~F|44MFYRO>ofqDvyl$ES~uo>fqd^v~E!IDhZ5apGm2S( a6BEt83c5vCDn)nzdf~2$CZqst7Wg09fC(}H literal 0 HcmV?d00001 diff --git a/src/main/java/com/booleanuk/core/diagrams/domain-model-1.0.md b/src/main/java/com/booleanuk/core/diagrams/domain-model-1.0.md index c9c30ab76..ef005de21 100644 --- a/src/main/java/com/booleanuk/core/diagrams/domain-model-1.0.md +++ b/src/main/java/com/booleanuk/core/diagrams/domain-model-1.0.md @@ -1,29 +1,16 @@ -Class , member , method , scenario, output - -| Class | Member | Method | Scenario | Output | -| Customer | | createACurrentAccount() | Create a current acc | boolean | -| | | createASavingsAccount() | Create a savings acc | boolean | -| | | createASavingsAccount() | Create a savings acc | boolean | - - - -| **Class** | **Member** | **Method** | **Scenario** | **Output** | -| --------------- |------------------------------|-------------------------------|--------------------------------------------------------------------------|---------------| -| **Customer** | `customerId` | `createACurrentAccount()` | As a customer, I want to create a current account. | `bool` | -| | `List` | `createASavingsAccount()` | As a customer, I want to create a savings account. | `bool` | -| | `` | `depositToSavings()` | As a customer, I want to deposit to a savings account. | `bool` | -| | `` | `depositToCurrent()` | As a customer, I want to deposit to a current account. | `bool` | -| | `` | `withdrawFromCurrent()` | As a customer, I want to withdraw from current. | `int` | -| | `` | `withdrawFromSavings()` | As a customer, I want to withdraw from svaings. | `int` | -| **Account** | `accountId` | `deposit(amount)` | As a customer, I want to deposit funds. | `boolean` | -| | `balance` | `withdraw(amount)` | As a customer, I want to withdraw funds. | `boolean` | -| | `accountType` | `generateBankStatement()` | As a customer, I want to generate bank statements. | `void` | -| | `` | `createCurrentAccount()` | As a customer, I want to create a current account. | `void` | -| | `` | `createSavingsAccount()` | As a customer, I want to create a savings account. | `void` | -| | `HashMap` | `addTransaction(transaction)` | On account transaction, store the data for future statement. | `void` | -| **Transaction** | `transactionId` | `getTransactionDetails()` | As a customer, I want to view a transaction. | `Transaction` | -| | `amount` | `getTransactionAmount()` | As a customer, I want to see the transaction amount. | `decimal` | -| | `date` | `getTransactionDate()` | As a customer, I want to see the date of the transaction. | `Date` | -| | `type` | `getTransactionType()` | As a customer, I want to see the type (debit/credit) of the transaction. | `type` | - -[//]: # (TODO: remove create account from Account class) \ No newline at end of file +| **Class** | **Member** | **Method** | **Scenario** | **Output** | +| --------------- |---------------------|-------------------------------|--------------------------------------------------------------------------|---------------| +| **Customer** | `customerId` | `createACurrentAccount()` | As a customer, I want to create a current account. | `bool` | +| | `List` | `createASavingsAccount()` | As a customer, I want to create a savings account. | `bool` | +| | `` | `depositToSavings()` | As a customer, I want to deposit to a savings account. | `bool` | +| | `` | `depositToCurrent()` | As a customer, I want to deposit to a current account. | `bool` | +| | `` | `withdrawFromCurrent()` | As a customer, I want to withdraw from current. | `int` | +| | `` | `withdrawFromSavings()` | As a customer, I want to withdraw from svaings. | `int` | +| **Account** | `accountId` | `deposit(amount)` | As a customer, I want to deposit funds. | `boolean` | +| | `balance` | `withdraw(amount)` | As a customer, I want to withdraw funds. | `boolean` | +| | `accountType` | `generateBankStatement()` | As a customer, I want to generate bank statements. | `void` | +| | `List` | `addTransaction(transaction)` | On account transaction, store the data for future statement. | `void` | +| **Transaction** | `transactionId` | `getTransactionDetails()` | As a customer, I want to view a transaction. | `Transaction` | +| | `amount` | `getTransactionAmount()` | As a customer, I want to see the transaction amount. | `decimal` | +| | `date` | `getTransactionDate()` | As a customer, I want to see the date of the transaction. | `Date` | +| | `type` | `getTransactionType()` | As a customer, I want to see the type (debit/credit) of the transaction. | `type` | diff --git a/src/test/java/com/booleanuk/core/AccountTest.java b/src/test/java/com/booleanuk/core/AccountTest.java index 76ffd5503..5ed5aca17 100644 --- a/src/test/java/com/booleanuk/core/AccountTest.java +++ b/src/test/java/com/booleanuk/core/AccountTest.java @@ -1,6 +1,9 @@ package com.booleanuk.core; import org.junit.jupiter.api.Test; + +import java.util.List; + import static org.junit.jupiter.api.Assertions.*; public class AccountTest { @@ -11,29 +14,29 @@ public void testCreateCurrentAccountWithDataPassVerifications() { assertEquals("savings", acc.getAccountType()); assertEquals(500, acc.getBalance()); assertThrows(IllegalArgumentException.class, () -> acc.setAccountType("test")); - assertThrows(IllegalArgumentException.class, () -> acc.setBalance(-530)); + assertThrows(IllegalArgumentException.class, () -> new Account(2, "current", -500)); } @Test public void depositAndUpdateAccountBalance() { Account acc = new Account(1, "savings", 444); - assertTrue(acc.deposit(5000)); + assertEquals(5444, acc.deposit(5000)); assertEquals(5444, acc.getBalance()); - assertTrue(acc.deposit(54)); - assertEquals(6000, acc.getBalance()); - assertFalse(acc.deposit(-54)); - assertFalse(acc.deposit(0)); + assertEquals(5500, acc.deposit(56)); + assertEquals(5500, acc.getBalance()); + assertEquals(0, acc.deposit(-54)); + assertEquals(0, acc.deposit(0)); } @Test public void withdrawAndUpdateAccountBalance() { Account acc = new Account(1, "savings", 444); - assertTrue(acc.withdraw(400)); + assertEquals(400 ,acc.withdraw(400)); assertEquals(44, acc.getBalance()); - assertTrue(acc.deposit(54)); - assertTrue(acc.withdraw(4)); + assertEquals(98, acc.deposit(54)); + assertEquals(4, acc.withdraw(4)); assertEquals(94, acc.getBalance()); } @@ -41,12 +44,29 @@ public void withdrawAndUpdateAccountBalance() { public void withdrawLessThanBalance() { Account acc = new Account(1, "savings", 444); - assertFalse(acc.withdraw(1000)); - assertFalse(acc.withdraw(-1000)); - assertFalse(acc.withdraw(0)); - assertTrue(acc.withdraw(44)); - assertTrue(acc.withdraw(400)); - assertFalse(acc.withdraw(1)); + assertEquals(0, acc.withdraw(1000)); + assertEquals(0, acc.withdraw(-1000)); + assertEquals(0, acc.withdraw(0)); + assertEquals(44, acc.withdraw(44)); + assertEquals(400, acc.getBalance()); + assertEquals(400, acc.withdraw(400)); + assertEquals(0, acc.withdraw(1)); + } + + @Test + public void createTransaction() { + Account acc = new Account(1, "savings", 500); + acc.addTransaction(500, ""); // unknown type + acc.deposit(300); // deposit = debit + + List list = acc.getTransactionList(); + assertEquals(2, list.size()); + Transaction test = list.getFirst(); + Transaction test2 = list.getLast(); + assertEquals(500, test.getAmount()); + assertEquals("unknown", test.getType()); + assertEquals("debit", test2.getType()); + assertEquals(300, test2.getAmount()); } } diff --git a/src/test/java/com/booleanuk/core/CustomerTest.java b/src/test/java/com/booleanuk/core/CustomerTest.java new file mode 100644 index 000000000..b33af0a82 --- /dev/null +++ b/src/test/java/com/booleanuk/core/CustomerTest.java @@ -0,0 +1,19 @@ +package com.booleanuk.core; + +import org.junit.jupiter.api.Test; + +public class CustomerTest { + + @Test + public void testForStatementPrintout() { + Customer c = new Customer(); + c.createAccount(2, "savings", 500); + c.depositToAccount(300); + c.depositToAccount(100); + c.withdrawFromAccount(150); + c.depositToAccount(500); + c.withdrawFromAccount(400); + + c.viewBankStatements(); + } +} From a81f25def892790697f65445f052b856b557d091 Mon Sep 17 00:00:00 2001 From: Andre Velkov Janusev Date: Wed, 20 Aug 2025 11:30:18 +0200 Subject: [PATCH 3/6] fix printout balance now correct --- src/main/java/com/booleanuk/core/Account.java | 6 +++--- .../java/com/booleanuk/core/Transaction.java | 8 +++++++- .../core/bank-statement-printout.png | Bin 10791 -> 11026 bytes 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/booleanuk/core/Account.java b/src/main/java/com/booleanuk/core/Account.java index 4ba00ea22..fb4f9398e 100644 --- a/src/main/java/com/booleanuk/core/Account.java +++ b/src/main/java/com/booleanuk/core/Account.java @@ -60,7 +60,7 @@ public void addTransaction(int amount, String type) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); String formattedDate = sdf.format(today); - Transaction transaction = new Transaction(amount, formattedDate, type); // amount, date, type + Transaction transaction = new Transaction(amount, this.balance, formattedDate, type); // amount, date, type transactionList.add(transaction); } @@ -69,9 +69,9 @@ public void generateBankStatement() { for (Transaction t : transactionList) { if (t.getType().equals("debit")) { - System.out.printf("%-20s %-10s %-10s %-10s\n", t.getDate(), " ", t.getAmount(), this.getBalance()); + System.out.printf("%-20s %-10s %-10s %-10s\n", t.getDate(), " ", t.getAmount(), t.getBalance()); } else if (t.getType().equals("credit")) { - System.out.printf("%-20s %-10s %-10s %-10s\n", t.getDate(), t.getAmount(), " ", this.getBalance()); + System.out.printf("%-20s %-10s %-10s %-10s\n", t.getDate(), t.getAmount(), " ", t.getBalance()); } } } diff --git a/src/main/java/com/booleanuk/core/Transaction.java b/src/main/java/com/booleanuk/core/Transaction.java index 6ee34b5ac..b2c1ca029 100644 --- a/src/main/java/com/booleanuk/core/Transaction.java +++ b/src/main/java/com/booleanuk/core/Transaction.java @@ -8,14 +8,20 @@ public class Transaction { private int amount; private String date; private String type; + private int balance; - public Transaction(int amount, String date, String type) { + public Transaction(int amount, int balance, String date, String type) { this.id = UUID.randomUUID().toString(); this.amount = amount; + this.balance = balance; this.date = date; this.type = type; } + public int getBalance() { + return this.balance; + } + public String getId() { return id; } diff --git a/src/main/java/com/booleanuk/core/bank-statement-printout.png b/src/main/java/com/booleanuk/core/bank-statement-printout.png index f11a17bc3b1c4c6d03cede8d55e3fab67ecdc6ae..697a2887a1ef733bc2f004bd488b732f3ab9c95a 100644 GIT binary patch literal 11026 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≥qB8|Wyh~d z8z)_T=a&&`1El4Pe_7hH6J7q!kRpMS=QfU9jOk&jQwV%5$z}ab% zx?wYKee`!OX;xWMGs)}YOL;$tTUQbRE^zfF?{#ZGt6<6Jz~gMM#TAs8jGp^Dz_ zh)rX>tv`+?-FoYg3{nC#UVn|eA@46Y=0kQ zl$+FGj#RS5?jNsCZ2M|k3InojL2sdLYy$_*QgXg06+YN;&!@n_z2o6Ym{9^fTwGV93$fmPl`&uf(4P4a*uflm{_MP`uti=iDY6zad+z~NM!_kEV%3?eu#9NGet^e7 zrT%@9vXl3)?t^2{!js25aiksk`tu$d^KL;;O+?CA(UY!OUSwRyCj^|{so(FsKWK`; zAx9oyX3W~F|44MFYRO>ofqDvyl$ES~uo>fqd^v~E!IDhZ5apGm2S( a6BEt83c5vCDn)nzdf~2$CZqst7Wg09fC(}H From e3cd317e8f633ad19b23d4bf8ed833d111967270 Mon Sep 17 00:00:00 2001 From: Andre Velkov Janusev Date: Wed, 20 Aug 2025 13:19:50 +0200 Subject: [PATCH 4/6] add extension classes and test case -> next impl to pass tests --- src/main/java/com/booleanuk/core/Account.java | 29 ++++++----- src/main/java/com/booleanuk/core/Branch.java | 50 +++++++++++++++++++ .../java/com/booleanuk/core/Transaction.java | 9 ++-- .../com/booleanuk/core/Users/BankManager.java | 24 +++++++++ .../booleanuk/core/{ => Users}/Customer.java | 6 ++- .../com/booleanuk/core/Users/Engineer.java | 44 ++++++++++++++++ .../java/com/booleanuk/core/Users/User.java | 10 ++++ .../core/diagrams/domain-model-1.0.md | 33 +++++++++++- .../java/com/booleanuk/core/AccountTest.java | 12 ++--- .../com/booleanuk/core/BankManagerTest.java | 24 +++++++++ .../java/com/booleanuk/core/CustomerTest.java | 1 + .../java/com/booleanuk/core/EngineerTest.java | 27 ++++++++++ 12 files changed, 244 insertions(+), 25 deletions(-) create mode 100644 src/main/java/com/booleanuk/core/Branch.java create mode 100644 src/main/java/com/booleanuk/core/Users/BankManager.java rename src/main/java/com/booleanuk/core/{ => Users}/Customer.java (81%) create mode 100644 src/main/java/com/booleanuk/core/Users/Engineer.java create mode 100644 src/main/java/com/booleanuk/core/Users/User.java create mode 100644 src/test/java/com/booleanuk/core/BankManagerTest.java create mode 100644 src/test/java/com/booleanuk/core/EngineerTest.java diff --git a/src/main/java/com/booleanuk/core/Account.java b/src/main/java/com/booleanuk/core/Account.java index fb4f9398e..94e022f52 100644 --- a/src/main/java/com/booleanuk/core/Account.java +++ b/src/main/java/com/booleanuk/core/Account.java @@ -5,15 +5,16 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.UUID; public class Account { - private int accountId; + private String accountId; private int balance = 0; private String accountType; private List transactionList = new ArrayList<>(); - public Account(int accountId, String accountType, int balance) { - setAccountId(accountId); + public Account(String accountType, int balance) { + this.accountId = UUID.randomUUID().toString(); setAccountType(accountType); if (balance < 0) @@ -22,8 +23,8 @@ public Account(int accountId, String accountType, int balance) { setBalance(balance); } - public Account(int accountId, String accountType) { - setAccountId(accountId); + public Account(String accountId, String accountType) { + this.accountId = UUID.randomUUID().toString(); setAccountType(accountType); } @@ -56,16 +57,19 @@ public void addTransaction(int amount, String type) { if (!type.toLowerCase().trim().equals("debit") && !type.toLowerCase().trim().equals("credit")) { type = "unknown"; } - Date today = new Date(); - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); - String formattedDate = sdf.format(today); - Transaction transaction = new Transaction(amount, this.balance, formattedDate, type); // amount, date, type + LocalDate today = LocalDate.now(); +// System.out.println(today); +// Date today = new Date(); +// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); +// String formattedDate = sdf.format(today); + + Transaction transaction = new Transaction(amount, this.balance, today, type); // amount, date, type transactionList.add(transaction); } public void generateBankStatement() { - System.out.printf("%-20s %-10s %-10s %-10s\n", "Date", "Credit", "Debit", "Balance"); + System.out.printf("\n%-20s %-10s %-10s %-10s\n", "Date", "Credit", "Debit", "Balance"); for (Transaction t : transactionList) { if (t.getType().equals("debit")) { @@ -74,15 +78,16 @@ public void generateBankStatement() { System.out.printf("%-20s %-10s %-10s %-10s\n", t.getDate(), t.getAmount(), " ", t.getBalance()); } } + System.out.println("\n"); } // GETTERS & SETTERS - public int getAccountId() { + public String getAccountId() { return accountId; } - public void setAccountId(int accountId) { + public void setAccountId(String accountId) { this.accountId = accountId; } diff --git a/src/main/java/com/booleanuk/core/Branch.java b/src/main/java/com/booleanuk/core/Branch.java new file mode 100644 index 000000000..88dbf1a69 --- /dev/null +++ b/src/main/java/com/booleanuk/core/Branch.java @@ -0,0 +1,50 @@ +package com.booleanuk.core; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +public class Branch { + private String id; + private String name; + private String location; + private List accounts = new ArrayList<>(); + + public Branch(String location, String name) { + this.id = UUID.randomUUID().toString(); + this.location = location; + this.name = name; + } + + public List getAccounts() { + return accounts; + } + + public void setAccounts(List accounts) { + this.accounts = accounts; + } + + public String getLocation() { + return location; + } + + public void setLocation(String location) { + this.location = location; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } +} diff --git a/src/main/java/com/booleanuk/core/Transaction.java b/src/main/java/com/booleanuk/core/Transaction.java index b2c1ca029..19c9445d4 100644 --- a/src/main/java/com/booleanuk/core/Transaction.java +++ b/src/main/java/com/booleanuk/core/Transaction.java @@ -1,16 +1,17 @@ package com.booleanuk.core; +import java.time.LocalDate; import java.util.Date; import java.util.UUID; public class Transaction { private String id; private int amount; - private String date; + private LocalDate date; private String type; private int balance; - public Transaction(int amount, int balance, String date, String type) { + public Transaction(int amount, int balance, LocalDate date, String type) { this.id = UUID.randomUUID().toString(); this.amount = amount; this.balance = balance; @@ -38,11 +39,11 @@ public void setType(String type) { this.type = type; } - public String getDate() { + public LocalDate getDate() { return this.date; } - public void setDate(String date) { + public void setDate(LocalDate date) { this.date = date; } diff --git a/src/main/java/com/booleanuk/core/Users/BankManager.java b/src/main/java/com/booleanuk/core/Users/BankManager.java new file mode 100644 index 000000000..ee4e5d7cf --- /dev/null +++ b/src/main/java/com/booleanuk/core/Users/BankManager.java @@ -0,0 +1,24 @@ +package com.booleanuk.core.Users; + +import com.booleanuk.core.Account; +import com.booleanuk.core.Branch; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +public class BankManager { + private String id; + List branches = new ArrayList<>(); + + public BankManager() { + this.id = UUID.randomUUID().toString(); + } + + // Approve if within balance range, if above double balance, deny + public Boolean verifyOverdraftRequest(Account account, int amount) { + + return null; + } + +} diff --git a/src/main/java/com/booleanuk/core/Customer.java b/src/main/java/com/booleanuk/core/Users/Customer.java similarity index 81% rename from src/main/java/com/booleanuk/core/Customer.java rename to src/main/java/com/booleanuk/core/Users/Customer.java index 1c2ce94af..5fee1bbc8 100644 --- a/src/main/java/com/booleanuk/core/Customer.java +++ b/src/main/java/com/booleanuk/core/Users/Customer.java @@ -1,4 +1,6 @@ -package com.booleanuk.core; +package com.booleanuk.core.Users; + +import com.booleanuk.core.Account; import java.util.UUID; @@ -11,7 +13,7 @@ public Customer() { } public void createAccount(int id, String type, int balance) { - this.account = new Account(1, type, balance); + this.account = new Account(type, balance); } public void viewBankStatements() { diff --git a/src/main/java/com/booleanuk/core/Users/Engineer.java b/src/main/java/com/booleanuk/core/Users/Engineer.java new file mode 100644 index 000000000..03692232f --- /dev/null +++ b/src/main/java/com/booleanuk/core/Users/Engineer.java @@ -0,0 +1,44 @@ +package com.booleanuk.core.Users; + +import com.booleanuk.core.Account; +import com.booleanuk.core.Transaction; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +public class Engineer { + private String id; + private List accountList = new ArrayList<>(); + + public Engineer(List list) { + this.id = UUID.randomUUID().toString(); + this.accountList = list; + } + + public int getAccountBalance(int id) { + Account account = null; + for (Account a: accountList) + if (a.getAccountId() == 1) + account = a; + + List list = null; + if (account != null) { + list = account.getTransactionList(); + } + + int balance = 0; + if (list != null) { + balance = list.getFirst().getBalance(); + + for (Transaction t : list) { + if (t.getType().equals("debit")) { + balance += t.getAmount(); + } else if (t.getType().equals("credit")) { + balance -= t.getAmount(); + } + } + } + return balance; + } +} diff --git a/src/main/java/com/booleanuk/core/Users/User.java b/src/main/java/com/booleanuk/core/Users/User.java new file mode 100644 index 000000000..e2c240149 --- /dev/null +++ b/src/main/java/com/booleanuk/core/Users/User.java @@ -0,0 +1,10 @@ +package com.booleanuk.core.Users; + +public class User { + private String id; + + public User() { + + } + +} diff --git a/src/main/java/com/booleanuk/core/diagrams/domain-model-1.0.md b/src/main/java/com/booleanuk/core/diagrams/domain-model-1.0.md index ef005de21..9e1162574 100644 --- a/src/main/java/com/booleanuk/core/diagrams/domain-model-1.0.md +++ b/src/main/java/com/booleanuk/core/diagrams/domain-model-1.0.md @@ -1,5 +1,7 @@ +# Core + | **Class** | **Member** | **Method** | **Scenario** | **Output** | -| --------------- |---------------------|-------------------------------|--------------------------------------------------------------------------|---------------| +|-----------------|---------------------|-------------------------------|--------------------------------------------------------------------------|---------------| | **Customer** | `customerId` | `createACurrentAccount()` | As a customer, I want to create a current account. | `bool` | | | `List` | `createASavingsAccount()` | As a customer, I want to create a savings account. | `bool` | | | `` | `depositToSavings()` | As a customer, I want to deposit to a savings account. | `bool` | @@ -14,3 +16,32 @@ | | `amount` | `getTransactionAmount()` | As a customer, I want to see the transaction amount. | `decimal` | | | `date` | `getTransactionDate()` | As a customer, I want to see the date of the transaction. | `Date` | | | `type` | `getTransactionType()` | As a customer, I want to see the type (debit/credit) of the transaction. | `type` | + +# Extensions + +| **Class** | **Member** | **Method** | **Scenario** | **Output** | +|-----------------|----------------------------------------------------------------|-----------------------------------|------------------------------------------------------------------------------------|--------------------------------------------------------| +| **Engineer** | `List accounts` | `getAccountBalance()` | As an engineer, I want account balances to be calculated from transaction history. | Returns balance amount | +| **BankManager** | `List branches` | `-` | As a bank manager, I want accounts to be associated with specific branches. | **`BankManager` contains a list of `Branch` objects.** | +| | | `verifyOverdraftRequest(account)` | As a bank manager, I want to approve/reject overdraft requests. | `boolean` | +| **Customer** | `-` | `requestOverdraft(account)` | As a customer, I want to request an overdraft on my account. | `boolean` | +| | | | | | +| **Branch** | `branchId`, `branchName`, `location`, `List accounts` | `-` | As a bank manager, I want accounts to be associated with specific branches. | | + + +// Notes: +Extension: + +User (Abstract?) - Customer, Manager (though they currently do not share anything) + +Engineer story + want balances acounted based on history instaed of memoery + -> no member variable -> calculate from history of transaction list on each call ? + +BankManager + Accounts -> associate with Branches + Branches (parent) -> Branch + Approve or Reject overdraft Request + +Customer + Emergency fund -> overdraft request on account diff --git a/src/test/java/com/booleanuk/core/AccountTest.java b/src/test/java/com/booleanuk/core/AccountTest.java index 5ed5aca17..c42bbc64d 100644 --- a/src/test/java/com/booleanuk/core/AccountTest.java +++ b/src/test/java/com/booleanuk/core/AccountTest.java @@ -10,16 +10,16 @@ public class AccountTest { @Test public void testCreateCurrentAccountWithDataPassVerifications() { - Account acc = new Account(1, "savings", 500); + Account acc = new Account("savings", 500); assertEquals("savings", acc.getAccountType()); assertEquals(500, acc.getBalance()); assertThrows(IllegalArgumentException.class, () -> acc.setAccountType("test")); - assertThrows(IllegalArgumentException.class, () -> new Account(2, "current", -500)); + assertThrows(IllegalArgumentException.class, () -> new Account("current", -500)); } @Test public void depositAndUpdateAccountBalance() { - Account acc = new Account(1, "savings", 444); + Account acc = new Account("savings", 444); assertEquals(5444, acc.deposit(5000)); assertEquals(5444, acc.getBalance()); @@ -31,7 +31,7 @@ public void depositAndUpdateAccountBalance() { @Test public void withdrawAndUpdateAccountBalance() { - Account acc = new Account(1, "savings", 444); + Account acc = new Account("savings", 444); assertEquals(400 ,acc.withdraw(400)); assertEquals(44, acc.getBalance()); @@ -42,7 +42,7 @@ public void withdrawAndUpdateAccountBalance() { @Test public void withdrawLessThanBalance() { - Account acc = new Account(1, "savings", 444); + Account acc = new Account("savings", 444); assertEquals(0, acc.withdraw(1000)); assertEquals(0, acc.withdraw(-1000)); @@ -55,7 +55,7 @@ public void withdrawLessThanBalance() { @Test public void createTransaction() { - Account acc = new Account(1, "savings", 500); + Account acc = new Account("savings", 500); acc.addTransaction(500, ""); // unknown type acc.deposit(300); // deposit = debit diff --git a/src/test/java/com/booleanuk/core/BankManagerTest.java b/src/test/java/com/booleanuk/core/BankManagerTest.java new file mode 100644 index 000000000..b785815ec --- /dev/null +++ b/src/test/java/com/booleanuk/core/BankManagerTest.java @@ -0,0 +1,24 @@ +package com.booleanuk.core; + +import com.booleanuk.core.Users.BankManager; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class BankManagerTest { + + @Test + public void ifBalanceAboveThresholdApproveOverdraftElseDeny() { + + Account acc = new Account("current", 1000); + BankManager bm = new BankManager(); + assertTrue(bm.verifyOverdraftRequest(acc, 1000)); + assertTrue(bm.verifyOverdraftRequest(acc, 999)); + assertFalse(bm.verifyOverdraftRequest(acc, 1100)); + assertFalse(bm.verifyOverdraftRequest(acc, 1001)); + assertTrue(bm.verifyOverdraftRequest(acc, 500)); + assertTrue(bm.verifyOverdraftRequest(acc, 0)); + assertFalse(bm.verifyOverdraftRequest(acc, -1000)); + } + +} diff --git a/src/test/java/com/booleanuk/core/CustomerTest.java b/src/test/java/com/booleanuk/core/CustomerTest.java index b33af0a82..4432c2ada 100644 --- a/src/test/java/com/booleanuk/core/CustomerTest.java +++ b/src/test/java/com/booleanuk/core/CustomerTest.java @@ -1,5 +1,6 @@ package com.booleanuk.core; +import com.booleanuk.core.Users.Customer; import org.junit.jupiter.api.Test; public class CustomerTest { diff --git a/src/test/java/com/booleanuk/core/EngineerTest.java b/src/test/java/com/booleanuk/core/EngineerTest.java new file mode 100644 index 000000000..1a685eabf --- /dev/null +++ b/src/test/java/com/booleanuk/core/EngineerTest.java @@ -0,0 +1,27 @@ +package com.booleanuk.core; + +import com.booleanuk.core.Users.Engineer; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +import java.util.ArrayList; +import java.util.List; + +public class EngineerTest { + + @Test + public void asEngineerCalculateAllHistoryTransactions() { + + Account account = new Account("current", 1000); + account.deposit(500); + account.withdraw(300); + account.deposit(150); + account.deposit(550); + account.withdraw(1000); + List list = new ArrayList<>(); + list.add(account); + Engineer e = new Engineer(list); + + assertEquals(900, e.getAccountBalance(1)); // shall be 900 + } +} From bff93b89e96cb487677df7fabe4dd46eba798dd7 Mon Sep 17 00:00:00 2001 From: Andre Velkov Janusev Date: Wed, 20 Aug 2025 14:38:56 +0200 Subject: [PATCH 5/6] User stories for extension done, -> refactor For now have only composition. Could have inheritance for example User but not much shared between the classes so skipped. Similar with Account. --- src/main/java/com/booleanuk/core/Account.java | 62 ++++++++++++++----- src/main/java/com/booleanuk/core/Branch.java | 17 ++--- .../com/booleanuk/core/Users/BankManager.java | 27 +++++++- .../com/booleanuk/core/Users/Customer.java | 24 ++++++- .../com/booleanuk/core/Users/Engineer.java | 4 +- .../java/com/booleanuk/core/Users/User.java | 10 --- .../core/diagrams/domain-model-1.0.md | 16 ++--- .../java/com/booleanuk/core/AccountTest.java | 14 ++--- .../com/booleanuk/core/BankManagerTest.java | 32 +++++++++- .../java/com/booleanuk/core/CustomerTest.java | 30 ++++++++- .../java/com/booleanuk/core/EngineerTest.java | 4 +- 11 files changed, 177 insertions(+), 63 deletions(-) delete mode 100644 src/main/java/com/booleanuk/core/Users/User.java diff --git a/src/main/java/com/booleanuk/core/Account.java b/src/main/java/com/booleanuk/core/Account.java index 94e022f52..e9c5e9e7b 100644 --- a/src/main/java/com/booleanuk/core/Account.java +++ b/src/main/java/com/booleanuk/core/Account.java @@ -1,31 +1,46 @@ package com.booleanuk.core; -import java.text.SimpleDateFormat; +import com.booleanuk.core.Users.BankManager; + import java.time.LocalDate; import java.util.ArrayList; -import java.util.Date; import java.util.List; import java.util.UUID; public class Account { + private List transactionList = new ArrayList<>(); + private BankManager bm; private String accountId; - private int balance = 0; private String accountType; - private List transactionList = new ArrayList<>(); + private String branch; + private int balance = 0; - public Account(String accountType, int balance) { + public Account(String accountType, int balance, String branch, BankManager bm) { this.accountId = UUID.randomUUID().toString(); + this.branch = branch; + this.bm = bm; setAccountType(accountType); + checkBalance(balance); + } - if (balance < 0) - throw new IllegalArgumentException("Initial balance cant be less than 0"); - else - setBalance(balance); + public Account(String accountType, int balance, String branch) { + this.accountId = UUID.randomUUID().toString(); + this.branch = branch; + setAccountType(accountType); + checkBalance(balance); } public Account(String accountId, String accountType) { this.accountId = UUID.randomUUID().toString(); setAccountType(accountType); + checkBalance(balance); + } + + public void checkBalance(int balance) { + if (balance < 0) + throw new IllegalArgumentException("Initial balance cant be less than 0"); + else + setBalance(balance); } public int deposit(int amount) { @@ -54,16 +69,12 @@ public int withdraw(int amount) { } public void addTransaction(int amount, String type) { + if (!type.toLowerCase().trim().equals("debit") && !type.toLowerCase().trim().equals("credit")) { type = "unknown"; } LocalDate today = LocalDate.now(); -// System.out.println(today); -// Date today = new Date(); -// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); -// String formattedDate = sdf.format(today); - Transaction transaction = new Transaction(amount, this.balance, today, type); // amount, date, type transactionList.add(transaction); } @@ -81,8 +92,31 @@ public void generateBankStatement() { System.out.println("\n"); } + public void genereateStatementForSMS() { + System.out.printf("%-10s %-10s %-10s %-10s\n", "Date", "Credit", "Debit", "Balance"); + for (Transaction t : transactionList) { + if (t.getType().equals("debit")) { + System.out.printf("%-10s %-10s %-10s %-10s\n", t.getDate().getMonth(), " ", t.getAmount(), t.getBalance()); + } else if (t.getType().equals("credit")) { + System.out.printf("%-10s %-10s %-10s %-10s\n", t.getDate().getMonth(), t.getAmount(), " ", t.getBalance()); + } + } + } + + public boolean requestOverdraft(int amount) { + return bm.verifyOverdraftRequest(this, amount); + } + // GETTERS & SETTERS + public String getBranch() { + return branch; + } + + public void setBranch(String branch) { + this.branch = branch; + } + public String getAccountId() { return accountId; } diff --git a/src/main/java/com/booleanuk/core/Branch.java b/src/main/java/com/booleanuk/core/Branch.java index 88dbf1a69..912c583a4 100644 --- a/src/main/java/com/booleanuk/core/Branch.java +++ b/src/main/java/com/booleanuk/core/Branch.java @@ -3,17 +3,20 @@ import java.util.ArrayList; import java.util.List; import java.util.UUID; +import java.util.concurrent.atomic.DoubleAccumulator; public class Branch { private String id; - private String name; private String location; private List accounts = new ArrayList<>(); - public Branch(String location, String name) { + public Branch(String location) { this.id = UUID.randomUUID().toString(); this.location = location; - this.name = name; + } + + public void addAccount(Account acc) { + accounts.add(acc); } public List getAccounts() { @@ -32,14 +35,6 @@ public void setLocation(String location) { this.location = location; } - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - public String getId() { return id; } diff --git a/src/main/java/com/booleanuk/core/Users/BankManager.java b/src/main/java/com/booleanuk/core/Users/BankManager.java index ee4e5d7cf..50bc5b19a 100644 --- a/src/main/java/com/booleanuk/core/Users/BankManager.java +++ b/src/main/java/com/booleanuk/core/Users/BankManager.java @@ -15,10 +15,33 @@ public BankManager() { this.id = UUID.randomUUID().toString(); } - // Approve if within balance range, if above double balance, deny + // True if within balance range, else deny public Boolean verifyOverdraftRequest(Account account, int amount) { + if (amount < 0) { + return false; + } else { + System.out.println("Approved Overdraft."); + return amount <= account.getBalance(); + } + } + + public Branch addBranch(String branchLocation) { + Branch branch = new Branch(branchLocation); + branches.add(branch); - return null; + return branch; } + public void addAccountToBranch(Account account) { + for (Branch branch : branches) { + if (account.getBranch().equalsIgnoreCase(branch.getLocation())) { + branch.addAccount(account); + return; + } + } + } + + public List getBranches() { + return this.branches; + } } diff --git a/src/main/java/com/booleanuk/core/Users/Customer.java b/src/main/java/com/booleanuk/core/Users/Customer.java index 5fee1bbc8..de6e84637 100644 --- a/src/main/java/com/booleanuk/core/Users/Customer.java +++ b/src/main/java/com/booleanuk/core/Users/Customer.java @@ -12,8 +12,13 @@ public Customer() { this.id = UUID.randomUUID().toString(); } - public void createAccount(int id, String type, int balance) { - this.account = new Account(type, balance); + public void createAccount(String type, int balance, String branch) { + this.account = new Account(type, balance, branch); + } + + // Mainly for testing interaction , Customer -> Account -> BankManager + public void createAccount(String type, int balance, String branch, BankManager bm) { + this.account = new Account(type, balance, branch, bm); } public void viewBankStatements() { @@ -27,4 +32,19 @@ public void depositToAccount(int amount) { public void withdrawFromAccount(int amount) { this.account.withdraw(amount); } + + public boolean requestOverdraft(int amount) { + return account.requestOverdraft(amount); + } + + public void sendStatementAsSMS(String num) { + System.out.println("\n\nSend to number: " + num); + System.out.println("Sending SMS..."); + System.out.println("..."); + System.out.println("..."); + System.out.println("\nIncoming..."); + account.genereateStatementForSMS(); + System.out.println("\n"); + } + } diff --git a/src/main/java/com/booleanuk/core/Users/Engineer.java b/src/main/java/com/booleanuk/core/Users/Engineer.java index 03692232f..86445f2af 100644 --- a/src/main/java/com/booleanuk/core/Users/Engineer.java +++ b/src/main/java/com/booleanuk/core/Users/Engineer.java @@ -16,10 +16,10 @@ public Engineer(List list) { this.accountList = list; } - public int getAccountBalance(int id) { + public int getAccountBalance(String id) { Account account = null; for (Account a: accountList) - if (a.getAccountId() == 1) + if (a.getAccountId().equals(id)) account = a; List list = null; diff --git a/src/main/java/com/booleanuk/core/Users/User.java b/src/main/java/com/booleanuk/core/Users/User.java deleted file mode 100644 index e2c240149..000000000 --- a/src/main/java/com/booleanuk/core/Users/User.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.booleanuk.core.Users; - -public class User { - private String id; - - public User() { - - } - -} diff --git a/src/main/java/com/booleanuk/core/diagrams/domain-model-1.0.md b/src/main/java/com/booleanuk/core/diagrams/domain-model-1.0.md index 9e1162574..6ea3bf0f3 100644 --- a/src/main/java/com/booleanuk/core/diagrams/domain-model-1.0.md +++ b/src/main/java/com/booleanuk/core/diagrams/domain-model-1.0.md @@ -19,14 +19,14 @@ # Extensions -| **Class** | **Member** | **Method** | **Scenario** | **Output** | -|-----------------|----------------------------------------------------------------|-----------------------------------|------------------------------------------------------------------------------------|--------------------------------------------------------| -| **Engineer** | `List accounts` | `getAccountBalance()` | As an engineer, I want account balances to be calculated from transaction history. | Returns balance amount | -| **BankManager** | `List branches` | `-` | As a bank manager, I want accounts to be associated with specific branches. | **`BankManager` contains a list of `Branch` objects.** | -| | | `verifyOverdraftRequest(account)` | As a bank manager, I want to approve/reject overdraft requests. | `boolean` | -| **Customer** | `-` | `requestOverdraft(account)` | As a customer, I want to request an overdraft on my account. | `boolean` | -| | | | | | -| **Branch** | `branchId`, `branchName`, `location`, `List accounts` | `-` | As a bank manager, I want accounts to be associated with specific branches. | | +| **Class** | **Member** | **Method** | **Scenario** | **Output** | +|-----------------|-------------------------------------------------------------|-----------------------------------|------------------------------------------------------------------------------------|--------------------------------------------------------| +| **Engineer** | `List accounts` | `getAccountBalance()` | As an engineer, I want account balances to be calculated from transaction history. | Returns balance amount | +| **BankManager** | `List branches` | `-` | As a bank manager, I want accounts to be associated with specific branches. | **`BankManager` contains a list of `Branch` objects.** | +| | | `verifyOverdraftRequest(account)` | As a bank manager, I want to approve/reject overdraft requests. | `boolean` | +| **Customer** | `-` | `requestOverdraft(account)` | As a customer, I want to request an overdraft on my account. | `boolean` | +| | | | | | +| **Branch** | `branchId`, `location`, `List accounts` | `-` | As a bank manager, I want accounts to be associated with specific branches. | | // Notes: diff --git a/src/test/java/com/booleanuk/core/AccountTest.java b/src/test/java/com/booleanuk/core/AccountTest.java index c42bbc64d..8aa240a50 100644 --- a/src/test/java/com/booleanuk/core/AccountTest.java +++ b/src/test/java/com/booleanuk/core/AccountTest.java @@ -1,25 +1,23 @@ package com.booleanuk.core; import org.junit.jupiter.api.Test; - import java.util.List; - import static org.junit.jupiter.api.Assertions.*; public class AccountTest { @Test public void testCreateCurrentAccountWithDataPassVerifications() { - Account acc = new Account("savings", 500); + Account acc = new Account("savings", 500, "rome"); assertEquals("savings", acc.getAccountType()); assertEquals(500, acc.getBalance()); assertThrows(IllegalArgumentException.class, () -> acc.setAccountType("test")); - assertThrows(IllegalArgumentException.class, () -> new Account("current", -500)); + assertThrows(IllegalArgumentException.class, () -> new Account("current", -500, "rome")); } @Test public void depositAndUpdateAccountBalance() { - Account acc = new Account("savings", 444); + Account acc = new Account("savings", 444, "rome"); assertEquals(5444, acc.deposit(5000)); assertEquals(5444, acc.getBalance()); @@ -31,7 +29,7 @@ public void depositAndUpdateAccountBalance() { @Test public void withdrawAndUpdateAccountBalance() { - Account acc = new Account("savings", 444); + Account acc = new Account("savings", 444, "rome"); assertEquals(400 ,acc.withdraw(400)); assertEquals(44, acc.getBalance()); @@ -42,7 +40,7 @@ public void withdrawAndUpdateAccountBalance() { @Test public void withdrawLessThanBalance() { - Account acc = new Account("savings", 444); + Account acc = new Account("savings", 444, "rome"); assertEquals(0, acc.withdraw(1000)); assertEquals(0, acc.withdraw(-1000)); @@ -55,7 +53,7 @@ public void withdrawLessThanBalance() { @Test public void createTransaction() { - Account acc = new Account("savings", 500); + Account acc = new Account("savings", 500, "rome"); acc.addTransaction(500, ""); // unknown type acc.deposit(300); // deposit = debit diff --git a/src/test/java/com/booleanuk/core/BankManagerTest.java b/src/test/java/com/booleanuk/core/BankManagerTest.java index b785815ec..0182086f2 100644 --- a/src/test/java/com/booleanuk/core/BankManagerTest.java +++ b/src/test/java/com/booleanuk/core/BankManagerTest.java @@ -3,15 +3,17 @@ import com.booleanuk.core.Users.BankManager; import org.junit.jupiter.api.Test; +import java.util.List; + import static org.junit.jupiter.api.Assertions.*; public class BankManagerTest { @Test public void ifBalanceAboveThresholdApproveOverdraftElseDeny() { - - Account acc = new Account("current", 1000); + Account acc = new Account("current", 1000, "rome"); BankManager bm = new BankManager(); + assertTrue(bm.verifyOverdraftRequest(acc, 1000)); assertTrue(bm.verifyOverdraftRequest(acc, 999)); assertFalse(bm.verifyOverdraftRequest(acc, 1100)); @@ -21,4 +23,30 @@ public void ifBalanceAboveThresholdApproveOverdraftElseDeny() { assertFalse(bm.verifyOverdraftRequest(acc, -1000)); } + @Test + public void addBranchesAndVerify() { + BankManager bm = new BankManager(); + Branch b1 = bm.addBranch("rome"); + Branch b2 = bm.addBranch("berlin"); + + Account acc = new Account("current", 1000, "rome"); + Account acc2 = new Account("current", 2000, "berlin"); + Account acc3 = new Account("current", 4000, "rome"); + Account acc4 = new Account("current", 6000, "rome"); + + bm.addAccountToBranch(acc); + bm.addAccountToBranch(acc2); + bm.addAccountToBranch(acc3); + bm.addAccountToBranch(acc4); + + List list = bm.getBranches(); + assertEquals("rome", list.getFirst().getLocation()); + assertEquals("berlin", list.getLast().getLocation()); + + List accs = list.getFirst().getAccounts(); + assertEquals("rome", accs.getFirst().getBranch()); + assertEquals("rome", accs.get(1).getBranch()); + assertEquals("rome", accs.get(2).getBranch()); + } + } diff --git a/src/test/java/com/booleanuk/core/CustomerTest.java b/src/test/java/com/booleanuk/core/CustomerTest.java index 4432c2ada..f15f2f55f 100644 --- a/src/test/java/com/booleanuk/core/CustomerTest.java +++ b/src/test/java/com/booleanuk/core/CustomerTest.java @@ -1,14 +1,19 @@ package com.booleanuk.core; +import com.booleanuk.core.Users.BankManager; import com.booleanuk.core.Users.Customer; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + public class CustomerTest { - @Test + @Test // Testing printout of method public void testForStatementPrintout() { + Customer c = new Customer(); - c.createAccount(2, "savings", 500); + c.createAccount("savings", 500, "rome"); c.depositToAccount(300); c.depositToAccount(100); c.withdrawFromAccount(150); @@ -17,4 +22,25 @@ public void testForStatementPrintout() { c.viewBankStatements(); } + + @Test + public void testRequestOverdraft() { + BankManager bm = new BankManager(); + Customer c = new Customer(); + c.createAccount("current", 500, "rome", bm); + assertTrue(c.requestOverdraft(500)); + } + + @Test // Testing printout of method + public void sendStatementAsSMS() { + Customer c = new Customer(); + c.createAccount("savings", 500, "rome"); + c.depositToAccount(300); + c.depositToAccount(100); + c.withdrawFromAccount(150); + c.depositToAccount(500); + c.withdrawFromAccount(400); + + c.sendStatementAsSMS("0708616843"); + } } diff --git a/src/test/java/com/booleanuk/core/EngineerTest.java b/src/test/java/com/booleanuk/core/EngineerTest.java index 1a685eabf..953e81b23 100644 --- a/src/test/java/com/booleanuk/core/EngineerTest.java +++ b/src/test/java/com/booleanuk/core/EngineerTest.java @@ -12,7 +12,7 @@ public class EngineerTest { @Test public void asEngineerCalculateAllHistoryTransactions() { - Account account = new Account("current", 1000); + Account account = new Account("current", 1000, "rome"); account.deposit(500); account.withdraw(300); account.deposit(150); @@ -22,6 +22,6 @@ public void asEngineerCalculateAllHistoryTransactions() { list.add(account); Engineer e = new Engineer(list); - assertEquals(900, e.getAccountBalance(1)); // shall be 900 + assertEquals(900, e.getAccountBalance(account.getAccountId())); // shall be 900 } } From bc9ed67c97d75638490f5bc86d7a76f662455b9b Mon Sep 17 00:00:00 2001 From: Andre Velkov Janusev Date: Wed, 20 Aug 2025 15:02:55 +0200 Subject: [PATCH 6/6] upd --- src/main/java/com/booleanuk/core/Account.java | 12 +++++++----- .../java/com/booleanuk/core/Users/BankManager.java | 8 +++----- src/main/java/com/booleanuk/core/Users/Customer.java | 2 +- src/test/java/com/booleanuk/core/CustomerTest.java | 8 ++++++-- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/booleanuk/core/Account.java b/src/main/java/com/booleanuk/core/Account.java index e9c5e9e7b..1a01bc9d1 100644 --- a/src/main/java/com/booleanuk/core/Account.java +++ b/src/main/java/com/booleanuk/core/Account.java @@ -15,6 +15,7 @@ public class Account { private String branch; private int balance = 0; + // Constructor with BankManager (mostly for test and lack of service layer); ! or account has a manager public Account(String accountType, int balance, String branch, BankManager bm) { this.accountId = UUID.randomUUID().toString(); this.branch = branch; @@ -23,6 +24,7 @@ public Account(String accountType, int balance, String branch, BankManager bm) { checkBalance(balance); } + // Constructor with balance public Account(String accountType, int balance, String branch) { this.accountId = UUID.randomUUID().toString(); this.branch = branch; @@ -30,6 +32,7 @@ public Account(String accountType, int balance, String branch) { checkBalance(balance); } + // Constructor with no initial balance public Account(String accountId, String accountType) { this.accountId = UUID.randomUUID().toString(); setAccountType(accountType); @@ -62,10 +65,10 @@ public int withdraw(int amount) { balance -= amount; addTransaction(amount, "credit"); return amount; - } else { - System.out.println("Cant withdraw amount, balance too low.."); - return 0; } + + System.out.println("Cant withdraw amount, balance too low.."); + return 0; } public void addTransaction(int amount, String type) { @@ -81,7 +84,6 @@ public void addTransaction(int amount, String type) { public void generateBankStatement() { System.out.printf("\n%-20s %-10s %-10s %-10s\n", "Date", "Credit", "Debit", "Balance"); - for (Transaction t : transactionList) { if (t.getType().equals("debit")) { System.out.printf("%-20s %-10s %-10s %-10s\n", t.getDate(), " ", t.getAmount(), t.getBalance()); @@ -92,7 +94,7 @@ public void generateBankStatement() { System.out.println("\n"); } - public void genereateStatementForSMS() { + public void generateStatementForSMS() { System.out.printf("%-10s %-10s %-10s %-10s\n", "Date", "Credit", "Debit", "Balance"); for (Transaction t : transactionList) { if (t.getType().equals("debit")) { diff --git a/src/main/java/com/booleanuk/core/Users/BankManager.java b/src/main/java/com/booleanuk/core/Users/BankManager.java index 50bc5b19a..cb69ae726 100644 --- a/src/main/java/com/booleanuk/core/Users/BankManager.java +++ b/src/main/java/com/booleanuk/core/Users/BankManager.java @@ -17,12 +17,10 @@ public BankManager() { // True if within balance range, else deny public Boolean verifyOverdraftRequest(Account account, int amount) { - if (amount < 0) { + if (amount < 0) return false; - } else { - System.out.println("Approved Overdraft."); - return amount <= account.getBalance(); - } + + return amount <= account.getBalance(); } public Branch addBranch(String branchLocation) { diff --git a/src/main/java/com/booleanuk/core/Users/Customer.java b/src/main/java/com/booleanuk/core/Users/Customer.java index de6e84637..fae97969b 100644 --- a/src/main/java/com/booleanuk/core/Users/Customer.java +++ b/src/main/java/com/booleanuk/core/Users/Customer.java @@ -43,7 +43,7 @@ public void sendStatementAsSMS(String num) { System.out.println("..."); System.out.println("..."); System.out.println("\nIncoming..."); - account.genereateStatementForSMS(); + account.generateStatementForSMS(); System.out.println("\n"); } diff --git a/src/test/java/com/booleanuk/core/CustomerTest.java b/src/test/java/com/booleanuk/core/CustomerTest.java index f15f2f55f..3a6e207cc 100644 --- a/src/test/java/com/booleanuk/core/CustomerTest.java +++ b/src/test/java/com/booleanuk/core/CustomerTest.java @@ -4,8 +4,7 @@ import com.booleanuk.core.Users.Customer; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; public class CustomerTest { @@ -29,6 +28,11 @@ public void testRequestOverdraft() { Customer c = new Customer(); c.createAccount("current", 500, "rome", bm); assertTrue(c.requestOverdraft(500)); + assertTrue(c.requestOverdraft(499)); + assertTrue(c.requestOverdraft(1)); + assertFalse(c.requestOverdraft(1000)); + assertFalse(c.requestOverdraft(1001)); + assertFalse(c.requestOverdraft(-151)); } @Test // Testing printout of method