본문 바로가기
BackEnd/Project

[Loan] Ch05. 대출 집행 수정 기능 구현

by 개발 Blog 2024. 9. 13.

공부 내용을 정리하고 앞으로의 학습에 이해를 돕기 위해 작성합니다.

 

이번 시간에는 대출 집행 내역을 수정하는 기능을 구현한다. 대출 집행이 완료된 이후, 집행 금액을 수정해야 하는 상황이 발생할 수 있다. 이를 위해 특정 대출 집행에 대한 금액 수정 및 해당 금액에 따른 잔고 업데이트를 처리하는 기능을 구현한다.

1. InternalController에 메서드 추가

대출 집행 내역을 수정하는 API를 InternalController에 추가하였다. PUT /internal/applications/entries/{entryId} 경로를 통해 대출 집행 ID와 수정할 금액을 요청받아, 해당 집행 내역을 수정하고 반영하는 로직을 처리한다.

@PutMapping("/entries/{entryId}")
public ResponseDTO<UpdateResponse> update(@PathVariable Long entryId, @RequestBody Request request) {
    return ok(entryService.update(entryId, request));
}

2. BalanceDTO에 클래스 추가

대출 집행 금액이 변경되면 그에 따라 잔고(balance)도 업데이트해야 한다. 이를 위해 BalanceDTO에 UpdateRequest 클래스를 추가하였다. 이 클래스는 대출 신청 ID, 수정 전 금액, 수정 후 금액을 포함하며, 잔고 계산에 필요한 데이터를 전달하는 역할을 한다.

@NoArgsConstructor
@AllArgsConstructor
@Builder
@Getter
@Service
public static class UpdateRequest{

    private Long applicationId;

    private BigDecimal beforeEntryAmount;

    private BigDecimal afterEntryAmount;
}

3. EntryDTO에 클래스 추가

수정된 대출 집행 내역을 반환하기 위해 EntryDTO에 UpdateResponse 클래스를 추가하였다. 이 클래스는 대출 집행 ID, 대출 신청 ID, 수정 전 금액, 수정 후 금액을 포함하며, 수정된 집행 정보를 응답으로 반환하는 데 사용된다.

@NoArgsConstructor
@AllArgsConstructor
@Builder
@Getter
@Setter
public static class UpdateResponse{

    private Long entryId;

    private Long applicationId;

    private BigDecimal beforeEntryAmount;

    private BigDecimal afterEntryAmount;

}

4. BalanceService에 메서드 추가

BalanceService에 잔고 업데이트를 처리하는 메서드를 추가하였다. 대출 집행 금액이 변경되면 잔고도 그에 따라 수정되어야 한다. 수정 전 금액을 잔고에서 차감하고, 수정 후 금액을 다시 잔고에 더하는 방식으로 잔고를 업데이트한다.

Response update(Long applicationId, UpdateRequest request);

5. EntryService에 메서드 추가

EntryService에 대출 집행 내역을 수정하는 메서드를 추가하였다. 해당 메서드는 수정하려는 대출 집행 ID를 받아서 기존 집행 금액을 수정하고, 그에 따른 잔고 업데이트를 함께 처리한다.

UpdateResponse update(Long entryId, Request request);

 

6. BalanceServiceImpl 및 EntryServiceImpl에 수정 로직 추가

대출 집행 내역을 수정하는 핵심 로직은 BalanceServiceImpl과 EntryServiceImpl에 구현된다.

 

EntryServiceImpl은 대출 집행 내역을 수정하는 로직을 담당한다. 이 과정에서 가장 먼저 해야 할 일은 수정하고자 하는 대출 집행 정보를 데이터베이스에서 조회하는 것이다.

@Override
public UpdateResponse update(Long entryId, Request request) {
    // entry
    Entry entry = entryRepository.findById(entryId).orElseThrow(() -> {
        throw new BaseException(ResultType.SYSTEM_ERROR);
    });

    // before -> after
    BigDecimal beforeEntryAmount = entry.getEntryAmount();
    entry.setEntryAmount(request.getEntryAmount());

    entryRepository.save(entry);

    // balance update
    Long applicationId = entry.getApplicationId();
    balanceService.update(applicationId, UpdateRequest.builder()
            .beforeEntryAmount(beforeEntryAmount)
            .afterEntryAmount(request.getEntryAmount())
            .build());
    // response
    return UpdateResponse.builder()
            .entryId(entryId)
            .applicationId(applicationId)
            .beforeEntryAmount(beforeEntryAmount)
            .afterEntryAmount(request.getEntryAmount())
            .build();
}
  • 대출 집행 조회: 대출 집행 ID로 EntryRepository를 통해 해당 Entry 객체를 조회한다. 만약 조회된 데이터가 없을 경우, 예외가 발생한다.
  • 금액 수정: 기존에 기록된 entryAmount(집행 금액)를 수정 요청에서 전달된 새로운 금액으로 업데이트한다.
  • 잔고 수정 호출: 대출 집행 금액이 변경되면, 그에 따라 잔고도 업데이트되어야 하므로 balanceService.update() 메서드를 호출하여 잔고 변동을 처리한다.

BalanceServiceImpl은 변경된 대출 집행 금액에 맞춰 대출 잔고를 수정하는 역할을 한다.

@Override
public Response update(Long applicationId, UpdateRequest request) {

    // balance
    Balance balance = balanceRepository.findByApplicationId(applicationId).orElseThrow(() -> {
        throw new BaseException(ResultType.SYSTEM_ERROR);
    });

    BigDecimal beforeEntryAmount = request.getBeforeEntryAmount();
    BigDecimal afterEntryAmount = request.getAfterEntryAmount();
    BigDecimal updatedBalance = balance.getBalance();

    updatedBalance = updatedBalance.subtract(beforeEntryAmount).add(afterEntryAmount);
    balance.setBalance(updatedBalance);

    Balance updated = balanceRepository.save(balance);

    // as-id -> to-be
    return modelMapper.map(updated, Response.class);
}
  • 잔고 조회: 먼저 applicationId를 기반으로 BalanceRepository에서 잔고 정보를 조회한다. 만약 해당 대출 신청에 대한 잔고 정보가 없다면 예외를 발생시킨다.
  • 잔고 계산: 잔고 수정 과정에서는 두 가지 금액이 사용된다. 수정 전 집행 금액(beforeEntryAmount)을 기존 잔고에서 차감한 후, 수정 후 집행 금액(afterEntryAmount)을 새로 더하는 방식으로 잔고를 업데이트한다. 이를 통해 변경된 집행 금액이 잔고에 반영된다.
  • 저장: 수정된 잔고는 다시 데이터베이스에 저장된다. 최종적으로 수정된 잔고 객체가 반환된다.

전체적인 흐름

  • 수정 전 금액 차감: 기존의 집행 금액을 잔고에서 차감한다.
  • 수정 후 금액 추가: 새로운 집행 금액을 잔고에 반영한다.
  • 일관성 유지: 수정된 대출 집행 금액과 그에 맞춘 잔고가 항상 일관되게 유지되도록 보장한다.

7. 실행 테스트 

대출 집행 수정 기능을 구현한 후, 테스트를 통해 기능이 정상적으로 동작하는지 확인하였다. 이번 테스트에서는 대출 집행 내역을 먼저 조회하고, 그 금액을 수정한 뒤, 잔고와 집행 금액이 정상적으로 반영되는지 확인하였다.

 

1) 대출 집행 정보 조회

먼저, 기존의 대출 집행 정보를 조회하기 위해 GET /internal/applications/1/entries 경로로 API를 호출했다. 응답 결과로 대출 집행 금액 5,000,000원이 반환되었다.

 

2)  대출 집행 정보 수정

그 후, 기존 집행 금액을 5,000,000원에서 3,000,000원으로 수정하기 위해 PUT /internal/applications/entries/1 경로로 요청을 보냈다. 응답 결과로 수정 전 금액과 수정 후 금액이 정상적으로 반환되었다.

3) 데이터베이스 확인

로그를 통해 entry 테이블과 balance 테이블에서 금액이 성공적으로 수정된 것을 확인할 수 있었다.

  • entry 테이블: 수정된 entryAmount(3,000,000원)가 반영되었고, 업데이트 시간도 함께 기록되었다.
  • balance 테이블: 기존 금액에서 5,000,000원을 차감하고 3,000,000원을 더해 잔고가 업데이트되었다.

테스트를 통해 대출 집행 수정 기능이 정상적으로 작동함을 확인하였다. 기존 집행 금액이 수정되었고, 잔고 또한 정확하게 반영되었다.