diff --git a/src/main/java/com/moneymong/domain/ledger/api/response/report/LedgerReportResponse.java b/src/main/java/com/moneymong/domain/ledger/api/response/report/LedgerReportResponse.java index b45c69c..8449a06 100644 --- a/src/main/java/com/moneymong/domain/ledger/api/response/report/LedgerReportResponse.java +++ b/src/main/java/com/moneymong/domain/ledger/api/response/report/LedgerReportResponse.java @@ -54,7 +54,8 @@ public record CategoryReport( String name, Integer income, Integer expense, - Double share + Double incomeShare, + Double expenseShare ) { } } diff --git a/src/main/java/com/moneymong/domain/ledger/service/reader/LedgerReportReader.java b/src/main/java/com/moneymong/domain/ledger/service/reader/LedgerReportReader.java index d040c4f..4610825 100644 --- a/src/main/java/com/moneymong/domain/ledger/service/reader/LedgerReportReader.java +++ b/src/main/java/com/moneymong/domain/ledger/service/reader/LedgerReportReader.java @@ -50,15 +50,19 @@ public LedgerReportResponse getReport( // 해당 agency의 모든 ledger details 조회 List allDetails = ledgerDetailRepository.findAllByAgencyId(agencyId); + // 장부 전체 기간 합계 (응답의 totalIncome/totalExpense/totalBalance, 비율 계산 분모) + int totalIncome = calculateTotalByFundType(allDetails, FundType.INCOME); + int totalExpense = calculateTotalByFundType(allDetails, FundType.EXPENSE); + int totalBalance = totalIncome - totalExpense; + // 기간 필터링 List filteredDetails = filterByPeriod(allDetails, startYear, startMonth, endYear, endMonth); - // 총 수입/지출 계산 - int totalIncome = calculateTotalByFundType(filteredDetails, FundType.INCOME); - int totalExpense = calculateTotalByFundType(filteredDetails, FundType.EXPENSE); - int totalBalance = totalIncome - totalExpense; + // 요청 기간 합계 (멤버별 share 계산용 - 기간 내 비율 의미 유지) + int periodIncome = calculateTotalByFundType(filteredDetails, FundType.INCOME); + int periodExpense = calculateTotalByFundType(filteredDetails, FundType.EXPENSE); - // 월별 집계 + // 월별 집계 (share 분모: 장부 전체 기간 합계) List monthlyReports = generateMonthlyReports( filteredDetails, startYear, startMonth, @@ -67,11 +71,11 @@ public LedgerReportResponse getReport( totalExpense ); - // 멤버별 집계 - List memberReports = generateMemberReports(filteredDetails, totalIncome, totalExpense); + // 멤버별 집계 (share 분모: 요청 기간 합계) + List memberReports = generateMemberReports(filteredDetails, periodIncome, periodExpense); - // 카테고리별 집계 - List categoryReports = generateCategoryReports(filteredDetails); + // 카테고리별 집계 (share 분모: 장부 전체 기간 합계) + List categoryReports = generateCategoryReports(filteredDetails, totalIncome, totalExpense); return LedgerReportResponse.builder() .agencyId(agencyId) @@ -219,8 +223,11 @@ private List generateMemberReports( .collect(Collectors.toList()); } - private List generateCategoryReports(List details) { - // 수입/지출 분리하여 처리 + private List generateCategoryReports( + List details, + int totalIncome, + int totalExpense + ) { Map incomeByCategory = new HashMap<>(); Map expenseByCategory = new HashMap<>(); @@ -236,11 +243,6 @@ private List generateCategoryReports(List details) } } - // 총 수입과 지출 계산 - int totalIncome = incomeByCategory.values().stream().mapToInt(Integer::intValue).sum(); - int totalExpense = expenseByCategory.values().stream().mapToInt(Integer::intValue).sum(); - - // 모든 카테고리 수집 Set allCategories = new HashSet<>(); allCategories.addAll(incomeByCategory.keySet()); allCategories.addAll(expenseByCategory.keySet()); @@ -250,21 +252,15 @@ private List generateCategoryReports(List details) int income = incomeByCategory.getOrDefault(categoryName, 0); int expense = expenseByCategory.getOrDefault(categoryName, 0); - // share는 수입이 있으면 전체 수입 대비, 지출이 있으면 전체 지출 대비 - double share; - if (income > 0 && totalIncome > 0) { - share = (double) income / totalIncome; - } else if (expense > 0 && totalExpense > 0) { - share = (double) expense / totalExpense; - } else { - share = 0.0; - } + double incomeShare = totalIncome > 0 ? (double) income / totalIncome : 0.0; + double expenseShare = totalExpense > 0 ? (double) expense / totalExpense : 0.0; return CategoryReport.builder() .name(categoryName) .income(income) .expense(expense) - .share(share) + .incomeShare(incomeShare) + .expenseShare(expenseShare) .build(); }) .sorted(Comparator.comparing(CategoryReport::name))