Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

105613_Actividad8.4_Cáceres_Agustín #8

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
# memo1-bank-app
Memo1 - Backend API
Link al video https://drive.google.com/file/d/1uqKoU4-sbHvLgx0gdSsL7Gl2easYvhAw/view?usp=sharing
Binary file added presentacion_bank_app.mp4
Binary file not shown.
1 change: 1 addition & 0 deletions src/main/java/com/aninfo/Memo1BankApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
Expand Down
72 changes: 72 additions & 0 deletions src/main/java/com/aninfo/controller/AccountController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.aninfo.controller;

import com.aninfo.model.Account;
import com.aninfo.model.Transaction;
import com.aninfo.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.Collection;
import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("/account")
public class AccountController {
@Autowired
AccountService accountService;

@PostMapping
public void createAccount(@RequestBody Account account){
this.accountService.createAccount(account);
}

@GetMapping("/list")
public Collection<Account> getAccounts(){
return this.accountService.getAccounts();
}

@GetMapping("{cbu}")
public Optional<Account> findById(@PathVariable Long cbu){
return this.accountService.findById(cbu);
}

@PutMapping("/save")
public void save(@RequestBody Account account){
this.accountService.save(account);
}

@DeleteMapping("{cbu}")
public void deleteById(@PathVariable Long cbu){
this.accountService.deleteById(cbu);
}

@PatchMapping("/deposit/{cbu}")
public void deposit(@PathVariable Long cbu, @RequestBody Double sum){
this.accountService.deposit(cbu,sum);
}

@PatchMapping("/withdraw/{cbu}")
public void withdraw(@PathVariable Long cbu, @RequestBody Double sum){
this.accountService.withdraw(cbu,sum);
}

@GetMapping("/list/transactions/{cbu}/{transactionNumber}")
public ResponseEntity<List<Transaction>> getTransactions(@PathVariable Long cbu){
List<Transaction> list = accountService.getTransactions(cbu);
return ResponseEntity.ok(list);
}

@GetMapping("/get/transaction/by/{cbu}/{transactionNumber}")
public ResponseEntity<Transaction> getTransactions(@PathVariable Long cbu,@PathVariable Long transactionNumber){
Transaction transaction = accountService.getTransaction(cbu,transactionNumber);
return ResponseEntity.ok(transaction);
}

@DeleteMapping("/transaction/delete/by/{cbu}/{transactionNumber}")
public void delete_transaction(@PathVariable Long cbu, @PathVariable Long transactionNumber){
this.accountService.deleteTransaction(cbu,transactionNumber);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.aninfo.exceptions;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

@ResponseStatus(code = HttpStatus.BAD_REQUEST)
public class TransactionNotFoundException extends RuntimeException {
public TransactionNotFoundException(String message) {super(message);}
}
14 changes: 14 additions & 0 deletions src/main/java/com/aninfo/model/Account.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.aninfo.model;

import org.springframework.util.MultiValueMap;

import javax.persistence.*;
import java.util.*;

@Entity
public class Account {
Expand All @@ -11,11 +14,15 @@ public class Account {

private Double balance;

private Double cap;


public Account(){
}

public Account(Double balance) {
this.balance = balance;
this.cap = 0.0;
}

public Long getCbu() {
Expand All @@ -34,4 +41,11 @@ public void setBalance(Double balance) {
this.balance = balance;
}

public void setCap(Double cap){this.cap = cap;}
public Double getCap(){return this.cap;}

public boolean maxCapReached(Double maxCap) {
return this.cap.equals(maxCap);
}

}
51 changes: 51 additions & 0 deletions src/main/java/com/aninfo/model/Transaction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.aninfo.model;

import org.springframework.data.annotation.PersistenceConstructor;

import javax.persistence.*;

@Entity
public class Transaction {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long transactionNumber;

private Double sum;
private String transactionType;

@ManyToOne
@JoinColumn(name = "account_id")
private Account account;

public Transaction() {
}

public Transaction(Double sum, String transactionType, Account account) {
this.sum = sum;
this.transactionType = transactionType;
this.account = account;
}

public String getTransactionType(){
return this.transactionType;
}
public Double getSum(){
return this.sum;
}
public Long getTransactionNumber() {
return transactionNumber;
}

public void setTransactionType(String type) {
this.transactionType = type;
}

public void setSum(Double sum) {
this.sum = sum;
}

public void setAccount(Account account) {
this.account = account;
}
}

5 changes: 5 additions & 0 deletions src/main/java/com/aninfo/repository/AccountRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

import com.aninfo.model.Account;
import java.util.List;

import com.aninfo.model.Transaction;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;

@RepositoryRestResource
Expand All @@ -13,4 +17,5 @@ public interface AccountRepository extends CrudRepository<Account, Long> {
@Override
List<Account> findAll();


}
14 changes: 14 additions & 0 deletions src/main/java/com/aninfo/repository/TransactionRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.aninfo.repository;

import com.aninfo.model.Transaction;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;

import java.util.List;

@RepositoryRestResource
public interface TransactionRepository extends CrudRepository<Transaction,Long> {
List<Transaction> findByAccountCbu(Long cbu);
Transaction findByAccountCbuAndTransactionNumber(Long cbu, Long transactionNumber);
void deleteByAccountCbuAndTransactionNumber(Long cbu, Long transactionNumber);
}
82 changes: 78 additions & 4 deletions src/main/java/com/aninfo/service/AccountService.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,63 @@
import com.aninfo.exceptions.DepositNegativeSumException;
import com.aninfo.exceptions.InsufficientFundsException;
import com.aninfo.model.Account;
import com.aninfo.model.Transaction;
import com.aninfo.repository.AccountRepository;
import com.aninfo.repository.TransactionRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.persistence.*;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import javax.security.auth.login.AccountNotFoundException;
import javax.transaction.Transactional;
import java.text.DecimalFormat;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.stream.Collectors;

@Service
public class AccountService {



@FunctionalInterface
public interface BankAccountPromo {
void applyPromo(Account account);
}

private static class DepositPromo implements BankAccountPromo {
private final Double MAXCAP = 500.0;
private Double sum;
private final float DISCOUNT = 0.10F;

public DepositPromo(Double sum) {
this.sum = sum;
}

@Override
public void applyPromo(Account account) {
var currentBalance = account.getBalance();
if (!account.maxCapReached(MAXCAP) && sum >= 2000) {
Double extra = Math.min(this.sum * DISCOUNT, MAXCAP - account.getCap());
DecimalFormat df = new DecimalFormat("#.###");
extra = Double.parseDouble(df.format(extra));

account.setBalance(currentBalance + extra);
account.setCap(account.getCap() + extra);
}
}
}

@Autowired
private AccountRepository accountRepository;
@Autowired
private TransactionRepository transactionRepository;


public Account createAccount(Account account) {
return accountRepository.save(account);
Expand Down Expand Up @@ -44,25 +88,55 @@ public Account withdraw(Long cbu, Double sum) {
if (account.getBalance() < sum) {
throw new InsufficientFundsException("Insufficient funds");
}

account.setBalance(account.getBalance() - sum);
accountRepository.save(account);

Transaction transaction = new Transaction(sum,"withdrawal",accountRepository.findAccountByCbu(cbu));
transactionRepository.save(transaction);

accountRepository.save(account);
return account;
}

@Transactional
public Account deposit(Long cbu, Double sum) {

if (sum <= 0) {
throw new DepositNegativeSumException("Cannot deposit negative sums");
}

Account account = accountRepository.findAccountByCbu(cbu);
account.setBalance(account.getBalance() + sum);

accountRepository.save(account);

Transaction transaction = new Transaction(sum,"deposit",accountRepository.findAccountByCbu(cbu));
transactionRepository.save(transaction);

BankAccountPromo promo = new DepositPromo(sum);
promo.applyPromo(account);

return account;
}

}
public List<Transaction> getTransactions(Long cbu){
return transactionRepository.findByAccountCbu(cbu);
}

public Transaction getTransaction(Long cbu, Long transactionNumber){
return transactionRepository.findByAccountCbuAndTransactionNumber(cbu, transactionNumber);
}

@Transactional
public void deleteTransaction(Long cbu, Long transactionNumber) {
Optional<Transaction> transaction = transactionRepository.findById(transactionNumber);
Optional<Account> account = accountRepository.findById(cbu);

if(transaction.get().getTransactionType() == "deposit"){
account.get().setBalance(account.get().getBalance() - transaction.get().getSum());
}else{
account.get().setBalance(account.get().getBalance() + transaction.get().getSum());
}
accountRepository.save(account.get());
transactionRepository.deleteByAccountCbuAndTransactionNumber(cbu, transactionNumber);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.aninfo.integration.cucumber;

import com.aninfo.model.Account;
import com.aninfo.service.AccountService;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
import org.springframework.beans.factory.annotation.Autowired;

import static org.junit.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

public class BankAccountPromoTest {


}
15 changes: 0 additions & 15 deletions src/test/resources/cucumber/bank_account_operations.feature
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,4 @@ Feature: Bank account operations
And Account balance should remain 200


Feature: Bank account promo, get 10% extra in your $2000+ deposits, up to $500

Scenario: Successfully promo applied, cap not reached.
Given Account with a balance of 0
When Trying to deposit 2000
Then Account balance should be 2200

Scenario: Successfully promo applied, cap reached.
Given Account with a balance of 0
When Trying to deposit 6000
Then Account balance should be 6500

Scenario: Promo not applied
Given Account with a balance of 0
When Trying to deposit 1500
Then Account balance should be 1500
16 changes: 16 additions & 0 deletions src/test/resources/cucumber/bank_account_promo.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Feature: Bank account promo, get 10% extra in your $2000+ deposits, up to $500

Scenario: Successfully promo applied, cap not reached.
Given Account with a balance of 0
When Trying to deposit 2000
Then Account balance should be 2200

Scenario: Successfully promo applied, cap reached.
Given Account with a balance of 0
When Trying to deposit 6000
Then Account balance should be 6500

Scenario: Promo not applied
Given Account with a balance of 0
When Trying to deposit 1500
Then Account balance should be 1500