feat(account): 대출 계좌 loan_amount/loan_rate/loan_method/loan_months/loan_start 필드 추가
- wallet 테이블: loan_amount(실행금액), loan_rate(연이자율%), loan_method(상환방식), loan_months(기간), loan_start(시작일) ALTER TABLE 추가 - Wallet 도메인/DTO/Mapper/Service 동기화 - WalletResponse.from()에 대출 필드 반영 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
24e235404b
commit
947c7a1f68
@@ -6,6 +6,7 @@ import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@@ -29,6 +30,11 @@ public class Wallet implements Serializable {
|
||||
private Long openingBalance; // 초기 잔액(부호있음: 자산+, 부채-)
|
||||
private LocalDate openingDate;
|
||||
private Long currentValue; // 현재 평가금액 (INVEST 전용, 수동 갱신)
|
||||
private Long loanAmount; // 대출 실행 금액(원금, 처음 빌린 금액) (LOAN 전용)
|
||||
private BigDecimal loanRate; // 연이자율(%) e.g. 5.25 (LOAN 전용)
|
||||
private String loanMethod; // 상환방식: EQUAL_PAYMENT / EQUAL_PRINCIPAL / BULLET (LOAN 전용)
|
||||
private Integer loanMonths; // 대출기간(개월) (LOAN 전용)
|
||||
private LocalDate loanStart; // 대출시작일 (LOAN 전용)
|
||||
private Integer sortOrder; // 표시 순서 (타입 내 정렬)
|
||||
private LocalDateTime createdAt;
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package com.sb.web.account.dto;
|
||||
|
||||
import jakarta.validation.constraints.DecimalMax;
|
||||
import jakarta.validation.constraints.DecimalMin;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.Pattern;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
@@ -37,4 +40,17 @@ public class WalletRequest {
|
||||
|
||||
/** 현재 평가금액 (INVEST 전용, 수동 갱신) */
|
||||
private Long currentValue;
|
||||
|
||||
// ===== 대출(LOAN) 전용 =====
|
||||
private Long loanAmount; // 대출 실행 금액(원금)
|
||||
|
||||
@DecimalMin(value = "0.0", inclusive = true)
|
||||
@DecimalMax(value = "100.0", message = "이자율은 100% 이하여야 합니다.")
|
||||
private BigDecimal loanRate; // 연이자율(%)
|
||||
|
||||
@Pattern(regexp = "EQUAL_PAYMENT|EQUAL_PRINCIPAL|BULLET|", message = "상환방식이 올바르지 않습니다.")
|
||||
private String loanMethod; // 상환방식
|
||||
|
||||
private Integer loanMonths; // 대출기간(개월)
|
||||
private LocalDate loanStart; // 대출시작일
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.sb.web.account.domain.Wallet;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
@@ -31,6 +32,13 @@ public class WalletResponse {
|
||||
private Long currentValue; // 평가액 직접입력값(퇴직연금·연금 등 수동 갱신). 있으면 총평가로 사용
|
||||
private Boolean manualValuation; // true면 평가액 직접입력형(종목 자동계산 대신)
|
||||
|
||||
// 대출(LOAN) 전용
|
||||
private Long loanAmount; // 대출 실행 금액(원금)
|
||||
private BigDecimal loanRate; // 연이자율(%) e.g. 5.25
|
||||
private String loanMethod; // EQUAL_PAYMENT / EQUAL_PRINCIPAL / BULLET
|
||||
private Integer loanMonths; // 대출기간(개월)
|
||||
private LocalDate loanStart; // 대출시작일
|
||||
|
||||
public static WalletResponse from(Wallet w, long balance) {
|
||||
return WalletResponse.builder()
|
||||
.id(w.getId())
|
||||
@@ -43,6 +51,11 @@ public class WalletResponse {
|
||||
.openingDate(w.getOpeningDate())
|
||||
.balance(balance)
|
||||
.currentValue(w.getCurrentValue())
|
||||
.loanAmount(w.getLoanAmount())
|
||||
.loanRate(w.getLoanRate())
|
||||
.loanMethod(w.getLoanMethod())
|
||||
.loanMonths(w.getLoanMonths())
|
||||
.loanStart(w.getLoanStart())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -535,6 +535,12 @@ public class AccountService {
|
||||
wallet.setOpeningBalance(req.getOpeningBalance() != null ? req.getOpeningBalance() : 0L);
|
||||
wallet.setOpeningDate(req.getOpeningDate());
|
||||
wallet.setCurrentValue("INVEST".equals(req.getType()) ? req.getCurrentValue() : null);
|
||||
boolean isLoan = "LOAN".equals(req.getType());
|
||||
wallet.setLoanAmount(isLoan ? req.getLoanAmount() : null);
|
||||
wallet.setLoanRate(isLoan ? req.getLoanRate() : null);
|
||||
wallet.setLoanMethod(isLoan ? blankToNull(req.getLoanMethod()) : null);
|
||||
wallet.setLoanMonths(isLoan ? req.getLoanMonths() : null);
|
||||
wallet.setLoanStart(isLoan ? req.getLoanStart() : null);
|
||||
walletMapper.update(wallet);
|
||||
return WalletResponse.from(wallet, balanceMap(memberId).getOrDefault(id, wallet.getOpeningBalance()));
|
||||
}
|
||||
@@ -564,6 +570,7 @@ public class AccountService {
|
||||
}
|
||||
|
||||
private Wallet toWallet(WalletRequest req) {
|
||||
boolean isLoan = "LOAN".equals(req.getType());
|
||||
return Wallet.builder()
|
||||
.type(req.getType())
|
||||
.name(req.getName().trim())
|
||||
@@ -573,6 +580,11 @@ public class AccountService {
|
||||
.openingBalance(req.getOpeningBalance() != null ? req.getOpeningBalance() : 0L)
|
||||
.openingDate(req.getOpeningDate())
|
||||
.currentValue("INVEST".equals(req.getType()) ? req.getCurrentValue() : null)
|
||||
.loanAmount(isLoan ? req.getLoanAmount() : null)
|
||||
.loanRate(isLoan ? req.getLoanRate() : null)
|
||||
.loanMethod(isLoan ? blankToNull(req.getLoanMethod()) : null)
|
||||
.loanMonths(isLoan ? req.getLoanMonths() : null)
|
||||
.loanStart(isLoan ? req.getLoanStart() : null)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user