Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import tamtam.mooney.domain.transaction.dto.MonthlyTransactionDayUnitDto;
import tamtam.mooney.domain.transaction.dto.ExpenseAddRequestDto;
import tamtam.mooney.domain.transaction.dto.IncomeAddRequestDto;
import tamtam.mooney.domain.transaction.dto.MonthlyTransactionResponseDto;
import tamtam.mooney.domain.transaction.dto.*;
import tamtam.mooney.domain.transaction.service.ExpenseDataLoader;
import tamtam.mooney.domain.transaction.service.ExpenseService;
import tamtam.mooney.domain.transaction.service.IncomeService;
Expand All @@ -30,7 +27,6 @@ public class TransactionController {
private final TransactionService transactionService;
private final ExpenseService expenseService;
private final IncomeService incomeService;
private final ExpenseDataLoader expenseDataLoader;

@Operation(summary = "지출 내역 추가")
@PostMapping("/expenses")
Expand All @@ -39,6 +35,13 @@ public ResponseEntity<String> createExpense(@RequestBody @Valid ExpenseAddReques
return ResponseEntity.ok(category);
}

@Operation(summary = "지출 내역 추가 w.카테고리")
@PostMapping("/expenses/category")
public ResponseEntity<String> createExpenseWithCategory(@RequestBody @Valid ExpenseWithCategoryAddRequestDto request) {
String category = expenseService.createExpenseWithCategory(request);
return ResponseEntity.ok(category);
}

@Operation(summary = "지출 내역 여러 건 추가")
@PostMapping("/expenses-multiple")
public ResponseEntity<Void> createMultipleExpenses(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package tamtam.mooney.domain.transaction.dto;

import java.time.LocalDateTime;

public interface BaseExpenseRequest {
String payee();
long amount();
LocalDateTime transactionTime();
String transactionSource();
String sourceApp();
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,16 @@
package tamtam.mooney.domain.transaction.dto;

import jakarta.validation.constraints.NotNull;
import tamtam.mooney.global.exception.CustomException;
import tamtam.mooney.global.exception.ErrorCode;

import java.time.LocalDateTime;

public record ExpenseAddRequestDto(
@NotNull(message = "Amount is required")
Long amount,
long amount,
@NotNull(message = "Transaction time is required")
LocalDateTime transactionTime,
String transactionSource,
String sourceApp,
@NotNull(message = "Payee is required")
String payee
) {
public ExpenseAddRequestDto {
// 금액 검증 (0 이상이어야 함)
if (amount != null && amount < 0) {
throw new CustomException(ErrorCode.INVALID_INPUT_VALUE);
}
}
}
) implements BaseExpenseRequest { }

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package tamtam.mooney.domain.transaction.dto;

import jakarta.validation.constraints.NotNull;
import tamtam.mooney.domain.enums.ExpenseCategory;

import java.time.LocalDateTime;

public record ExpenseWithCategoryAddRequestDto(
long amount,
@NotNull(message = "Transaction time is required")
LocalDateTime transactionTime,
String transactionSource,
String sourceApp,
@NotNull(message = "Payee is required")
String payee,
ExpenseCategory expenseCategory
) implements BaseExpenseRequest {
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tamtam.mooney.domain.mission.repository.MissionRepository;
import tamtam.mooney.domain.mission.service.MissionService;
import tamtam.mooney.domain.transaction.dto.BaseExpenseRequest;
import tamtam.mooney.domain.transaction.dto.ExpenseAddRequestDto;
import tamtam.mooney.domain.transaction.dto.ExpenseWithCategoryAddRequestDto;
import tamtam.mooney.domain.transaction.entity.Expense;
import tamtam.mooney.domain.enums.ExpenseCategory;
import tamtam.mooney.domain.transaction.repository.ExpenseRepository;
Expand All @@ -30,20 +31,31 @@ public class ExpenseService {
private final ExpenseRepository expenseRepository;
private final UserService userService;
// private final LlmCategoryClassifier llmCategoryClassifier;
private final MissionRepository missionRepository;
private final MissionService missionService;

// 지출 추가
// 지출 추가 (카테고리 예측)
public String createExpense(ExpenseAddRequestDto request) {
User user = userService.getCurrentUser();
String predicted = "FOOD"; //llmCategoryClassifier.classifyCategory(request.payee(), true);
ExpenseCategory category = ExpenseCategory.valueOf(predicted);
return saveAndReturnCategory(request, user, category);
}

// String predictedCategory = llmCategoryClassifier.classifyCategory(request.payee(), true);
String predictedCategory = ExpenseCategory.FOOD.name();
ExpenseCategory expenseCategory = ExpenseCategory.valueOf(predictedCategory);
// 지출 추가 (카테고리 직접 지정)
public String createExpenseWithCategory(ExpenseWithCategoryAddRequestDto request) {
User user = userService.getCurrentUser();
return saveAndReturnCategory(request, user, request.expenseCategory());
}

// ——— private 헬퍼 메서드 ———
private <T extends BaseExpenseRequest> String saveAndReturnCategory(
T request,
User user,
ExpenseCategory category
) {
Expense expense = Expense.builder()
.payee(request.payee())
.expenseCategory(expenseCategory)
.expenseCategory(category)
.amount(request.amount())
.transactionTime(request.transactionTime())
.transactionSource(request.transactionSource())
Expand All @@ -52,11 +64,8 @@ public String createExpense(ExpenseAddRequestDto request) {
.build();

transactionRepository.save(expense);

//들어온 지출의 payee가 현재 진행중인 미션 place에 해당된다면 missionRepo에 save
missionService.updateMission(user, request.payee(),request.amount());

return expense.getExpenseCategory().name();
missionService.updateMission(user, request.payee(), request.amount());
return category.name();
}

@Transactional(readOnly = true)
Expand Down
Loading