Merge branch 'dev'
Deploy / deploy (push) Failing after 11m55s
CI / build (push) Failing after 13m43s

This commit is contained in:
ByungCheol
2026-06-12 22:52:23 +09:00
2 changed files with 23 additions and 4 deletions
@@ -8,7 +8,7 @@ import lombok.Data;
import java.time.LocalDate;
/**
* 대출/카드 상환·납부 요청. 원금은 이체, 이자는 지출로 분리 생성된다.
* 대출/카드 상환·납부 요청. 원금은 이체, 이자·연회비는 지출로 분리 생성된다.
*/
@Data
public class RepaymentRequest {
@@ -28,6 +28,9 @@ public class RepaymentRequest {
@PositiveOrZero(message = "이자는 0 이상이어야 합니다.")
private Long interest;
@PositiveOrZero(message = "연회비는 0 이상이어야 합니다.")
private Long annualFee;
@Size(max = 255, message = "메모는 255자 이내여야 합니다.")
private String memo;
}
@@ -292,13 +292,14 @@ public class AccountService {
/* ===================== 상환/납부 ===================== */
/** 대출/카드 상환·납부: 원금은 이체(부채↓), 이자는 지출로 분리해 2건 생성 */
/** 대출/카드 상환·납부: 원금은 이체(부채↓), 이자·연회비는 지출로 분리 생성 */
@Transactional
public void repay(RepaymentRequest req, Long memberId) {
long principal = req.getPrincipal() != null ? req.getPrincipal() : 0L;
long interest = req.getInterest() != null ? req.getInterest() : 0L;
if (principal <= 0 && interest <= 0) {
throw new ApiException(HttpStatus.BAD_REQUEST, "원금 또는 이자를 입력하세요.");
long annualFee = req.getAnnualFee() != null ? req.getAnnualFee() : 0L;
if (principal <= 0 && interest <= 0 && annualFee <= 0) {
throw new ApiException(HttpStatus.BAD_REQUEST, "원금·이자·연회비 중 하나는 입력하세요.");
}
requireOwnedWallet(req.getFromWalletId(), memberId);
Wallet target = walletMapper.findByIdAndMember(req.getTargetWalletId(), memberId);
@@ -308,6 +309,9 @@ public class AccountService {
if (!"LOAN".equals(target.getType()) && !"CARD".equals(target.getType())) {
throw new ApiException(HttpStatus.BAD_REQUEST, "상환 대상은 대출/카드만 가능합니다.");
}
if (annualFee > 0 && !"CARD".equals(target.getType())) {
throw new ApiException(HttpStatus.BAD_REQUEST, "연회비는 카드 상환에만 입력할 수 있습니다.");
}
if (req.getFromWalletId().equals(req.getTargetWalletId())) {
throw new ApiException(HttpStatus.BAD_REQUEST, "출금/대상 계좌가 같을 수 없습니다.");
}
@@ -336,6 +340,18 @@ public class AccountService {
.memo(req.getMemo() != null ? req.getMemo() : "이자")
.build());
}
// 연회비: 지출 (카드, 출금 계좌에서, 분류=연회비)
if (annualFee > 0) {
mapper.insert(AccountEntry.builder()
.memberId(memberId)
.entryDate(req.getEntryDate())
.type("EXPENSE")
.category("연회비")
.amount(annualFee)
.walletId(req.getFromWalletId())
.memo(req.getMemo() != null ? req.getMemo() : "연회비")
.build());
}
}
/* ===================== 계좌/카드 (사용자별) ===================== */