Skip to content

Commit 175ce0f

Browse files
committed
feat: deposit
1 parent 271636f commit 175ce0f

File tree

10 files changed

+124
-22
lines changed

10 files changed

+124
-22
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.example.paul.constants;
2+
3+
public enum ACTION {
4+
DEPOSIT,
5+
WITHDRAW
6+
}

src/main/java/com/example/paul/constants/constants.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
import java.util.regex.Pattern;
44

55
public class constants {
6+
7+
public static final String SUCCESS =
8+
"Operation completed successfully";
69
public static final String NO_ACCOUNT_FOUND =
710
"Unable to find an account matching this sort code and account number";
811
public static final String INVALID_SEARCH_CRITERIA =
@@ -16,4 +19,8 @@ public class constants {
1619
public static final String ACCOUNT_NUMBER_PATTERN_STRING = "[0-9]{8}";
1720
public static final Pattern SORT_CODE_PATTERN = Pattern.compile("^[0-9]{2}-[0-9]{2}-[0-9]{2}$");
1821
public static final Pattern ACCOUNT_NUMBER_PATTERN = Pattern.compile("^[0-9]{8}$");
22+
23+
public static final String INVALID_TRANSACTION =
24+
"Account information is invalid or transaction has been denied for your protection. Please try again.";
1925
}
26+

src/main/java/com/example/paul/controllers/AccountRestController.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public ResponseEntity<?> checkAccountBalance(
5252

5353
// Return the account details, or warn that no account was found for given input
5454
if (account == null) {
55-
return new ResponseEntity<>(constants.NO_ACCOUNT_FOUND, HttpStatus.NO_CONTENT);
55+
return new ResponseEntity<>(constants.NO_ACCOUNT_FOUND, HttpStatus.OK);
5656
} else {
5757
return new ResponseEntity<>(account, HttpStatus.OK);
5858
}
@@ -77,7 +77,7 @@ public ResponseEntity<?> createAccount(
7777

7878
// Return the account details, or warn that no account was found for given input
7979
if (account == null) {
80-
return new ResponseEntity<>(CREATE_ACCOUNT_FAILED, HttpStatus.NO_CONTENT);
80+
return new ResponseEntity<>(CREATE_ACCOUNT_FAILED, HttpStatus.OK);
8181
} else {
8282
return new ResponseEntity<>(account, HttpStatus.OK);
8383
}

src/main/java/com/example/paul/controllers/TransactionRestController.java

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
package com.example.paul.controllers;
22

3+
import com.example.paul.constants.ACTION;
34
import com.example.paul.models.Account;
45
import com.example.paul.services.AccountService;
56
import com.example.paul.services.TransactionService;
6-
import com.example.paul.utils.AccountInput;
7-
import com.example.paul.utils.InputValidator;
8-
import com.example.paul.utils.TransactionInput;
9-
import com.example.paul.utils.WithdrawInput;
7+
import com.example.paul.utils.*;
108
import org.slf4j.Logger;
119
import org.slf4j.LoggerFactory;
1210
import org.springframework.beans.factory.annotation.Autowired;
@@ -20,7 +18,6 @@
2018
import javax.validation.Valid;
2119
import java.util.HashMap;
2220
import java.util.Map;
23-
import java.util.Optional;
2421

2522
import static com.example.paul.constants.constants.*;
2623

@@ -30,9 +27,6 @@ public class TransactionRestController {
3027

3128
private static final Logger LOGGER = LoggerFactory.getLogger(TransactionRestController.class);
3229

33-
private static final String INVALID_TRANSACTION =
34-
"Account information is invalid or transaction has been denied for your protection. Please try again.";
35-
3630
private final AccountService accountService;
3731
private final TransactionService transactionService;
3832

@@ -71,13 +65,38 @@ public ResponseEntity<?> withdraw(
7165

7266
// Return the account details, or warn that no account was found for given input
7367
if (account == null) {
74-
return new ResponseEntity<>(NO_ACCOUNT_FOUND, HttpStatus.NO_CONTENT);
68+
return new ResponseEntity<>(NO_ACCOUNT_FOUND, HttpStatus.OK);
7569
} else {
7670
if (transactionService.isAmountAvailable(withdrawInput.getAmount(), account.getCurrentBalance())) {
77-
transactionService.updateAccountBalance(account, withdrawInput.getAmount());
78-
return new ResponseEntity<>(account, HttpStatus.OK);
71+
transactionService.updateAccountBalance(account, withdrawInput.getAmount(), ACTION.WITHDRAW);
72+
return new ResponseEntity<>(SUCCESS, HttpStatus.OK);
7973
}
80-
return new ResponseEntity<>(INSUFFICIENT_ACCOUNT_BALANCE, HttpStatus.NOT_ACCEPTABLE);
74+
return new ResponseEntity<>(INSUFFICIENT_ACCOUNT_BALANCE, HttpStatus.OK);
75+
}
76+
} else {
77+
return new ResponseEntity<>(INVALID_SEARCH_CRITERIA, HttpStatus.BAD_REQUEST);
78+
}
79+
}
80+
81+
82+
@PostMapping(value = "/deposit",
83+
consumes = MediaType.APPLICATION_JSON_VALUE,
84+
produces = MediaType.APPLICATION_JSON_VALUE)
85+
public ResponseEntity<?> deposit(
86+
@Valid @RequestBody DepositInput depositInput) {
87+
LOGGER.debug("Triggered AccountRestController.depositInput");
88+
89+
// Validate input
90+
if (InputValidator.isAccountNoValid(depositInput.getTargetAccountNo())) {
91+
// Attempt to retrieve the account information
92+
Account account = accountService.getAccount(depositInput.getTargetAccountNo());
93+
94+
// Return the account details, or warn that no account was found for given input
95+
if (account == null) {
96+
return new ResponseEntity<>(NO_ACCOUNT_FOUND, HttpStatus.OK);
97+
} else {
98+
transactionService.updateAccountBalance(account, depositInput.getAmount(), ACTION.DEPOSIT);
99+
return new ResponseEntity<>(SUCCESS, HttpStatus.OK);
81100
}
82101
} else {
83102
return new ResponseEntity<>(INVALID_SEARCH_CRITERIA, HttpStatus.BAD_REQUEST);

src/main/java/com/example/paul/repositories/AccountRepository.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@
88
public interface AccountRepository extends JpaRepository<Account, Long> {
99

1010
Optional<Account> findBySortCodeAndAccountNumber(String sortCode, String accountNumber);
11+
Optional<Account> findByAccountNumber(String accountNumber);
1112
}

src/main/java/com/example/paul/services/AccountService.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ public Account getAccount(String sortCode, String accountNumber) {
2929
return account.orElse(null);
3030
}
3131

32+
public Account getAccount(String accountNumber) {
33+
Optional<Account> account = accountRepository
34+
.findByAccountNumber(accountNumber);
35+
36+
return account.orElse(null);
37+
}
38+
3239
public Account createAccount(String bankName, String ownerName) {
3340
CodeGenerator codeGenerator = new CodeGenerator();
3441
Account newAccount = new Account(bankName, ownerName, codeGenerator.generateSortCode(), codeGenerator.generateAccountNumber(), 0.00);

src/main/java/com/example/paul/services/TransactionService.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.example.paul.services;
22

3+
import com.example.paul.constants.ACTION;
34
import com.example.paul.models.Account;
45
import com.example.paul.models.Transaction;
56
import com.example.paul.repositories.AccountRepository;
@@ -13,7 +14,6 @@
1314

1415
@Service
1516
public class TransactionService {
16-
1717
@Autowired
1818
private AccountRepository accountRepository;
1919

@@ -46,7 +46,7 @@ public boolean makeTransfer(TransactionInput transactionInput) {
4646
transaction.setLatitude(transactionInput.getLatitude());
4747
transaction.setLongitude(transactionInput.getLongitude());
4848

49-
updateAccountBalance(sourceAccount.get(), transactionInput.getAmount());
49+
updateAccountBalance(sourceAccount.get(), transactionInput.getAmount(), ACTION.WITHDRAW);
5050
transactionRepository.save(transaction);
5151

5252
return true;
@@ -55,8 +55,12 @@ public boolean makeTransfer(TransactionInput transactionInput) {
5555
return false;
5656
}
5757

58-
public void updateAccountBalance(Account account, double amount) {
59-
account.setCurrentBalance((account.getCurrentBalance() - amount));
58+
public void updateAccountBalance(Account account, double amount, ACTION action) {
59+
if (action == ACTION.WITHDRAW) {
60+
account.setCurrentBalance((account.getCurrentBalance() - amount));
61+
} else if (action == ACTION.DEPOSIT) {
62+
account.setCurrentBalance((account.getCurrentBalance() + amount));
63+
}
6064
accountRepository.save(account);
6165
}
6266

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package com.example.paul.utils;
2+
3+
import javax.validation.constraints.NotBlank;
4+
import javax.validation.constraints.Positive;
5+
import java.util.Objects;
6+
7+
public class DepositInput {
8+
9+
@NotBlank(message = "Target account no is mandatory")
10+
private String targetAccountNo;
11+
12+
// Prevent fraudulent transfers attempting to abuse currency conversion errors
13+
@Positive(message = "Transfer amount must be positive")
14+
private double amount;
15+
16+
public DepositInput() {
17+
}
18+
19+
public String getTargetAccountNo() {
20+
return targetAccountNo;
21+
}
22+
23+
public void setTargetAccountNo(String targetAccountNo) {
24+
this.targetAccountNo = targetAccountNo;
25+
}
26+
27+
public double getAmount() {
28+
return amount;
29+
}
30+
31+
public void setAmount(double amount) {
32+
this.amount = amount;
33+
}
34+
35+
@Override
36+
public String toString() {
37+
return "DepositInput{" +
38+
"targetAccountNo='" + targetAccountNo + '\'' +
39+
", amount='" + amount + '\'' +
40+
'}';
41+
}
42+
43+
@Override
44+
public boolean equals(Object o) {
45+
if (this == o) return true;
46+
if (o == null || getClass() != o.getClass()) return false;
47+
DepositInput that = (DepositInput) o;
48+
return Objects.equals(targetAccountNo, that.targetAccountNo) &&
49+
Objects.equals(amount, that.amount);
50+
}
51+
52+
@Override
53+
public int hashCode() {
54+
return Objects.hash(targetAccountNo, amount);
55+
}
56+
}

src/main/java/com/example/paul/utils/InputValidator.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ public static boolean isSearchCriteriaValid(AccountInput accountInput) {
99
constants.ACCOUNT_NUMBER_PATTERN.matcher(accountInput.getAccountNumber()).find();
1010
}
1111

12+
public static boolean isAccountNoValid(String accountNo) {
13+
return constants.ACCOUNT_NUMBER_PATTERN.matcher(accountNo).find();
14+
}
15+
1216
public static boolean isCreateAccountCriteriaValid(CreateAccountInput createAccountInput) {
1317
return (!createAccountInput.getBankName().isBlank() && !createAccountInput.getOwnerName().isBlank());
1418
}

src/main/java/com/example/paul/utils/WithdrawInput.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
package com.example.paul.utils;
22

3-
import javax.validation.constraints.Min;
4-
import javax.validation.constraints.NotBlank;
53
import javax.validation.constraints.Positive;
64
import java.util.Objects;
75

86
public class WithdrawInput extends AccountInput{
97
String sortCode;
108
String accountNumber;
11-
@Positive(message = "Transfer amount must be positive")
9+
1210
// Prevent fraudulent transfers attempting to abuse currency conversion errors
13-
@Min(value = 0, message = "Amount must be larger than 0")
11+
@Positive(message = "Transfer amount must be positive")
1412
private double amount;
1513

1614
public WithdrawInput() {

0 commit comments

Comments
 (0)