본문 바로가기
Project

[Toss] 계좌 생성(2)

by sangyunpark 2023. 8. 18.

요구사항 정의

(1) 사용자가 존재하지 않는 경우, 계좌 생성은 불가능하다.

(2) 계좌를 생성할때, DB에 있는 이전계좌에 + 1을 한 10자리 수를 계좌번호로 지정한다.(단, 계좌번호가 하나도 없는경우 100000000으로 시작한다.)

 

AccountController

@RestController
@RequiredArgsConstructor
public class AccountController { // service에만 의존
    private final AccountService accountService;
    
    @PostMapping("/account")
    public CreateAccount.Response createAccount(
            @RequestBody @Valid CreateAccount.Request request
    ) {
        accountService.createAccount(request.getUserId(), request.getInitalBalance()); // 계정 생성
        return new CreateAccount.Response();
    }
 }

 

AccountController에 사용되는 AccountService

@Service
@RequiredArgsConstructor // final, @NotNull
public class AccountService {
    private final AccountRepository accountRepository; // repository에만 의
    private final AccountUserRepository accountUserRepository;

    /**
     * 사용자가 존재하는지 조회
     * 계죄의 번호를 생성
     * 계좌를 저장하고, 그 정보를 넘겨준다.
     */
    @Transactional
    public Account createAccount(Long userId, Long initialBalance) {

		// User가 존재하지 않는 경우 custom 에러 발생 -> 다음 코드로 못넘어간다!
        AccountUser accountUser = accountUserRepository.findById(userId)
                .orElseThrow(() -> new AccountException(ErrorCode.USER_NOT_FOUND));
		
        String newAccountNumber = accountRepository.findFirstByOrderByIdDesc()
                .map(account -> (Integer.parseInt(account.getAccountNumber())) + 1 + "")
                .orElse("10000000000"); // 계죄번호가 하나도 없는 경우 10000000000으로 등록

		// repository에 데이터 저장(빌더 패턴)
        Account savedAccount = accountRepository.save(
                Account.builder()
                        .accountUser(accountUser)
                        .accountStatus(IN_USE) // static import
                        .accountNumber(newAccountNumber)
                        .registeredAt(LocalDateTime.now())
                        .build()
        );

        return savedAccount;
    }

 

가장 최근에 생성된 계좌의 값을 가져오는 메소드

AccountRepository

@Repository
public interface AccountRepository extends JpaRepository<Account, Long> {
    Optional<Account> findFirstByOrderByIdDesc(); // 값이 존재하거나 존재하지 않을 수 도 있기 때문에
}

 

 

예외 상황에 사용할 CustomException : AccountException - unchecked exception(RuntimeException 상속)

// Custom Exception 만들기
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class AccountException extends RuntimeException{
    private ErrorCode errorCode;
    private String errorMessage;

    public AccountException(ErrorCode errorCode){
        this.errorCode = errorCode;
        this.errorMessage = errorCode.getDescription();
    }
}

 

Type ( AccountStatus, ErrorCode )

 

AccountStatus

public enum AccountStatus {
    IN_USE, // 계좌를 사용중
    UNREGISTERED, // 계좌 해지
}

ErrorCode

@Getter
@AllArgsConstructor
public enum ErrorCode {
    USER_NOT_FOUND("사용자가 존재하지 않습니다.");

    private final String description;
}

 

'Project' 카테고리의 다른 글

[Toss] 계좌 해제(1)  (0) 2023.08.21
[Toss] 계좌 생성(4)  (0) 2023.08.21
[Toss] 계좌 생성(3)  (0) 2023.08.18
[Toss] 계좌 생성(1)  (0) 2023.08.17
[Toss] 설계 및 기본 구조  (0) 2023.08.17