Spring boot/Bank App

21. 이체 기능 만들기

H_u 2024. 8. 9. 17:07
728x90
반응형
SMALL

0. 작업순서

  1. transfer.jsp 파일 생성
  2. 이체 기능 만들기
  3. 주요 파일 전체 코드 확인
  4. 동작 테스트

화면 확인 하기

1.  작성한 파일 확인

transfer.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!-- header.jsp -->
<%@ include file="/WEB-INF/view/layout/header.jsp"%>

<!-- start of context.jsp(xxx.jsp) -->
<div class="col-sm-8">
	<h2>계좌 이체(인증)</h2>
	<h5>Bank App에 오신걸 환영합니다.</h5>

	<form action="/account/transfer" method="post">
		<div class="form-group">
			<label for="amount">이체 금액:</label> <input type="number" class="form-control" placeholder="Enter amount" id="amount" name="amount" value="1000">
		</div>
		<div class="form-group">
			<label for="wAccountNumber">출금 계좌 번호:</label> <input type="text" class="form-control" placeholder="Enter account number" id="wAccountNumber" name="wAccountNumber" value="1111">
		</div>
		<div class="form-group">
			<label for="password">출금 계좌 비밀 번호:</label> <input type="password" class="form-control" placeholder="Enter password" id="password" name="password" value="1234">
		</div>
		<div class="form-group">
			<label for="dAccountNumber">입금 계좌 번호:</label> <input type="text" class="form-control" placeholder="Enter account number" id="dAccountNumber" name="dAccountNumber" value="2222">
		</div>
		<div class="text-right">
			<button type="submit" class="btn btn-primary">이체 요청</button>
		</div>
	</form>

</div>
<!-- end of col-sm-8 -->
</div>
</div>
<!-- end of context.jsp(xxx.jsp) -->

<!-- footer.jsp -->
<%@ include file="/WEB-INF/view/layout/footer.jsp"%>
TransferDTO
package com.tenco.bank.dto;

import lombok.Data;

@Data
public class TransferDTO {

	private Long amount; // 거래 금액
	private String wAccountNumber; // 출금 계좌 번호
	private String password; // 출금 계좌 비밀 번호
	private String dAccountNumber; // 입금 계좌 번호

}
AccountController
// 이체 페이지 요청
@GetMapping("/transfer")
public String transferPage() {
    User principal = (User) session.getAttribute(Define.PRINCIPAL);
    if (principal == null) {
        throw new UnAuthorizedException(Define.NOT_AN_AUTHENTICATED_USER, HttpStatus.UNAUTHORIZED);
    }
    return "account/transfer";
}

// 이체 기능 처리 요청
@PostMapping("/transfer")
public String transferProc(TransferDTO dto) {
    User principal = (User) session.getAttribute(Define.PRINCIPAL);
    if (principal == null) {
        throw new UnAuthorizedException(Define.NOT_AN_AUTHENTICATED_USER, HttpStatus.UNAUTHORIZED);
    }
    // 유효성 검사 (자바 코드를 개발) --> 스프링 부트 @Valid 라이브러리가 존재
    if (dto.getAmount() == null) {
        throw new DataDeliveryException(Define.ENTER_YOUR_BALANCE, HttpStatus.BAD_REQUEST);
    }
    if (dto.getAmount().longValue() <= 0) {
        throw new DataDeliveryException(Define.W_BALANCE_VALUE, HttpStatus.BAD_REQUEST);
    }
    if (dto.getWAccountNumber() == null || dto.getWAccountNumber().trim().isEmpty()) {
        throw new DataDeliveryException(Define.ENTER_YOUR_ACCOUNT_NUMBER, HttpStatus.BAD_REQUEST);
    }
    if (dto.getPassword() == null || dto.getPassword().trim().isEmpty()) {
        throw new DataDeliveryException(Define.ENTER_YOUR_PASSWORD, HttpStatus.BAD_REQUEST);
    }
    if (dto.getDAccountNumber() == null || dto.getDAccountNumber().trim().isEmpty()) {
        throw new DataDeliveryException(Define.ENTER_YOUR_ACCOUNT_NUMBER, HttpStatus.BAD_REQUEST);
    }
    accountService.updateAccountTransfer(dto, principal.getId());
    return "redirect:/account/list";
}
AccountService
// 이체 기능 만들기
// 1. 출금 계좌 존재 여부를 확인 -- select
// 2. 입금 계좌 존재 여부 확인 -- select
// 3. 출금 계좌 본인 계좌 여부를 확인 -- 객체 상태값에서 비교
// 4. 출금 계좌 비밀 번호 확인 -- 객체 상태값에서 비교
// 5. 출금 계좌 잔액 여부 확인 -- 객체 상태값에서 확인
// 6. 입금 계좌 객체 상태값 변경 처리 (거래금액 증가)
// 7. 입금 계좌 -- update
// 8. 출금 계좌 객체 상태값 변경 처리 (잔액 - 거래금액)
// 9. 출금 계좌 -- update
// 10. 거래 내역 등록 -- insert(history)
// 11. 트랜잭션 처리
public void updateAccountTransfer(TransferDTO dto, Integer principalId) {
    // 1.
    Account wAccountEntity = accountRepository.findByNumber(dto.getWAccountNumber());
    if (wAccountEntity == null) {
        throw new DataDeliveryException(Define.NOT_EXIST_ACCOUNT, HttpStatus.BAD_REQUEST);
    }
    // 2.
    Account dAccountEntity = accountRepository.findByNumber(dto.getDAccountNumber());
    if (dAccountEntity == null) {
        throw new DataDeliveryException(Define.NOT_EXIST_ACCOUNT, HttpStatus.BAD_REQUEST);
    }
    // 3.
    wAccountEntity.checkOwner(principalId);
    // 4.
    wAccountEntity.checkPassword(dto.getPassword());
    // 5.
    wAccountEntity.checkBalance(dto.getAmount());
    // 6.
    dAccountEntity.deposit(dto.getAmount());
    // 7.
    accountRepository.updateById(dAccountEntity);
    // 8.
    wAccountEntity.withdraw(dto.getAmount());
    // 9.
    accountRepository.updateById(wAccountEntity);
    // 10.
    History history = History.builder()
        .amount(dto.getAmount())
        .wAccountId(wAccountEntity.getId())
        .dAccountId(dAccountEntity.getId())
        .wBalance(wAccountEntity.getBalance())
        .dBalance(dAccountEntity.getBalance())
        .build();
    historyRepository.insert(history);
}
728x90
반응형
SMALL